JAPAn
Just Another Parity Analyzer
Loading...
Searching...
No Matches
QwHelicity.cc
Go to the documentation of this file.
1/**********************************************************\
2* File: QwHelicity.C *
3* *
4* Contributor: Arindam Sen (asen@jlab.org) *
5* Time-stamp: November, 2025 *
6\**********************************************************/
7
8#include "QwHelicity.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 "QwRootFile.h"
19
20// Qweak headers
21#include "QwHistogramHelper.h"
22#include "QwLog.h"
23
25
26//**************************************************//
27/// Default helicity bit pattern of 0x69 represents a -++-+--+ octet
28/// (event polarity listed in reverse time order), where the LSB
29/// of the bit pattern is the first event of the pattern.
30//**************************************************//
31
32/// Constructor with name
44
45//**************************************************//
47: VQwSubsystem(source.GetName()),
48 QwHelicityBase(source.GetName()),
53{
56 // Default helicity delay to two patterns.
58 // Default the EventType flags to HelPlus=1 and HelMinus=4
59 // These are only used in Moller decoding mode.
62 //
66 kUserbit=-1;
72 fHelicityBitPlus=kFALSE;
73 fHelicityBitMinus=kFALSE;
74 fGoodHelicity=kFALSE;
75 fGoodPattern=kFALSE;
77
78 this->fWord.resize(source.fWord.size());
79 for(size_t i=0;i<this->fWord.size();i++)
80 {
81 this->fWord[i].fWordName=source.fWord[i].fWordName;
82 this->fWord[i].fModuleType=source.fWord[i].fModuleType;
83 this->fWord[i].fWordType=source.fWord[i].fWordType;
84 }
91 fEventType = source.fEventType;
93 fRandBits = source.fRandBits;
101 iseed_Actual = source.iseed_Actual;
102 n_ranbits = source.n_ranbits;
103 fEventNumber = source.fEventNumber;
109
110 this->kUserbit = source.kUserbit;
111 this->fIgnoreHelicity = source.fIgnoreHelicity;
112}
113
114//**************************************************//
116{
117 options.AddOptions("Helicity options")
118 ("helicity.seed", po::value<int>(),
119 "Number of bits in random seed");
120 options.AddOptions("Helicity options")
121 ("helicity.bitpattern", po::value<std::string>(),
122 "Helicity bit pattern: 0x1 (pair), 0x9 (quartet), 0x69 (octet), 0x666999 (hexo-quad), 0x66669999 (octo-quad)");
123 options.AddOptions("Helicity options")
124 ("helicity.patternoffset", po::value<int>(),
125 "Set 1 when pattern starts with 1 or 0 when starts with 0");
126 options.AddOptions("Helicity options")
127 ("helicity.patternphase", po::value<int>(),
128 "Maximum pattern phase");
129 options.AddOptions("Helicity options")
130 ("helicity.delay", po::value<int>(),
131 "Default delay is 2 patterns, set at the helicity map file.");
132 options.AddOptions("Helicity options")
133 ("helicity.toggle-mode", po::value<bool>()->default_bool_value(false),
134 "Activates helicity toggle-mode, overriding the 'delay', 'patternphase', 'bitpattern', and 'seed' options.");
135}
136
137//**************************************************//
138
140{
141 // Read the cmd options and override channel map settings
142 QwMessage << "QwHelicity::ProcessOptions" << QwLog::endl;
143 if (options.HasValue("helicity.patternoffset")) {
144 if (options.GetValue<int>("helicity.patternoffset") == 1
145 || options.GetValue<int>("helicity.patternoffset") == 0) {
146 fPatternPhaseOffset = options.GetValue<int>("helicity.patternoffset");
147 QwMessage << " Pattern Phase Offset = " << fPatternPhaseOffset << QwLog::endl;
148 } else QwError << "Pattern phase offset should be 0 or 1!" << QwLog::endl;
149 }
150
151 if (options.HasValue("helicity.patternphase")) {
152 if (options.GetValue<int>("helicity.patternphase") % 2 == 0) {
153 fMaxPatternPhase = options.GetValue<int>("helicity.patternphase");
154 QwMessage << " Maximum Pattern Phase = " << fMaxPatternPhase << QwLog::endl;
155 } else QwError << "Pattern phase should be an even integer!" << QwLog::endl;
156 }
157
158 if (options.HasValue("helicity.seed")) {
159 if (options.GetValue<int>("helicity.seed") == 24
160 || options.GetValue<int>("helicity.seed") == 30) {
161 QwMessage << " Random Bits = " << options.GetValue<int>("helicity.seed") << QwLog::endl;
162 fRandBits = options.GetValue<int>("helicity.seed");
163 } else QwError << "Number of random seed bits should be 24 or 30!" << QwLog::endl;
164 }
165
166 if (options.HasValue("helicity.delay")) {
167 QwMessage << " Helicity Delay = " << options.GetValue<int>("helicity.delay") << QwLog::endl;
168 SetHelicityDelay(options.GetValue<int>("helicity.delay"));
169 }
170
171 if (options.HasValue("helicity.bitpattern")) {
172 QwMessage << " Helicity Pattern ="
173 << options.GetValue<std::string>("helicity.bitpattern")
174 << QwLog::endl;
175 std::string hex = options.GetValue<std::string>("helicity.bitpattern");
177 } else {
178 }
179
180 if (options.GetValue<bool>("helicity.toggle-mode")) {
181 fHelicityDelay = 0;
182 fUsePredictor = kFALSE;
185 }
186
187 // If we have the default Helicity Bit Pattern & a large fMaxPatternPhase,
188 // try to recompute the Helicity Bit Pattern.
190 }
191
192 // Here we're going to try to get the "online" option which
193 // is defined by QwEventBuffer.
194 if (options.HasValue("online")){
195 fSuppressMPSErrorMsgs = options.GetValue<bool>("online");
196 } else {
197 fSuppressMPSErrorMsgs = kFALSE;
198 }
199}
200
201
203{
204 SetDataLoaded(kFALSE);
205 for (size_t i=0;i<fWord.size();i++)
207
208 /**Reset data by setting the old event number, pattern number and pattern phase
209 to the values of the previous event.*/
210 if (fEventNumberFirst==-1 && fEventNumberOld!= -1){
212 }
216 }
217
221
222 //fIgnoreHelicity = kFALSE;
223
224 /**Clear out helicity variables */
228 fHelicityBitPlus = kFALSE;
229 fHelicityBitMinus = kFALSE;
230 // be careful: it is not that I forgot to reset fActualPatternPolarity
231 // or fDelayedPatternPolarity. One doesn't want to do that here.
232 /** Set the new event number and pattern number to -1. If we are not reading these correctly
233 from the data stream, -1 will allow us to identify that.*/
234 fEventNumber = -1;
236 fPatternNumber = -1;
237 return;
238}
239
240Int_t QwHelicity::ProcessConfigurationBuffer(const ROCID_t roc_id, const BankID_t bank_id, UInt_t* buffer, UInt_t num_words)
241{
242 //stub function
243 // QwError << " this function QwHelicity::ProcessConfigurationBuffer does nothing yet " << QwLog::endl;
244 return 0;
245}
246
247Int_t QwHelicity::LoadInputParameters(TString pedestalfile)
248{
249 return 0;
250}
251
252
254 //impose single event cuts //Paul's modifications
255
256 return kTRUE;
257}
258
259/*!
260 * \brief Process helicity information from userbit configuration data.
261 *
262 * This is a complex function (~80 lines) that extracts helicity information
263 * from userbit data for injector tests and special configurations. It handles:
264 *
265 * Userbit Decoding:
266 * - Extracts 3-bit userbit pattern from bits 28-30 of userbit word
267 * - Decodes quartet synchronization bit (bit 3) for pattern timing
268 * - Decodes helicity bit (bit 2) for spin state determination
269 * - Manages scaler offset calculations for event counting
270 *
271 * Event Counting Logic:
272 * - Increments event numbers based on scaler counter ratios
273 * - Handles missed events when scaler offset > 1 (indicates DAQ issues)
274 * - Maintains pattern phase and pattern number synchronization
275 * - Resets quartet phase on quartet sync bit assertion
276 *
277 * Helicity State Management:
278 * - Sets fHelicityBitPlus/fHelicityBitMinus based on userbit helicity bit
279 * - Updates fHelicityReported for downstream processing
280 * - Maintains helicity predictor state for data quality monitoring
281 *
282 * Error Recovery:
283 * - Detects missed events through scaler offset analysis
284 * - Resets helicity predictor when event sequence is uncertain
285 * - Provides debug output for missed event scenarios
286 *
287 * Pattern Synchronization:
288 * - Manages quartet boundaries using sync bits
289 * - Handles pattern phase wraparound at maximum phase
290 * - Maintains continuous event numbering across pattern boundaries
291 *
292 * \note This mode is primarily used for injector testing and is not the
293 * standard helicity decoding method for production Qweak data analysis.
294 *
295 * \warning Missed events (scaler offset > 1) will reset the helicity
296 * predictor and may affect downstream helicity-dependent analyses.
297 */
299{
300
301 /** In this version of the code, the helicity is extracted for a userbit configuration.
302 This is not what we plan to have for Qweak but it was done for injector tests and
303 so is useful to have as another option to get helicity information. */
304
305 Bool_t ldebug=kFALSE;
306 UInt_t userbits;
307 static UInt_t lastuserbits = 0xFF;
308 UInt_t scaleroffset=fWord[kScalerCounter].fValue/32;
309
310 if(scaleroffset==1 || scaleroffset==0) {
311 userbits = (fWord[kUserbit].fValue & 0xE0000000)>>28;
312
313 // Now fake the input register, MPS counter, QRT counter, and QRT phase.
315
316 lastuserbits = userbits;
317
318 if (lastuserbits==0xFF) {
320 } else {
321 if ((lastuserbits & 0x8) == 0x8) {
322 // Quartet bit is set.
323 fPatternPhaseNumber = fMinPatternPhase; // Reset the QRT phase
324 fPatternNumber=fPatternNumberOld+1; // Increment the QRT counter
325 } else {
326 fPatternPhaseNumber=fPatternPhaseNumberOld+1; // Increment the QRT phase
327 }
328
330
331 if ((lastuserbits & 0x4) == 0x4){ // Helicity bit is set.
332 fHelicityReported |= 1; // Set the InputReg HEL+ bit.
333 fHelicityBitPlus=kTRUE;
334 fHelicityBitMinus=kFALSE;
335 } else {
336 fHelicityReported |= 0; // Set the InputReg HEL- bit.
337 fHelicityBitPlus=kFALSE;
338 fHelicityBitMinus=kTRUE;
339 }
340 }
341 } else {
342 QwError << " QwHelicity::ProcessEvent finding a missed read event in the scaler" << QwLog::endl;
343 if(ldebug) {
344 std::cout << " QwHelicity::ProcessEvent :" << scaleroffset << " events were missed \n";
345 std::cout << " before manipulation \n";
346 Print();
347 }
348 //there was more than one event since the last reading of the scalers
349 //ie we should read only one event at the time,
350 //if not something is wrong
351 fEventNumber=fEventNumberOld+scaleroffset;
352 Int_t localphase=fPatternPhaseNumberOld;
353 Int_t localpatternnumber=fPatternNumberOld;
354 for (UInt_t i=0;i<scaleroffset;i++) {
355 fPatternPhaseNumber=localphase+1;
359 localpatternnumber=fPatternNumber;
360 }
361 localphase=fPatternPhaseNumber;
362 }
363 //Reset helicity predictor because we are not sure of what we are doing
366 if(ldebug) {
367 std::cout << " after manipulation \n";
368 Print();
369 }
370 }
371 return;
372}
373
374
376{
377 static Bool_t firstevent = kTRUE;
378 static Bool_t firstpattern = kTRUE;
379 static Bool_t fake_the_counters=kFALSE;
380 UInt_t thisinputregister=fWord[kInputRegister].fValue;
381
382 if (firstpattern){
383 // If any of the special counters are negative or zero, setup to
384 // generate the counters internally.
385 fake_the_counters |= (kPatternCounter<=0)
386 || ( kMpsCounter<=0) || (kPatternPhase<=0);
387 }
388
389 if (CheckIORegisterMask(thisinputregister,fInputReg_FakeMPS))
390 fIgnoreHelicity = kTRUE;
391 else
392 fIgnoreHelicity = kFALSE;
393
394 /** If we get junk for the mps and pattern information from the run
395 we can enable fake counters for mps, pattern number and pattern
396 phase to get the job done.
397 */
398 if (!fake_the_counters){
399 /**
400 In the Input Register Mode,
401 the event number is obtained straight from the wordkMPSCounter.
402 */
404 // When we have the minimum phase from the pattern phase word
405 // and the input register minimum phase bit is set
406 // we can select the second pattern as below.
407 if(fWord[kPatternPhase].fValue - fPatternPhaseOffset == 0)
408 if (firstpattern && CheckIORegisterMask(thisinputregister,fInputReg_PatternSync)){
409 firstpattern = kFALSE;
410 }
411
412 // If firstpattern is still TRUE, we are still searching for the first
413 // pattern of the data stream. So set the pattern number = 0
414 if (firstpattern)
415 fPatternNumber = -1;
416 else {
419 }
420 } else {
421 // Use internal variables for all the counters.
423 if (CheckIORegisterMask(thisinputregister,fInputReg_PatternSync)) {
426 } else {
429 }
430 }
431
432
433 if (firstevent){
434 firstevent = kFALSE;
435 } else if(fEventNumber!=(fEventNumberOld+1)){
436 Int_t nummissed(fEventNumber - (fEventNumberOld+1));
438 QwError << "QwHelicity::ProcessEvent read event# ("
439 << fEventNumber << ") is not old_event#+1; missed "
440 << nummissed << " gates" << QwLog::endl;
441 }
442 fNumMissedGates += nummissed;
445 }
446
448 // Quartet bit is set.
449 QwError << "QwHelicity::ProcessEvent: The Multiplet Sync bit is set, but the Pattern Phase is ("
450 << fPatternPhaseNumber << ") not "
451 << fMinPatternPhase << "! Please check the fPatternPhaseOffset in the helicity map file." << QwLog::endl;
454 }
455
457
458 /**
459 Extract the reported helicity from the input register for each event.
460 */
461
462 if (CheckIORegisterMask(thisinputregister,fInputReg_HelPlus)
463 && CheckIORegisterMask(thisinputregister,fInputReg_HelMinus) ){
464 // Both helicity bits are set.
465 QwError << "QwHelicity::ProcessEvent: Both the H+ and H- bits are set: thisinputregister=="
466 << thisinputregister << QwLog::endl;
468 fHelicityBitPlus = kFALSE;
469 fHelicityBitMinus = kFALSE;
470 } else if (CheckIORegisterMask(thisinputregister,fInputReg_HelPlus)){ // HelPlus bit is set.
471 fHelicityReported |= 1; // Set the InputReg HEL+ bit.
472 fHelicityBitPlus = kTRUE;
473 fHelicityBitMinus = kFALSE;
474 } else {
475 fHelicityReported |= 0; // Set the InputReg HEL- bit.
476 fHelicityBitPlus = kFALSE;
477 fHelicityBitMinus = kTRUE;
478 }
479
480 return;
481}
482
484{
485 static Bool_t firstpattern = kTRUE;
486
487 if(firstpattern && fWord[kPatternCounter].fValue > fPatternNumberOld){
488 firstpattern = kFALSE;
489 }
490
493 Int_t nummissed(fEventNumber - (fEventNumberOld+1));
494 QwError << "QwHelicity::ProcessEvent read event# ("
495 << fEventNumber << ") is not old_event#+1; missed "
496 << nummissed << " gates" << QwLog::endl;
497 fNumMissedGates += nummissed;
499 }
500 if (firstpattern){
501 fPatternNumber = -1;
503 } else {
506 // We are at a new pattern!
508 } else {
510 }
511 }
512
515 // fHelicityReported = (fEventType == 1 ? 0 : 1);
516
517 if (fHelicityReported == 1){
518 fHelicityBitPlus=kTRUE;
519 fHelicityBitMinus=kFALSE;
520 } else {
521 fHelicityBitPlus=kFALSE;
522 fHelicityBitMinus=kTRUE;
523 }
524 return;
525}
526
527
529{
530 Bool_t ldebug = kFALSE;
531 fErrorFlag = 0;
532
533 if (! HasDataLoaded()) return;
534
535 switch (fHelicityDecodingMode)
536 {
537 case kHelUserbitMode :
539 break;
542 break;
545 break;
546 default:
547 QwError << "QwHelicity::ProcessEvent no instructions on how to decode the helicity !!!!" << QwLog::endl;
548 abort();
549 break;
550 }
551
554
555 // Predict helicity if delay is non zero.
558 } else {
559 // Else use the reported helicity values.
562
567 }
568
569 }
570
571 if(ldebug){
572 std::cout<<"\nevent number= "<<fEventNumber<<std::endl;
573 std::cout<<"pattern number = "<<fPatternNumber<<std::endl;
574 std::cout<<"pattern phase = "<<fPatternPhaseNumber<<std::endl;
575 std::cout<<"max pattern phase = "<<fMaxPatternPhase<<std::endl;
576 std::cout<<"min pattern phase = "<<fMinPatternPhase<<std::endl;
577 }
578
579 return;
580}
581
582
583void QwHelicity::EncodeEventData(std::vector<UInt_t> &buffer)
584{
585 std::vector<UInt_t> localbuffer;
586 localbuffer.clear();
587
588 // Userbit mode
589 switch (fHelicityDecodingMode) {
590 case kHelUserbitMode: {
591 UInt_t userbit = 0x0;
592 if (fPatternPhaseNumber == fMinPatternPhase) userbit |= 0x80000000;
593 if (fHelicityDelayed == 1) userbit |= 0x40000000;
594
595 // Write the words to the buffer
596 localbuffer.push_back(0x1); // cleandata
597 localbuffer.push_back(0xa); // scandata1
598 localbuffer.push_back(0xa); // scandata2
599 localbuffer.push_back(0x0); // scalerheader
600 localbuffer.push_back(0x20); // scalercounter (32)
601 localbuffer.push_back(userbit); // userbit
602
603 for (int i = 0; i < 64; i++) localbuffer.push_back(0x0); // (not used)
604 break;
605 }
607 UInt_t input_register = 0x0;
608 if (fHelicityDelayed == 1) input_register |= fInputReg_HelPlus;
609 if (fHelicityDelayed == 0) input_register |= fInputReg_HelMinus;
611
612 // Write the words to the buffer
613 localbuffer.push_back(input_register); // input_register
614 localbuffer.push_back(0x0); // output_register
615 localbuffer.push_back(fEventNumber); // mps_counter
616 localbuffer.push_back(fPatternNumber); // pat_counter
617 localbuffer.push_back(fPatternPhaseNumber - fMinPatternPhase + fPatternPhaseOffset); // pat_phase
618
619 for (int i = 0; i < 17; i++) localbuffer.push_back(0x0); // (not used)
620 break;
621 }
622 default:
623 QwWarning << "QwHelicity::EncodeEventData: Unsupported helicity encoding!" << QwLog::endl;
624 break;
625 }
626
627 // If there is element data, generate the subbank header
628 std::vector<UInt_t> subbankheader;
629 std::vector<UInt_t> rocheader;
630 if (localbuffer.size() > 0) {
631
632 // Form CODA subbank header
633 subbankheader.clear();
634 subbankheader.push_back(localbuffer.size() + 1); // subbank size
635 subbankheader.push_back((fCurrentBank_ID << 16) | (0x01 << 8) | (1 & 0xff));
636 // subbank tag | subbank type | event number
637
638 // Form CODA bank/roc header
639 rocheader.clear();
640 rocheader.push_back(subbankheader.size() + localbuffer.size() + 1); // bank/roc size
641 rocheader.push_back((fCurrentROC_ID << 16) | (0x10 << 8) | (1 & 0xff));
642 // bank tag == ROC | bank type | event number
643
644 // Add bank header, subbank header and element data to output buffer
645 buffer.insert(buffer.end(), rocheader.begin(), rocheader.end());
646 buffer.insert(buffer.end(), subbankheader.begin(), subbankheader.end());
647 buffer.insert(buffer.end(), localbuffer.begin(), localbuffer.end());
648 }
649}
650
651Int_t QwHelicity::LoadChannelMap(TString mapfile)
652{
653 Bool_t ldebug=kFALSE;
654
655 Int_t wordsofar=0;
656 Int_t bankindex=-1;
657
658 fPatternPhaseOffset=1;//Phase number offset is set to 1 by default and will be set to 0 if phase number starts from 0
659
660
661 // Default value for random seed is 30 bits
662 fRandBits = 30;
663
664
665 QwParameterFile mapstr(mapfile.Data()); //Open the file
667 mapstr.EnableGreediness();
668 mapstr.SetCommentChars("!");
669
670 UInt_t value = 0;
671 TString valuestr;
672
673 while (mapstr.ReadNextLine()){
674 RegisterRocBankMarker(mapstr);
675
676 if (mapstr.PopValue("patternphase",value)) {
677 fMaxPatternPhase=value;
679 }
680 if (mapstr.PopValue("patternbits",valuestr)) {
681 SetHelicityBitPattern(valuestr);
682 }
683 if (mapstr.PopValue("inputregmask_fakemps",value)) {
684 fInputReg_FakeMPS = value;
685 }
686 if (mapstr.PopValue("inputregmask_helicity",value)) {
687 fInputReg_HelPlus = value;
689 }
690 if (mapstr.PopValue("inputregmask_helplus",value)) {
691 fInputReg_HelPlus = value;
692 }
693 if (mapstr.PopValue("inputregmask_helminus",value)) {
694 fInputReg_HelMinus = value;
695 }
696 if (mapstr.PopValue("inputregmask_pattsync",value)) {
697 fInputReg_PatternSync = value;
698 }
699 if (mapstr.PopValue("inputregmask_pairsync",value)) {
700 fInputReg_PairSync = value;
701 }
702 if (mapstr.PopValue("fakempsbit",value)) {
703 fInputReg_FakeMPS = value;
704 QwWarning << " fInputReg_FakeMPS 0x" << std::hex << fInputReg_FakeMPS << std::dec << QwLog::endl;
705 }
706 if (mapstr.PopValue("numberpatternsdelayed",value)) {
707 SetHelicityDelay(value);
708 }
709 if (mapstr.PopValue("randseedbits",value)) {
710 if (value==24 || value==30)
711 fRandBits = value;
712 }
713 if (mapstr.PopValue("patternphaseoffset",value)) {
715 }
716 if (mapstr.PopValue("helpluseventtype",value)) {
717 kEventTypeHelPlus = value;
718 }
719 if (mapstr.PopValue("helminuseventtype",value)) {
720 kEventTypeHelMinus = value;
721 }
722 if (mapstr.PopValue("helicitydecodingmode",valuestr)) {
723 if (valuestr=="InputRegisterMode") {
724 QwMessage << " **** Input Register Mode **** " << QwLog::endl;
726 } else if (valuestr=="UserbitMode"){
727 QwMessage << " **** Userbit Mode **** " << QwLog::endl;
729 } else if (valuestr=="HelLocalyMadeUp"){
730 QwMessage << "**** Helicity Locally Made Up ****" << QwLog::endl;
732 } else if (valuestr=="InputMollerMode") {
733 QwMessage << "**** Input Moller Mode ****" << QwLog::endl;
735 } else {
736 QwError << "The helicity decoding mode read in file " << mapfile
737 << " is not recognized in function QwHelicity::LoadChannelMap \n"
738 << " Quitting this execution." << QwLog::endl;
739 }
740 }
741
744 if ((bankindex+1)>0){
745 UInt_t numbanks = UInt_t(bankindex+1);
746 if (fWordsPerSubbank.size()<numbanks){
747 fWordsPerSubbank.resize(numbanks,
748 std::pair<Int_t, Int_t>(fWord.size(),fWord.size()));
749 }
750 }
751 wordsofar=0;
752 }
753 mapstr.TrimWhitespace(); // Get rid of leading and trailing spaces.
754 if (mapstr.LineIsEmpty()) continue;
755
756 // Break this line into tokens to process it.
757 TString modtype = mapstr.GetTypedNextToken<TString>(); // module type
758 Int_t modnum = mapstr.GetTypedNextToken<Int_t>(); //slot number
759 /* Int_t channum = */ mapstr.GetTypedNextToken<Int_t>(); //channel number /* unused */
760 TString dettype = mapstr.GetTypedNextToken<TString>(); //type-purpose of the detector
761 dettype.ToLower();
762 TString namech = mapstr.GetTypedNextToken<TString>(); //name of the detector
763 namech.ToLower();
764 TString keyword = mapstr.GetTypedNextToken<TString>();
765 keyword.ToLower();
766 // Notice that "namech" and "keyword" are now forced to lower-case.
767
768 if(modtype=="SKIP"){
769 if (modnum<=0) wordsofar+=1;
770 else wordsofar+=modnum;
771 } else if(modtype!="WORD"|| dettype!="helicitydata") {
772 QwError << "QwHelicity::LoadChannelMap: Unknown detector type: "
773 << dettype << ", the detector " << namech << " will not be decoded "
774 << QwLog::endl;
775 continue;
776 } else {
777 QwWord localword;
778 localword.fSubbankIndex=bankindex;
779 localword.fWordInSubbank=wordsofar;
780 wordsofar+=1;
781 // I assume that one data = one word here. But it is not always the case, for
782 // example the triumf adc gives 6 words per channel
783 localword.fModuleType=modtype;
784 localword.fWordName=namech;
785 localword.fWordType=dettype;
786 fWord.push_back(localword);
787 fWordsPerSubbank.at(bankindex).second = fWord.size();
788
789 // Notice that "namech" is in lower-case, so these checks
790 // should all be in lower-case
791 switch (fHelicityDecodingMode)
792 {
793 case kHelUserbitMode :
794 if(namech.Contains("userbit")) kUserbit=fWord.size()-1;
795 if(namech.Contains("scalercounter")) kScalerCounter=fWord.size()-1;
796 break;
798 if(namech.Contains("input_register")) kInputRegister= fWord.size()-1;
799 if(namech.Contains("mps_counter")) kMpsCounter= fWord.size()-1;
800 if(namech.Contains("pat_counter")) kPatternCounter= fWord.size()-1;
801 if(namech.Contains("pat_phase")) kPatternPhase= fWord.size()-1;
802 break;
804 if(namech.Contains("mps_counter")) {
805 kMpsCounter= fWord.size()-1;
806 }
807 if(namech.Contains("pat_counter")) {
808 kPatternCounter = fWord.size()-1;
809 }
810 break;
811 }
812 }
813 }
814
815
816 if(ldebug) {
817 std::cout << "Done with Load map channel \n";
818 for(size_t i=0;i<fWord.size();i++)
819 fWord[i].PrintID();
820 std::cout << " kUserbit=" << kUserbit << "\n";
821 }
822 ldebug=kFALSE;
823
825 // Check to be sure kEventTypeHelPlus and kEventTypeHelMinus are both defined and not equal
829 // Everything is okay
830 QwDebug << "QwHelicity::LoadChannelMap:"
831 << " We are in Moller Helicity Mode, with HelPlusEventType = "
833 << "and HelMinusEventType = " << kEventTypeHelMinus
834 << QwLog::endl;
835 } else {
836 QwError << "QwHelicity::LoadChannelMap:"
837 << " We are in Moller Helicity Mode, and the HelPlus and HelMinus event types are not set properly."
838 << " HelPlusEventType = " << kEventTypeHelPlus
839 << ", HelMinusEventType = " << kEventTypeHelMinus
840 << ". Please correct the helicity map file!"
841 << QwLog::endl;
842 exit(65);
843 }
844 }
845
846std::cout << fHelicityBitPattern.size() << std::endl;
847
848 mapstr.Close(); // Close the file (ifstream)
849 return 0;
850}
851
852
853Int_t QwHelicity::LoadEventCuts(TString filename){
854 return 0;
855}
856
857Int_t QwHelicity::ProcessEvBuffer(UInt_t event_type, const ROCID_t roc_id, const BankID_t bank_id, UInt_t* buffer, UInt_t num_words)
858{
859 Bool_t lkDEBUG = kFALSE;
860
861 if (((0x1 << (event_type - 1)) & this->GetEventTypeMask()) == 0)
862 return 0;
863 fEventType = event_type;
864
865 Int_t index = GetSubbankIndex(roc_id,bank_id);
866 if (index >= 0 && num_words > 0) {
867 SetDataLoaded(kTRUE);
868 // We want to process this ROC. Begin loopilooping through the data.
869 QwDebug << "QwHelicity::ProcessEvBuffer: "
870 << "Begin processing ROC" << roc_id
871 << " and subbank " << bank_id
872 << " number of words=" << num_words << QwLog::endl;
873
874 for(Int_t i=fWordsPerSubbank.at(index).first; i<fWordsPerSubbank.at(index).second; i++) {
875 if(fWord[i].fWordInSubbank+1<= (Int_t) num_words) {
876 fWord[i].fValue=buffer[fWord[i].fWordInSubbank];
877 } else {
878 QwWarning << "QwHelicity::ProcessEvBuffer: There is not enough word in the buffer to read data for "
879 << fWord[i].fWordName << QwLog::endl;
880 QwWarning << "QwHelicity::ProcessEvBuffer: Words in this buffer:" << num_words
881 << " trying to read word number =" << fWord[i].fWordInSubbank << QwLog::endl;
882 }
883 }
884 if(lkDEBUG) {
885 QwDebug << "QwHelicity::ProcessEvBuffer: Done with Processing this event" << QwLog::endl;
886 for(size_t i=0;i<fWord.size();i++) {
887 std::cout << "QwHelicity::ProcessEvBuffer: word number = " << i << " ";
888 fWord[i].Print();
889 }
890 }
891 }
892 lkDEBUG=kFALSE;
893 return 0;
894}
895
896
897void QwHelicity::ConstructHistograms(TDirectory *folder, TString &prefix)
898{
899 SetHistoTreeSave(prefix);
900 if (folder != NULL) folder->cd();
901 TString basename;
902 size_t index=0;
903
905 {
906 //do nothing
907 }
909 {
910 fHistograms.resize(1+fWord.size(), NULL);
911 basename="pattern_polarity";
912 fHistograms[index] = gQwHists.Construct1DHist(basename);
913 index+=1;
914 for (size_t i=0; i<fWord.size(); i++){
915 basename="hel_"+fWord[i].fWordName;
916 fHistograms[index] = gQwHists.Construct1DHist(basename);
917 index+=1;
918 }
919 }
920 else if(fHistoType==kHelSaveMPS)
921 {
922 fHistograms.resize(4+fWord.size(), NULL);
923 //eventnumber, patternnumber, helicity, patternphase + fWord.size
924 basename=prefix+"delta_event_number";
925 fHistograms[index] = gQwHists.Construct1DHist(basename);
926 index+=1;
927 basename=prefix+"delta_pattern_number";
928 fHistograms[index] = gQwHists.Construct1DHist(basename);
929 index+=1;
930 basename=prefix+"pattern_phase";
931 fHistograms[index] = gQwHists.Construct1DHist(basename);
932 index+=1;
933 basename=prefix+"helicity";
934 fHistograms[index] = gQwHists.Construct1DHist(basename);
935 index+=1;
936 for (size_t i=0; i<fWord.size(); i++){
937 basename=prefix+fWord[i].fWordName;
938 fHistograms[index] = gQwHists.Construct1DHist(basename);
939 index+=1;
940 }
941 }
942 else
943 QwError << "QwHelicity::ConstructHistograms this prefix--" << prefix << "-- is not unknown:: no histo created" << QwLog::endl;
944
945 return;
946}
947
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 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 state management and pattern recognition.
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.
T GetTypedNextToken()
Get next token into specific type.
Bool_t PopValue(const std::string keyname, T &retvalue)
void TrimWhitespace(TString::EStripType head_tail=TString::kBoth)
void SetCommentChars(const std::string value)
Set various sets of special characters.
const std::pair< TString, TString > GetParamFileNameContents()
Word-level data manipulation and bit operations.
Definition QwWord.h:31
Int_t fWordInSubbank
Definition QwWord.h:38
Int_t fSubbankIndex
Definition QwWord.h:37
TString fWordType
Definition QwWord.h:41
TString fModuleType
Definition QwWord.h:39
TString fWordName
Definition QwWord.h:40
BankID_t fCurrentBank_ID
Bank ID (and Marker word) that is currently being processed;.
Int_t GetSubbankIndex() const
UInt_t GetEventTypeMask() const
Get event type mask.
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)
ROCID_t fCurrentROC_ID
ROC ID that is currently being processed.
Bool_t HasDataLoaded() const
Int_t LoadEventCuts(TString filename) override
Optional event cut file.
Bool_t CheckIORegisterMask(const UInt_t &ioregister, const UInt_t &mask) const
Definition QwHelicity.h:88
void ProcessEventInputRegisterMode()
void ProcessOptions(QwOptions &options) override
Process the command line options.
void ClearEventData() override
Int_t ProcessConfigurationBuffer(const ROCID_t roc_id, const BankID_t bank_id, UInt_t *buffer, UInt_t num_words) override
UInt_t fInputReg_FakeMPS
Definition QwHelicity.h:105
Int_t LoadInputParameters(TString pedestalfile) override
Mandatory parameter file definition.
virtual void ConstructHistograms()
Construct the histograms for this subsystem.
Int_t LoadChannelMap(TString mapfile) override
Mandatory map file definition.
QwHelicity()
Private default constructor (not implemented, will throw linker error on use)
UInt_t fInputReg_HelMinus
Definition QwHelicity.h:107
@ kDefaultInputReg_FakeMPS
Definition QwHelicity.h:101
@ kDefaultInputReg_PatternSync
Definition QwHelicity.h:100
@ kDefaultInputReg_HelPlus
Definition QwHelicity.h:98
@ kDefaultInputReg_HelMinus
Definition QwHelicity.h:99
@ kHelInputMollerMode
Definition QwHelicity.h:95
@ kHelInputRegisterMode
Definition QwHelicity.h:93
@ kHelUserbitMode
Definition QwHelicity.h:92
@ kHelLocalyMadeUp
Definition QwHelicity.h:94
Int_t ProcessEvBuffer(const ROCID_t roc_id, const BankID_t bank_id, UInt_t *buffer, UInt_t num_words) override
TODO: The non-event-type-aware ProcessEvBuffer routine should be replaced with the event-type-aware v...
Definition QwHelicity.h:63
UInt_t fInputReg_HelPlus
Definition QwHelicity.h:106
void ProcessEventUserbitMode()
Process helicity information from userbit configuration data.
UInt_t fInputReg_PairSync
Definition QwHelicity.h:109
UInt_t fInputReg_PatternSync
Definition QwHelicity.h:108
Bool_t ApplySingleEventCuts() override
Apply the single event cuts.
void ProcessEventInputMollerMode()
void ProcessEvent() override
void EncodeEventData(std::vector< UInt_t > &buffer) override
void SetHelicityBitPattern(TString hex)
void SetHelicityDelay(Int_t delay)
static const std::vector< UInt_t > kDefaultHelicityBitPattern
std::vector< std::pair< Int_t, Int_t > > fWordsPerSubbank
std::vector< QwWord > fWord
UInt_t BuildHelicityBitPattern(Int_t patternsize)
Int_t fActualPatternPolarity
True polarity of the current pattern.
QwHelicityBase()
Private default constructor (not implemented, will throw linker error on use)
Bool_t fSuppressMPSErrorMsgs
UInt_t kEventTypeHelMinus
Int_t fNumMissedEventBlocks
Int_t fPreviousPatternPolarity
True polarity of the previous pattern.
std::vector< UInt_t > fHelicityBitPattern
void Print() const
Int_t fHelicityDecodingMode
static const Int_t kUndefinedHelicity
Int_t fDelayedPatternPolarity
Reported polarity of the current pattern.
Int_t fPatternPhaseNumberOld
void SetHistoTreeSave(const TString &prefix)
void ClearErrorCounters()