QwAnalysis
QwHelicity.cc
Go to the documentation of this file.
1 /**********************************************************\
2 * File: QwHelicity.C *
3 * *
4 * Author: *
5 * Time-stamp: *
6 \**********************************************************/
7 
8 #include "QwHelicity.h"
9 
10 // System headers
11 #include <stdexcept>
12 
13 // ROOT headers
14 #include "TRegexp.h"
15 
16 // Qweak headers
17 #include "QwHistogramHelper.h"
18 #define MYSQLPP_SSQLS_NO_STATICS
19 #include "QwParitySSQLS.h"
20 #include "QwParityDB.h"
21 #include "QwLog.h"
22 
24 //**************************************************//
25 
26 // Register this subsystem with the factory
28 
29 
30 /// Default helicity bit pattern of 0x69 represents a -++-+--+ octet
31 /// (event polarity listed in reverse time order), where the LSB
32 /// of the bit pattern is the first event of the pattern.
33 const UInt_t QwHelicity::kDefaultHelicityBitPattern = 0x69;
34 
35 /// Default mask for fake MPS latch bit
36 const UInt_t QwHelicity::kInputReg_FakeMPS = 0x8000;
37 
38 //**************************************************//
39 /// Constructor with name
40 QwHelicity::QwHelicity(const TString& name)
41 : VQwSubsystem(name),
42  VQwSubsystemParity(name),
43  fHelicityBitPattern(kDefaultHelicityBitPattern),
44  fMinPatternPhase(1), fUsePredictor(kTRUE), fIgnoreHelicity(kFALSE),
45  fEventNumberFirst(-1),fPatternNumberFirst(-1),
46  fSuppressMPSErrorMsgs(kFALSE)
47 {
49  // Default helicity delay to two patterns.
50  fHelicityDelay = 2;
51  // Default the EventType flags to HelPlus=1 and HelMinus=4
52  // These are only used in Moller decoding mode.
55  //
59  kUserbit=-1;
65  fHelicityBitPlus=kFALSE;
66  fHelicityBitMinus=kFALSE;
67  fGoodHelicity=kFALSE;
68  fGoodPattern=kFALSE;
70 
72 }
73 
74 //**************************************************//
75 /// Copy constructor
76 // FIXME this is pretty horrible as a copy constructor, but it gets around
77 // all of the copy protection built into the helicity subsystem. I can't be
78 // bothered to clean it up right now... (wdc)
80 : VQwSubsystem(source.GetSubsystemName()),
81  VQwSubsystemParity(source.GetSubsystemName()),
82  fHelicityBitPattern(kDefaultHelicityBitPattern),
83  fMinPatternPhase(1), fUsePredictor(kTRUE), fIgnoreHelicity(kFALSE),
84  fEventNumberFirst(-1),fPatternNumberFirst(-1),
85  fSuppressMPSErrorMsgs(kFALSE)
86 {
88  // Default helicity delay to two patterns.
89  fHelicityDelay = 2;
90  // Default the EventType flags to HelPlus=1 and HelMinus=4
91  // These are only used in Moller decoding mode.
94  //
98  kUserbit=-1;
104  fHelicityBitPlus=kFALSE;
105  fHelicityBitMinus=kFALSE;
106  fGoodHelicity=kFALSE;
107  fGoodPattern=kFALSE;
109 
111 
112  this->fWord.resize(source.fWord.size());
113  for(size_t i=0;i<this->fWord.size();i++)
114  {
115  this->fWord[i].fWordName=source.fWord[i].fWordName;
116  this->fWord[i].fModuleType=source.fWord[i].fModuleType;
117  this->fWord[i].fWordType=source.fWord[i].fWordType;
118  }
125  fEventType = source.fEventType;
127  fRandBits = source.fRandBits;
128  fUsePredictor = source.fUsePredictor;
134  iseed_Delayed = source.iseed_Delayed;
135  iseed_Actual = source.iseed_Actual;
136  n_ranbits = source.n_ranbits;
137  fEventNumber = source.fEventNumber;
143 
144  this->kUserbit = source.kUserbit;
145  this->fIgnoreHelicity = source.fIgnoreHelicity;
146 }
147 
148 //**************************************************//
150 {
151  options.AddOptions("Helicity options")
152  ("helicity.seed", po::value<int>(),
153  "Number of bits in random seed");
154  options.AddOptions("Helicity options")
155  ("helicity.bitpattern", po::value<std::string>(),
156  "Helicity bit pattern: 0x1 (pair), 0x9 (quartet), 0x69 (octet), 0x666999 (hexo-quad), 0x66669999 (octo-quad)");
157  options.AddOptions("Helicity options")
158  ("helicity.patternoffset", po::value<int>(),
159  "Set 1 when pattern starts with 1 or 0 when starts with 0");
160  options.AddOptions("Helicity options")
161  ("helicity.patternphase", po::value<int>(),
162  "Maximum pattern phase");
163  options.AddOptions("Helicity options")
164  ("helicity.delay", po::value<int>(),
165  "Default delay is 2 patterns, set at the helicity map file.");
166  options.AddOptions("Helicity options")
167  ("helicity.toggle-mode", po::value<bool>()->default_bool_value(false),
168  "Activates helicity toggle-mode, overriding the 'delay', 'patternphase', 'bitpattern', and 'seed' options.");
169 }
170 
171 //**************************************************//
172 
174 {
175  // Read the cmd options and override channel map settings
176  QwMessage << "QwHelicity::ProcessOptions" << QwLog::endl;
177  if (options.HasValue("helicity.patternoffset")) {
178  if (options.GetValue<int>("helicity.patternoffset") == 1
179  || options.GetValue<int>("helicity.patternoffset") == 0) {
180  fPatternPhaseOffset = options.GetValue<int>("helicity.patternoffset");
181  QwMessage << " Pattern Phase Offset = " << fPatternPhaseOffset << QwLog::endl;
182  } else QwError << "Pattern phase offset should be 0 or 1!" << QwLog::endl;
183  }
184 
185  if (options.HasValue("helicity.patternphase")) {
186  if (options.GetValue<int>("helicity.patternphase") % 2 == 0) {
187  fMaxPatternPhase = options.GetValue<int>("helicity.patternphase");
188  QwMessage << " Maximum Pattern Phase = " << fMaxPatternPhase << QwLog::endl;
189  } else QwError << "Pattern phase should be an even integer!" << QwLog::endl;
190  }
191 
192  if (options.HasValue("helicity.seed")) {
193  if (options.GetValue<int>("helicity.seed") == 24
194  || options.GetValue<int>("helicity.seed") == 30) {
195  QwMessage << " Random Bits = " << options.GetValue<int>("helicity.seed") << QwLog::endl;
196  fRandBits = options.GetValue<int>("helicity.seed");
197  } else QwError << "Number of random seed bits should be 24 or 30!" << QwLog::endl;
198  }
199 
200  if (options.HasValue("helicity.delay")) {
201  QwMessage << " Helicity Delay = " << options.GetValue<int>("helicity.delay") << QwLog::endl;
202  SetHelicityDelay(options.GetValue<int>("helicity.delay"));
203  }
204 
205  if (options.HasValue("helicity.bitpattern")) {
206  QwMessage << " Helicity Pattern ="
207  << options.GetValue<std::string>("helicity.bitpattern")
208  << QwLog::endl;
209  std::string hex = options.GetValue<std::string>("helicity.bitpattern");
210  UInt_t bits = QwParameterFile::GetUInt(hex);
211  SetHelicityBitPattern(bits);
212  } else {
214  }
215 
216  if (options.GetValue<bool>("helicity.toggle-mode")) {
217  fHelicityDelay = 0;
218  fUsePredictor = kFALSE;
219  fMaxPatternPhase = 2;
221  }
222 
223  // If we have the default Helicity Bit Pattern & a large fMaxPatternPhase,
224  // try to recompute the Helicity Bit Pattern.
227  }
228 
229  // Here we're going to try to get the "online" option which
230  // is defined by QwEventBuffer.
231  if (options.HasValue("online")){
232  fSuppressMPSErrorMsgs = options.GetValue<bool>("online");
233  } else {
234  fSuppressMPSErrorMsgs = kFALSE;
235  }
236 }
237 
238 
240 {
241  Bool_t results=kFALSE;
243  results=kTRUE;
244  return results;
245 }
246 
247 
249 {
250  Bool_t results;
251 
252  if((fPatternNumber == fPatternNumberOld) && (fPatternPhaseNumber == fPatternPhaseNumberOld+1))//same pattern new phase
253  results = kTRUE; //got same pattern
255  results=kTRUE; //new pattern
256  else results=kFALSE; //wrong pattern
257 
258  if(!results) {
259  QwWarning << "QwHelicity::IsGoodPatternNumber: This is not a good pattern number. New = "<< fPatternNumber << " Old = " << fPatternNumberOld << QwLog::endl;
260  //Print();
261  }
262 
263  return results;
264 }
265 
266 
268 {
269  Bool_t results;
270  if(fEventNumber == fEventNumberOld + 1)
271  results= kTRUE;
272  else
273  results= kFALSE;
274 
275  if(!results) {
276  QwWarning << "QwHelicity::IsGoodEventNumber: \n this is not a good event number indeed:" << QwLog::endl;
277  Print();
278  }
279  return results;
280 }
281 
282 
284 {
285  Bool_t results;
286 
287  if((fPatternPhaseNumber == fMaxPatternPhase) && (fPatternNumber == fPatternNumberOld )) //maximum phase of old pattern
288  results = kTRUE;
290  results = kTRUE;
292  results= kTRUE;
293  else
294  results = kFALSE;
295 
297  results=kFALSE;
298 
299  if(!results) {
300  QwWarning << "QwHelicity::IsGoodPhaseNumber: not a good phase number \t"
301  << "Phase: " << fPatternPhaseNumber << " out of "
303  << "(was " << fPatternPhaseNumberOld << ")"
304  << "\tPattern #" << fPatternNumber << "(was "
305  << fPatternNumberOld << ")"
306  << QwLog::endl; //Paul's modifications
307  Print();
308  }
309 
310  return results;
311 }
312 
313 
315 {
316  fGoodHelicity = kTRUE;
318  /**We are not ignoring the helicity, and the helicities do not match.
319  Check phase number to see if its a new pattern.*/
320  fGoodHelicity=kFALSE;
323  //first event in a new pattern
324  QwError << "QwHelicity::IsGoodHelicity : The helicity reported in event "
325  << fEventNumber
326  << " is not what we expect from the randomseed. Not a good event nor pattern"
327  << QwLog::endl;
328  } else {
329  QwError << "QwHelicity::IsGoodHelicity - The helicity reported in event "
330  << fEventNumber
331  << " is not what we expect according to pattern structure. Not a good event nor pattern"
332  << QwLog::endl;
333  }
334  }
335  if(!fGoodHelicity) {
339  //Have to start over again
340  ResetPredictor();
341  }
342 
343  return fGoodHelicity;
344 }
345 
346 
348 {
349  SetDataLoaded(kFALSE);
350  for (size_t i=0;i<fWord.size();i++)
351  fWord[i].ClearEventData();
352 
353  /**Reset data by setting the old event number, pattern number and pattern phase
354  to the values of the previous event.*/
355  if (fEventNumberFirst==-1 && fEventNumberOld!= -1){
357  }
358  if (fPatternNumberFirst==-1 && fPatternNumberOld!=-1
361  }
362 
366 
367  //fIgnoreHelicity = kFALSE;
368 
369  /**Clear out helicity variables */
373  fHelicityBitPlus = kFALSE;
374  fHelicityBitMinus = kFALSE;
375  // be careful: it is not that I forgot to reset fActualPatternPolarity
376  // or fDelayedPatternPolarity. One doesn't want to do that here.
377  /** Set the new event number and pattern number to -1. If we are not reading these correctly
378  from the data stream, -1 will allow us to identify that.*/
379  fEventNumber = -1;
380  fPatternPhaseNumber = -1;
381  return;
382 }
383 
384 Int_t QwHelicity::ProcessConfigurationBuffer(const UInt_t roc_id, const UInt_t bank_id, UInt_t* buffer, UInt_t num_words)
385 {
386  //stub function
387  // QwError << " this function QwHelicity::ProcessConfigurationBuffer does nothing yet " << QwLog::endl;
388  return 0;
389 }
390 
391 Int_t QwHelicity::LoadInputParameters(TString pedestalfile)
392 {
393  return 0;
394 }
395 
396 
398  //impose single event cuts //Paul's modifications
399 
400  return kTRUE;
401 }
402 
404 {
405  /// TODO: Implement QwHelicity::IncrementErrorCounters()
406 }
407 
409  // report number of events failed due to HW and event cut faliure
410  QwMessage << "\n*********QwHelicity Error Summary****************"
411  << QwLog::endl;
412  QwMessage << "First helicity gate counter: "
414  << "; last helicity gate counter: "
415  << fEventNumber
416  << QwLog::endl;
417  QwMessage << "First pattern counter: "
419  << "; last pattern counter: "
420  << fPatternNumber
421  << QwLog::endl;
422  QwMessage << "Missed " << fNumMissedGates << " helicity gates in "
423  << fNumMissedEventBlocks << " blocks of missed events."
424  << QwLog::endl;
425  QwMessage << "Number of multiplet-sync-bit errors: "
427  << QwLog::endl;
428  QwMessage << "Number of helicity prediction errors: "
430  << QwLog::endl;
431  QwMessage <<"---------------------------------------------------\n"
432  << QwLog::endl;
433 }
434 
435 UInt_t QwHelicity::GetEventcutErrorFlag(){//return the error flag
436 
437  return 0;
438 
439 }
440 
442 {
443 
444  /** In this version of the code, the helicity is extracted for a userbit configuration.
445  This is not what we plan to have for Qweak but it was done for injector tests and
446  so is usefull to have as another option to get helicity information. */
447 
448  Bool_t ldebug=kFALSE;
449  UInt_t userbits;
450  static UInt_t lastuserbits = 0xFF;
451  UInt_t scaleroffset=fWord[kScalerCounter].fValue/32;
452 
453  if(scaleroffset==1 || scaleroffset==0) {
454  userbits = (fWord[kUserbit].fValue & 0xE0000000)>>28;
455 
456  // Now fake the input register, MPS coutner, QRT counter, and QRT phase.
458 
459  lastuserbits = userbits;
460 
461  if (lastuserbits==0xFF) {
463  } else {
464  if ((lastuserbits & 0x8) == 0x8) {
465  // Quartet bit is set.
466  fPatternPhaseNumber = fMinPatternPhase; // Reset the QRT phase
467  fPatternNumber=fPatternNumberOld+1; // Increment the QRT counter
468  } else {
469  fPatternPhaseNumber=fPatternPhaseNumberOld+1; // Increment the QRT phase
470  }
471 
473 
474  if ((lastuserbits & 0x4) == 0x4){ // Helicity bit is set.
475  fHelicityReported |= 1; // Set the InputReg HEL+ bit.
476  fHelicityBitPlus=kTRUE;
477  fHelicityBitMinus=kFALSE;
478  } else {
479  fHelicityReported |= 0; // Set the InputReg HEL- bit.
480  fHelicityBitPlus=kFALSE;
481  fHelicityBitMinus=kTRUE;
482  }
483  }
484  } else {
485  QwError << " QwHelicity::ProcessEvent finding a missed read event in the scaler" << QwLog::endl;
486  if(ldebug) {
487  std::cout << " QwHelicity::ProcessEvent :" << scaleroffset << " events were missed \n";
488  std::cout << " before manipulation \n";
489  Print();
490  }
491  //there was more than one event since the last reading of the scalers
492  //ie we should read only one event at the time,
493  //if not something is wrong
494  fEventNumber=fEventNumberOld+scaleroffset;
495  Int_t localphase=fPatternPhaseNumberOld;
496  Int_t localpatternnumber=fPatternNumberOld;
497  for (UInt_t i=0;i<scaleroffset;i++) {
498  fPatternPhaseNumber=localphase+1;
502  localpatternnumber=fPatternNumber;
503  }
504  localphase=fPatternPhaseNumber;
505  }
506  //Reset helicity predictor because we are not sure of what we are doing
508  ResetPredictor();
509  if(ldebug) {
510  std::cout << " after manipulation \n";
511  Print();
512  }
513  }
514  return;
515 }
516 
517 
519 {
520  static Bool_t firstpattern = kTRUE;
521  Bool_t fake_the_counters=kFALSE;
522  UInt_t thisinputregister=fWord[kInputRegister].fValue;
523 
524  /**
525  In the Input Register Mode,
526  the event number is obtained straight from the wordkMPSCounter.
527  */
529 
530  if (CheckIORegisterMask(thisinputregister,fInputReg_FakeMPS))
531  fIgnoreHelicity = kTRUE;
532  else
533  fIgnoreHelicity = kFALSE;
534 
535  // When we have the minimum phase from the pattern phase word
536  // and the input register minimum phase bit is set
537  // we can select the second pattern as below.
538  if(fWord[kPatternPhase].fValue - fPatternPhaseOffset == 0)
539  if (firstpattern && CheckIORegisterMask(thisinputregister,kInputReg_PatternSync)){
540  firstpattern = kFALSE;
541  }
542 
543  // If firstpattern is still TRUE, we are still searching for the first
544  // pattern of the data stream. So set the pattern number = 0
545  if (firstpattern)
546  fPatternNumber = -1;
547  else {
550  }
551 
552  /** Tf we get junk for the mps and pattern information from the run
553  we can enable fake counters for mps, pattern number and pattern phase to get the job done.
554  */
555  if (fake_the_counters){
557  if (CheckIORegisterMask(thisinputregister,kInputReg_PatternSync)) {
560  } else {
563  }
564  }
565 
566 
567  if(fEventNumber!=(fEventNumberOld+1)){
568  Int_t nummissed(fEventNumber - (fEventNumberOld+1));
569  if (!fSuppressMPSErrorMsgs){
570  QwError << "QwHelicity::ProcessEvent read event# ("
571  << fEventNumber << ") is not old_event#+1; missed "
572  << nummissed << " gates" << QwLog::endl;
573  }
574  fNumMissedGates += nummissed;
576  }
577 
579  // Quartet bit is set.
580  QwError << "QwHelicity::ProcessEvent: The Multiplet Sync bit is set, but the Pattern Phase is ("
581  << fPatternPhaseNumber << ") not "
582  << fMinPatternPhase << "! Please check the fPatternPhaseOffset in the helicity map file." << QwLog::endl;
584  }
585 
587 
588  /**
589  Extract the reported helicity from the input register for each event.
590  */
591 
592  if (CheckIORegisterMask(thisinputregister,kInputReg_HelPlus)
593  && CheckIORegisterMask(thisinputregister,kInputReg_HelMinus) ){
594  // Both helicity bits are set.
595  QwError << "QwHelicity::ProcessEvent: Both the H+ and H- bits are set: thisinputregister=="
596  << thisinputregister << QwLog::endl;
598  fHelicityBitPlus = kFALSE;
599  fHelicityBitMinus = kFALSE;
600  } else if (CheckIORegisterMask(thisinputregister,kInputReg_HelPlus)){ // HelPlus bit is set.
601  fHelicityReported |= 1; // Set the InputReg HEL+ bit.
602  fHelicityBitPlus = kTRUE;
603  fHelicityBitMinus = kFALSE;
604  } else {
605  fHelicityReported |= 0; // Set the InputReg HEL- bit.
606  fHelicityBitPlus = kFALSE;
607  fHelicityBitMinus = kTRUE;
608  }
609 
610  return;
611 }
612 
614 {
615  static Bool_t firstpattern = kTRUE;
616 
617  if(firstpattern && fWord[kPatternCounter].fValue > fPatternNumberOld){
618  firstpattern = kFALSE;
619  }
620 
622  if(fEventNumber!=(fEventNumberOld+1)){
623  Int_t nummissed(fEventNumber - (fEventNumberOld+1));
624  QwError << "QwHelicity::ProcessEvent read event# ("
625  << fEventNumber << ") is not old_event#+1; missed "
626  << nummissed << " gates" << QwLog::endl;
627  fNumMissedGates += nummissed;
629  }
630  if (firstpattern){
631  fPatternNumber = -1;
633  } else {
636  // We are at a new pattern!
638  } else {
640  }
641  }
642 
645  // fHelicityReported = (fEventType == 1 ? 0 : 1);
646 
647  if (fHelicityReported == 1){
648  fHelicityBitPlus=kTRUE;
649  fHelicityBitMinus=kFALSE;
650  } else {
651  fHelicityBitPlus=kFALSE;
652  fHelicityBitMinus=kTRUE;
653  }
654  return;
655 }
656 
657 
659 {
660  Bool_t ldebug = kFALSE;
661 
662  if (! HasDataLoaded()) return;
663 
664  switch (fHelicityDecodingMode)
665  {
666  case kHelUserbitMode :
668  break;
669  case kHelInputRegisterMode :
671  break;
672  case kHelInputMollerMode :
674  break;
675  default:
676  QwError << "QwHelicity::ProcessEvent no instructions on how to decode the helicity !!!!" << QwLog::endl;
677  abort();
678  break;
679  }
680 
683 
684  // Predict helicity if delay is non zero.
686  PredictHelicity();
687  } else {
688  // Else use the reported helicity values.
691 
696  }
697 
698  }
699 
700  if(ldebug){
701  std::cout<<"\nevent number= "<<fEventNumber<<std::endl;
702  std::cout<<"pattern number = "<<fPatternNumber<<std::endl;
703  std::cout<<"pattern phase = "<<fPatternPhaseNumber<<std::endl;
704  std::cout<<"max pattern phase = "<<fMaxPatternPhase<<std::endl;
705  std::cout<<"min pattern phase = "<<fMinPatternPhase<<std::endl;
706 
707 
708  }
709 
710  return;
711 }
712 
713 
714 void QwHelicity::EncodeEventData(std::vector<UInt_t> &buffer)
715 {
716  std::vector<UInt_t> localbuffer;
717  localbuffer.clear();
718 
719  // Userbit mode
720  switch (fHelicityDecodingMode) {
721  case kHelUserbitMode: {
722  UInt_t userbit = 0x0;
723  if (fPatternPhaseNumber == fMinPatternPhase) userbit |= 0x80000000;
724  if (fHelicityDelayed == 1) userbit |= 0x40000000;
725 
726  // Write the words to the buffer
727  localbuffer.push_back(0x1); // cleandata
728  localbuffer.push_back(0xa); // scandata1
729  localbuffer.push_back(0xa); // scandata2
730  localbuffer.push_back(0x0); // scalerheader
731  localbuffer.push_back(0x20); // scalercounter (32)
732  localbuffer.push_back(userbit); // userbit
733 
734  for (int i = 0; i < 64; i++) localbuffer.push_back(0x0); // (not used)
735  break;
736  }
737  case kHelInputRegisterMode: {
738  UInt_t input_register = 0x0;
739  if (fHelicityDelayed == 1) input_register |= kInputReg_HelPlus;
740  if (fHelicityDelayed == 0) input_register |= kInputReg_HelMinus; // even the mock data has balanced inputs!
742 
743  // Write the words to the buffer
744  localbuffer.push_back(input_register); // input_register
745  localbuffer.push_back(0x0); // output_register
746  localbuffer.push_back(fEventNumber); // mps_counter
747  localbuffer.push_back(fPatternNumber); // pat_counter
748  localbuffer.push_back(fPatternPhaseNumber - fMinPatternPhase + fPatternPhaseOffset); // pat_phase
749 
750  for (int i = 0; i < 17; i++) localbuffer.push_back(0x0); // (not used)
751  break;
752  }
753  default:
754  QwWarning << "QwHelicity::EncodeEventData: Unsupported helicity encoding!" << QwLog::endl;
755  break;
756  }
757 
758  // If there is element data, generate the subbank header
759  std::vector<UInt_t> subbankheader;
760  std::vector<UInt_t> rocheader;
761  if (localbuffer.size() > 0) {
762 
763  // Form CODA subbank header
764  subbankheader.clear();
765  subbankheader.push_back(localbuffer.size() + 1); // subbank size
766  subbankheader.push_back((fCurrentBank_ID << 16) | (0x01 << 8) | (1 & 0xff));
767  // subbank tag | subbank type | event number
768 
769  // Form CODA bank/roc header
770  rocheader.clear();
771  rocheader.push_back(subbankheader.size() + localbuffer.size() + 1); // bank/roc size
772  rocheader.push_back((fCurrentROC_ID << 16) | (0x10 << 8) | (1 & 0xff));
773  // bank tag == ROC | bank type | event number
774 
775  // Add bank header, subbank header and element data to output buffer
776  buffer.insert(buffer.end(), rocheader.begin(), rocheader.end());
777  buffer.insert(buffer.end(), subbankheader.begin(), subbankheader.end());
778  buffer.insert(buffer.end(), localbuffer.begin(), localbuffer.end());
779  }
780 }
781 
782 void QwHelicity::Print() const
783 {
784  QwOut << "===========================\n"
785  << "This event: Event#, Pattern#, PatternPhase#="
786  << fEventNumber << ", "
787  << fPatternNumber << ", "
789  QwOut << "Previous event: Event#, Pattern#, PatternPhase#="
790  << fEventNumberOld << ", "
791  << fPatternNumberOld << ", "
793  QwOut << "delta = \n(fEventNumberOld)-(fMaxPatternPhase)x(fPatternNumberOld)-(fPatternPhaseNumberOld)= "
795  QwOut << "Helicity Reported, Delayed, Actual ="
796  << fHelicityReported << ","
797  << fHelicityDelayed << ","
799  QwOut << "===" << QwLog::endl;
800  return;
801 }
802 
803 
804 Int_t QwHelicity::LoadChannelMap(TString mapfile)
805 {
806  Bool_t ldebug=kFALSE;
807 
808  Int_t currentrocread=0;
809  Int_t currentbankread=0;
810  Int_t wordsofar=0;
811  Int_t currentsubbankindex=-1;
812 
813  fPatternPhaseOffset=1;//Phase number offset is set to 1 by default and will be set to 0 if phase number starts from 0
814 
815 
816  // Default value for random seed is 30 bits
817  fRandBits = 30;
818 
819 
820  QwParameterFile mapstr(mapfile.Data()); //Open the file
821  fDetectorMaps.insert(mapstr.GetParamFileNameContents());
822 
823  while (mapstr.ReadNextLine()){
824  mapstr.TrimComment('!'); // Remove everything after a '!' character.
825  mapstr.TrimWhitespace(); // Get rid of leading and trailing spaces.
826  if (mapstr.LineIsEmpty()) continue;
827 
828  TString varname, varvalue;
829  if (mapstr.HasVariablePair("=",varname,varvalue)){
830  // This is a declaration line. Decode it.
831  varname.ToLower();
832  UInt_t value = QwParameterFile::GetUInt(varvalue);
833 
834  if (varname=="roc")
835  {
836  currentrocread=value;
837  RegisterROCNumber(value,0);
838  fWordsPerSubbank.push_back( std::pair<Int_t, Int_t>(fWord.size(),fWord.size()));
839  }
840  else if (varname=="bank")
841  {
842  currentbankread=value;
843  RegisterSubbank(value);
844  fWordsPerSubbank.push_back( std::pair<Int_t, Int_t>(fWord.size(),fWord.size()));
845  }
846  else if (varname=="patternphase")
847  {
848  fMaxPatternPhase=value;
849  //QwMessage << " fMaxPatternPhase " << fMaxPatternPhase << QwLog::endl;
850  }
851  else if (varname=="patternbits")
852  {
853  SetHelicityBitPattern(value);
854  }
855  else if (varname=="fakempsbit")
856  {
857  fInputReg_FakeMPS = value;
858  QwWarning << " fInputReg_FakeMPS 0x" << std::hex << fInputReg_FakeMPS << std::dec << QwLog::endl;
859  }
860  else if (varname=="numberpatternsdelayed")
861  {
862  SetHelicityDelay(value);
863  }
864  else if (varname=="randseedbits")
865  {
866  if (value==24 || value==30)
867  fRandBits = value;
868  }
869  else if (varname=="patternphaseoffset")
870  {
871  fPatternPhaseOffset=value;
872  }
873  else if(varname=="helpluseventtype")
874  {
875  kEventTypeHelPlus = value;
876  }
877  else if(varname=="helminuseventtype")
878  {
879  kEventTypeHelMinus = value;
880  }
881  else if (varname=="helicitydecodingmode")
882  {
883  if (varvalue=="InputRegisterMode") {
884  QwMessage << " **** Input Register Mode **** " << QwLog::endl;
886  }
887  else if (varvalue=="UserbitMode"){
888  QwMessage << " **** Userbit Mode **** " << QwLog::endl;
890  }
891  else if (varvalue=="HelLocalyMadeUp"){
892  QwMessage << "**** Helicity Locally Made Up ****" << QwLog::endl;
894  }
895  else if (varvalue=="InputMollerMode") {
896  QwMessage << "**** Input Moller Mode ****" << QwLog::endl;
898  }
899  else {
900  QwError << "The helicity decoding mode read in file " << mapfile
901  << " is not recognized in function QwHelicity::LoadChannelMap \n"
902  << " Quiting this execution." << QwLog::endl;
903  }
904  }
905  } else {
906  // Break this line into tokens to process it.
907  TString modtype = mapstr.GetTypedNextToken<TString>(); // module type
908  Int_t modnum = mapstr.GetTypedNextToken<Int_t>(); //slot number
909  /* Int_t channum = */ mapstr.GetTypedNextToken<Int_t>(); //channel number /* unused */
910  TString dettype = mapstr.GetTypedNextToken<TString>(); //type-purpose of the detector
911  dettype.ToLower();
912  TString namech = mapstr.GetTypedNextToken<TString>(); //name of the detector
913  namech.ToLower();
914  TString keyword = mapstr.GetTypedNextToken<TString>();
915  keyword.ToLower();
916  // Notice that "namech" and "keyword" are now forced to lower-case.
917 
918  if(currentsubbankindex!=GetSubbankIndex(currentrocread,currentbankread))
919  {
920  currentsubbankindex=GetSubbankIndex(currentrocread,currentbankread);
921  wordsofar=0;
922  }
923 
924  if(modtype=="SKIP"){
925  if (modnum<=0) wordsofar+=1;
926  else wordsofar+=modnum;
927  }
928  else if(modtype!="WORD"|| dettype!="helicitydata")
929  {
930  QwError << "QwHelicity::LoadChannelMap: Unknown detector type: "
931  << dettype << ", the detector " << namech << " will not be decoded "
932  << QwLog::endl;
933  continue;
934  }
935  else
936  {
937  QwWord localword;
938  localword.fSubbankIndex=currentsubbankindex;
939  localword.fWordInSubbank=wordsofar;
940  wordsofar+=1;
941  // I assume that one data = one word here. But it is not always the case, for
942  // example the triumf adc gives 6 words per channel
943  localword.fModuleType=modtype;
944  localword.fWordName=namech;
945  localword.fWordType=dettype;
946  fWord.push_back(localword);
947  fWordsPerSubbank[currentsubbankindex].second = fWord.size();
948  QwDebug << "--" << namech << "--" << fWord.size()-1 << QwLog::endl;
949 
950  // Notice that "namech" is in lower-case, so these checks
951  // should all be in lower-case
952  switch (fHelicityDecodingMode)
953  {
954  case kHelUserbitMode :
955  if(namech.Contains("userbit")) kUserbit=fWord.size()-1;
956  if(namech.Contains("scalercounter")) kScalerCounter=fWord.size()-1;
957  break;
958  case kHelInputRegisterMode :
959  if(namech.Contains("input_register")) kInputRegister= fWord.size()-1;
960  if(namech.Contains("mps_counter")) kMpsCounter= fWord.size()-1;
961  if(namech.Contains("pat_counter")) kPatternCounter= fWord.size()-1;
962  if(namech.Contains("pat_phase")) kPatternPhase= fWord.size()-1;
963  break;
964  case kHelInputMollerMode :
965  if(namech.Contains("mps_counter")) {
966  kMpsCounter= fWord.size()-1;
967  }
968  if(namech.Contains("pat_counter")) {
969  kPatternCounter = fWord.size()-1;
970  }
971  break;
972  }
973  }
974  }
975  }
976 
977  if(ldebug)
978  {
979  std::cout << "Done with Load map channel \n";
980  for(size_t i=0;i<fWord.size();i++)
981  fWord[i].PrintID();
982  std::cout << " kUserbit=" << kUserbit << "\n";
983 
984  }
985  ldebug=kFALSE;
986 
987 
989  // Check to be sure kEventTypeHelPlus and kEventTypeHelMinus are both defined and not equal
993  // Everything is okay
994  QwDebug << "QwHelicity::LoadChannelMap:"
995  << " We are in Moller Helicity Mode, with HelPlusEventType = "
997  << "and HelMinusEventType = " << kEventTypeHelMinus
998  << QwLog::endl;
999  } else {
1000  QwError << "QwHelicity::LoadChannelMap:"
1001  << " We are in Moller Helicity Mode, and the HelPlus and HelMinus event types are not set properly."
1002  << " HelPlusEventType = " << kEventTypeHelPlus
1003  << ", HelMinusEventType = " << kEventTypeHelMinus
1004  << ". Please correct the helicity map file!"
1005  << QwLog::endl;
1006  exit(65);
1007  }
1008  }
1009 
1010  mapstr.Close(); // Close the file (ifstream)
1011  return 0;
1012 }
1013 
1014 
1015 Int_t QwHelicity::LoadEventCuts(TString filename){
1016  return 0;
1017 }
1018 
1019 Int_t QwHelicity::ProcessEvBuffer(UInt_t event_type, const UInt_t roc_id, const UInt_t bank_id, UInt_t* buffer, UInt_t num_words)
1020 {
1021  Bool_t lkDEBUG = kFALSE;
1022 
1023  if (((0x1 << (event_type - 1)) & this->GetEventTypeMask()) == 0)
1024  return 0;
1025  fEventType = event_type;
1026 
1027  Int_t index = GetSubbankIndex(roc_id,bank_id);
1028  if (index >= 0 && num_words > 0) {
1029  SetDataLoaded(kTRUE);
1030  // We want to process this ROC. Begin loopilooping through the data.
1031  QwDebug << "QwHelicity::ProcessEvBuffer: "
1032  << "Begin processing ROC" << roc_id
1033  << " and subbank " << bank_id
1034  << " number of words=" << num_words << QwLog::endl;
1035 
1036  for(Int_t i=fWordsPerSubbank[index].first; i<fWordsPerSubbank[index].second; i++) {
1037  if(fWord[i].fWordInSubbank+1<= (Int_t) num_words) {
1038  fWord[i].fValue=buffer[fWord[i].fWordInSubbank];
1039  } else {
1040  QwWarning << "QwHelicity::ProcessEvBuffer: There is not enough word in the buffer to read data for "
1041  << fWord[i].fWordName << QwLog::endl;
1042  QwWarning << "QwHelicity::ProcessEvBuffer: Words in this buffer:" << num_words
1043  << " trying to read word number =" << fWord[i].fWordInSubbank << QwLog::endl;
1044  }
1045  }
1046  if(lkDEBUG) {
1047  QwDebug << "QwHelicity::ProcessEvBuffer: Done with Processing this event" << QwLog::endl;
1048  for(size_t i=0;i<fWord.size();i++) {
1049  std::cout << " word number = " << i << " ";
1050  fWord[i].Print();
1051  }
1052  }
1053  }
1054  lkDEBUG=kFALSE;
1055  return 0;
1056 }
1057 
1058 
1060 {
1061  return fHelicityReported;
1062 }
1063 
1065 {
1066  return fHelicityActual;
1067 }
1068 
1070 {
1071  return fHelicityDelayed;
1072 }
1073 
1075 {
1076  return fPatternNumber;
1077 }
1078 
1080 {
1081  return fEventNumber;
1082 }
1083 
1085 {
1086  return fPatternPhaseNumber;
1087 }
1088 
1089 void QwHelicity::SetEventPatternPhase(Int_t event, Int_t pattern, Int_t phase)
1090 {
1091  fEventNumber = event;
1092  fPatternNumber = pattern;
1093  fPatternPhaseNumber = phase;
1094 }
1095 
1096 void QwHelicity::SetFirstBits(UInt_t nbits, UInt_t seed)
1097 {
1098  // This gives the predictor a quick start
1099  UShort_t firstbits[nbits];
1100  for (unsigned int i = 0; i < nbits; i++) firstbits[i] = (seed >> i) & 0x1;
1101  // Set delayed seed
1102  iseed_Delayed = GetRandomSeed(firstbits);
1103  // Progress actual seed by the helicity delay
1105  for (int i = 0; i < fHelicityDelay; i++) GetRandbit(iseed_Actual);
1106 }
1107 
1108 void QwHelicity::SetHistoTreeSave(const TString &prefix)
1109 {
1110  Ssiz_t len;
1111  if (prefix == "diff_"
1112  || TRegexp("asym[1-9]*_").Index(prefix,&len) == 0)
1114  else if (prefix == "yield_")
1116  else
1118 }
1119 
1120 void QwHelicity::ConstructHistograms(TDirectory *folder, TString &prefix)
1121 {
1122  SetHistoTreeSave(prefix);
1123  if (folder != NULL) folder->cd();
1124  TString basename;
1125  size_t index=0;
1126 
1127  if(fHistoType==kHelNoSave)
1128  {
1129  //do nothing
1130  }
1131  else if(fHistoType==kHelSavePattern)
1132  {
1133  fHistograms.resize(1+fWord.size(), NULL);
1134  basename="pattern_polarity";
1135  fHistograms[index] = gQwHists.Construct1DHist(basename);
1136  index+=1;
1137  for (size_t i=0; i<fWord.size(); i++){
1138  basename="hel_"+fWord[i].fWordName;
1139  fHistograms[index] = gQwHists.Construct1DHist(basename);
1140  index+=1;
1141  }
1142  }
1143  else if(fHistoType==kHelSaveMPS)
1144  {
1145  fHistograms.resize(4+fWord.size(), NULL);
1146  //eventnumber, patternnumber, helicity, patternphase + fWord.size
1147  basename=prefix+"delta_event_number";
1148  fHistograms[index] = gQwHists.Construct1DHist(basename);
1149  index+=1;
1150  basename=prefix+"delta_pattern_number";
1151  fHistograms[index] = gQwHists.Construct1DHist(basename);
1152  index+=1;
1153  basename=prefix+"pattern_phase";
1154  fHistograms[index] = gQwHists.Construct1DHist(basename);
1155  index+=1;
1156  basename=prefix+"helicity";
1157  fHistograms[index] = gQwHists.Construct1DHist(basename);
1158  index+=1;
1159  for (size_t i=0; i<fWord.size(); i++){
1160  basename=prefix+fWord[i].fWordName;
1161  fHistograms[index] = gQwHists.Construct1DHist(basename);
1162  index+=1;
1163  }
1164  }
1165  else
1166  QwError << "QwHelicity::ConstructHistograms this prefix--" << prefix << "-- is not unknown:: no histo created" << QwLog::endl;
1167 
1168  return;
1169 }
1170 
1172 {
1173  // Bool_t localdebug=kFALSE;
1174 
1175  size_t index=0;
1176  if(fHistoType==kHelNoSave)
1177  {
1178  //do nothing
1179  }
1180  else if(fHistoType==kHelSavePattern)
1181  {
1182  QwDebug << "QwHelicity::FillHistograms helicity info " << QwLog::endl;
1183  QwDebug << "QwHelicity::FillHistograms pattern polarity=" << fActualPatternPolarity << QwLog::endl;
1184  if (fHistograms[index]!=NULL)
1185  fHistograms[index]->Fill(fActualPatternPolarity);
1186  index+=1;
1187 
1188  for (size_t i=0; i<fWord.size(); i++){
1189  if (fHistograms[index]!=NULL)
1190  fHistograms[index]->Fill(fWord[i].fValue);
1191  index+=1;
1192  QwDebug << "QwHelicity::FillHistograms " << fWord[i].fWordName << "=" << fWord[i].fValue << QwLog::endl;
1193  }
1194  }
1195  else if(fHistoType==kHelSaveMPS)
1196  {
1197  QwDebug << "QwHelicity::FillHistograms mps info " << QwLog::endl;
1198  if (fHistograms[index]!=NULL)
1200  index+=1;
1201  if (fHistograms[index]!=NULL)
1203  index+=1;
1204  if (fHistograms[index]!=NULL)
1205  fHistograms[index]->Fill(fPatternPhaseNumber);
1206  index+=1;
1207  if (fHistograms[index]!=NULL)
1208  fHistograms[index]->Fill(fHelicityActual);
1209  index+=1;
1210  for (size_t i=0; i<fWord.size(); i++){
1211  if (fHistograms[index]!=NULL)
1212  fHistograms[index]->Fill(fWord[i].fValue);
1213  index+=1;
1214  QwDebug << "QwHelicity::FillHistograms " << fWord[i].fWordName << "=" << fWord[i].fValue << QwLog::endl;
1215  }
1216  }
1217 
1218  return;
1219 }
1220 
1221 
1222 void QwHelicity::ConstructBranchAndVector(TTree *tree, TString &prefix, std::vector<Double_t> &values)
1223 {
1224  SetHistoTreeSave(prefix);
1225 
1226 
1227  fTreeArrayIndex = values.size();
1228  TString basename;
1229  if(fHistoType==kHelNoSave)
1230  {
1231  //do nothing
1232  }
1233  else if(fHistoType==kHelSaveMPS)
1234  {
1235  basename = "actual_helicity"; //predicted actual helicity before being delayed.
1236  values.push_back(0.0);
1237  tree->Branch(basename, &(values.back()), basename+"/D");
1238  //
1239  basename = "delayed_helicity"; //predicted delayed helicity
1240  values.push_back(0.0);
1241  tree->Branch(basename, &(values.back()), basename+"/D");
1242  //
1243  basename = "reported_helicity"; //delayed helicity reported by the input register.
1244  values.push_back(0.0);
1245  tree->Branch(basename, &(values.back()), basename+"/D");
1246  //
1247  basename = "pattern_phase";
1248  values.push_back(0.0);
1249  tree->Branch(basename, &(values.back()), basename+"/D");
1250  //
1251  basename = "pattern_number";
1252  values.push_back(0.0);
1253  tree->Branch(basename, &(values.back()), basename+"/D");
1254  //
1255  basename = "pattern_seed";
1256  values.push_back(0.0);
1257  tree->Branch(basename, &(values.back()), basename+"/D");
1258  //
1259  basename = "event_number";
1260  values.push_back(0.0);
1261  tree->Branch(basename, &(values.back()), basename+"/D");
1262  //
1263  for (size_t i=0; i<fWord.size(); i++)
1264  {
1265  basename = fWord[i].fWordName;
1266  values.push_back(0.0);
1267  tree->Branch(basename, &(values.back()), basename+"/D");
1268  }
1269  }
1270  else if(fHistoType==kHelSavePattern)
1271  {
1272  basename = "actual_pattern_polarity";
1273  values.push_back(0.0);
1274  tree->Branch(basename, &(values.back()), basename+"/D");
1275  //
1276  basename = "actual_previous_pattern_polarity";
1277  values.push_back(0.0);
1278  tree->Branch(basename, &(values.back()), basename+"/D");
1279  //
1280  basename = "delayed_pattern_polarity";
1281  values.push_back(0.0);
1282  tree->Branch(basename, &(values.back()), basename+"/D");
1283  //
1284  basename = "pattern_number";
1285  values.push_back(0.0);
1286  tree->Branch(basename, &(values.back()), basename+"/D");
1287  //
1288  basename = "pattern_seed";
1289  values.push_back(0.0);
1290  tree->Branch(basename, &(values.back()), basename+"/D");
1291  //
1292  for (size_t i=0; i<fWord.size(); i++)
1293  {
1294  basename = fWord[i].fWordName;
1295  values.push_back(0.0);
1296  tree->Branch(basename, &(values.back()), basename+"/D");
1297  }
1298  }
1299 
1300  return;
1301 }
1302 
1303 void QwHelicity::ConstructBranch(TTree *tree, TString &prefix)
1304 {
1305  TString basename;
1306 
1307  SetHistoTreeSave(prefix);
1308  if(fHistoType==kHelNoSave)
1309  {
1310  //do nothing
1311  }
1312  else if(fHistoType==kHelSaveMPS)
1313  {
1314  basename = "actual_helicity"; //predicted actual helicity before being delayed.
1315  tree->Branch(basename, &fHelicityActual, basename+"/I");
1316  //
1317  basename = "delayed_helicity"; //predicted delayed helicity
1318  tree->Branch(basename, &fHelicityDelayed, basename+"/I");
1319  //
1320  basename = "reported_helicity"; //delayed helicity reported by the input register.
1321  tree->Branch(basename, &fHelicityReported, basename+"/I");
1322  //
1323  basename = "pattern_phase";
1324  tree->Branch(basename, &fPatternPhaseNumber, basename+"/I");
1325  //
1326  basename = "pattern_number";
1327  tree->Branch(basename, &fPatternNumber, basename+"/I");
1328  //
1329  basename = "pattern_seed";
1330  tree->Branch(basename, &fPatternSeed, basename+"/I");
1331  //
1332  basename = "event_number";
1333  tree->Branch(basename, &fEventNumber, basename+"/I");
1334  }
1335  else if(fHistoType==kHelSavePattern)
1336  {
1337  basename = "actual_pattern_polarity";
1338  tree->Branch(basename, &fActualPatternPolarity, basename+"/I");
1339  //
1340  basename = "actual_previous_pattern_polarity";
1341  tree->Branch(basename, &fPreviousPatternPolarity, basename+"/I");
1342  //
1343  basename = "delayed_pattern_polarity";
1344  tree->Branch(basename, &fDelayedPatternPolarity, basename+"/I");
1345  //
1346  basename = "pattern_number";
1347  tree->Branch(basename, &fPatternNumber, basename+"/I");
1348  //
1349  basename = "pattern_seed";
1350  tree->Branch(basename, &fPatternSeed, basename+"/I");
1351 
1352  for (size_t i=0; i<fWord.size(); i++)
1353  {
1354  basename = fWord[i].fWordName;
1355  tree->Branch(basename, &fWord[i].fValue, basename+"/I");
1356  }
1357  }
1358 
1359  return;
1360 }
1361 
1362 void QwHelicity::ConstructBranch(TTree *tree, TString &prefix, QwParameterFile& trim_file)
1363 {
1364  TString basename;
1365 
1366  SetHistoTreeSave(prefix);
1367  if(fHistoType==kHelNoSave)
1368  {
1369  //do nothing
1370  }
1371  else if(fHistoType==kHelSaveMPS)
1372  {
1373  basename = "actual_helicity"; //predicted actual helicity before being delayed.
1374  tree->Branch(basename, &fHelicityActual, basename+"/I");
1375  //
1376  basename = "delayed_helicity"; //predicted delayed helicity
1377  tree->Branch(basename, &fHelicityDelayed, basename+"/I");
1378  //
1379  basename = "reported_helicity"; //delayed helicity reported by the input register.
1380  tree->Branch(basename, &fHelicityReported, basename+"/I");
1381  //
1382  basename = "pattern_phase";
1383  tree->Branch(basename, &fPatternPhaseNumber, basename+"/I");
1384  //
1385  basename = "pattern_number";
1386  tree->Branch(basename, &fPatternNumber, basename+"/I");
1387  //
1388  basename = "pattern_seed";
1389  tree->Branch(basename, &fPatternSeed, basename+"/I");
1390  //
1391  basename = "event_number";
1392  tree->Branch(basename, &fEventNumber, basename+"/I");
1393  }
1394  else if(fHistoType==kHelSavePattern)
1395  {
1396  basename = "actual_pattern_polarity";
1397  tree->Branch(basename, &fActualPatternPolarity, basename+"/I");
1398  //
1399  basename = "actual_previous_pattern_polarity";
1400  tree->Branch(basename, &fPreviousPatternPolarity, basename+"/I");
1401  //
1402  basename = "delayed_pattern_polarity";
1403  tree->Branch(basename, &fDelayedPatternPolarity, basename+"/I");
1404  //
1405  basename = "pattern_number";
1406  tree->Branch(basename, &fPatternNumber, basename+"/I");
1407  //
1408  basename = "pattern_seed";
1409  tree->Branch(basename, &fPatternSeed, basename+"/I");
1410 
1411  for (size_t i=0; i<fWord.size(); i++)
1412  {
1413  basename = fWord[i].fWordName;
1414  tree->Branch(basename,&fWord[i].fValue, basename+"/I");
1415  }
1416 
1417  }
1418 
1419 
1420  return;
1421 }
1422 
1423 void QwHelicity::FillTreeVector(std::vector<Double_t> &values) const
1424 {
1425 
1426  size_t index=fTreeArrayIndex;
1427  if(fHistoType==kHelSaveMPS)
1428  {
1429  values[index++] = fHelicityActual;
1430  values[index++] = fHelicityDelayed;
1431  values[index++] = fHelicityReported;
1432  values[index++] = fPatternPhaseNumber;
1433  values[index++] = fPatternNumber;
1434  values[index++] = fPatternSeed;
1435  values[index++] = fEventNumber;
1436  for (size_t i=0; i<fWord.size(); i++)
1437  values[index++] = fWord[i].fValue;
1438  }
1439  else if(fHistoType==kHelSavePattern)
1440  {
1441  values[index++] = fActualPatternPolarity;
1442  values[index++] = fPreviousPatternPolarity;
1443  values[index++] = fDelayedPatternPolarity;
1444  values[index++] = fPatternNumber;
1445  values[index++] = fPatternSeed;
1446  for (size_t i=0; i<fWord.size(); i++){
1447  values[index++] = fWord[i].fValue;
1448  }
1449  }
1450 
1451  return;
1452 }
1453 
1454 void QwHelicity::FillDB(QwParityDB *db, TString type)
1455 {
1456  if (type=="yield" || type=="asymmetry")
1457  return;
1458 
1459  db->Connect();
1460  mysqlpp::Query query = db->Query();
1461 
1462  db->Disconnect();
1463 }
1464 
1465 
1466 
1467 void QwHelicity::FillErrDB(QwParityDB *db, TString type)
1468 {
1469  return;
1470 }
1471 
1472 
1473 UInt_t QwHelicity::GetRandbit(UInt_t& ranseed){
1474  Bool_t status = false;
1475 
1476  if (fRandBits == 24)
1477  status = GetRandbit24(ranseed);
1478  if (fRandBits == 30)
1479  status = GetRandbit30(ranseed);
1480 
1481  return status;
1482 }
1483 
1484 UInt_t QwHelicity::GetRandbit24(UInt_t& ranseed)
1485 {
1486  /** This is a 24 bit random bit generator according to the "new" algorithm
1487  described in "G0 Helicity Digital Controls" by E. Stangland, R. Flood, H. Dong.
1488 
1489 
1490  The helicity board uses a maximum-length linear feedback shift registers
1491  for the generation of a pseudo-random sequence of bits. The length of the
1492  register (24 bits or 30 bits) defines the length before a sequence is
1493  repeated: 2^n - 1.
1494 
1495  For a mathematical introduction to the generation of pseudo-random numbers
1496  with maximum-length linear feedback shift registers (LFSR), see the
1497  following web references:
1498  http://en.wikipedia.org/wiki/Linear_feedback_shift_register
1499  http://www.newwaveinstruments.com/resources/articles/m_sequence_linear_feedback_shift_register_lfsr.htm
1500 
1501  In particular, the used solutions are to place XNOR taps at the bits
1502  24 stages, 4 taps: (47 sets)
1503  [24, 23, 21, 20]
1504  30 stages, 4 taps: (104 sets)
1505  [30, 29, 28, 7]
1506 
1507  The 24 stage solution we use has been mirrored by transforming [m, A, B, C]
1508  into [m, m-C, m-B, m-A]. This goes through the sequence in the opposite
1509  direction.
1510  */
1511 
1512  const UInt_t IB1 = 1; //Bit 1 of shift register 000000000000000000000001
1513  const UInt_t IB3 = 4; //Bit 3 of shift register 000000000000000000000100
1514  const UInt_t IB4 = 8; //Bit 4 of shift register 000000000000000000001000
1515  const UInt_t IB24 = 8388608; //Bit 24 of shift register 100000000000000000000000
1516  const UInt_t MASK = IB1+IB3+IB4+IB24; //Sum of the four feedback bits is 100000000000000000001101
1517 
1518  UInt_t result; //The generated pattern
1519 
1520  if(ranseed<=0)
1521  {
1522  QwError << "ranseed must be greater than zero!" << QwLog::endl;
1523  result = 0;
1524  }
1525 
1526  if(ranseed & IB24) // if bit 24 of ranseed = 1, then output 1
1527  {
1528  ranseed = ((ranseed^MASK) << 1|IB1);
1529  result = 1;
1530  }
1531  else
1532  {
1533  ranseed <<= 1;
1534  result = 0;
1535  }
1536  return(result);
1537 
1538 }
1539 
1540 
1541 UInt_t QwHelicity::GetRandbit30(UInt_t& ranseed)
1542 {
1543  /* For an explanation of the algorithm, see above in GetRandbit24() */
1544 
1545  UInt_t bit7 = (ranseed & 0x00000040) != 0;
1546  UInt_t bit28 = (ranseed & 0x08000000) != 0;
1547  UInt_t bit29 = (ranseed & 0x10000000) != 0;
1548  UInt_t bit30 = (ranseed & 0x20000000) != 0;
1549 
1550  UInt_t result = (bit30 ^ bit29 ^ bit28 ^ bit7) & 0x1;
1551 
1552  if(ranseed<=0) {
1553  QwError << "ranseed must be greater than zero!" << QwLog::endl;
1554  result = 0;
1555  }
1556  ranseed = ( (ranseed << 1) | result ) & 0x3FFFFFFF;
1557 
1558  return(result);
1559 }
1560 
1561 
1562 UInt_t QwHelicity::GetRandomSeed(UShort_t* first24randbits)
1563 {
1564  Bool_t ldebug=0;
1565  QwDebug << " Entering QwHelicity::GetRandomSeed \n";
1566 
1567  /** This the random seed generator used in G0 (L.Jianglai)
1568  Here we get the 24 random bits and derive the randome seed from that.
1569  randome seed : b24 b23 b22.....b2 b1
1570  first 24 random bit from this seed: h1 h2 h3 ....h23 h24
1571  we have,
1572  b23 = h1, b22 = h2,... b5 = h20,
1573  h21^b24 = b4 , h3^b24^b23 = b3 ,h23^b23^b22 = b2, h24^b22^b24 = b1.
1574  Thus by using h1,...h24, we can derive the b24,..b1 of the randseed.
1575  */
1576 
1577  UShort_t b[25];
1578  UInt_t ranseed = 0;
1579 
1580  if(ldebug)
1581  {
1582  for(size_t i=0;i<25;i++)
1583  std::cout << i << " : " << first24randbits[i] << "\n";
1584  }
1585 
1586  for(size_t i=24;i>=5;i--) b[i]= first24randbits[24-i+1]; //fill h24..h5
1587 
1588  // fill b[4] to b[1]
1589  b[4] = first24randbits[21]^b[24]; //h21^b24 = b4
1590  b[3] = first24randbits[22]^b[24]^b[23]; //h22^b24^b23 = b3
1591  b[2] = first24randbits[23]^b[23]^b[22];// h23^b23^b22 = b2
1592  b[1] = first24randbits[24]^b[21]^b[22]^b[24];// h24^b22^b24 = b1
1593 
1594  ///assign the values in the h aray and into the sead
1595  for(size_t i=24;i>=1;i--) ranseed=ranseed << 1|(b[i]&1);
1596 
1597  ranseed = ranseed&0xFFFFFF; //put a mask
1598 
1599  QwDebug << " seed =" << ranseed <<QwLog::endl;
1600  QwDebug << " Exiting QwHelicity::GetRandomSeed \n";
1601 
1602 
1603  return ranseed;
1604 
1605 }
1606 
1607 
1609 {
1610  Int_t ldebug = kFALSE;
1611 
1612  if(ldebug) std::cout << "Entering QwHelicity::RunPredictor for fEventNumber, " << fEventNumber
1613  << ", fPatternNumber, " << fPatternNumber
1614  << ", and fPatternPhaseNumber, " << fPatternPhaseNumber << std::endl;
1615 
1616  /**Update the random seed if the new event is from a different pattern.
1617  Check the difference between old pattern number and the new one and
1618  to see how many patterns we have missed or skipped. Then loop back
1619  to get the correct pattern polarities.
1620  */
1621 
1622 
1623  for (int i = 0; i < fPatternNumber - fPatternNumberOld; i++) //got a new pattern
1624  {
1628  QwDebug << "Predicting : seed actual, delayed: " << iseed_Actual
1629  << ":" << iseed_Delayed <<QwLog::endl;
1630  }
1631 
1632  /**Predict the helicity according to pattern
1633  Defined patterns:
1634  Pair: +- or -+
1635  Quartet: +--+ or -++-
1636  Octet: +--+-++- or -++-+--+
1637  Symmetric octet: +-+--+-+ or -+-++-+-
1638  Octo-quad: +--++--++--++--+-++--++--++--++-
1639  */
1640 
1641  Int_t localphase = fPatternPhaseNumber-fMinPatternPhase;//Paul's modifications
1642 
1643 
1644  // Use the stored helicity bit pattern to calculate the helicity of this window
1645  if (((fHelicityBitPattern >> localphase) & 0x1) == (fHelicityBitPattern & 0x1)) {
1648  } else {
1651  }
1652  // Past highest pattern phase
1653  if (localphase > fMaxPatternPhase)
1654  ResetPredictor();
1655 
1656  if(ldebug){
1657  std::cout << "Predicted Polarity ::: Delayed ="
1658  << fDelayedPatternPolarity << " Actual ="
1659  << fActualPatternPolarity << "\n";
1660  std::cout << "Predicted Helicity ::: Delayed Helicity=" << fHelicityDelayed
1661  << " Actual Helicity=" << fHelicityActual << " Reported Helicity=" << fHelicityReported << "\n";
1662  QwError << "Exiting QwHelicity::RunPredictor " << QwLog::endl;
1663 
1664  }
1665 
1666  return;
1667 }
1668 
1669 
1671 {
1672  Bool_t status = false;
1673 
1674  if (fRandBits == 24)
1675  status = CollectRandBits24();
1676  if (fRandBits == 30)
1677  status = CollectRandBits30();
1678 
1679  return status;
1680 }
1681 
1682 
1683 
1685 {
1686  //routine to collect 24 random bits before getting the randseed for prediction
1687  Bool_t ldebug = kFALSE;
1688  const UInt_t ranbit_goal = 24;
1689 
1690  QwDebug << "QwHelicity::Entering CollectRandBits24...." << QwLog::endl;
1691 
1692 
1693  if (n_ranbits==ranbit_goal) return kTRUE;
1694 
1696  {
1697  QwMessage << "Collecting information from event #" << fEventNumber << " to generate helicity seed"
1698  << "(need 24 bit, so far got " << n_ranbits << " bits )" << QwLog::endl;
1699  }
1700 
1701 
1702  static UShort_t first24bits[25]; //array to store the first 24 bits
1703 
1704  fGoodHelicity = kFALSE; //reset before prediction begins
1705  if(IsContinuous())
1706  {
1708  {
1709  first24bits[n_ranbits+1] = fHelicityReported;
1710  n_ranbits ++;
1711  if(ldebug)
1712  {
1713  std::cout << " event number" << fEventNumber << ", fPatternNumber"
1714  << fPatternNumber << ", n_ranbit" << n_ranbits
1715  << ", fHelicityReported" << fHelicityReported << "\n";
1716  }
1717 
1718  if(n_ranbits == ranbit_goal ) //If its the 24th consecative random bit,
1719  {
1720  if(ldebug)
1721  {
1722  std::cout << "Collected 24 random bits. Get the random seed for the predictor." << "\n";
1723  for(UInt_t i=0;i<ranbit_goal;i++) std::cout << " i:bit =" << i << ":" << first24bits[i] << "\n";
1724  }
1725  iseed_Delayed = GetRandomSeed(first24bits);
1726  //This random seed will predict the helicity of the event (24+fHelicityDelay) patterns before;
1727  // run GetRandBit 24 times to get the delayed helicity for this event
1728  QwDebug << "The reported seed 24 patterns ago = " << iseed_Delayed << "\n";
1729 
1730  for(UInt_t i=0;i<ranbit_goal;i++) fDelayedPatternPolarity =GetRandbit(iseed_Delayed);
1732  //The helicity of the first phase in a pattern is
1733  //equal to the polarity of the pattern
1734 
1735  //Check whether the reported helicity is the same as the helicity predicted by the random seed
1736 
1737  if(fHelicityDelay >=0){
1739  for(Int_t i=0; i<fHelicityDelay; i++)
1740  {
1741  QwDebug << "Delaying helicity " << QwLog::endl;
1744  }
1745  }
1746  else
1747  {
1748  QwError << "QwHelicity::CollectRandBits We cannot handle negative delay(prediction) in the reported helicity. Exiting." << QwLog::endl;
1749  ResetPredictor();
1750  }
1751 
1753  }
1754  }
1755  }
1756  else // while collecting the seed, we encounter non continuous events.
1757  {
1758  ResetPredictor();
1759  QwError << "QwHelicity::CollectRandBits, while collecting the seed, we encountered non continuous events: need to reset the seed collecting " << QwLog::endl
1760  << " event number=" << fEventNumber << ", fPatternNumber="
1761  << fPatternNumber << ", fPatternPhaseNumber=" << fPatternPhaseNumber << QwLog::endl;
1762  }
1763 
1764  //else n randbits have been set to zero in the error checking routine
1765  //start over from the next pattern
1766  QwDebug << "QwHelicity::CollectRandBits24 => Done collecting ..." << QwLog::endl;
1767 
1768  return kFALSE;
1769 
1770 }
1771 
1772 
1774 {
1775  /** Starting to collect 30 bits/helicity state to get the
1776  random seed for the 30 bit helicity predictor.
1777  These bits (1/0) are the reported helicity states of the first event
1778  of each new pattern ot the so called pattern polarity.*/
1779 
1780  // Bool_t ldebug = kFALSE;
1781  const UInt_t ranbit_goal = 30;
1782 
1783  /** If we have finished collecting the bits then ignore the rest of this funciton and return true.
1784  No need to recollect!*/
1785  if (n_ranbits == ranbit_goal) return kTRUE;
1786 
1787  /** If we are still collecting the bits, make sure we collect them from only the
1788  events with the minimum pattern phase.*/
1789 
1790  if (n_ranbits < ranbit_goal && fPatternPhaseNumber == fMinPatternPhase) {
1791  QwMessage << "Collecting information (";
1792  if (fHelicityReported == 1) QwMessage << "+";
1793  else QwMessage << "-";
1794  QwMessage << ") from event #" << fEventNumber << " to generate helicity seed ";
1795  QwMessage << "(need " << ranbit_goal << " bit, so far got " << n_ranbits << " bits )" << QwLog::endl;
1796  }
1797 
1798  /** If the events are continuous, start to make the ranseed for the helicity
1799  pattern we are getting which is the delayed helicity.*/
1800 
1801  fGoodHelicity = kFALSE; //reset before prediction begins
1802 
1803  if(IsContinuous()) {
1804  /** Make sure we are at the beging of a valid pattern. */
1806  iseed_Delayed = ((iseed_Delayed << 1)&0x3FFFFFFF)|fHelicityReported;
1807  QwDebug << "QwHelicity:: CollectRandBits30: Collecting randbit " << n_ranbits << ".." << QwLog::endl;
1808  n_ranbits++;
1809 
1810  /** If we got the 30th bit,*/
1811  if(n_ranbits == ranbit_goal){
1812  QwDebug << "QwHelicity:: CollectRandBits30: done Collecting 30 randbits" << QwLog::endl;
1813 
1814  /** set the polarity of the current pattern to be equal to the reported helicity,*/
1816  QwDebug << "QwHelicity:: CollectRandBits30: delayedpatternpolarity =" << fDelayedPatternPolarity << QwLog::endl;
1817 
1818  /** then use it as the delayed helicity, */
1820 
1821  /**if the helicity is delayed by a positive number of patterns then loop the delayed ranseed backward to get the ranseed
1822  for the actual helicity */
1823  if(fHelicityDelay >=0){
1825  for(Int_t i=0; i<fHelicityDelay; i++) {
1826  /**, get the pattern polarity for the actual pattern using that actual ranseed.*/
1829  }
1830  } else {
1831  /** If we have a negative delay. Reset the predictor.*/
1832  QwError << "QwHelicity::CollectRandBits30: We cannot handle negative delay(prediction) in the reported helicity. Exiting." << QwLog::endl;
1833  ResetPredictor();
1834  }
1835  /** If all is well so far, set the actual pattern polarity as the actual helicity.*/
1837  }
1838  }
1839  } else {
1840  /** while collecting the seed, we encounter non continuous events.Discard bit. Reset the predition*/
1841  ResetPredictor();
1842  QwWarning << "QwHelicity::CollectRandBits30: While collecting the seed, we encountered non continuous events: Need to reset the seed collecting " << QwLog::endl;
1843  QwDebug << " event number=" << fEventNumber << ", fPatternNumber="<< fPatternNumber << ", fPatternPhaseNumber=" << fPatternPhaseNumber << QwLog::endl;
1844  }
1845  return kFALSE;
1846 }
1847 
1848 
1850 {
1851  Bool_t ldebug=kFALSE;
1852 
1853  if(ldebug) std::cout << "Entering QwHelicity::PredictHelicity \n";
1854 
1855  /**Routine to predict the true helicity from the delayed helicity.
1856  Helicities are usually delayed by 8 events or 2 quartets. This delay
1857  can now be set as a cmd line option.
1858  */
1859 
1860  if(CollectRandBits()) {
1861  /**After accumulating 24/30 helicity bits, iseed is up-to-date.
1862  If nothing goes wrong, n-ranbits will stay as 24/30
1863  Reset it to zero if something goes wrong.
1864  */
1865 
1866  if(ldebug) std::cout << "QwHelicity::PredictHelicity=>Predicting the helicity \n";
1867  RunPredictor();
1868 
1869  /** If not good helicity, start over again by resetting the predictor. */
1870  if(!IsGoodHelicity())
1871  ResetPredictor();
1872  }
1873 
1874  if(ldebug) std::cout << "n_ranbit exiting the function = " << n_ranbits << "\n";
1875 
1876  return;
1877 }
1878 
1879 
1880 
1882 {
1883  /**Sets the number of bits the helicity reported gets delayed with.
1884  We predict helicity only if there is a non-zero pattern delay given. */
1885 
1886  if(delay>=0){
1887  fHelicityDelay = delay;
1888  if(delay == 0){
1889  QwWarning << "QwHelicity : SetHelicityDelay :: helicity delay is set to 0."
1890  << " Disabling helicity predictor and using reported helicity information."
1891  << QwLog::endl;
1892  fUsePredictor = kFALSE;
1893  }
1894  else
1895  fUsePredictor = kTRUE;
1896  }
1897  else
1898  QwError << "QwHelicity::SetHelicityDelay We cannot handle negative delay in the prediction of delayed helicity. Exiting.." << QwLog::endl;
1899 
1900  return;
1901 }
1902 
1903 
1905 {
1906  // Set the helicity pattern bits
1907  if (parity(bits) == 0)
1908  fHelicityBitPattern = bits;
1909  else QwError << "What, exactly, are you trying to do ?!?!?" << QwLog::endl;
1910  // Notify the user
1911  QwMessage << " fPatternBits 0x" << std::hex << fHelicityBitPattern << std::dec << QwLog::endl;
1912 }
1913 
1915 {
1916  /**Start a new helicity prediction sequence.*/
1917 
1918  QwWarning << "QwHelicity::ResetPredictor: Resetting helicity prediction!" << QwLog::endl;
1919  n_ranbits = 0;
1920  fGoodHelicity = kFALSE;
1921  fGoodPattern = kFALSE;
1922  return;
1923 }
1924 
1925 
1926 
1928 {
1929  Bool_t ldebug = kFALSE;
1930  if(Compare(value))
1931  {
1932 
1933  //QwHelicity* input= (QwHelicity*)value;
1934  VQwSubsystem::operator=(value);
1935  QwHelicity* input= dynamic_cast<QwHelicity*>(value);
1936 
1937  for(size_t i=0;i<input->fWord.size();i++)
1938  this->fWord[i].fValue=input->fWord[i].fValue;
1939  this->fHelicityActual = input->fHelicityActual;
1940  this->fPatternNumber = input->fPatternNumber;
1941  this->fPatternSeed = input->fPatternSeed;
1942  this->fPatternPhaseNumber=input->fPatternPhaseNumber;
1943  this->fEventNumber=input->fEventNumber;
1944  this->fActualPatternPolarity=input->fActualPatternPolarity;
1945  this->fDelayedPatternPolarity=input->fDelayedPatternPolarity;
1946  this->fPreviousPatternPolarity=input->fPreviousPatternPolarity;
1947  this->fHelicityReported=input->fHelicityReported;
1948  this->fHelicityActual=input->fHelicityActual;
1949  this->fHelicityDelayed=input->fHelicityDelayed;
1950  this->fHelicityBitPlus=input->fHelicityBitPlus;
1951  this->fHelicityBitMinus=input->fHelicityBitMinus;
1952  this->fGoodHelicity=input->fGoodHelicity;
1953  this->fGoodPattern=input->fGoodPattern;
1954  this->fIgnoreHelicity = input->fIgnoreHelicity;
1955 
1956  if(ldebug){
1957  std::cout << "QwHelicity::operator = this->fPatternNumber=" << this->fPatternNumber << std::endl;
1958  std::cout << "input->fPatternNumber=" << input->fPatternNumber << "\n";
1959  }
1960  }
1961 
1962  return *this;
1963 }
1964 
1966 {
1967  // Bool_t localdebug=kFALSE;
1968  QwDebug << "Entering QwHelicity::operator+= adding " << value->GetSubsystemName() << " to " << this->GetSubsystemName() << " " << QwLog::endl;
1969 
1970  //this routine is most likely to be called during the computatin of assymetry
1971  //this call doesn't make too much sense for this class so the following lines
1972  //are only use to put safe gards testing for example if the two instantiation indeed
1973  // refers to elements in the same pattern.
1974  if(Compare(value))
1975  {
1976  QwHelicity* input= dynamic_cast<QwHelicity*>(value);
1977  QwDebug << "QwHelicity::operator+=: this->fPatternNumber=" << this->fPatternNumber
1978  << ", input->fPatternNumber=" << input->fPatternNumber << QwLog::endl;
1979 
1980  if(this->fPatternNumber!=input->fPatternNumber)
1981  this->fPatternNumber=-999999;
1983  this->fPatternNumber=-999999;
1984  }
1985  return *this;
1986 }
1987 
1989 {
1990  //this routine is most likely to be called during the computatin of assymetry
1991  //this call doesn't make too much sense for this class so the followign lines
1992  //are only use to put safe gards testing for example if the two instantiation indeed
1993  // refers to elements in the same pattern
1994  if(Compare(value1)&&Compare(value2)) {
1995  *this = value1;
1996  //*this += value2;
1997  }
1998 }
1999 
2001 {
2002  // this is stub function defined here out of completion and uniformity between each subsystem
2003  *this = value1;
2004 }
2005 
2007 {
2008  // this is stub function defined here out of completion and uniformity between each subsystem
2009  *this = value1;
2010 }
2011 
2012 
2014 {
2015  Bool_t res=kTRUE;
2016  if(typeid(*value)!=typeid(*this)) {
2017  res=kFALSE;
2018  } else {
2019  QwHelicity* input= dynamic_cast<QwHelicity*>(value);
2020  if(input->fWord.size()!=fWord.size()) {
2021  res=kFALSE;
2022  }
2023  }
2024  return res;
2025 }
2026 
2027 
2028 UInt_t QwHelicity::BuildHelicityBitPattern(Int_t patternsize){
2029  UInt_t bitpattern = 0;
2030  // Standard helicity board patterns (last to first):
2031  // Pair, quad, octet: -++-+--+ : 0x69
2032  // Hexo-quad: -++--++--++-+--++--++--+ : 0x666999
2033  // Octo-quad: -++--++--++--++-+--++--++--++--+ : 0x66669999
2034  //
2035  if (patternsize<8){
2036  bitpattern = kDefaultHelicityBitPattern;
2037  } else if (patternsize%8==0){
2038  Int_t halfshift = patternsize/2;
2039  for (Int_t i=0; i<(patternsize/8); i++){
2040  bitpattern += (0x9<<(i*4));
2041  bitpattern += (0x6<<(halfshift+i*4));
2042  }
2043  } else {
2044  QwError << "QwHelicity::BuildHelicityBitPattern: "
2045  << "Unable to build standard bit pattern for pattern size of "
2046  << patternsize << ". Try a pattern of 0x69."
2047  << QwLog::endl;
2048  bitpattern = kDefaultHelicityBitPattern;
2049  }
2050  QwDebug << "QwHelicity::BuildHelicityBitPattern: "
2051  << "Built pattern 0x" << std::hex << bitpattern
2052  << std::dec << " for pattern size "
2053  << patternsize << "." << QwLog::endl;
2054  // Now set the bit pattern.
2055  SetHelicityBitPattern(bitpattern);
2056  return bitpattern;
2057 }
Int_t GetSubbankIndex() const
Definition: VQwSubsystem.h:303
#define QwMessage
Predefined log drain for regular messages.
Definition: QwLog.h:50
Int_t fHelicityDelay
Definition: QwHelicity.h:233
void ProcessEventInputRegisterMode()
Definition: QwHelicity.cc:518
Int_t fNumMissedGates
Definition: QwHelicity.h:275
std::map< TString, TString > fDetectorMaps
Definition: VQwSubsystem.h:322
Int_t GetPhaseNumber()
Definition: QwHelicity.cc:1084
#define QwOut
Predefined log drain for explicit output.
Definition: QwLog.h:35
Int_t fEventNumber
Definition: QwHelicity.h:194
UInt_t GetRandbit24(UInt_t &ranseed)
Definition: QwHelicity.cc:1484
Int_t kScalerCounter
Definition: QwHelicity.h:186
void PredictHelicity()
Definition: QwHelicity.cc:1849
#define default_bool_value(b)
Definition: QwOptions.h:51
void SetFirstBits(UInt_t nbits, UInt_t firstbits)
Definition: QwHelicity.cc:1096
TString fWordType
Definition: QwWord.h:30
void Difference(VQwSubsystem *value1, VQwSubsystem *value2)
Definition: QwHelicity.cc:2000
Definition: QwWord.h:19
void Disconnect()
Definition: QwDatabase.h:59
void Ratio(VQwSubsystem *numer, VQwSubsystem *denom)
Definition: QwHelicity.cc:2006
void FillErrDB(QwParityDB *db, TString datatype)
Definition: QwHelicity.cc:1467
Int_t kInputRegister
Definition: QwHelicity.h:190
UInt_t GetRandbit30(UInt_t &ranseed)
Definition: QwHelicity.cc:1541
Bool_t Connect()
Open a connection to the database using the predefined parameters.
Definition: QwDatabase.cc:175
Int_t ProcessEvBuffer(const UInt_t roc_id, const UInt_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...
Definition: QwHelicity.h:72
virtual UInt_t GetRandbit(UInt_t &ranseed)
Definition: QwHelicity.cc:1473
void Sum(VQwSubsystem *value1, VQwSubsystem *value2)
Definition: QwHelicity.cc:1988
Int_t ProcessConfigurationBuffer(const UInt_t roc_id, const UInt_t bank_id, UInt_t *buffer, UInt_t num_words)
Definition: QwHelicity.cc:384
An options class.
Definition: QwOptions.h:133
std::vector< std::pair< Int_t, Int_t > > fWordsPerSubbank
Definition: QwHelicity.h:173
Int_t fWordInSubbank
Definition: QwWord.h:27
static UInt_t GetUInt(const TString &varvalue)
bool HasValue(const std::string &key)
Has this key been defined.
Definition: QwOptions.h:233
void ProcessOptions(QwOptions &options)
Process the command line options.
Definition: QwHelicity.cc:173
Bool_t IsGoodPhaseNumber()
Definition: QwHelicity.cc:283
void ProcessEventUserbitMode()
Definition: QwHelicity.cc:441
std::vector< TH1_ptr > fHistograms
Histograms associated with this data element.
Definition: MQwHistograms.h:46
virtual Bool_t CollectRandBits()
Definition: QwHelicity.cc:1670
Int_t fHistoType
Definition: QwHelicity.h:212
Int_t fNumHelicityErrors
Definition: QwHelicity.h:281
Bool_t HasDataLoaded() const
Definition: VQwSubsystem.h:94
Long_t GetPatternNumber()
Definition: QwHelicity.cc:1074
Bool_t fIgnoreHelicity
Definition: QwHelicity.h:262
virtual Bool_t IsGoodHelicity()
Definition: QwHelicity.cc:314
Virtual base class for the parity subsystems.
static const UInt_t kInputReg_FakeMPS
Default mask for fake MPS latch bit.
Definition: QwHelicity.h:165
void IncrementErrorCounters()
Increment the error counters.
Definition: QwHelicity.cc:403
void ClearErrorCounters()
Definition: QwHelicity.h:270
Int_t fPatternNumberOld
Definition: QwHelicity.h:196
Int_t fPatternSeed
Definition: QwHelicity.h:197
unsigned int parity(unsigned int v)
Definition: QwHelicity.h:292
UInt_t kEventTypeHelMinus
Definition: QwHelicity.h:192
virtual void ConstructHistograms()
Construct the histograms for this subsystem.
Definition: VQwSubsystem.h:209
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:164
void SetHelicityDelay(Int_t delay)
Definition: QwHelicity.cc:1881
static const Int_t kUndefinedHelicity
Definition: QwHelicity.h:223
size_t fTreeArrayIndex
Definition: QwHelicity.h:227
Long_t GetEventNumber()
Definition: QwHelicity.cc:1079
UInt_t fHelicityBitPattern
Definition: QwHelicity.h:170
Int_t fEventNumberFirst
Definition: QwHelicity.h:267
void PrintErrorCounters() const
Report the number of events failed due to HW and event cut failures.
Definition: QwHelicity.cc:408
void FillDB(QwParityDB *db, TString type)
Fill the database.
Definition: QwHelicity.cc:1454
Int_t fHelicityReported
Definition: QwHelicity.h:201
T GetValue(const std::string &key)
Get a templated value.
Definition: QwOptions.h:240
Bool_t CollectRandBits30()
Definition: QwHelicity.cc:1773
Int_t fPatternPhaseOffset
Definition: QwHelicity.h:260
virtual VQwSubsystem & operator=(VQwSubsystem *value)
Assignment Note: Must be called at the beginning of all subsystems routine call to operator=(VQwSubsy...
Bool_t IsGoodPatternNumber()
Definition: QwHelicity.cc:248
Int_t GetHelicityDelayed()
Definition: QwHelicity.cc:1069
VQwSubsystem & operator+=(VQwSubsystem *value)
Definition: QwHelicity.cc:1965
VQwSubsystem & operator=(VQwSubsystem *value)
Assignment Note: Must be called at the beginning of all subsystems routine call to operator=(VQwSubsy...
Definition: QwHelicity.cc:1927
#define QwDebug
Predefined log drain for debugging output.
Definition: QwLog.h:60
Int_t GetHelicityReported()
Definition: QwHelicity.cc:1059
static void DefineOptions()
Define options function (note: no virtual static functions in C++)
Definition: VQwSubsystem.h:88
Int_t fDelayedPatternPolarity
Reported polarity of the current pattern.
Definition: QwHelicity.h:199
A logfile class, based on an identical class in the Hermes analyzer.
Int_t fNumMultSyncErrors
Definition: QwHelicity.h:280
void EncodeEventData(std::vector< UInt_t > &buffer)
Definition: QwHelicity.cc:714
Int_t fMaxPatternPhase
Definition: QwHelicity.h:236
Int_t LoadEventCuts(TString filename)
Load the event cuts file.
Definition: QwHelicity.cc:1015
Bool_t Compare(VQwSubsystem *source)
Definition: QwHelicity.cc:2013
Int_t fRandBits
Definition: QwHelicity.h:257
UInt_t fInputReg_FakeMPS
Definition: QwHelicity.h:166
UInt_t n_ranbits
Definition: QwHelicity.h:229
Bool_t fHelicityInfoOK
Definition: QwHelicity.h:259
Bool_t fUsePredictor
Definition: QwHelicity.h:258
mysqlpp::Query Query(const char *qstr=0)
Definition: QwDatabase.h:66
Bool_t fGoodPattern
Definition: QwHelicity.h:210
Int_t fMinPatternPhase
Definition: QwHelicity.h:237
Int_t fEventNumberOld
Definition: QwHelicity.h:194
Int_t LoadChannelMap(TString mapfile)
Mandatory map file definition.
Definition: QwHelicity.cc:804
Int_t fActualPatternPolarity
True polarity of the current pattern.
Definition: QwHelicity.h:198
Int_t kMpsCounter
Definition: QwHelicity.h:190
virtual void ClearEventData()
Definition: QwHelicity.cc:347
UInt_t GetEventcutErrorFlag()
Return the error flag to the top level routines related to stability checks and ErrorFlag updates...
Definition: QwHelicity.cc:435
void SetHelicityBitPattern(UInt_t bits)
Definition: QwHelicity.cc:1904
Int_t fSubbankIndex
Definition: QwWord.h:24
QwHelicity()
Private default constructor (not implemented, will throw linker error on use)
void FillHistograms()
Fill the histograms for this subsystem.
Definition: QwHelicity.cc:1171
UInt_t BuildHelicityBitPattern(Int_t patternsize)
Definition: QwHelicity.cc:2028
Int_t fPreviousPatternPolarity
True polarity of the previous pattern.
Definition: QwHelicity.h:200
Int_t fNumMissedEventBlocks
Definition: QwHelicity.h:279
QwHistogramHelper gQwHists
Globally defined instance of the QwHistogramHelper class.
The pure virtual base class of all subsystems.
Definition: VQwSubsystem.h:59
Bool_t fSuppressMPSErrorMsgs
Definition: QwHelicity.h:286
Int_t fHelicityDelayed
Definition: QwHelicity.h:201
void SetEventPatternPhase(Int_t event, Int_t pattern, Int_t phase)
Definition: QwHelicity.cc:1089
TString fModuleType
Definition: QwWord.h:28
void ResetPredictor()
Definition: QwHelicity.cc:1914
Bool_t fHelicityBitMinus
Definition: QwHelicity.h:208
Int_t fCurrentROC_ID
ROC ID that is currently being processed.
Definition: VQwSubsystem.h:325
Int_t RegisterSubbank(const UInt_t bank_id)
Tell the object that it will decode data from this sub-bank in the ROC currently open for registratio...
virtual Int_t RegisterROCNumber(const UInt_t roc_id, const UInt_t bank_id=0)
Tell the object that it will decode data from this ROC and sub-bank.
TString fWordName
Definition: QwWord.h:29
static std::ostream & endl(std::ostream &)
End of the line.
Definition: QwLog.cc:299
Int_t LoadInputParameters(TString pedestalfile)
Mandatory parameter file definition.
Definition: QwHelicity.cc:391
Bool_t CheckIORegisterMask(const UInt_t &ioregister, const UInt_t &mask) const
Definition: QwHelicity.h:146
void FillTreeVector(std::vector< Double_t > &values) const
Fill the tree vector.
Definition: QwHelicity.cc:1423
UInt_t GetRandomSeed(UShort_t *first24randbits)
Definition: QwHelicity.cc:1562
Int_t kPatternCounter
Definition: QwHelicity.h:190
std::vector< QwWord > fWord
Definition: QwHelicity.h:172
void RunPredictor()
Definition: QwHelicity.cc:1608
UInt_t iseed_Delayed
Definition: QwHelicity.h:231
Int_t fHelicityDecodingMode
Definition: QwHelicity.h:175
Bool_t fHelicityBitPlus
Definition: QwHelicity.h:207
void ProcessEventInputMollerMode()
Definition: QwHelicity.cc:613
#define QwWarning
Predefined log drain for warnings.
Definition: QwLog.h:45
Int_t kUserbit
Definition: QwHelicity.h:182
UInt_t GetEventTypeMask() const
Get event type mask.
Definition: VQwSubsystem.h:168
Int_t fPatternPhaseNumber
Definition: QwHelicity.h:195
void SetHistoTreeSave(const TString &prefix)
Definition: QwHelicity.cc:1108
UInt_t iseed_Actual
Definition: QwHelicity.h:230
Int_t GetHelicityActual()
Definition: QwHelicity.cc:1064
virtual void ProcessEvent()
Definition: QwHelicity.cc:658
Bool_t IsContinuous()
Definition: QwHelicity.cc:239
TH1F * Construct1DHist(const TString &inputfile, const TString &name_title)
Int_t fCurrentBank_ID
Bank ID that is currently being processed.
Definition: VQwSubsystem.h:326
Int_t fHelicityActual
Definition: QwHelicity.h:201
static const UInt_t kDefaultHelicityBitPattern
Definition: QwHelicity.h:168
Bool_t CollectRandBits24()
Definition: QwHelicity.cc:1684
UInt_t fEventType
Definition: QwHelicity.h:264
Int_t fPatternNumber
Definition: QwHelicity.h:196
Bool_t ApplySingleEventCuts()
Apply the single event cuts.
Definition: QwHelicity.cc:397
void ConstructBranchAndVector(TTree *tree, TString &prefix, std::vector< Double_t > &values)
Construct the branch and tree vector.
Definition: QwHelicity.cc:1222
Int_t kPatternPhase
Definition: QwHelicity.h:190
#define RegisterSubsystemFactory(A)
Definition: QwFactory.h:230
Bool_t fGoodHelicity
Definition: QwHelicity.h:209
#define QwError
Predefined log drain for errors.
Definition: QwLog.h:40
TString GetSubsystemName() const
Definition: VQwSubsystem.h:93
Bool_t IsGoodEventNumber()
Definition: QwHelicity.cc:267
Int_t fPatternPhaseNumberOld
Definition: QwHelicity.h:195
UInt_t kEventTypeHelPlus
Definition: QwHelicity.h:192
void Print() const
Definition: QwHelicity.cc:782
Int_t fPatternNumberFirst
Definition: QwHelicity.h:268
void ConstructBranch(TTree *tree, TString &prefix)
Construct the branch and tree vector.
Definition: QwHelicity.cc:1303
void SetDataLoaded(Bool_t flag)
Definition: VQwSubsystem.h:305