JAPAn
Just Another Parity Analyzer
Loading...
Searching...
No Matches
QwHelicityDecoder.cc
Go to the documentation of this file.
1/**********************************************************\
2* File: QwHelicityDecoder.C *
3* Implemented the helicity data decoder *
4* Contributor: Arindam Sen (asen@jlab.org) *
5* Time-stamp: *
6\**********************************************************/
7
8#include "QwHelicityDecoder.h"
9
10// System headers
11#include <stdexcept>
12
13// ROOT headers
14#include "TRegexp.h"
15#include "TMath.h"
16
17// Qweak headers
18#include "QwHistogramHelper.h"
19#include "QwRootFile.h"
20#include "QwLog.h"
21#ifdef __USE_DATABASE__
22#include "QwParitySchema.h"
23#include "QwParityDB.h"
24#endif // __USE_DATABASE__
25
28
29//**************************************************//
30
31const std::vector<UInt_t> QwHelicityDecoder::kDefaultHelicityBitPattern{0x69};
32
33/// constructor
34
35//**************************************************//
36
38: VQwSubsystem(name),
39 QwHelicityBase(name)
40{
41}
42
43//**************************************************//
49
50//**************************************************//
52{
53 options.AddOptions("Helicity options")
54 ("helicity.seed", po::value<int>(),
55 "Number of bits in random seed");
56 options.AddOptions("Helicity options")
57 ("helicity.bitpattern", po::value<std::string>(),
58 "Helicity bit pattern: 0x1 (pair), 0x9 (quartet), 0x69 (octet), 0x666999 (hexo-quad), 0x66669999 (octo-quad)");
59 options.AddOptions("Helicity options")
60 ("helicity.patternoffset", po::value<int>(),
61 "Set 1 when pattern starts with 1 or 0 when starts with 0");
62 options.AddOptions("Helicity options")
63 ("helicity.patternphase", po::value<int>(),
64 "Maximum pattern phase");
65 options.AddOptions("Helicity options")
66 ("helicity.delay", po::value<int>(),
67 "Default delay is 2 patterns, set at the helicity map file.");
68 options.AddOptions("Helicity options")
69 ("helicity.toggle-mode", po::value<bool>()->default_bool_value(false),
70 "Activates helicity toggle-mode, overriding the 'delay', 'patternphase', 'bitpattern', and 'seed' options.");
71}
72
73//**************************************************//
74
76{
77 // Read the cmd options and override channel map settings
78 QwMessage << "QwHelicityDecoder::ProcessOptions" << QwLog::endl;
79 if (options.HasValue("helicity.patternoffset")) {
80 if (options.GetValue<int>("helicity.patternoffset") == 1
81 || options.GetValue<int>("helicity.patternoffset") == 0) {
82 fPatternPhaseOffset = options.GetValue<int>("helicity.patternoffset");
83 QwMessage << " Pattern Phase Offset = " << fPatternPhaseOffset << QwLog::endl;
84 } else QwError << "Pattern phase offset should be 0 or 1!" << QwLog::endl;
85 }
86
87 if (options.HasValue("helicity.patternphase")) {
88 if (options.GetValue<int>("helicity.patternphase") % 2 == 0) {
89 fMaxPatternPhase = options.GetValue<int>("helicity.patternphase");
90 QwMessage << " Maximum Pattern Phase = " << fMaxPatternPhase << QwLog::endl;
91 } else QwError << "Pattern phase should be an even integer!" << QwLog::endl;
92 }
93
94 if (options.HasValue("helicity.seed")) {
95 if (options.GetValue<int>("helicity.seed") == 24
96 || options.GetValue<int>("helicity.seed") == 30) {
97 QwMessage << " Random Bits = " << options.GetValue<int>("helicity.seed") << QwLog::endl;
98 fRandBits = options.GetValue<int>("helicity.seed");
99 } else QwError << "Number of random seed bits should be 24 or 30!" << QwLog::endl;
100 }
101
102 if (options.HasValue("helicity.delay")) {
103 QwMessage << " Helicity Delay = " << options.GetValue<int>("helicity.delay") << QwLog::endl;
104 SetHelicityDelay(options.GetValue<int>("helicity.delay"));
105 }
106
107 if (options.HasValue("helicity.bitpattern")) {
108 QwMessage << " Helicity Pattern ="
109 << options.GetValue<std::string>("helicity.bitpattern")
110 << QwLog::endl;
111 std::string hex = options.GetValue<std::string>("helicity.bitpattern");
112 //UInt_t bits = QwParameterFile::GetUInt(hex);
114 } else {
116 }
117
118 if (options.GetValue<bool>("helicity.toggle-mode")) {
119 fHelicityDelay = 0;
120 fUsePredictor = kFALSE;
123 }
124
125 // If we have the default Helicity Bit Pattern & a large fMaxPatternPhase,
126 // try to recompute the Helicity Bit Pattern.
129 }
130
131 // Here we're going to try to get the "online" option which
132 // is defined by QwEventBuffer.
133 if (options.HasValue("online")){
134 fSuppressMPSErrorMsgs = options.GetValue<bool>("online");
135 } else {
136 fSuppressMPSErrorMsgs = kFALSE;
137 }
138}
139
141{
142 SetDataLoaded(kFALSE);
143 for (size_t i=0;i<fWord.size();i++)
145
146 /**Reset data by setting the old event number, pattern number and pattern phase
147 to the values of the previous event.*/
148 if (fEventNumberFirst==-1 && fEventNumberOld!= -1){
150 }
154 }
155
159
160 /**Clear out helicity variables */
164 fHelicityBitPlus = kFALSE;
165 fHelicityBitMinus = kFALSE;
166 fEventNumber = -1;
168 fPatternNumber = -1;
169 return;
170}
171
172Int_t QwHelicityDecoder::ProcessConfigurationBuffer(const ROCID_t roc_id, const BankID_t bank_id, UInt_t* buffer, UInt_t num_words)
173{
174 return 0;
175}
176
177Int_t QwHelicityDecoder::LoadInputParameters(TString pedestalfile)
178{
179 return 0;
180}
181
182
184
185 return kTRUE;
186}
187
189{
190 Bool_t ldebug = kFALSE;
191 fErrorFlag = 0;
192
193 if (! HasDataLoaded()) return;
194
195 static Bool_t firstpattern = kTRUE;
196
197 if(firstpattern && fPatternNumber > fPatternNumberOld){
198 firstpattern = kFALSE;
199 }
200
202 Int_t nummissed(fEventNumber - (fEventNumberOld+1));
203 QwError << "QwHelicityDecoder::ProcessEvent read event# ("
204 << fEventNumber << ") is not old_event#+1; missed "
205 << nummissed << " gates" << QwLog::endl;
206 fNumMissedGates += nummissed;
208 }
209
211
212 if (fHelicityReported == 1){
213 fHelicityBitPlus=kTRUE;
214 fHelicityBitMinus=kFALSE;
215 } else {
216 fHelicityBitPlus=kFALSE;
217 fHelicityBitMinus=kTRUE;
218 }
219
220
223
224 // Predict helicity if delay is non zero.
227 } else {
228 // Else use the reported helicity values.
231 }
232
233 fPatternSeed = fSeed_Reported & 0x7fffffff;
234
235 if(ldebug){
236 std::cout<<"\nevent number= "<<fEventNumber<<std::endl;
237 std::cout<<"pattern number = "<<fPatternNumber<<std::endl;
238 std::cout<<"pattern phase = "<<fPatternPhaseNumber<<std::endl;
239 std::cout<<"max pattern phase = "<<fMaxPatternPhase<<std::endl;
240 std::cout<<"min pattern phase = "<<fMinPatternPhase<<std::endl;
241 std::cout << "Helicity Info: [Reported = " << fHelicityReported
242 << ", Delayed = " << fHelicityDelayed
243 << ", Actual = " << fHelicityActual << "]" << std::endl;
244
245
246 }
247 return;
248}
249
250
251void QwHelicityDecoder::EncodeEventData(std::vector<UInt_t> &buffer)
252{
253}
254
256{
257 QwOut << "===========================\n"
258 << "This event: Event#, Pattern#, PatternPhase#="
259 << fEventNumber << ", "
260 << fPatternNumber << ", "
262 QwOut << "Previous event: Event#, Pattern#, PatternPhase#="
263 << fEventNumberOld << ", "
264 << fPatternNumberOld << ", "
266 QwOut << "delta = \n(fEventNumberOld)-(fMaxPatternPhase)x(fPatternNumberOld)-(fPatternPhaseNumberOld)= "
268 QwOut << "Helicity Reported, Delayed, Actual ="
269 << fHelicityReported << ","
270 << fHelicityDelayed << ","
272 QwOut << "===" << QwLog::endl;
273 return;
274}
275
276
278{
279 UInt_t value = 0;
280 TString valuestr;
281
282 QwParameterFile mapstr(mapfile.Data()); //Open the file
284 mapstr.EnableGreediness();
285 mapstr.SetCommentChars("!");
286
287 while (mapstr.ReadNextLine()){
288 // This class doesn't have any normal decode lines in the map file,
289 // so there is nothing to do in this loop. We just need the one
290 // call to "ReadNextLine" to populate the list of key/vale pairs.
291
292 // std::cout << "in the loop: " << mapstr.GetLine() << std::endl;
293 // RegisterRocBankMarker(mapstr);
294 }
295 //std::cout << "finished loop" << std::endl;
296
297 // Call "RegisterRocBankMarker" to record the ROC/Bank our data is in.
298 RegisterRocBankMarker(mapstr);
299
300 // If we have other key/values we want to use, we'd need to go though
301 // them here to see if they were found in the mapfile.
302 if (mapstr.PopValue("patternphase",value)) {
303 fMaxPatternPhase=value;
304 //QwMessage << " fMaxPatternPhase " << fMaxPatternPhase << QwLog::endl;
305 }
306
307
308 //PrintInfo();
309 return 0;
310}
311
312
313Int_t QwHelicityDecoder::LoadEventCuts(TString filename){
314
315 return 0;
316}
317
318Int_t QwHelicityDecoder::ProcessEvBuffer(UInt_t event_type, const ROCID_t roc_id, const BankID_t bank_id, UInt_t* buffer, UInt_t num_words)
319{
320
321 Bool_t lkDEBUG = kFALSE;
322 //std::cout << " roc id = " << roc_id << "bank id = " << bank_id << std::endl;
323 Int_t index = GetSubbankIndex(roc_id,bank_id);
324 //std::cout << "index = " << index << std::endl;
325 if (index >= 0 && num_words > 0) {
326 SetDataLoaded(kTRUE);
327 // lkDEBUG=kTRUE;
328
329 uint32_t type_last = 15; /* initialize to type FILLER WORD */
330 uint32_t time_last = 0;
331 uint32_t decoder_index = 0;
332 uint32_t num_decoder_words = 1;
333
334 uint32_t slot_id_ev_hd = 0;
335 uint32_t slot_id_dnv = 0;
336 uint32_t slot_id_fill = 0;
337
338 uint32_t new_type;
339 uint32_t type;
340 uint32_t slot_id_hd;
341 uint32_t mod_id_hd;
342 uint32_t slot_id_tr;
343 uint32_t n_evts;
344 uint32_t blk_num;
345 uint32_t n_words;
346 uint32_t evt_num_1;
347 uint32_t trig_time;
348 uint32_t time_now=0;
349 uint32_t time_1;
350 uint32_t time_2;
351
352 uint32_t data;
353
354 if (num_words<fNumDecoderWords+4){
355 std::cerr << "Not enough words in the bank:"<< std::endl;
356 return kFALSE;
357
358 } else
359 for (size_t i=0; i<num_words; i++){
360
361 data = buffer[i];
362 if(decoder_index) /* decoder type data word - set by decoder header word */
363 {
364 type = 16; /* set decoder data words as type 16 */
365 new_type = 0;
366 if(decoder_index < num_decoder_words)
367 {
368 FillHDVariables(data, decoder_index - 1);
369 if(lkDEBUG)
370 printf("%8X - decoder data(%d) = %d\n", data, (decoder_index - 1),
371 data);
372 decoder_index++;
373 }
374 else /* last decoder word */
375
376 {
377 FillHDVariables(data, decoder_index - 1);
378 if(lkDEBUG)
379 printf("%8X - decoder data(%d) = %d\n", data, (decoder_index - 1),
380 data);
381 decoder_index = 0;
382 num_decoder_words = 1;
383 }
384 }
385 else /* normal typed word */
386 {
387 if(data & 0x80000000) /* data type defining word */
388 {
389 new_type = 1;
390 type = (data & 0x78000000) >> 27;
391 }
392 else /* data type continuation word */
393 {
394 new_type = 0;
395 type = type_last;
396 }
397
398 switch (type)
399 {
400 case 0: /* BLOCK HEADER */
401 slot_id_hd = (data & 0x7C00000) >> 22;
402 mod_id_hd = (data & 0x3C0000) >> 18;
403 n_evts = (data & 0x000FF);
404 blk_num = (data & 0x3FF00) >> 8;
405 if(lkDEBUG)
406 printf
407 ("%8X - BLOCK HEADER - slot = %d id = %d n_evts = %d n_blk = %d\n",
408 data, slot_id_hd, mod_id_hd, n_evts,
409 blk_num);
410 break;
411
412 case 1: /* BLOCK TRAILER */
413 slot_id_tr = (data & 0x7C00000) >> 22;
414 n_words = (data & 0x3FFFFF);
415 if(lkDEBUG)
416 printf("%8X - BLOCK TRAILER - slot = %d n_words = %d\n",
417 data, slot_id_tr, n_words);
418 break;
419
420 case 2: /* EVENT HEADER */
421 if(new_type)
422 {
423 slot_id_ev_hd = (data & 0x07C00000) >> 22;
424 evt_num_1 = (data & 0x00000FFF);
425 trig_time = (data & 0x003FF000) >> 12;
426 if(lkDEBUG)
427 printf
428 ("%8X - EVENT HEADER - slot = %d evt_num = %d trig_time = %d (%X)\n",
429 data, slot_id_ev_hd, evt_num_1, trig_time,
430 trig_time);
431 }
432 break;
433
434 case 3: /* TRIGGER TIME */
435
436 if(new_type)
437 {
438 time_1 = (data & 0x7FFFFFF);
439 if(lkDEBUG)
440 printf("%8X - TRIGGER TIME 1 - time = %X\n", data,
441 time_1);
442 time_now = 1;
443 time_last = 1;
444 }
445 else
446 {
447 if(time_last == 1)
448 {
449 time_2 = (data & 0xFFFFF);
450 if(lkDEBUG)
451 printf("%8X - TRIGGER TIME 2 - time = %X\n", data,
452 time_2);
453 time_now = 2;
454 }
455 else if(lkDEBUG)
456 printf("%8X - TRIGGER TIME - (ERROR)\n", data);
457
458 time_last = time_now;
459 }
460 break;
461
462 case 4: /* UNDEFINED TYPE */
463 if(lkDEBUG)
464 printf("%8X - UNDEFINED TYPE = %d\n", data, type);
465 break;
466
467 case 5: /* UNDEFINED TYPE */
468 if(lkDEBUG)
469 printf("%8X - UNDEFINED TYPE = %d\n", data, type);
470 break;
471
472 case 6: /* UNDEFINED TYPE */
473 if(lkDEBUG)
474 printf("%8X - UNDEFINED TYPE = %d\n", data, type);
475 break;
476
477 case 7: /* UNDEFINED TYPE */
478 if(lkDEBUG)
479 printf("%8X - UNDEFINED TYPE = %d\n", data, type);
480 break;
481
482 case 8: /* DECODER HEADER */
483 num_decoder_words = (data & 0x3F); /* number of decoder words to follow */
484 decoder_index = 1; /* identify next word as a decoder data word */
485 if(lkDEBUG)
486 printf("%8X - DECODER HEADER = %d (NUM DECODER WORDS = %d)\n",
487 data, type, num_decoder_words);
488 break;
489
490 case 9: /* UNDEFINED TYPE */
491 if(lkDEBUG)
492 printf("%8X - UNDEFINED TYPE = %d\n", data, type);
493 break;
494
495 case 10: /* UNDEFINED TYPE */
496 if(lkDEBUG)
497 printf("%8X - UNDEFINED TYPE = %d\n", data, type);
498 break;
499
500 case 11: /* UNDEFINED TYPE */
501 if(lkDEBUG)
502 printf("%8X - UNDEFINED TYPE = %d\n", data, type);
503 break;
504
505 case 12: /* UNDEFINED TYPE */
506 if(lkDEBUG)
507 printf("%8X - UNDEFINED TYPE = %d\n", data, type);
508 break;
509
510 case 13: /* END OF EVENT */
511 if(lkDEBUG)
512 printf("%8X - END OF EVENT = %d\n", data, type);
513 break;
514
515 case 14: /* DATA NOT VALID (no data available) */
516 slot_id_dnv = (data & 0x7C00000) >> 22;
517 if(lkDEBUG)
518 printf("%8X - DATA NOT VALID = %d slot = %d\n", data,
519 type, slot_id_dnv);
520 break;
521
522 case 15: /* FILLER WORD */
523 slot_id_fill = (data & 0x7C00000) >> 22;
524 if(lkDEBUG)
525 printf("%8X - FILLER WORD = %d slot = %d\n", data, type,
526 slot_id_fill);
527 break;
528 }
529
530 type_last = type; /* save type of current data word */
531
532 }
533 }
534 }
535 return 0;
536}
537
538void QwHelicityDecoder::FillHDVariables(uint32_t data, uint32_t index) {
539
540 switch (index) {
541 case 0:
542 fSeed_Reported=data;
543 break;
544 case 1:
546 break;
547 case 2:
548 fEventNumber=data;
549 break;
550 case 3:
551 fPatternNumber=data;
552 break;
553 case 4:
554 fNum_Pair_Sync=data;
555 break;
556 case 5:
558 break;
559 case 6:
561 break;
562 case 7:
564 break;
565 case 8:
567 break;
568 case 9:
569 fPatternPhaseNumber = ((data>>8) & 0xff)+1;
570 fEventPolarity = (data>>5) & 0x1;
571 fReportedPatternHel = (data>>4) & 0x1;
572 fBit_Helicity = (data>>3) & 0x1;
573 fBit_PairSync = (data>>2) & 0x1;
574 fBit_PatSync = (data>>1) & 0x1;
575 fBit_TStable = data & 0x1;
576 break;
577 case 10:
579 break;
580 case 11:
582 break;
583 case 12:
585 break;
586 case 13:
588 break;
589 }
590}
591
592void QwHelicityDecoder::SetFirstBits(UInt_t nbits, UInt_t seed)
593{
594 // This gives the predictor a quick start
595 UShort_t firstbits[nbits];
596 for (unsigned int i = 0; i < nbits; i++) firstbits[i] = (seed >> i) & 0x1;
597 // Set delayed seed
598 iseed_Delayed = GetRandomSeed(firstbits);
599 // Progress actual seed by the helicity delay
601 for (int i = 0; i < fHelicityDelay; i++) GetRandbit(iseed_Actual);
602}
603
604void QwHelicityDecoder::SetHistoTreeSave(const TString &prefix)
605{
606 Ssiz_t len;
607 if (TRegexp("diff_").Index(prefix,&len) == 0
608 || TRegexp("asym[1-9]*_").Index(prefix,&len) == 0)
610 else if (TRegexp("yield_").Index(prefix,&len) == 0)
612 else
614
615}
616
617void QwHelicityDecoder::ConstructHistograms(TDirectory *folder, TString &prefix)
618{
619 SetHistoTreeSave(prefix);
620 if (folder != NULL) folder->cd();
621 TString basename;
622 size_t index=0;
623
625 {
626 //do nothing
627 }
629 {
630 fHistograms.resize(1+fWord.size(), NULL);
631 basename="pattern_polarity";
632 fHistograms[index] = gQwHists.Construct1DHist(basename);
633 index+=1;
634 for (size_t i=0; i<fWord.size(); i++){
635 basename="hel_"+fWord[i].fWordName;
636 fHistograms[index] = gQwHists.Construct1DHist(basename);
637 index+=1;
638 }
639 }
640 else if(fHistoType==kHelSaveMPS)
641 {
642 fHistograms.resize(4+fWord.size(), NULL);
643 //eventnumber, patternnumber, helicity, patternphase + fWord.size
644 basename=prefix+"delta_event_number";
645 fHistograms[index] = gQwHists.Construct1DHist(basename);
646 index+=1;
647 basename=prefix+"delta_pattern_number";
648 fHistograms[index] = gQwHists.Construct1DHist(basename);
649 index+=1;
650 basename=prefix+"pattern_phase";
651 fHistograms[index] = gQwHists.Construct1DHist(basename);
652 index+=1;
653 basename=prefix+"helicity";
654 fHistograms[index] = gQwHists.Construct1DHist(basename);
655 index+=1;
656 for (size_t i=0; i<fWord.size(); i++){
657 basename=prefix+fWord[i].fWordName;
658 fHistograms[index] = gQwHists.Construct1DHist(basename);
659 index+=1;
660 }
661 }
662 else
663 QwError << "QwHelicityDecoder::ConstructHistograms this prefix--" << prefix << "-- is not unknown:: no histo created" << QwLog::endl;
664
665 return;
666}
667
669{
670 if (fHistograms.size()==0){return;}
671 size_t index=0;
673 {
674 //do nothing
675 }
677 {
678 QwDebug << "QwHelicityDecoder::FillHistograms helicity info " << QwLog::endl;
679 QwDebug << "QwHelicityDecoder::FillHistograms pattern polarity=" << fActualPatternPolarity << QwLog::endl;
680 if (fHistograms[index]!=NULL)
682 index+=1;
683
684 for (size_t i=0; i<fWord.size(); i++){
685 if (fHistograms[index]!=NULL)
686 fHistograms[index]->Fill(fWord[i].fValue);
687 index+=1;
688 QwDebug << "QwHelicityDecoder::FillHistograms " << fWord[i].fWordName << "=" << fWord[i].fValue << QwLog::endl;
689 }
690 }
691 else if(fHistoType==kHelSaveMPS)
692 {
693 QwDebug << "QwHelicityDecoder::FillHistograms mps info " << QwLog::endl;
694 if (fHistograms[index]!=NULL)
696 index+=1;
697 if (fHistograms[index]!=NULL)
699 index+=1;
700 if (fHistograms[index]!=NULL)
701 fHistograms[index]->Fill(fPatternPhaseNumber);
702 index+=1;
703 if (fHistograms[index]!=NULL)
704 fHistograms[index]->Fill(fHelicityActual);
705 index+=1;
706 for (size_t i=0; i<fWord.size(); i++){
707 if (fHistograms[index]!=NULL)
708 fHistograms[index]->Fill(fWord[i].fValue);
709 index+=1;
710 QwDebug << "QwHelicityDecoder::FillHistograms " << fWord[i].fWordName << "=" << fWord[i].fValue << QwLog::endl;
711 }
712 }
713
714 return;
715}
716
717
719{
720 SetHistoTreeSave(prefix);
721 fTreeArrayIndex = values.size();
722 TString basename;
724 {
725 //do nothing
726 }
727 else if(fHistoType==kHelSaveMPS)
728 {
729 basename = "hd_actual_helicity"; //predicted actual helicity before being delayed.
730 values.push_back(basename, 'I');
731 tree->Branch(basename, &(values.back<Double_t>()), basename+"/I");
732
733 basename = "hd_delayed_helicity"; //predicted delayed helicity
734 values.push_back(basename, 'I');
735 tree->Branch(basename, &(values.back<Double_t>()), basename+"/I");
736 //
737 basename = "hd_reported_helicity"; //delayed helicity reported by the input register.
738 values.push_back(basename, 'I');
739 tree->Branch(basename, &(values.back<Double_t>()), basename+"/I");
740 //
741 basename = "hd_pattern_phase";
742 values.push_back(basename, 'I');
743 tree->Branch(basename, &(values.back<Double_t>()), basename+"/I");
744 //
745 basename = "hd_pattern_number";
746 values.push_back(basename, 'I');
747 tree->Branch(basename, &(values.back<Double_t>()), basename+"/I");
748 //
749 basename = "hd_pattern_seed";
750 values.push_back(basename, 'I');
751 tree->Branch(basename, &(values.back<Double_t>()), basename+"/I");
752 //
753 basename = "hd_event_number";
754 values.push_back(basename, 'I');
755 tree->Branch(basename, &(values.back<Double_t>()), basename+"/I");
756
757 basename = "hd_event_Polarity";
758 values.push_back(basename, 'I');
759 tree->Branch(basename, &(values.back<Double_t>()), basename+"/I");
760
761 basename = "hd_Reported_Pattern_Hel";
762 values.push_back(basename, 'I');
763 tree->Branch(basename, &(values.back<Double_t>()), basename+"/I");
764 //new time / status variables
765 basename = "hd_num_tstable_fall";
766 values.push_back(basename, 'I');
767 tree->Branch(basename, &(values.back<Double_t>()), basename+"/I");
768
769 basename = "hd_num_pair_sync";
770 values.push_back(basename, 'I');
771 tree->Branch(basename, &(values.back<Double_t>()), basename+"/I");
772
773 basename = "hd_time_since_tstable";
774 values.push_back(basename, 'I');
775 tree->Branch(basename, &(values.back<Double_t>()), basename+"/I");
776
777 basename = "hd_time_since_tsettle";
778 values.push_back(basename, 'I');
779 tree->Branch(basename, &(values.back<Double_t>()), basename+"/I");
780
781 basename = "hd_last_duration_tstable";
782 values.push_back(basename, 'I');
783 tree->Branch(basename, &(values.back<Double_t>()), basename+"/I");
784
785 basename = "hd_last_duration_tsettle";
786 values.push_back(basename, 'I');
787 tree->Branch(basename, &(values.back<Double_t>()), basename+"/I");
788
789 for (size_t i=0; i<fWord.size(); i++)
790 {
791 basename = fWord[i].fWordName;
792 values.push_back(basename, 'I');
793 tree->Branch(basename, &(values.back<Double_t>()), basename+"/I");
794 }
795 }
797 {
798 basename = "hd_actual_helicity"; //predicted actual helicity before being delayed.
799 values.push_back(basename, 'I');
800 tree->Branch(basename, &(values.back<Double_t>()), basename+"/I");
801 //
802 basename = "hd_actual_pattern_polarity";
803 values.push_back(basename, 'I');
804 tree->Branch(basename, &(values.back<Double_t>()), basename+"/I");
805 //
806 basename = "hd_actual_previous_pattern_polarity";
807 values.push_back(basename, 'I');
808 tree->Branch(basename, &(values.back<Double_t>()), basename+"/I");
809 //
810 basename = "hd_delayed_pattern_polarity";
811 values.push_back(basename, 'I');
812 tree->Branch(basename, &(values.back<Double_t>()), basename+"/I");
813 //
814 basename = "hd_pattern_number";
815 values.push_back(basename, 'I');
816 tree->Branch(basename, &(values.back<Double_t>()), basename+"/I");
817 //
818 basename = "hd_pattern_seed";
819 values.push_back(basename, 'I');
820 tree->Branch(basename, &(values.back<Double_t>()), basename+"/I");
821 //
822 for (size_t i=0; i<fWord.size(); i++)
823 {
824 basename = fWord[i].fWordName;
825 values.push_back(basename, 'I');
826 tree->Branch(basename, &(values.back<Double_t>()), basename+"/I");
827 }
828 }
829 std::cout << "after construction size " << values.size() << std::endl;
830 return;
831}
832
833void QwHelicityDecoder::ConstructBranch(TTree *tree, TString &prefix)
834{
835TString basename;
836
837 SetHistoTreeSave(prefix);
838// print the branch and type name (arindam)
839//std::cout << "QwHelicityDecoder::ConstructBranch" << std::endl;
840//std::cout << tree->GetName() << " " << prefix << " " << std::endl;
841//std::cout << "Histo type --> " << fHistoType << std::endl;
843 {
844 //do nothing
845 }
846 else if(fHistoType==kHelSaveMPS)
847 {
848 // basename = "hd_actual_helicity"; //predicted actual helicity before being delayed.
849 // tree->Branch(basename, &fHelicityActual, basename+"/I");
850 //
851 basename = "hd_delayed_helicity"; //predicted delayed helicity
852 tree->Branch(basename, &fHelicityDelayed, basename+"/I");
853 //
854 basename = "hd_reported_helicity"; //delayed helicity reported by the input register.
855 tree->Branch(basename, &fHelicityReported, basename+"/I");
856 //
857 basename = "hd_pattern_phase";
858 tree->Branch(basename, &fPatternPhaseNumber, basename+"/I");
859 //
860 basename = "hd_pattern_number";
861 tree->Branch(basename, &fPatternNumber, basename+"/I");
862 //
863 basename = "hd_pattern_seed";
864 tree->Branch(basename, &fPatternSeed, basename+"/I");
865 //
866 basename = "hd_event_number";
867 tree->Branch(basename, &fEventNumber, basename+"/I");
868
869 basename = "hd_event_Polarity";
870 tree->Branch(basename, &fEventPolarity, basename+"/I");
871
872 basename = "hd_Reported_Pattern_Hel";
873 tree->Branch(basename, &fReportedPatternHel, basename+"/I");
874 }
876 {
877 basename = "hd_actual_helicity"; //predicted actual helicity before being delayed.
878 tree->Branch(basename, &fHelicityActual, basename+"/I");
879 //
880 basename = "hd_actual_pattern_polarity";
881 tree->Branch(basename, &fActualPatternPolarity, basename+"/I");
882 //
883 basename = "hd_actual_previous_pattern_polarity";
884 tree->Branch(basename, &fPreviousPatternPolarity, basename+"/I");
885 //
886 basename = "hd_delayed_pattern_polarity";
887 tree->Branch(basename, &fDelayedPatternPolarity, basename+"/I");
888 //
889 basename = "hd_pattern_number";
890 tree->Branch(basename, &fPatternNumber, basename+"/I");
891 //
892 basename = "hd_pattern_seed";
893 tree->Branch(basename, &fPatternSeed, basename+"/I");
894
895 for (size_t i=0; i<fWord.size(); i++)
896 {
897 basename = fWord[i].fWordName;
898 tree->Branch(basename, &fWord[i].fValue, basename+"/I");
899 }
900 }
901 //QwError << "entering construct branch should not be here : arindam" << QwLog::endl;
902
903 return;
904}
905
906void QwHelicityDecoder::ConstructBranch(TTree *tree, TString &prefix, QwParameterFile& trim_file)
907{
908 TString basename;
909
910 SetHistoTreeSave(prefix);
912 {
913 //do nothing
914 }
915 else if(fHistoType==kHelSaveMPS)
916 {
917 // basename = "hd_actual_helicity"; //predicted actual helicity before being delayed.
918 // tree->Branch(basename, &fHelicityActual, basename+"/I");
919 //
920 basename = "hd_delayed_helicity"; //predicted delayed helicity
921 tree->Branch(basename, &fHelicityDelayed, basename+"/I");
922 //
923 basename = "hd_reported_helicity"; //delayed helicity reported by the input register.
924 tree->Branch(basename, &fHelicityReported, basename+"/I");
925 //
926 basename = "hd_pattern_phase";
927 tree->Branch(basename, &fPatternPhaseNumber, basename+"/I");
928 //
929 basename = "hd_pattern_number";
930 tree->Branch(basename, &fPatternNumber, basename+"/I");
931 //
932 basename = "hd_pattern_seed";
933 tree->Branch(basename, &fPatternSeed, basename+"/I");
934 //
935 basename = "hd_event_number";
936 tree->Branch(basename, &fEventNumber, basename+"/I");
937
938 basename = "hd_event_Polarity";
939 tree->Branch(basename, &fEventPolarity, basename+"/I");
940
941 basename = "hd_Reported_Pattern_Hel";
942 tree->Branch(basename, &fReportedPatternHel, basename+"/I");
943 }
945 {
946 basename = "hd_actual_helicity"; //predicted actual helicity before being delayed.
947 tree->Branch(basename, &fHelicityActual, basename+"/I");
948 //
949 basename = "hd_actual_pattern_polarity";
950 tree->Branch(basename, &fActualPatternPolarity, basename+"/I");
951 //
952 basename = "hd_actual_previous_pattern_polarity";
953 tree->Branch(basename, &fPreviousPatternPolarity, basename+"/I");
954 //
955 basename = "hd_delayed_pattern_polarity";
956 tree->Branch(basename, &fDelayedPatternPolarity, basename+"/I");
957 //
958 basename = "hd_pattern_number";
959 tree->Branch(basename, &fPatternNumber, basename+"/I");
960 //
961 basename = "hd_pattern_seed";
962 tree->Branch(basename, &fPatternSeed, basename+"/I");
963
964 for (size_t i=0; i<fWord.size(); i++)
965 {
966 basename = fWord[i].fWordName;
967 tree->Branch(basename,&fWord[i].fValue, basename+"/I");
968 }
969
970 }
971
972 return;
973}
974
976{
977
978 size_t index=fTreeArrayIndex;
980 {
981 values.SetValue(index++, fHelicityActual);
982 values.SetValue(index++, fHelicityDelayed);
983 values.SetValue(index++, fHelicityReported);
984 values.SetValue(index++, fPatternPhaseNumber);
985 values.SetValue(index++, fPatternNumber);
986 values.SetValue(index++, fPatternSeed);
987 values.SetValue(index++, fEventNumber);
988 values.SetValue(index++, fEventPolarity);
989 values.SetValue(index++, fReportedPatternHel);
990 // NEW TIME / STATUS VARIABLES
991 values.SetValue(index++, fNum_TStable_Fall);
992 values.SetValue(index++, fNum_Pair_Sync);
993 values.SetValue(index++, fTime_since_TStable);
994 values.SetValue(index++, fTime_since_TSettle);
995 values.SetValue(index++, fLast_Duration_TStable);
996 values.SetValue(index++, fLast_Duration_TSettle);
997
998 for (size_t i=0; i<fWord.size(); i++)
999 values.SetValue(index++, fWord[i].fValue);
1000 }
1001 else if(fHistoType==kHelSavePattern)
1002 {
1003 values.SetValue(index++, fHelicityActual);
1004 values.SetValue(index++, fActualPatternPolarity);
1005 values.SetValue(index++, fPreviousPatternPolarity);
1006 values.SetValue(index++, fDelayedPatternPolarity);
1007 values.SetValue(index++, fPatternNumber);
1008 values.SetValue(index++, fPatternSeed);
1009 for (size_t i=0; i<fWord.size(); i++){
1010 values.SetValue(index++, fWord[i].fValue);
1011 }
1012 }
1013
1014 return;
1015}
1016
1018{
1019 Int_t ldebug = kFALSE;
1020
1021 if(ldebug) std::cout << "Entering QwHelicityDecoder::RunPredictor for fEventNumber, " << fEventNumber
1022 << ", fPatternNumber, " << fPatternNumber
1023 << ", and fPatternPhaseNumber, " << fPatternPhaseNumber << std::endl;
1024
1025 /**Update the random seed if the new event is from a different pattern.
1026 Check the difference between old pattern number and the new one and
1027 to see how many patterns we have missed or skipped. Then loop back
1028 to get the correct pattern polarities.
1029 */
1031 iseed_Delayed = fSeed_Reported & 0x7fffffff;
1032
1033 /** set the polarity of the current pattern to be equal to the reported helicity,*/
1035 QwDebug << "QwHelicityDecoder:: CollectRandBits30: delayedpatternpolarity =" << fDelayedPatternPolarity << QwLog::endl;
1036
1037 /** then use it as the delayed helicity, */
1039
1040 /**if the helicity is delayed by a positive number of patterns then loop the delayed ranseed backward to get the ranseed
1041 for the actual helicity */
1042 if(fHelicityDelay >=0){
1044 for(Int_t i=0; i<fHelicityDelay; i++) {
1045 /**, get the pattern polarity for the actual pattern using that actual ranseed.*/
1048 }
1049 }
1050 }
1053//std::cout << "printing values : fHelicityDelayed = " << fHelicityDelayed << " : fDelayedPatternPolarity = " << fDelayedPatternPolarity << " : fEventPolarity = " << fEventPolarity << " : reported hel =" << fHelicityReported << " : pattern phase=" << fPatternPhaseNumber << std::endl;
1054
1055 if(ldebug){
1056 std::cout << "Predicted Polarity ::: Delayed ="
1057 << fDelayedPatternPolarity << " Actual ="
1058 << fActualPatternPolarity << "\n";
1059 std::cout << "Predicted Helicity ::: Delayed Helicity=" << fHelicityDelayed
1060 << " Actual Helicity=" << fHelicityActual << " Reported Helicity=" << fHelicityReported << "\n";
1061 QwError << "Exiting QwHelicityDecoder::RunPredictor " << QwLog::endl;
1062
1063 }
1064
1065 return;
1066}
1067
1069{
1070 Bool_t ldebug=kFALSE;
1071
1072 if(ldebug) std::cout << "Entering QwHelicityDecoder::PredictHelicity \n";
1073 if(ldebug) std::cout << "QwHelicityDecoder::PredictHelicity=>Predicting the helicity \n";
1074 RunPredictor();
1075
1076 if(ldebug) std::cout << "n_ranbit exiting the function = " << n_ranbits << "\n";
1077
1078 return;
1079}
1080
1081
1082
1084{
1085 /**Sets the number of bits the helicity reported gets delayed with.
1086 We predict helicity only if there is a non-zero pattern delay given. */
1087
1088 if(delay>=0){
1089 fHelicityDelay = delay;
1090 if(delay == 0){
1091 QwWarning << "QwHelicityDecoder : SetHelicityDelay :: helicity delay is set to 0."
1092 << " Disabling helicity predictor and using reported helicity information."
1093 << QwLog::endl;
1094 fUsePredictor = kFALSE;
1095 }
1096 else
1097 fUsePredictor = kTRUE;
1098 }
1099 else
1100 QwError << "QwHelicityDecoder::SetHelicityDelay We cannot handle negative delay in the prediction of delayed helicity. Exiting.." << QwLog::endl;
1101
1102 return;
1103}
1104
1105
1107{
1108 fHelicityBitPattern.clear();
1110 /* // Set the helicity pattern bits
1111 if (parity(bits) == 0)
1112 fHelicityBitPattern = bits;
1113 else QwError << "What, exactly, are you trying to do ?!?!?" << QwLog::endl;
1114 */
1115 // Notify the user
1116 QwMessage << " fPatternBits 0x" ;
1117 for (int i = fHelicityBitPattern.size()-1;i>=0; i--){
1118 QwMessage << std::hex << fHelicityBitPattern[i] << " ";
1119 }
1120 QwMessage << std::dec << QwLog::endl;
1121}
1122
1124{
1125 Bool_t ldebug = kFALSE;
1126 if(Compare(value))
1127 {
1128
1129 //QwHelicityDecoder* input= (QwHelicityDecoder*)value;
1131 QwHelicityDecoder* input= dynamic_cast<QwHelicityDecoder*>(value);
1132
1133 for(size_t i=0;i<input->fWord.size();i++)
1134 this->fWord[i].fValue=input->fWord[i].fValue;
1135 this->fHelicityActual = input->fHelicityActual;
1136 this->fPatternNumber = input->fPatternNumber;
1137 this->fPatternSeed = input->fPatternSeed;
1139 this->fEventNumber=input->fEventNumber;
1144 this->fHelicityActual=input->fHelicityActual;
1148 this->fGoodHelicity=input->fGoodHelicity;
1149 this->fGoodPattern=input->fGoodPattern;
1150 this->fIgnoreHelicity = input->fIgnoreHelicity;
1151 this->fEventPolarity = input->fEventPolarity;
1153 //new time / status variables
1154 this->fNum_TStable_Fall = input->fNum_TStable_Fall;
1155 this->fNum_Pair_Sync = input->fNum_Pair_Sync;
1160
1161 this->fErrorFlag = input->fErrorFlag;
1162 this->fEventNumberFirst = input->fEventNumberFirst;
1164 this->fNumMissedGates = input->fNumMissedGates;
1168
1169 if(ldebug){
1170 std::cout << "QwHelicityDecoder::operator = this->fPatternNumber=" << this->fPatternNumber << std::endl;
1171 std::cout << "input->fPatternNumber=" << input->fPatternNumber << "\n";
1172 }
1173 }
1174
1175 return *this;
1176}
1177
1179{
1180 // Bool_t localdebug=kFALSE;
1181 QwDebug << "Entering QwHelicityDecoder::operator+= adding " << value->GetName() << " to " << this->GetName() << " " << QwLog::endl;
1182
1183 //this routine is most likely to be called during the computation of asymmetry
1184 //this call doesn't make too much sense for this class so the following lines
1185 //are only use to put safe gards testing for example if the two instantiation indeed
1186 // refers to elements in the same pattern.
1187 CheckPatternNum(value);
1188 MergeCounters(value);
1189 return *this;
1190}
1191
1193{
1194 // Bool_t localdebug=kFALSE;
1195 if(Compare(value)) {
1196 QwHelicityDecoder* input= dynamic_cast<QwHelicityDecoder*>(value);
1197 QwDebug << "QwHelicityDecoder::MergeCounters: this->fPatternNumber=" << this->fPatternNumber
1198 << ", input->fPatternNumber=" << input->fPatternNumber << QwLog::endl;
1199
1200 this->fErrorFlag |= input->fErrorFlag;
1201
1202 // Make sure the pattern number and poalrity agree!
1203 if(this->fPatternNumber!=input->fPatternNumber)
1204 this->fPatternNumber=-999999;
1206 this->fPatternNumber=-999999;
1207 if (this->fPatternNumber==-999999){
1209 }
1210 }
1211}
1212
1214{
1215 // Bool_t localdebug=kFALSE;
1216 if(Compare(value)) {
1217 QwHelicityDecoder* input= dynamic_cast<QwHelicityDecoder*>(value);
1218
1219 fEventNumber = (fEventNumber == 0) ? input->fEventNumber :
1220 std::min(fEventNumber, input->fEventNumber);
1221 for (size_t i=0; i<fWord.size(); i++) {
1222 fWord[i].fValue = (fWord[i].fValue == 0) ? input->fWord[i].fValue :
1223 std::min( fWord[i].fValue, input->fWord[i].fValue);
1224 }
1225 }
1226}
1227
1229{
1230 // this is stub function defined here out of completion and uniformity between each subsystem
1231 *this = value1;
1232 CheckPatternNum(value2);
1233 MergeCounters(value2);
1234}
1235
1236void QwHelicityDecoder::AccumulateRunningSum(VQwSubsystem* value, Int_t count, Int_t ErrorMask){
1237 if (Compare(value)) {
1238 MergeCounters(value);
1239 QwHelicityDecoder* input = dynamic_cast<QwHelicityDecoder*>(value);
1240 fPatternNumber = (fPatternNumber <=0 ) ? input->fPatternNumber :
1241 std::min(fPatternNumber, input->fPatternNumber);
1242 // Keep track of the various error quantities, so we can print
1243 // them at the end.
1248 }
1249}
1250
1252{
1253 Bool_t res=kTRUE;
1254 if(typeid(*value)!=typeid(*this)) {
1255 res=kFALSE;
1256 } else {
1257 QwHelicityDecoder* input= dynamic_cast<QwHelicityDecoder*>(value);
1258 if(input->fWord.size()!=fWord.size()) {
1259 res=kFALSE;
1260 }
1261 }
1262 return res;
1263}
A logfile class, based on an identical class in the Hermes analyzer.
#define QwOut
Predefined log drain for explicit output.
Definition QwLog.h:34
#define QwError
Predefined log drain for errors.
Definition QwLog.h:39
#define QwWarning
Predefined log drain for warnings.
Definition QwLog.h:44
#define QwMessage
Predefined log drain for regular messages.
Definition QwLog.h:49
#define QwDebug
Predefined log drain for debugging output.
Definition QwLog.h:59
Helper functions and utilities for ROOT histogram management.
QwHistogramHelper gQwHists
Globally defined instance of the QwHistogramHelper class.
ROOT file and tree management wrapper classes.
static const UInt_t kErrorFlag_Helicity
Definition QwTypes.h:175
static const UInt_t kGlobalCut
Definition QwTypes.h:182
ULong64_t BankID_t
Definition QwTypes.h:21
static const UInt_t kEventCutMode3
Definition QwTypes.h:174
UInt_t ROCID_t
Definition QwTypes.h:20
Helicity data decoder from the data file.
std::vector< TH1_ptr > fHistograms
Histograms associated with this data element.
Utility class for histogram creation and management.
static std::ostream & endl(std::ostream &)
End of the line.
Definition QwLog.cc:297
Command-line and configuration file options processor.
Definition QwOptions.h:141
T GetValue(const std::string &key)
Get a templated value.
Definition QwOptions.h:236
bool HasValue(const std::string &key)
Has this key been defined.
Definition QwOptions.h:229
po::options_description_easy_init AddOptions(const std::string &blockname="Specialized options")
Add an option to a named block or create new block.
Definition QwOptions.h:170
Configuration file parser with flexible tokenization and search capabilities.
Bool_t PopValue(const std::string keyname, T &retvalue)
void SetCommentChars(const std::string value)
Set various sets of special characters.
const std::pair< TString, TString > GetParamFileNameContents()
A helper class to manage a vector of branch entries for ROOT trees.
Definition QwRootFile.h:55
size_type size() const noexcept
Definition QwRootFile.h:83
void push_back(const std::string &name, const char type='D')
Definition QwRootFile.h:197
void SetValue(size_type index, Double_t val)
Definition QwRootFile.h:110
Int_t GetSubbankIndex() const
virtual VQwSubsystem & operator=(VQwSubsystem *value)
Assignment Note: Must be called at the beginning of all subsystems routine call to operator=(VQwSubsy...
void RegisterRocBankMarker(QwParameterFile &mapstr)
static void DefineOptions()
Define options function (note: no virtual static functions in C++)
TString GetName() const
std::map< TString, TString > fDetectorMaps
Map of file name to full path or content.
VQwSubsystem(const TString &name)
Constructor with name.
void SetDataLoaded(Bool_t flag)
Bool_t HasDataLoaded() const
std::vector< QwWord > fWord
UInt_t BuildHelicityBitPattern(Int_t patternsize)
Int_t fActualPatternPolarity
True polarity of the current pattern.
UInt_t GetRandomSeed(UShort_t *first24randbits)
QwHelicityBase()
Private default constructor (not implemented, will throw linker error on use)
Bool_t fSuppressMPSErrorMsgs
virtual UInt_t GetRandbit(UInt_t &ranseed)
Int_t fNumMissedEventBlocks
Int_t fPreviousPatternPolarity
True polarity of the previous pattern.
std::vector< UInt_t > fHelicityBitPattern
UInt_t GetRandbit30(UInt_t &ranseed)
Int_t fDelayedPatternPolarity
Reported polarity of the current pattern.
Int_t fPatternPhaseNumberOld
static const Int_t kUndefinedHelicity
virtual void ProcessEvent() override
void MergeCounters(VQwSubsystem *value)
VQwSubsystem & operator=(VQwSubsystem *value) override
Assignment Note: Must be called at the beginning of all subsystems routine call to operator=(VQwSubsy...
Int_t LoadChannelMap(TString mapfile) override
Mandatory map file definition.
void FillTreeVector(QwRootTreeBranchVector &values) const override
Fill the tree vector.
Int_t ProcessEvBuffer(const ROCID_t roc_id, const BankID_t bank_id, UInt_t *buffer, UInt_t num_words)
TODO: The non-event-type-aware ProcessEvBuffer routine should be replaced with the event-type-aware v...
virtual void ClearEventData() override
void AccumulateRunningSum(VQwSubsystem *value, Int_t count=0, Int_t ErrorMask=0xFFFFFFF) override
Update the running sums for devices.
Bool_t Compare(VQwSubsystem *source)
void SetFirstBits(UInt_t nbits, UInt_t firstbits)
QwHelicityDecoder()
Private default constructor (not implemented, will throw linker error on use)
virtual void ConstructHistograms()
Construct the histograms for this subsystem.
void Ratio(VQwSubsystem *numer, VQwSubsystem *denom) override
Bool_t ApplySingleEventCuts() override
Apply the single event cuts.
void ConstructBranch(TTree *tree, TString &prefix) override
Construct the branch and tree vector.
VQwSubsystem & operator+=(VQwSubsystem *value) override
void ProcessOptions(QwOptions &options) override
Process the command line options.
void EncodeEventData(std::vector< UInt_t > &buffer) override
static const Int_t fNumDecoderWords
static const std::vector< UInt_t > kDefaultHelicityBitPattern
void SetHelicityBitPattern(TString hex)
Int_t LoadInputParameters(TString pedestalfile) override
Mandatory parameter file definition.
Int_t LoadEventCuts(TString filename) override
Optional event cut file.
void CheckPatternNum(VQwSubsystem *value)
Int_t ProcessConfigurationBuffer(const ROCID_t roc_id, const BankID_t bank_id, UInt_t *buffer, UInt_t num_words) override
void SetHelicityDelay(Int_t delay)
void FillHDVariables(uint32_t data, uint32_t index)
void FillHistograms() override
Fill the histograms for this subsystem.
void SetHistoTreeSave(const TString &prefix)
void ConstructBranchAndVector(TTree *tree, TString &prefix, QwRootTreeBranchVector &values) override
Construct the branch and tree vector.