JAPAn
Just Another Parity Analyzer
Loading...
Searching...
No Matches
QwLinearDiodeArray.cc
Go to the documentation of this file.
1/**********************************************************\
2* File: QwLinearDiodeArray.cc *
3* *
4* Author: B. Waidyawansa *
5* Time-stamp: 09-14-2010 *
6\**********************************************************/
7
9
10// System headers
11#include <stdexcept>
12
13// ROOT headers for RNTuple support
14#ifdef HAS_RNTUPLE_SUPPORT
15#include <ROOT/RNTupleModel.hxx>
16#include <ROOT/RNTupleWriter.hxx>
17#endif // HAS_RNTUPLE_SUPPORT
18
19// Qweak headers
20#include "QwParameterFile.h"
21#ifdef __USE_DATABASE__
22#include "QwDBInterface.h"
23#endif // __USE_DATABASE__
24
26
27/*Individual pads of the linear array*/
28const TString QwLinearDiodeArray::subelement[8]={"p1","p2","p3","p4","p5","p6","p7","p8"};
29
30/* Pad size in mm*/
32
33/**
34 * \brief Initialize this linear diode array with a detector name.
35 * \param name Detector name used for subchannel naming.
36 */
38{
39
40 Int_t i=0;
41 Bool_t localdebug = kFALSE;
43
44 for(i=0;i<8;i++) {
45 fPhotodiode[i].InitializeChannel(name+subelement[i],"raw");
46
47 if(localdebug)
48 std::cout<<" photodiode ["<<i<<"]="<<fPhotodiode[i].GetElementName()<<"\n";
49 }
50
51
52 fEffectiveCharge.InitializeChannel(name+"WS","derived");
53
54 // We don't initialize the photodiode channels yet.
55 fRelPos[0].InitializeChannel(name+"RelMean","derived");
56 fRelPos[1].InitializeChannel(name+"RelVariance","derived");
57
58 bFullSave=kTRUE;
59
60 return;
61}
62
63/**
64 * \brief Initialize this linear diode array with subsystem and name.
65 * \param subsystem Subsystem identifier.
66 * \param name Detector name used for subchannel naming.
67 */
68void QwLinearDiodeArray::InitializeChannel(TString subsystem, TString name)
69{
70
71 Int_t i=0;
72 Bool_t localdebug = kFALSE;
73
75
76 for(i=0;i<8;i++) {
77 fPhotodiode[i].InitializeChannel(subsystem, "QwLinearDiodeArray", name+subelement[i],"raw");
78 if(localdebug)
79 std::cout<<" photodiode ["<<i<<"]="<<fPhotodiode[i].GetElementName()<<"\n";
80 }
81
82 fEffectiveCharge.InitializeChannel(subsystem, "QwLinearDiodeArray", name+"WS","derived");
83
84 // We don't initialize the photodiode channels yet.
85
86 fRelPos[0].InitializeChannel(subsystem, "QwLinearDiodeArray", name+"RelMean","derived");
87 fRelPos[1].InitializeChannel(subsystem, "QwLinearDiodeArray", name+"RelVariance","derived");
88
89 bFullSave=kTRUE;
90
91 return;
92}
93
94/** \brief Clear event-scoped data for all pads and derived channels. */
96{
97 size_t i=0;
98
99 for(i=0;i<8;i++) fPhotodiode[i].ClearEventData();
100
101 for(i=kXAxis;i<kNumAxes;i++){
102 fRelPos[i].ClearEventData();
103 }
104 fEffectiveCharge.ClearEventData();
105
106 return;
107}
108
109
110/**
111 * \brief Apply hardware checks for all photodiode pads.
112 * \return kTRUE if no hardware error was detected; otherwise kFALSE.
113 */
115{
116 Bool_t eventokay=kTRUE;
117
118 UInt_t deviceerror=0;
119 for(size_t i=0;i<8;i++)
120 {
121 deviceerror|= fPhotodiode[i].ApplyHWChecks(); //OR the error code from each wire
122 eventokay &= (deviceerror & 0x0);//AND with 0 since zero means HW is good.
123
124 if (bDEBUG) std::cout<<" Inconsistent within LinearArray terminals photodiode[ "<<i<<" ] "<<std::endl;
125 if (bDEBUG) std::cout<<" photodiode[ "<<i<<" ] sequence num "<<fPhotodiode[i].GetSequenceNumber()<<" sample size "<<fPhotodiode[i].GetNumberOfSamples()<<std::endl;
126 }
127
128 return eventokay;
129}
130
131/** \brief Increment error counters for all internal channels. */
133{
134 size_t i=0;
135 for(i=0;i<8;i++) fPhotodiode[i].IncrementErrorCounters();
136 for(i=kXAxis;i<kNumAxes;i++) {
137 fRelPos[i].IncrementErrorCounters();
138 }
139 fEffectiveCharge.IncrementErrorCounters();
140}
141
142/** \brief Print error counters for all internal channels. */
144{
145 size_t i=0;
146 for(i=0;i<8;i++) fPhotodiode[i].PrintErrorCounters();
147 for(i=kXAxis;i<kNumAxes;i++) {
148 fRelPos[i].PrintErrorCounters();
149 }
150 fEffectiveCharge.PrintErrorCounters();
151}
152
153/** \brief Aggregate and return the event-cut error flag for this array. */
155{
156 size_t i=0;
157 UInt_t error=0;
158 for(i=0;i<8;i++) error|=fPhotodiode[i].GetEventcutErrorFlag();
159 for(i=kXAxis;i<kNumAxes;i++) {
160 error|=fRelPos[i].GetEventcutErrorFlag();
161 }
162 error|=fEffectiveCharge.GetEventcutErrorFlag();
163
164 return error;
165}
166
167/** \brief Update and return the aggregated event-cut error flag. */
169{
170 size_t i=0;
171 UInt_t error1=0;
172 UInt_t error2=0;
173 for(i=0;i<8;i++){
174 error1|=fPhotodiode[i].GetErrorCode();
175 error2|=fPhotodiode[i].GetEventcutErrorFlag();
176 }
177 for(i=kXAxis;i<kNumAxes;i++) {
178 fRelPos[i].UpdateErrorFlag(error1);
179 error2|=fRelPos[i].GetEventcutErrorFlag();
180 }
181 fEffectiveCharge.UpdateErrorFlag(error1);
182 error2|=fEffectiveCharge.GetEventcutErrorFlag();
183 return error2;
184}
185
186/**
187 * \brief Apply single-event cuts across photodiodes and derived channels.
188 * \return kTRUE if the event passes all configured cuts; otherwise kFALSE.
189 */
191{
192 Bool_t status=kTRUE;
193 size_t i=0;
194 UInt_t error_code = 0;
195 //Event cuts for four wires
196 for(i=0;i<8;i++){
198 status&=kTRUE;
199 }
200 else{
201 status&=kFALSE;
202 if (bDEBUG) std::cout<<" array ["<<i<<"] event cut failed ";
203 }
204 //Get the Event cut error flag for wires
205 error_code|=fPhotodiode[i].GetErrorCode();
206 }
207
208 //Event cuts for Relative X & Y
209 for(i=kXAxis;i<kNumAxes;i++){
210 fRelPos[i].UpdateErrorFlag(error_code);//To update the event cut failed error code from the channels/wires error codes
211 if (fRelPos[i].ApplySingleEventCuts()){ //for RelX
212 status&=kTRUE;
213 }
214 else{
215 status&=kFALSE;
216 if (bDEBUG) std::cout<<" Rel X event cut failed ";
217 }
218 }
219
220 //Event cuts for four wire sum (EffectiveCharge)
221 fEffectiveCharge.UpdateErrorFlag(error_code);//To update the eff-charge error code from the channels/wires event cut error codes
222 if (fEffectiveCharge.ApplySingleEventCuts()){
223 status&=kTRUE;
224 }
225 else{
226 status&=kFALSE;
227 if (bDEBUG) std::cout<<"EffectiveCharge event cut failed ";
228 }
229 return status;
230}
231
232
233/**
234 * \brief Resolve an internal channel pointer by subelement name.
235 * \param ch_name Subelement symbolic name (e.g., relx, rely, absx, absy).
236 * \return Non-owning pointer to the requested hardware channel.
237 */
239{
240 VQwHardwareChannel* tmpptr = NULL;
241 ch_name.ToLower();
242 if (ch_name=="relx"){
243 tmpptr = &fRelPos[0];
244 }else if (ch_name=="rely"){
245 tmpptr = &fRelPos[1];
246 }else if (ch_name=="absx" || ch_name=="x" ){
247 tmpptr = &fAbsPos[0];
248 }else if (ch_name=="absy" || ch_name=="y"){
249 tmpptr = &fAbsPos[1];
250 }else if (ch_name=="effectivecharge" || ch_name=="charge"){
251 tmpptr = &fEffectiveCharge;
252 } else {
253 TString loc="QwLinearDiodeArray::GetSubelementByName for"
254 + this->GetElementName() + " was passed "
255 + ch_name + ", which is an unrecognized subelement name.";
256 throw std::invalid_argument(loc.Data());
257 }
258 return tmpptr;
259}
260
261/*
262void QwLinearDiodeArray::SetSingleEventCuts(TString ch_name, Double_t minX, Double_t maxX)
263{
264 QwWarning << "QwLinearDiodeArray::SetSingleEventCuts: "
265 << "Does not do anything yet." << QwLog::endl;
266}*/
267
268/**
269 * \brief Configure detailed single-event cuts for a named subelement.
270 * \param ch_name Subelement name.
271 * \param errorflag Device-specific error flag mask to set.
272 * \param minX Lower limit.
273 * \param maxX Upper limit.
274 * \param stability Stability threshold.
275 * \param burplevel Burp detection threshold.
276 */
277void QwLinearDiodeArray::SetSingleEventCuts(TString ch_name, UInt_t errorflag,Double_t minX, Double_t maxX, Double_t stability, Double_t burplevel){
278 errorflag|=kBPMErrorFlag;//update the device flag (Do not have a error flag yet)
279 // QwWarning << "QwLinearDiodeArray::SetSingleEventCuts: " << "Does not do anything yet." << QwLog::endl;
280 if (ch_name=="relx"){
281 QwMessage<<"RelX LL " << minX <<" UL " << maxX <<QwLog::endl;
282 fRelPos[0].SetSingleEventCuts(errorflag,minX,maxX,stability,burplevel);
283
284 }else if (ch_name=="rely"){
285 QwMessage<<"RelY LL " << minX <<" UL " << maxX <<QwLog::endl;
286 fRelPos[1].SetSingleEventCuts(errorflag,minX,maxX,stability,burplevel);
287
288 } else if (ch_name=="effectivecharge"){
289 QwMessage<<"EffectveQ LL " << minX <<" UL " << maxX <<QwLog::endl;
290 fEffectiveCharge.SetSingleEventCuts(errorflag,minX,maxX,stability,burplevel);
291
292 } else if (ch_name=="photodiode"){
293 QwMessage<<"photodiode LL " << minX <<" UL " << maxX <<QwLog::endl;
294 fPhotodiode[1].SetSingleEventCuts(errorflag,minX,maxX,stability,burplevel);
295 }
296}
297
298/**
299 * \brief Check for burp failures against another linear array of same type.
300 * \param ev_error Reference array to compare against.
301 * \return kTRUE if a burp failure was detected; otherwise kFALSE.
302 */
304 Short_t i=0;
305 Bool_t burpstatus = kFALSE;
306 try {
307 if(typeid(*ev_error)==typeid(*this)) {
308 //std::cout<<" Here in QwLinearDiodeArray::CheckForBurpFail \n";
309 if (this->GetElementName()!="") {
310 const QwLinearDiodeArray* value_lin = dynamic_cast<const QwLinearDiodeArray* >(ev_error);
311 for(i=kXAxis;i<kNumAxes;i++) {
312 burpstatus |= fRelPos[i].CheckForBurpFail(&(value_lin->fRelPos[i]));
313 }
314 for(i=0;i<8;i++){
315 burpstatus |= fPhotodiode[i].CheckForBurpFail(&(value_lin->fPhotodiode[i]));
316 }
317 burpstatus |= fEffectiveCharge.CheckForBurpFail(&(value_lin->fEffectiveCharge));
318 }
319 } else {
320 TString loc="Standard exception from QwLinearDiodeArray::CheckForBurpFail :"+
321 ev_error->GetElementName()+" "+this->GetElementName()+" are not of the "
322 +"same type";
323 throw std::invalid_argument(loc.Data());
324 }
325 } catch (std::exception& e) {
326 std::cerr<< e.what()<<std::endl;
327 }
328 return burpstatus;
329};
330
332 Short_t i=0;
333 try {
334 if(typeid(*ev_error)==typeid(*this)) {
335 // std::cout<<" Here in QwQPD::UpdateErrorFlag \n";
336 if (this->GetElementName()!="") {
337 const QwLinearDiodeArray* value_bpm = dynamic_cast<const QwLinearDiodeArray* >(ev_error);
338 for(i=0;i<4;i++){
339 fPhotodiode[i].UpdateErrorFlag(value_bpm->fPhotodiode[i]);
340 }
341 for(i=kXAxis;i<kNumAxes;i++) {
342 fRelPos[i].UpdateErrorFlag(value_bpm->fRelPos[i]);
343 }
344 fEffectiveCharge.UpdateErrorFlag(value_bpm->fEffectiveCharge);
345 }
346 } else {
347 TString loc="Standard exception from QwLinearDiodeArray::UpdateErrorFlag :"+
348 ev_error->GetElementName()+" "+this->GetElementName()+" are not of the "
349 +"same type";
350 throw std::invalid_argument(loc.Data());
351 }
352 } catch (std::exception& e) {
353 std::cerr<< e.what()<<std::endl;
354 }
355};
356
358{
359 Bool_t localdebug = kFALSE;
360 static QwVQWK_Channel mean, meansqr;
361 static QwVQWK_Channel tmp("tmp");
362 static QwVQWK_Channel tmp2("tmp2");
363
364 mean.InitializeChannel("mean","raw");
365 meansqr.InitializeChannel("meansqr","raw");
366
367
368 size_t i = 0;
369
370
372 //first apply HW checks and update HW error flags.
373 // Calling this routine here and not in ApplySingleEventCuts
374 //makes a difference for a LinearArrays because they have derived devices.
375
376 fEffectiveCharge.ClearEventData();
377 for(i=0;i<8;i++){
378 fPhotodiode[i].ProcessEvent();
380 }
381
382
383 // First calculate the mean pad position and mean of squared pad position
384 // with respect to the center of the array, in units of pad spacing.
385 mean.ClearEventData();
386 meansqr.ClearEventData();
387 for (i=0;i<8;i++){
388 Double_t pos = kQwLinearDiodeArrayPadSize*i*0.5;
389 tmp = fPhotodiode[i];
390 tmp.Scale(pos); // Scale for S(i)*pos
391 mean+=tmp;
392 tmp.Scale(pos); // Scale again for S(i)*(pos**2)
393 meansqr+=tmp;
394 }
395 fRelPos[0].Ratio(mean,fEffectiveCharge);
396 tmp = meansqr;
397 meansqr.Ratio(tmp,fEffectiveCharge);
398 tmp2.Product(fRelPos[0], fRelPos[0]);
399
400 // Now calculate the variance
401 fRelPos[1].Difference(meansqr,tmp2);
402
403 if(localdebug){
404 std::cout<<"\n#################"<<std::endl;
405 std::cout<<" LinearArray name="<<fElementName<<std::endl;
406 std::cout<<" Size of the linear array = "<<8<<std::endl;
407 std::cout<<" event number= "<<fPhotodiode[0].GetSequenceNumber()<<std::endl;
408 for(Int_t i = 0; i<8; i++)
409 std::cout<<" pad"<<i<<" ="<<fPhotodiode[i].GetValue()<<std::endl;
410 std::cout<<" mean ="<<fRelPos[0].GetValue()<<std::endl;
411 std::cout<<" variance ="<<fRelPos[1].GetValue()<<std::endl;
412 std::cout<<" total charge ="<<fEffectiveCharge.GetValue()<<std::endl;
413
414 }
415
416 return;
417}
418
419
420Int_t QwLinearDiodeArray::ProcessEvBuffer(UInt_t* buffer, UInt_t word_position_in_buffer,UInt_t index)
421{
422 if(index<8)
423 {
424 fPhotodiode[index].ProcessEvBuffer(buffer,word_position_in_buffer);
425 }
426 else
427 {
428 std::cerr <<
429 "QwLinearDiodeArray::ProcessEvBuffer(): attempt to fill in raw data for a pad that doesn't exist \n";
430 }
431 return word_position_in_buffer;
432}
433
434
435
437{
438 for (size_t i = 0; i < 2; i++) {
439 fRelPos[i].PrintValue();
440 }
441 return;
442}
443
445{
446 size_t i = 0;
447 for (i = 0; i < 8; i++) fPhotodiode[i].PrintInfo();
448 for (i = 0; i < 2; i++) {
449 fAbsPos[i].PrintInfo();
450 }
451 fEffectiveCharge.PrintInfo();
452}
453
454
456{
457 TString thisname;
458 size_t localindex=kInvalidSubelementIndex;
459 if (subindex>-1) localindex = subindex;
460
461 if(localindex<8)
462 thisname=fPhotodiode[subindex].GetElementName();
463 else
464 std::cerr<< "QwLinearDiodeArray::GetSubElementName for "
465 << GetElementName()<<" this subindex, "
466 << subindex << ", doesn't exist \n";
467
468 return thisname;
469}
470
472{
473 size_t localindex=kInvalidSubelementIndex;
474 TString padindex;
475
476 padindex = subname(subname.Sizeof()-2,1);
477 // Interpret the subname as the pad index.
478 if (padindex.IsDigit()){
479 Int_t tmpval = padindex.Atoi();
480 if (tmpval>-1) localindex = tmpval-1;
481 }
482
483 // localindex is unsigned int and always positive
484 if (localindex > kMaxElements){
485 std::cerr << "QwLinearDiodeArray::GetSubElementIndex is unable to associate the string -"
486 <<subname<<"- to any index"<<std::endl;
487 localindex=kInvalidSubelementIndex;
488 }
489 return localindex;
490}
491
493{
494 for(size_t i=kXAxis;i<kNumAxes;i++){
495 fAbsPos[i].AddChannelOffset(fPositionCenter[i]);
496 }
497
498}
499
500
502{
503 *(dynamic_cast<QwLinearDiodeArray*>(this)) =
504 *(dynamic_cast<const QwLinearDiodeArray*>(&value));
505 return *this;
506}
507
509{
510 VQwBPM::operator= (value);
511
512 if (GetElementName()!=""){
513 size_t i = 0;
515 for(i=0;i<8;i++) this->fPhotodiode[i]=value.fPhotodiode[i];
516 for(i=kXAxis;i<kNumAxes;i++) {
517 this->fRelPos[i]=value.fRelPos[i];
518 }
519 }
520 return *this;
521}
522
524{
525 *(dynamic_cast<QwLinearDiodeArray*>(this)) +=
526 *(dynamic_cast<const QwLinearDiodeArray*>(&value));
527 return *this;
528}
529
531{
532
533 if (GetElementName()!=""){
534 size_t i = 0;
536 for(i=0;i<8;i++) this->fPhotodiode[i]+=value.fPhotodiode[i];
537 for(i=kXAxis;i<kNumAxes;i++) {
538 this->fRelPos[i]+=value.fRelPos[i];
539 }
540 }
541 return *this;
542}
543
545{
546 *(dynamic_cast<QwLinearDiodeArray*>(this)) -=
547 *(dynamic_cast<const QwLinearDiodeArray*>(&value));
548 return *this;
549}
550
552{
553
554 if (GetElementName()!=""){
555 size_t i = 0;
557 for(i=0;i<8;i++) this->fPhotodiode[i]-=value.fPhotodiode[i];
558 for(i=kXAxis;i<kNumAxes;i++) {
559 this->fRelPos[i]-=value.fRelPos[i];
560 }
561 }
562 return *this;
563}
564
565
567{
568 // this function is called when forming asymmetries. In this case what we actually want for the
569 // LinearArray is the difference only not the asymmetries
570
571 *this=numer;
572 this->fEffectiveCharge.Ratio(numer.fEffectiveCharge,denom.fEffectiveCharge);
573 return;
574}
575
577{
578 Ratio(*(dynamic_cast<QwLinearDiodeArray*>(&numer)), *(dynamic_cast<QwLinearDiodeArray*>(&denom)));
579}
580
581
582void QwLinearDiodeArray::Scale(Double_t factor)
583{
584 size_t i = 0;
585 fEffectiveCharge.Scale(factor);
586
587 for(i=0;i<8;i++) fPhotodiode[i].Scale(factor);
588 for(i=kXAxis;i<kNumAxes;i++){
589 fRelPos[i].Scale(factor);
590 }
591 return;
592}
593
594
596{
597 size_t i = 0;
598 for(i=0;i<8;i++) fPhotodiode[i].CalculateRunningAverage();
599 for (i = 0; i < 2; i++) fRelPos[i].CalculateRunningAverage();
600 fEffectiveCharge.CalculateRunningAverage();
601 return;
602}
603
604void QwLinearDiodeArray::AccumulateRunningSum(const VQwBPM& value, Int_t count, Int_t ErrorMask){
605 AccumulateRunningSum(*dynamic_cast<const QwLinearDiodeArray* >(&value), count, ErrorMask);
606}
607
608void QwLinearDiodeArray::AccumulateRunningSum(const QwLinearDiodeArray& value, Int_t count, Int_t ErrorMask)
609{
610 size_t i = 0;
611 for(i=0;i<8;i++) fPhotodiode[i].AccumulateRunningSum(value.fPhotodiode[i], count, ErrorMask);
612 for (i = 0; i < 2; i++) fRelPos[i].AccumulateRunningSum(value.fRelPos[i], count, ErrorMask);
613 fEffectiveCharge.AccumulateRunningSum(value.fEffectiveCharge, count, ErrorMask);
614 return;
615}
616
618 DeaccumulateRunningSum(*dynamic_cast<QwLinearDiodeArray* >(&value), ErrorMask);
619}
620
622{
623 size_t i = 0;
624 for(i=0;i<8;i++) fPhotodiode[i].DeaccumulateRunningSum(value.fPhotodiode[i], ErrorMask);
625 for (i = 0; i < 2; i++) fRelPos[i].DeaccumulateRunningSum(value.fRelPos[i], ErrorMask);
626 fEffectiveCharge.DeaccumulateRunningSum(value.fEffectiveCharge, ErrorMask);
627 return;
628}
629
630
631
632void QwLinearDiodeArray::ConstructHistograms(TDirectory *folder, TString &prefix)
633{
634
635 if (GetElementName()=="") {
636 // This channel is not used, so skip filling the histograms.
637 } else {
638 fEffectiveCharge.ConstructHistograms(folder, prefix);
639 TString thisprefix=prefix;
640
641 if(prefix.Contains("asym_"))
642 thisprefix.ReplaceAll("asym_","diff_");
643 SetRootSaveStatus(prefix);
644 size_t i = 0;
645 if(bFullSave) {
646 for(i=0;i<8;i++) fPhotodiode[i].ConstructHistograms(folder, thisprefix);
647 }
648 for(i=kXAxis;i<kNumAxes;i++) {
649 fRelPos[i].ConstructHistograms(folder, thisprefix);
650 }
651 }
652 return;
653}
654
656{
657 if (GetElementName()=="") {
658 // This channel is not used, so skip filling the histograms.
659 }
660 else {
661 fEffectiveCharge.FillHistograms();
662 size_t i = 0;
663 if(bFullSave) {
664 for(i=0;i<8;i++) fPhotodiode[i].FillHistograms();
665 }
666 for(i=kXAxis;i<kNumAxes;i++){
667 fRelPos[i].FillHistograms();
668 }
669 }
670 return;
671}
672
674{
675 if (GetElementName()==""){
676 // This channel is not used, so skip constructing trees.
677 }
678 else {
679 TString thisprefix=prefix;
680 if(prefix.Contains("asym_"))
681 thisprefix.ReplaceAll("asym_","diff_");
682
683 SetRootSaveStatus(prefix);
684
685 fEffectiveCharge.ConstructBranchAndVector(tree,prefix,values);
686 size_t i = 0;
687 if(bFullSave) {
688 for(i=0;i<8;i++) fPhotodiode[i].ConstructBranchAndVector(tree,thisprefix,values);
689 }
690 for(i=kXAxis;i<kNumAxes;i++) {
691 fRelPos[i].ConstructBranchAndVector(tree,thisprefix,values);
692 }
693
694 }
695 return;
696}
697
698void QwLinearDiodeArray::ConstructBranch(TTree *tree, TString &prefix)
699{
700 if (GetElementName()==""){
701 // This channel is not used, so skip constructing trees.
702 }
703 else {
704 TString thisprefix=prefix;
705 if(prefix.Contains("asym_"))
706 thisprefix.ReplaceAll("asym_","diff_");
707
708 SetRootSaveStatus(prefix);
709
710 fEffectiveCharge.ConstructBranch(tree,prefix);
711 size_t i = 0;
712 if(bFullSave) {
713 for(i=0;i<8;i++) fPhotodiode[i].ConstructBranch(tree,thisprefix);
714 }
715 for(i=kXAxis;i<kNumAxes;i++) {
716 fRelPos[i].ConstructBranch(tree,thisprefix);
717 }
718
719 }
720 return;
721}
722
723void QwLinearDiodeArray::ConstructBranch(TTree *tree, TString &prefix, QwParameterFile& modulelist)
724{
725 TString devicename;
726
727 devicename=GetElementName();
728 devicename.ToLower();
729 if (GetElementName()==""){
730 // This channel is not used, so skip filling the histograms.
731 } else
732 {
733 if (modulelist.HasValue(devicename)){
734 TString thisprefix=prefix;
735 if(prefix.Contains("asym_"))
736 thisprefix.ReplaceAll("asym_","diff_");
737
738 SetRootSaveStatus(prefix);
739
740 fEffectiveCharge.ConstructBranch(tree,prefix);
741 size_t i = 0;
742 if(bFullSave) {
743 for(i=0;i<8;i++) fPhotodiode[i].ConstructBranch(tree,thisprefix);
744 }
745 for(i=kXAxis;i<kNumAxes;i++) {
746 fRelPos[i].ConstructBranch(tree,thisprefix);
747 }
748
749 QwMessage <<" Tree leaves added to "<<devicename<<" Corresponding channels"<<QwLog::endl;
750 }
751 // this functions doesn't do anything yet
752 }
753
754
755
756
757
758 return;
759}
760
762{
763 if (GetElementName()=="") {
764 // This channel is not used, so skip filling the tree.
765 }
766 else {
767 fEffectiveCharge.FillTreeVector(values);
768 size_t i = 0;
769 if(bFullSave) {
770 for(i=0;i<8;i++) fPhotodiode[i].FillTreeVector(values);
771 }
772 for(i=kXAxis;i<kNumAxes;i++){
773 fRelPos[i].FillTreeVector(values);
774 }
775 }
776 return;
777}
778
779#ifdef HAS_RNTUPLE_SUPPORT
780void QwLinearDiodeArray::ConstructNTupleAndVector(std::unique_ptr<ROOT::RNTupleModel>& model, TString& prefix, std::vector<Double_t>& values, std::vector<std::shared_ptr<Double_t>>& fieldPtrs)
781{
782 if (GetElementName()==""){
783 // This channel is not used, so skip constructing.
784 }
785 else {
786 TString thisprefix=prefix;
787 if(prefix.Contains("asym_"))
788 thisprefix.ReplaceAll("asym_","diff_");
789
790 SetRootSaveStatus(prefix);
791
792 fEffectiveCharge.ConstructNTupleAndVector(model,prefix,values,fieldPtrs);
793 size_t i = 0;
794 if(bFullSave) {
795 for(i=0;i<8;i++) fPhotodiode[i].ConstructNTupleAndVector(model,thisprefix,values,fieldPtrs);
796 }
797 for(i=kXAxis;i<kNumAxes;i++) {
798 fRelPos[i].ConstructNTupleAndVector(model,thisprefix,values,fieldPtrs);
799 }
800
801 }
802 return;
803}
804
805void QwLinearDiodeArray::FillNTupleVector(std::vector<Double_t>& values) const
806{
807 if (GetElementName()=="") {
808 // This channel is not used, so skip filling.
809 }
810 else {
811 fEffectiveCharge.FillNTupleVector(values);
812 size_t i = 0;
813 if(bFullSave) {
814 for(i=0;i<8;i++) fPhotodiode[i].FillNTupleVector(values);
815 }
816 for(i=kXAxis;i<kNumAxes;i++){
817 fRelPos[i].FillNTupleVector(values);
818 }
819 }
820 return;
821}
822#endif
823
824
826{
827 size_t i = 0;
828 // bEVENTCUTMODE=bcuts;
829 for (i=0;i<8;i++) fPhotodiode[i].SetEventCutMode(bcuts);
830 for (i=kXAxis;i<kNumAxes;i++) {
831 fRelPos[i].SetEventCutMode(bcuts);
832 fAbsPos[i].SetEventCutMode(bcuts);
833 }
834 fEffectiveCharge.SetEventCutMode(bcuts);
835}
836
837
839{
840 for (size_t i = kXAxis; i < kNumAxes; i++) {
841 QwVQWK_Channel relpos(fRelPos[i]);
842 relpos = fRelPos[i];
843 fLinearArrayElementList.push_back(relpos);
844 }
845 QwVQWK_Channel effectivecharge(fEffectiveCharge);
846 effectivecharge = fEffectiveCharge;
847 fLinearArrayElementList.push_back(effectivecharge);
848}
849
850#ifdef __USE_DATABASE__
851std::vector<QwDBInterface> QwLinearDiodeArray::GetDBEntry()
852{
853 std::vector <QwDBInterface> row_list;
854 row_list.clear();
855
856 for(size_t i=0;i<2;i++) {
857 fRelPos[i].AddEntriesToList(row_list);
858 }
859 fEffectiveCharge.AddEntriesToList(row_list);
860 return row_list;
861}
862
863std::vector<QwErrDBInterface> QwLinearDiodeArray::GetErrDBEntry()
864{
865 std::vector <QwErrDBInterface> row_list;
866 row_list.clear();
867 for(size_t i=0;i<2;i++) {
868 fRelPos[i].AddErrEntriesToList(row_list);
869 }
870 fEffectiveCharge.AddErrEntriesToList(row_list);
871 return row_list;
872}
873#endif // __USE_DATABASE__
874
875
876/**********************************
877 * Mock data generation routines
878 **********************************/
879
880void QwLinearDiodeArray::SetRandomEventParameters(Double_t meanX, Double_t sigmaX, Double_t meanY, Double_t sigmaY)
881{
882 // Average values of the signals in the stripline ADCs
883 Double_t sumX = 1.1e8; // These are just guesses, but I made X and Y different
884 Double_t sumY = 0.9e8; // to make it more interesting for the analyzer...
885
886
887 // Determine the asymmetry from the position
888 Double_t meanXP = (1.0 + meanX) * sumX / 2.0;
889 Double_t meanXM = (1.0 - meanX) * sumX / 2.0; // = sumX - meanXP;
890 Double_t meanYP = (1.0 + meanY) * sumY / 2.0;
891 Double_t meanYM = (1.0 - meanY) * sumY / 2.0; // = sumY - meanYP;
892
893 // Determine the spread of the asymmetry (this is not tested yet)
894 // (negative sigma should work in the QwVQWK_Channel, but still using fabs)
895 Double_t sigmaXP = fabs(sumX * sigmaX / meanX);
896 Double_t sigmaXM = sigmaXP;
897 Double_t sigmaYP = fabs(sumY * sigmaY / meanY);
898 Double_t sigmaYM = sigmaYP;
899
900 // Propagate these parameters to the ADCs
901 fPhotodiode[0].SetRandomEventParameters(meanXP, sigmaXP);
902 fPhotodiode[1].SetRandomEventParameters(meanXM, sigmaXM);
903 fPhotodiode[2].SetRandomEventParameters(meanYP, sigmaYP);
904 fPhotodiode[3].SetRandomEventParameters(meanYM, sigmaYM);
905}
906
907
908void QwLinearDiodeArray::RandomizeEventData(int helicity, double time)
909{
910 for (size_t i=0; i<8; i++) fPhotodiode[i].RandomizeEventData(helicity, time);
911
912 return;
913}
914
915
916void QwLinearDiodeArray::SetEventData(Double_t* relpos, UInt_t sequencenumber)
917{
918 for (size_t i=0; i<2; i++)
919 {
920 fRelPos[i].SetHardwareSum(relpos[i], sequencenumber);
921 }
922
923 return;
924}
925
926
927void QwLinearDiodeArray::EncodeEventData(std::vector<UInt_t> &buffer)
928{
929 for (size_t i=0; i<8; i++) fPhotodiode[i].EncodeEventData(buffer);
930}
931
932
934{
935 for(size_t i=0;i<8;i++) fPhotodiode[i].SetDefaultSampleSize((size_t)sample_size);
936 return;
937}
938
939
940void QwLinearDiodeArray::SetSubElementPedestal(Int_t j, Double_t value)
941{
942 fPhotodiode[j].SetPedestal(value);
943 return;
944}
945
947{
948 fPhotodiode[j].SetCalibrationFactor(value);
949 return;
950}
#define QwMessage
Predefined log drain for regular messages.
Definition QwLog.h:49
Parameter file parsing and management.
static const UInt_t kBPMErrorFlag
Definition QwTypes.h:170
static const UInt_t kInvalidSubelementIndex
Definition QwTypes.h:198
Database interface for QwIntegrationPMT and subsystems.
Linear diode array beam position monitor implementation.
static std::ostream & endl(std::ostream &)
End of the line.
Definition QwLog.cc:297
Configuration file parser with flexible tokenization and search capabilities.
Bool_t HasValue(TString &vname)
A helper class to manage a vector of branch entries for ROOT trees.
Definition QwRootFile.h:55
Concrete hardware channel for VQWK ADC modules (6x32-bit words)
void InitializeChannel(TString name, TString datatosave) override
Initialize the fields in this object.
void ClearEventData() override
Clear the event data in this element.
void Ratio(const QwVQWK_Channel &numer, const QwVQWK_Channel &denom)
void Product(const QwVQWK_Channel &value1, const QwVQWK_Channel &value2)
void Scale(Double_t Offset) override
VQwDataElement()
Default constructor.
TString fElementName
Name of this data element.
virtual const TString & GetElementName() const
Get the name of this element.
Abstract base for concrete hardware channels implementing dual-operator pattern.
void AddEntriesToList(std::vector< QwDBInterface > &row_list)
static UInt_t GetSubElementIndex(TString subname)
void SetSubElementCalibrationFactor(Int_t j, Double_t value) override
void ProcessEvent() override
std::vector< QwVQWK_Channel > fLinearArrayElementList
void FillTreeVector(QwRootTreeBranchVector &values) const override
Bool_t ApplySingleEventCuts() override
Apply single-event cuts across photodiodes and derived channels.
void SetSingleEventCuts(TString ch_name, UInt_t errorflag, Double_t minX, Double_t maxX, Double_t stability, Double_t burplevel)
Inherited from VQwDataElement to set the upper and lower limits (fULimit and fLLimit),...
void DeaccumulateRunningSum(QwLinearDiodeArray &value, Int_t ErrorMask=0xFFFFFFF)
VQwHardwareChannel * GetSubelementByName(TString ch_name) override
Resolve an internal channel pointer by subelement name.
void GetAbsolutePosition() override
Bool_t ApplyHWChecks()
Apply hardware checks for all photodiode pads.
void RandomizeEventData(int helicity=0, double time=0.0) override
void InitializeChannel(TString name)
Initialize this linear diode array with a detector name.
void ClearEventData() override
Clear event-scoped data for all pads and derived channels.
static const size_t kMaxElements
VQwBPM & operator-=(const VQwBPM &value) override
void PrintInfo() const override
Print multiple lines of information about this data element.
QwVQWK_Channel fRelPos[2]
void SetEventData(Double_t *block, UInt_t sequencenumber)
void EncodeEventData(std::vector< UInt_t > &buffer) override
void PrintValue() const override
Print single line of value and error of this data element.
void PrintErrorCounters() const override
Print error counters for all internal channels.
VQwBPM & operator+=(const VQwBPM &value) override
QwVQWK_Channel fAbsPos[2]
void IncrementErrorCounters() override
Increment error counters for all internal channels.
TString GetSubElementName(Int_t subindex) override
UInt_t UpdateErrorFlag() override
Update and return the aggregated event-cut error flag.
QwVQWK_Channel fPhotodiode[8]
UInt_t GetEventcutErrorFlag() override
Aggregate and return the event-cut error flag for this array.
static const TString subelement[8]
void SetDefaultSampleSize(Int_t sample_size) override
void CalculateRunningAverage() override
void SetEventCutMode(Int_t bcuts) override
void SetSubElementPedestal(Int_t j, Double_t value) override
void SetRandomEventParameters(Double_t meanX, Double_t sigmaX, Double_t meanY, Double_t sigmaY) override
Int_t ProcessEvBuffer(UInt_t *buffer, UInt_t word_position_in_buffer, UInt_t indexnumber) override
Process the CODA event buffer for this element.
static const Double_t kQwLinearDiodeArrayPadSize
VQwBPM & operator=(const VQwBPM &value) override
void ConstructHistograms(TDirectory *folder, TString &prefix) override
Construct the histograms for this data element.
void AccumulateRunningSum(const QwLinearDiodeArray &value, Int_t count=0, Int_t ErrorMask=0xFFFFFFF)
void Ratio(VQwBPM &numer, VQwBPM &denom) override
void Scale(Double_t factor) override
void FillHistograms() override
Fill the histograms for this data element.
void ConstructBranch(TTree *tree, TString &prefix) override
Bool_t CheckForBurpFail(const VQwDataElement *ev_error) override
Check for burp failures against another linear array of same type.
void ConstructBranchAndVector(TTree *tree, TString &prefix, QwRootTreeBranchVector &values) override
QwVQWK_Channel fEffectiveCharge
Double_t fPositionCenter[3]
Definition VQwBPM.h:328
@ kXAxis
Definition VQwBPM.h:72
@ kNumAxes
Definition VQwBPM.h:72
void SetRootSaveStatus(TString &prefix)
Definition VQwBPM.cc:220
void InitializeChannel(TString name)
Initialize common BPM state and set the element name.
Definition VQwBPM.cc:35
static const Bool_t bDEBUG
Definition VQwBPM.h:350
Bool_t bFullSave
Definition VQwBPM.h:348
virtual VQwBPM & operator=(const VQwBPM &value)=0
Definition VQwBPM.cc:156
VQwBPM()
Definition VQwBPM.h:76