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 = kTRUE;
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
242
243 }
244 return;
245}
246
247
248void QwHelicityDecoder::EncodeEventData(std::vector<UInt_t> &buffer)
249{
250}
251
253{
254 QwOut << "===========================\n"
255 << "This event: Event#, Pattern#, PatternPhase#="
256 << fEventNumber << ", "
257 << fPatternNumber << ", "
259 QwOut << "Previous event: Event#, Pattern#, PatternPhase#="
260 << fEventNumberOld << ", "
261 << fPatternNumberOld << ", "
263 QwOut << "delta = \n(fEventNumberOld)-(fMaxPatternPhase)x(fPatternNumberOld)-(fPatternPhaseNumberOld)= "
265 QwOut << "Helicity Reported, Delayed, Actual ="
266 << fHelicityReported << ","
267 << fHelicityDelayed << ","
269 QwOut << "===" << QwLog::endl;
270 return;
271}
272
273
275{
276 UInt_t value = 0;
277 TString valuestr;
278
279 QwParameterFile mapstr(mapfile.Data()); //Open the file
281 mapstr.EnableGreediness();
282 mapstr.SetCommentChars("!");
283
284 while (mapstr.ReadNextLine()){
285 // This class doesn't have any normal decode lines in the map file,
286 // so there is nothing to do in this loop. We just need the one
287 // call to "ReadNextLine" to populate the list of key/vale pairs.
288
289 // std::cout << "in the loop: " << mapstr.GetLine() << std::endl;
290 // RegisterRocBankMarker(mapstr);
291 }
292 //std::cout << "finished loop" << std::endl;
293
294 // Call "RegisterRocBankMarker" to record the ROC/Bank our data is in.
295 RegisterRocBankMarker(mapstr);
296
297 // If we have other key/values we want to use, we'd need to go though
298 // them here to see if they were found in the mapfile.
299 if (mapstr.PopValue("patternphase",value)) {
300 fMaxPatternPhase=value;
301 //QwMessage << " fMaxPatternPhase " << fMaxPatternPhase << QwLog::endl;
302 }
303
304
305 //PrintInfo();
306 return 0;
307}
308
309
310Int_t QwHelicityDecoder::LoadEventCuts(TString filename){
311
312 return 0;
313}
314
315Int_t QwHelicityDecoder::ProcessEvBuffer(UInt_t event_type, const ROCID_t roc_id, const BankID_t bank_id, UInt_t* buffer, UInt_t num_words)
316{
317
318 Bool_t lkDEBUG = kFALSE;
319 //std::cout << " roc id = " << roc_id << "bank id = " << bank_id << std::endl;
320 Int_t index = GetSubbankIndex(roc_id,bank_id);
321 //std::cout << "index = " << index << std::endl;
322 if (index >= 0 && num_words > 0) {
323 SetDataLoaded(kTRUE);
324 // lkDEBUG=kTRUE;
325
326 uint32_t type_last = 15; /* initialize to type FILLER WORD */
327 uint32_t time_last = 0;
328 uint32_t decoder_index = 0;
329 uint32_t num_decoder_words = 1;
330
331 uint32_t slot_id_ev_hd = 0;
332 uint32_t slot_id_dnv = 0;
333 uint32_t slot_id_fill = 0;
334
335 uint32_t new_type;
336 uint32_t type;
337 uint32_t slot_id_hd;
338 uint32_t mod_id_hd;
339 uint32_t slot_id_tr;
340 uint32_t n_evts;
341 uint32_t blk_num;
342 uint32_t n_words;
343 uint32_t evt_num_1;
344 uint32_t trig_time;
345 uint32_t time_now=0;
346 uint32_t time_1;
347 uint32_t time_2;
348
349 uint32_t data;
350
351 if (num_words<fNumDecoderWords+4){
352 std::cerr << "Not enough words in the bank:"<< std::endl;
353 return kFALSE;
354
355 } else
356 for (size_t i=0; i<num_words; i++){
357
358 data = buffer[i];
359 if(decoder_index) /* decoder type data word - set by decoder header word */
360 {
361 type = 16; /* set decoder data words as type 16 */
362 new_type = 0;
363 if(decoder_index < num_decoder_words)
364 {
365 FillHDVariables(data, decoder_index - 1);
366 if(lkDEBUG)
367 printf("%8X - decoder data(%d) = %d\n", data, (decoder_index - 1),
368 data);
369 decoder_index++;
370 }
371 else /* last decoder word */
372
373 {
374 FillHDVariables(data, decoder_index - 1);
375 if(lkDEBUG)
376 printf("%8X - decoder data(%d) = %d\n", data, (decoder_index - 1),
377 data);
378 decoder_index = 0;
379 num_decoder_words = 1;
380 }
381 }
382 else /* normal typed word */
383 {
384 if(data & 0x80000000) /* data type defining word */
385 {
386 new_type = 1;
387 type = (data & 0x78000000) >> 27;
388 }
389 else /* data type continuation word */
390 {
391 new_type = 0;
392 type = type_last;
393 }
394
395 switch (type)
396 {
397 case 0: /* BLOCK HEADER */
398 slot_id_hd = (data & 0x7C00000) >> 22;
399 mod_id_hd = (data & 0x3C0000) >> 18;
400 n_evts = (data & 0x000FF);
401 blk_num = (data & 0x3FF00) >> 8;
402 if(lkDEBUG)
403 printf
404 ("%8X - BLOCK HEADER - slot = %d id = %d n_evts = %d n_blk = %d\n",
405 data, slot_id_hd, mod_id_hd, n_evts,
406 blk_num);
407 break;
408
409 case 1: /* BLOCK TRAILER */
410 slot_id_tr = (data & 0x7C00000) >> 22;
411 n_words = (data & 0x3FFFFF);
412 if(lkDEBUG)
413 printf("%8X - BLOCK TRAILER - slot = %d n_words = %d\n",
414 data, slot_id_tr, n_words);
415 break;
416
417 case 2: /* EVENT HEADER */
418 if(new_type)
419 {
420 slot_id_ev_hd = (data & 0x07C00000) >> 22;
421 evt_num_1 = (data & 0x00000FFF);
422 trig_time = (data & 0x003FF000) >> 12;
423 if(lkDEBUG)
424 printf
425 ("%8X - EVENT HEADER - slot = %d evt_num = %d trig_time = %d (%X)\n",
426 data, slot_id_ev_hd, evt_num_1, trig_time,
427 trig_time);
428 }
429 break;
430
431 case 3: /* TRIGGER TIME */
432
433 if(new_type)
434 {
435 time_1 = (data & 0x7FFFFFF);
436 if(lkDEBUG)
437 printf("%8X - TRIGGER TIME 1 - time = %X\n", data,
438 time_1);
439 time_now = 1;
440 time_last = 1;
441 }
442 else
443 {
444 if(time_last == 1)
445 {
446 time_2 = (data & 0xFFFFF);
447 if(lkDEBUG)
448 printf("%8X - TRIGGER TIME 2 - time = %X\n", data,
449 time_2);
450 time_now = 2;
451 }
452 else if(lkDEBUG)
453 printf("%8X - TRIGGER TIME - (ERROR)\n", data);
454
455 time_last = time_now;
456 }
457 break;
458
459 case 4: /* UNDEFINED TYPE */
460 if(lkDEBUG)
461 printf("%8X - UNDEFINED TYPE = %d\n", data, type);
462 break;
463
464 case 5: /* UNDEFINED TYPE */
465 if(lkDEBUG)
466 printf("%8X - UNDEFINED TYPE = %d\n", data, type);
467 break;
468
469 case 6: /* UNDEFINED TYPE */
470 if(lkDEBUG)
471 printf("%8X - UNDEFINED TYPE = %d\n", data, type);
472 break;
473
474 case 7: /* UNDEFINED TYPE */
475 if(lkDEBUG)
476 printf("%8X - UNDEFINED TYPE = %d\n", data, type);
477 break;
478
479 case 8: /* DECODER HEADER */
480 num_decoder_words = (data & 0x3F); /* number of decoder words to follow */
481 decoder_index = 1; /* identify next word as a decoder data word */
482 if(lkDEBUG)
483 printf("%8X - DECODER HEADER = %d (NUM DECODER WORDS = %d)\n",
484 data, type, num_decoder_words);
485 break;
486
487 case 9: /* UNDEFINED TYPE */
488 if(lkDEBUG)
489 printf("%8X - UNDEFINED TYPE = %d\n", data, type);
490 break;
491
492 case 10: /* UNDEFINED TYPE */
493 if(lkDEBUG)
494 printf("%8X - UNDEFINED TYPE = %d\n", data, type);
495 break;
496
497 case 11: /* UNDEFINED TYPE */
498 if(lkDEBUG)
499 printf("%8X - UNDEFINED TYPE = %d\n", data, type);
500 break;
501
502 case 12: /* UNDEFINED TYPE */
503 if(lkDEBUG)
504 printf("%8X - UNDEFINED TYPE = %d\n", data, type);
505 break;
506
507 case 13: /* END OF EVENT */
508 if(lkDEBUG)
509 printf("%8X - END OF EVENT = %d\n", data, type);
510 break;
511
512 case 14: /* DATA NOT VALID (no data available) */
513 slot_id_dnv = (data & 0x7C00000) >> 22;
514 if(lkDEBUG)
515 printf("%8X - DATA NOT VALID = %d slot = %d\n", data,
516 type, slot_id_dnv);
517 break;
518
519 case 15: /* FILLER WORD */
520 slot_id_fill = (data & 0x7C00000) >> 22;
521 if(lkDEBUG)
522 printf("%8X - FILLER WORD = %d slot = %d\n", data, type,
523 slot_id_fill);
524 break;
525 }
526
527 type_last = type; /* save type of current data word */
528
529 }
530 }
531 }
532 return 0;
533}
534
535void QwHelicityDecoder::FillHDVariables(uint32_t data, uint32_t index) {
536
537 switch (index) {
538 case 0:
539 fSeed_Reported=data;
540 break;
541 case 1:
543 break;
544 case 2:
545 fEventNumber=data;
546 break;
547 case 3:
548 fPatternNumber=data;
549 break;
550 case 4:
551 fNum_Pair_Sync=data;
552 break;
553 case 5:
555 break;
556 case 6:
558 break;
559 case 7:
561 break;
562 case 8:
564 break;
565 case 9:
566 fPatternPhaseNumber = ((data>>8) & 0xff)+1;
567 fEventPolarity = (data>>5) & 0x1;
568 fReportedPatternHel = (data>>4) & 0x1;
569 fBit_Helicity = (data>>3) & 0x1;
570 fBit_PairSync = (data>>2) & 0x1;
571 fBit_PatSync = (data>>1) & 0x1;
572 fBit_TStable = data & 0x1;
573 break;
574 case 10:
576 break;
577 case 11:
579 break;
580 case 12:
582 break;
583 case 13:
585 break;
586 }
587}
588
589void QwHelicityDecoder::SetFirstBits(UInt_t nbits, UInt_t seed)
590{
591 // This gives the predictor a quick start
592 UShort_t firstbits[nbits];
593 for (unsigned int i = 0; i < nbits; i++) firstbits[i] = (seed >> i) & 0x1;
594 // Set delayed seed
595 iseed_Delayed = GetRandomSeed(firstbits);
596 // Progress actual seed by the helicity delay
598 for (int i = 0; i < fHelicityDelay; i++) GetRandbit(iseed_Actual);
599}
600
601void QwHelicityDecoder::SetHistoTreeSave(const TString &prefix)
602{
603 Ssiz_t len;
604 if (TRegexp("diff_").Index(prefix,&len) == 0
605 || TRegexp("asym[1-9]*_").Index(prefix,&len) == 0)
607 else if (TRegexp("yield_").Index(prefix,&len) == 0)
609 else
611
612}
613
614void QwHelicityDecoder::ConstructHistograms(TDirectory *folder, TString &prefix)
615{
616 SetHistoTreeSave(prefix);
617 if (folder != NULL) folder->cd();
618 TString basename;
619 size_t index=0;
620
622 {
623 //do nothing
624 }
626 {
627 fHistograms.resize(1+fWord.size(), NULL);
628 basename="pattern_polarity";
629 fHistograms[index] = gQwHists.Construct1DHist(basename);
630 index+=1;
631 for (size_t i=0; i<fWord.size(); i++){
632 basename="hel_"+fWord[i].fWordName;
633 fHistograms[index] = gQwHists.Construct1DHist(basename);
634 index+=1;
635 }
636 }
637 else if(fHistoType==kHelSaveMPS)
638 {
639 fHistograms.resize(4+fWord.size(), NULL);
640 //eventnumber, patternnumber, helicity, patternphase + fWord.size
641 basename=prefix+"delta_event_number";
642 fHistograms[index] = gQwHists.Construct1DHist(basename);
643 index+=1;
644 basename=prefix+"delta_pattern_number";
645 fHistograms[index] = gQwHists.Construct1DHist(basename);
646 index+=1;
647 basename=prefix+"pattern_phase";
648 fHistograms[index] = gQwHists.Construct1DHist(basename);
649 index+=1;
650 basename=prefix+"helicity";
651 fHistograms[index] = gQwHists.Construct1DHist(basename);
652 index+=1;
653 for (size_t i=0; i<fWord.size(); i++){
654 basename=prefix+fWord[i].fWordName;
655 fHistograms[index] = gQwHists.Construct1DHist(basename);
656 index+=1;
657 }
658 }
659 else
660 QwError << "QwHelicityDecoder::ConstructHistograms this prefix--" << prefix << "-- is not unknown:: no histo created" << QwLog::endl;
661
662 return;
663}
664
666{
667 if (fHistograms.size()==0){return;}
668 size_t index=0;
670 {
671 //do nothing
672 }
674 {
675 QwDebug << "QwHelicityDecoder::FillHistograms helicity info " << QwLog::endl;
676 QwDebug << "QwHelicityDecoder::FillHistograms pattern polarity=" << fActualPatternPolarity << QwLog::endl;
677 if (fHistograms[index]!=NULL)
679 index+=1;
680
681 for (size_t i=0; i<fWord.size(); i++){
682 if (fHistograms[index]!=NULL)
683 fHistograms[index]->Fill(fWord[i].fValue);
684 index+=1;
685 QwDebug << "QwHelicityDecoder::FillHistograms " << fWord[i].fWordName << "=" << fWord[i].fValue << QwLog::endl;
686 }
687 }
688 else if(fHistoType==kHelSaveMPS)
689 {
690 QwDebug << "QwHelicityDecoder::FillHistograms mps info " << QwLog::endl;
691 if (fHistograms[index]!=NULL)
693 index+=1;
694 if (fHistograms[index]!=NULL)
696 index+=1;
697 if (fHistograms[index]!=NULL)
698 fHistograms[index]->Fill(fPatternPhaseNumber);
699 index+=1;
700 if (fHistograms[index]!=NULL)
701 fHistograms[index]->Fill(fHelicityActual);
702 index+=1;
703 for (size_t i=0; i<fWord.size(); i++){
704 if (fHistograms[index]!=NULL)
705 fHistograms[index]->Fill(fWord[i].fValue);
706 index+=1;
707 QwDebug << "QwHelicityDecoder::FillHistograms " << fWord[i].fWordName << "=" << fWord[i].fValue << QwLog::endl;
708 }
709 }
710
711 return;
712}
713
714
716{
717 SetHistoTreeSave(prefix);
718 fTreeArrayIndex = values.size();
719 TString basename;
721 {
722 //do nothing
723 }
724 else if(fHistoType==kHelSaveMPS)
725 {
726 basename = "hd_actual_helicity"; //predicted actual helicity before being delayed.
727 values.push_back(basename, 'I');
728 tree->Branch(basename, &(values.back<Double_t>()), basename+"/I");
729
730 basename = "hd_delayed_helicity"; //predicted delayed helicity
731 values.push_back(basename, 'I');
732 tree->Branch(basename, &(values.back<Double_t>()), basename+"/I");
733 //
734 basename = "hd_reported_helicity"; //delayed helicity reported by the input register.
735 values.push_back(basename, 'I');
736 tree->Branch(basename, &(values.back<Double_t>()), basename+"/I");
737 //
738 basename = "hd_pattern_phase";
739 values.push_back(basename, 'I');
740 tree->Branch(basename, &(values.back<Double_t>()), basename+"/I");
741 //
742 basename = "hd_pattern_number";
743 values.push_back(basename, 'I');
744 tree->Branch(basename, &(values.back<Double_t>()), basename+"/I");
745 //
746 basename = "hd_pattern_seed";
747 values.push_back(basename, 'I');
748 tree->Branch(basename, &(values.back<Double_t>()), basename+"/I");
749 //
750 basename = "hd_event_number";
751 values.push_back(basename, 'I');
752 tree->Branch(basename, &(values.back<Double_t>()), basename+"/I");
753
754 basename = "hd_event_Polarity";
755 values.push_back(basename, 'I');
756 tree->Branch(basename, &(values.back<Double_t>()), basename+"/I");
757
758 basename = "hd_Reported_Pattern_Hel";
759 values.push_back(basename, 'I');
760 tree->Branch(basename, &(values.back<Double_t>()), basename+"/I");
761 //
762 for (size_t i=0; i<fWord.size(); i++)
763 {
764 basename = fWord[i].fWordName;
765 values.push_back(basename, 'I');
766 tree->Branch(basename, &(values.back<Double_t>()), basename+"/I");
767 }
768 }
770 {
771 basename = "hd_actual_helicity"; //predicted actual helicity before being delayed.
772 values.push_back(basename, 'I');
773 tree->Branch(basename, &(values.back<Double_t>()), basename+"/I");
774 //
775 basename = "hd_actual_pattern_polarity";
776 values.push_back(basename, 'I');
777 tree->Branch(basename, &(values.back<Double_t>()), basename+"/I");
778 //
779 basename = "hd_actual_previous_pattern_polarity";
780 values.push_back(basename, 'I');
781 tree->Branch(basename, &(values.back<Double_t>()), basename+"/I");
782 //
783 basename = "hd_delayed_pattern_polarity";
784 values.push_back(basename, 'I');
785 tree->Branch(basename, &(values.back<Double_t>()), basename+"/I");
786 //
787 basename = "hd_pattern_number";
788 values.push_back(basename, 'I');
789 tree->Branch(basename, &(values.back<Double_t>()), basename+"/I");
790 //
791 basename = "hd_pattern_seed";
792 values.push_back(basename, 'I');
793 tree->Branch(basename, &(values.back<Double_t>()), basename+"/I");
794 //
795 for (size_t i=0; i<fWord.size(); i++)
796 {
797 basename = fWord[i].fWordName;
798 values.push_back(basename, 'I');
799 tree->Branch(basename, &(values.back<Double_t>()), basename+"/I");
800 }
801 }
802 std::cout << "after construction size " << values.size() << std::endl;
803 return;
804}
805
806void QwHelicityDecoder::ConstructBranch(TTree *tree, TString &prefix)
807{
808TString basename;
809
810 SetHistoTreeSave(prefix);
811// print the branch and type name (arindam)
812//std::cout << "QwHelicityDecoder::ConstructBranch" << std::endl;
813//std::cout << tree->GetName() << " " << prefix << " " << std::endl;
814//std::cout << "Histo type --> " << fHistoType << std::endl;
816 {
817 //do nothing
818 }
819 else if(fHistoType==kHelSaveMPS)
820 {
821 // basename = "hd_actual_helicity"; //predicted actual helicity before being delayed.
822 // tree->Branch(basename, &fHelicityActual, basename+"/I");
823 //
824 basename = "hd_delayed_helicity"; //predicted delayed helicity
825 tree->Branch(basename, &fHelicityDelayed, basename+"/I");
826 //
827 basename = "hd_reported_helicity"; //delayed helicity reported by the input register.
828 tree->Branch(basename, &fHelicityReported, basename+"/I");
829 //
830 basename = "hd_pattern_phase";
831 tree->Branch(basename, &fPatternPhaseNumber, basename+"/I");
832 //
833 basename = "hd_pattern_number";
834 tree->Branch(basename, &fPatternNumber, basename+"/I");
835 //
836 basename = "hd_pattern_seed";
837 tree->Branch(basename, &fPatternSeed, basename+"/I");
838 //
839 basename = "hd_event_number";
840 tree->Branch(basename, &fEventNumber, basename+"/I");
841
842 basename = "hd_event_Polarity";
843 tree->Branch(basename, &fEventPolarity, basename+"/I");
844
845 basename = "hd_Reported_Pattern_Hel";
846 tree->Branch(basename, &fReportedPatternHel, basename+"/I");
847 }
849 {
850 basename = "hd_actual_helicity"; //predicted actual helicity before being delayed.
851 tree->Branch(basename, &fHelicityActual, basename+"/I");
852 //
853 basename = "hd_actual_pattern_polarity";
854 tree->Branch(basename, &fActualPatternPolarity, basename+"/I");
855 //
856 basename = "hd_actual_previous_pattern_polarity";
857 tree->Branch(basename, &fPreviousPatternPolarity, basename+"/I");
858 //
859 basename = "hd_delayed_pattern_polarity";
860 tree->Branch(basename, &fDelayedPatternPolarity, basename+"/I");
861 //
862 basename = "hd_pattern_number";
863 tree->Branch(basename, &fPatternNumber, basename+"/I");
864 //
865 basename = "hd_pattern_seed";
866 tree->Branch(basename, &fPatternSeed, basename+"/I");
867
868 for (size_t i=0; i<fWord.size(); i++)
869 {
870 basename = fWord[i].fWordName;
871 tree->Branch(basename, &fWord[i].fValue, basename+"/I");
872 }
873 }
874 //QwError << "entering construct branch should not be here : arindam" << QwLog::endl;
875
876 return;
877}
878
879void QwHelicityDecoder::ConstructBranch(TTree *tree, TString &prefix, QwParameterFile& trim_file)
880{
881 TString basename;
882
883 SetHistoTreeSave(prefix);
885 {
886 //do nothing
887 }
888 else if(fHistoType==kHelSaveMPS)
889 {
890 // basename = "hd_actual_helicity"; //predicted actual helicity before being delayed.
891 // tree->Branch(basename, &fHelicityActual, basename+"/I");
892 //
893 basename = "hd_delayed_helicity"; //predicted delayed helicity
894 tree->Branch(basename, &fHelicityDelayed, basename+"/I");
895 //
896 basename = "hd_reported_helicity"; //delayed helicity reported by the input register.
897 tree->Branch(basename, &fHelicityReported, basename+"/I");
898 //
899 basename = "hd_pattern_phase";
900 tree->Branch(basename, &fPatternPhaseNumber, basename+"/I");
901 //
902 basename = "hd_pattern_number";
903 tree->Branch(basename, &fPatternNumber, basename+"/I");
904 //
905 basename = "hd_pattern_seed";
906 tree->Branch(basename, &fPatternSeed, basename+"/I");
907 //
908 basename = "hd_event_number";
909 tree->Branch(basename, &fEventNumber, basename+"/I");
910
911 basename = "hd_event_Polarity";
912 tree->Branch(basename, &fEventPolarity, basename+"/I");
913
914 basename = "hd_Reported_Pattern_Hel";
915 tree->Branch(basename, &fReportedPatternHel, basename+"/I");
916 }
918 {
919 basename = "hd_actual_helicity"; //predicted actual helicity before being delayed.
920 tree->Branch(basename, &fHelicityActual, basename+"/I");
921 //
922 basename = "hd_actual_pattern_polarity";
923 tree->Branch(basename, &fActualPatternPolarity, basename+"/I");
924 //
925 basename = "hd_actual_previous_pattern_polarity";
926 tree->Branch(basename, &fPreviousPatternPolarity, basename+"/I");
927 //
928 basename = "hd_delayed_pattern_polarity";
929 tree->Branch(basename, &fDelayedPatternPolarity, basename+"/I");
930 //
931 basename = "hd_pattern_number";
932 tree->Branch(basename, &fPatternNumber, basename+"/I");
933 //
934 basename = "hd_pattern_seed";
935 tree->Branch(basename, &fPatternSeed, basename+"/I");
936
937 for (size_t i=0; i<fWord.size(); i++)
938 {
939 basename = fWord[i].fWordName;
940 tree->Branch(basename,&fWord[i].fValue, basename+"/I");
941 }
942
943 }
944
945 return;
946}
947
949{
950
951 size_t index=fTreeArrayIndex;
953 {
954 values.SetValue(index++, fHelicityActual);
955 values.SetValue(index++, fHelicityDelayed);
956 values.SetValue(index++, fHelicityReported);
957 values.SetValue(index++, fPatternPhaseNumber);
958 values.SetValue(index++, fPatternNumber);
959 values.SetValue(index++, fPatternSeed);
960 values.SetValue(index++, fEventNumber);
961 values.SetValue(index++, fEventPolarity);
962 values.SetValue(index++, fReportedPatternHel);
963 for (size_t i=0; i<fWord.size(); i++)
964 values.SetValue(index++, fWord[i].fValue);
965 }
967 {
968 values.SetValue(index++, fHelicityActual);
969 values.SetValue(index++, fActualPatternPolarity);
970 values.SetValue(index++, fPreviousPatternPolarity);
971 values.SetValue(index++, fDelayedPatternPolarity);
972 values.SetValue(index++, fPatternNumber);
973 values.SetValue(index++, fPatternSeed);
974 for (size_t i=0; i<fWord.size(); i++){
975 values.SetValue(index++, fWord[i].fValue);
976 }
977 }
978
979 return;
980}
981
983{
984 Int_t ldebug = kFALSE;
985
986 if(ldebug) std::cout << "Entering QwHelicityDecoder::RunPredictor for fEventNumber, " << fEventNumber
987 << ", fPatternNumber, " << fPatternNumber
988 << ", and fPatternPhaseNumber, " << fPatternPhaseNumber << std::endl;
989
990 /**Update the random seed if the new event is from a different pattern.
991 Check the difference between old pattern number and the new one and
992 to see how many patterns we have missed or skipped. Then loop back
993 to get the correct pattern polarities.
994 */
996 iseed_Delayed = fSeed_Reported & 0x7fffffff;
997
998 /** set the polarity of the current pattern to be equal to the reported helicity,*/
1000 QwDebug << "QwHelicityDecoder:: CollectRandBits30: delayedpatternpolarity =" << fDelayedPatternPolarity << QwLog::endl;
1001
1002 /** then use it as the delayed helicity, */
1004
1005 /**if the helicity is delayed by a positive number of patterns then loop the delayed ranseed backward to get the ranseed
1006 for the actual helicity */
1007 if(fHelicityDelay >=0){
1009 for(Int_t i=0; i<fHelicityDelay; i++) {
1010 /**, get the pattern polarity for the actual pattern using that actual ranseed.*/
1013 }
1014 }
1015 }
1018//std::cout << "printing values : fHelicityDelayed = " << fHelicityDelayed << " : fDelayedPatternPolarity = " << fDelayedPatternPolarity << " : fEventPolarity = " << fEventPolarity << " : reported hel =" << fHelicityReported << " : pattern phase=" << fPatternPhaseNumber << std::endl;
1019
1020 if(ldebug){
1021 std::cout << "Predicted Polarity ::: Delayed ="
1022 << fDelayedPatternPolarity << " Actual ="
1023 << fActualPatternPolarity << "\n";
1024 std::cout << "Predicted Helicity ::: Delayed Helicity=" << fHelicityDelayed
1025 << " Actual Helicity=" << fHelicityActual << " Reported Helicity=" << fHelicityReported << "\n";
1026 QwError << "Exiting QwHelicityDecoder::RunPredictor " << QwLog::endl;
1027
1028 }
1029
1030 return;
1031}
1032
1034{
1035 Bool_t ldebug=kFALSE;
1036
1037 if(ldebug) std::cout << "Entering QwHelicityDecoder::PredictHelicity \n";
1038 if(ldebug) std::cout << "QwHelicityDecoder::PredictHelicity=>Predicting the helicity \n";
1039 RunPredictor();
1040
1041 if(ldebug) std::cout << "n_ranbit exiting the function = " << n_ranbits << "\n";
1042
1043 return;
1044}
1045
1046
1047
1049{
1050 /**Sets the number of bits the helicity reported gets delayed with.
1051 We predict helicity only if there is a non-zero pattern delay given. */
1052
1053 if(delay>=0){
1054 fHelicityDelay = delay;
1055 if(delay == 0){
1056 QwWarning << "QwHelicityDecoder : SetHelicityDelay :: helicity delay is set to 0."
1057 << " Disabling helicity predictor and using reported helicity information."
1058 << QwLog::endl;
1059 fUsePredictor = kFALSE;
1060 }
1061 else
1062 fUsePredictor = kTRUE;
1063 }
1064 else
1065 QwError << "QwHelicityDecoder::SetHelicityDelay We cannot handle negative delay in the prediction of delayed helicity. Exiting.." << QwLog::endl;
1066
1067 return;
1068}
1069
1070
1072{
1073 fHelicityBitPattern.clear();
1075 /* // Set the helicity pattern bits
1076 if (parity(bits) == 0)
1077 fHelicityBitPattern = bits;
1078 else QwError << "What, exactly, are you trying to do ?!?!?" << QwLog::endl;
1079 */
1080 // Notify the user
1081 QwMessage << " fPatternBits 0x" ;
1082 for (int i = fHelicityBitPattern.size()-1;i>=0; i--){
1083 QwMessage << std::hex << fHelicityBitPattern[i] << " ";
1084 }
1085 QwMessage << std::dec << QwLog::endl;
1086}
1087
1089{
1090 Bool_t ldebug = kFALSE;
1091 if(Compare(value))
1092 {
1093
1094 //QwHelicityDecoder* input= (QwHelicityDecoder*)value;
1096 QwHelicityDecoder* input= dynamic_cast<QwHelicityDecoder*>(value);
1097
1098 for(size_t i=0;i<input->fWord.size();i++)
1099 this->fWord[i].fValue=input->fWord[i].fValue;
1100 this->fHelicityActual = input->fHelicityActual;
1101 this->fPatternNumber = input->fPatternNumber;
1102 this->fPatternSeed = input->fPatternSeed;
1104 this->fEventNumber=input->fEventNumber;
1109 this->fHelicityActual=input->fHelicityActual;
1113 this->fGoodHelicity=input->fGoodHelicity;
1114 this->fGoodPattern=input->fGoodPattern;
1115 this->fIgnoreHelicity = input->fIgnoreHelicity;
1116 this->fEventPolarity = input->fEventPolarity;
1118
1119 this->fErrorFlag = input->fErrorFlag;
1120 this->fEventNumberFirst = input->fEventNumberFirst;
1122 this->fNumMissedGates = input->fNumMissedGates;
1126
1127 if(ldebug){
1128 std::cout << "QwHelicityDecoder::operator = this->fPatternNumber=" << this->fPatternNumber << std::endl;
1129 std::cout << "input->fPatternNumber=" << input->fPatternNumber << "\n";
1130 }
1131 }
1132
1133 return *this;
1134}
1135
1137{
1138 // Bool_t localdebug=kFALSE;
1139 QwDebug << "Entering QwHelicityDecoder::operator+= adding " << value->GetName() << " to " << this->GetName() << " " << QwLog::endl;
1140
1141 //this routine is most likely to be called during the computatin of assymetry
1142 //this call doesn't make too much sense for this class so the following lines
1143 //are only use to put safe gards testing for example if the two instantiation indeed
1144 // refers to elements in the same pattern.
1145 CheckPatternNum(value);
1146 MergeCounters(value);
1147 return *this;
1148}
1149
1151{
1152 // Bool_t localdebug=kFALSE;
1153 if(Compare(value)) {
1154 QwHelicityDecoder* input= dynamic_cast<QwHelicityDecoder*>(value);
1155 QwDebug << "QwHelicityDecoder::MergeCounters: this->fPatternNumber=" << this->fPatternNumber
1156 << ", input->fPatternNumber=" << input->fPatternNumber << QwLog::endl;
1157
1158 this->fErrorFlag |= input->fErrorFlag;
1159
1160 // Make sure the pattern number and poalrity agree!
1161 if(this->fPatternNumber!=input->fPatternNumber)
1162 this->fPatternNumber=-999999;
1164 this->fPatternNumber=-999999;
1165 if (this->fPatternNumber==-999999){
1167 }
1168 }
1169}
1170
1172{
1173 // Bool_t localdebug=kFALSE;
1174 if(Compare(value)) {
1175 QwHelicityDecoder* input= dynamic_cast<QwHelicityDecoder*>(value);
1176
1177 fEventNumber = (fEventNumber == 0) ? input->fEventNumber :
1178 std::min(fEventNumber, input->fEventNumber);
1179 for (size_t i=0; i<fWord.size(); i++) {
1180 fWord[i].fValue = (fWord[i].fValue == 0) ? input->fWord[i].fValue :
1181 std::min( fWord[i].fValue, input->fWord[i].fValue);
1182 }
1183 }
1184}
1185
1187{
1188 // this is stub function defined here out of completion and uniformity between each subsystem
1189 *this = value1;
1190 CheckPatternNum(value2);
1191 MergeCounters(value2);
1192}
1193
1194void QwHelicityDecoder::AccumulateRunningSum(VQwSubsystem* value, Int_t count, Int_t ErrorMask){
1195 if (Compare(value)) {
1196 MergeCounters(value);
1197 QwHelicityDecoder* input = dynamic_cast<QwHelicityDecoder*>(value);
1198 fPatternNumber = (fPatternNumber <=0 ) ? input->fPatternNumber :
1199 std::min(fPatternNumber, input->fPatternNumber);
1200 // Keep track of the various error quantities, so we can print
1201 // them at the end.
1206 }
1207}
1208
1210{
1211 Bool_t res=kTRUE;
1212 if(typeid(*value)!=typeid(*this)) {
1213 res=kFALSE;
1214 } else {
1215 QwHelicityDecoder* input= dynamic_cast<QwHelicityDecoder*>(value);
1216 if(input->fWord.size()!=fWord.size()) {
1217 res=kFALSE;
1218 }
1219 }
1220 return res;
1221}
Helper functions and utilities for ROOT histogram management.
QwHistogramHelper gQwHists
Globally defined instance of the QwHistogramHelper class.
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
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.