Hall C ROOT/C++ Analyzer (hcana)
THcHelicity.cxx
Go to the documentation of this file.
1 
8 //
9 // Helicity of the beam in delayed mode using quartets
10 // +1 = plus, -1 = minus, 0 = unknown
11 //
12 // Also supports in-time mode with delay = 0
13 //
15 
16 #include "THcHelicity.h"
17 
18 #include "THaApparatus.h"
19 #include "THaEvData.h"
20 #include "THcGlobals.h"
21 #include "THcParmList.h"
22 #include "THcHelicityScaler.h"
23 #include "TH1F.h"
24 #include "TMath.h"
25 #include <iostream>
26 #include <bitset>
27 
28 using namespace std;
29 
30 //_____________________________________________________________________________
31 THcHelicity::THcHelicity( const char* name, const char* description,
32  THaApparatus* app ):
33  THaHelicityDet( name, description, app ),
34  fnQrt(-1), fHelDelay(8), fMAXBIT(30)
35 {
36  // for( Int_t i = 0; i < NHIST; ++i )
37  // fHisto[i] = 0;
38  // memset(fHbits, 0, sizeof(fHbits));
40  fHelicityHistory = 0;
41 }
42 
43 //_____________________________________________________________________________
45  : fnQrt(-1), fHelDelay(8), fMAXBIT(30)
46 {
47  // Default constructor for ROOT I/O
48 
49  // for( Int_t i = 0; i < NHIST; ++i )
50  // fHisto[i] = 0;
51 }
52 
53 //_____________________________________________________________________________
55 {
56  DefineVariables( kDelete );
57 
58  // for( Int_t i = 0; i < NHIST; ++i ) {
59  // delete fHisto[i];
60  // }
61 }
62 
63 //_____________________________________________________________________________
64 THaAnalysisObject::EStatus THcHelicity::Init(const TDatime& date) {
65  // Call `Setup` before everything else.
66  Setup(GetName(), GetTitle());
67 
69  fActualHelicity = kUnknown;
70  fPredictedHelicity = kUnknown;
71  fLastMPSTime = 0;
72  fFoundMPS = kFALSE;
73 
74  // Call initializer for base class.
75  // This also calls `ReadDatabase` and `DefineVariables`.
76  EStatus status = THaDetector::Init(date);
77  if (status) {
78  fStatus = status;
79  return fStatus;
80  }
81 
82  fEvNumCheck = 0;
83  fDisabled = kFALSE;
84 
85  fLastHelpCycle=-1;
86  fQuadPattern[0] = fQuadPattern[1] = fQuadPattern[2] = fQuadPattern[3] = 0;
87  fQuadPattern[4] = fQuadPattern[5] = fQuadPattern[6] = fQuadPattern[7] = 0;
90  fScalerSeed=0;
91  fNBits = 0;
92  lastispos = 0;
93  fLastReportedHelicity = kUnknown;
95  fHaveQRT = kFALSE;
96  fNQRTProblems = 0;
97  fPeriodCheck = 0.0;
98  fPeriodCheckOffset = 0.0;
99  fCycle = 0.0;
100  fRecommendedFreq = -1.0;
101 
102  fStatus = kOK;
103  return fStatus;
104 }
105 
106 //_____________________________________________________________________________
107 void THcHelicity::Setup(const char* name, const char* description) {
108  // Prefix for parameters in `param` file.
109  string kwPrefix = string(GetApparatus()->GetName()) + "_" + name;
110  std::transform(kwPrefix.begin(), kwPrefix.end(), kwPrefix.begin(), ::tolower);
111  fKwPrefix = kwPrefix;
112 }
113 
114 //_____________________________________________________________________________
116 {
117 
118  cout << "In THcHelicity::ReadDatabase" << endl;
119  // Read general HelicityDet database values (e.g. fSign)
120  // Int_t st = THaHelicityDet::ReadDatabase( date );
121  // if( st != kOK )
122  // return st;
123 
124  // Read readout parameters (ROC addresses etc.)
125  Int_t st = THcHelicityReader::ReadDatabase( GetDBFileName(), GetPrefix(),
126  date, fQWEAKDebug );
127  if( st != kOK )
128  return st;
129 
130  fSign = 1; // Default helicity sign
131  fRingSeed_reported_initial = 0; // Initial see that should predict reported
132  // helicity of first quartet.
133  fFirstCycle = -1; // First Cycle that starts a quad (0 to 3)
134  fNLastQuartet = -1;
135  fNQuartet = 0;
136  // fFreq = 29.5596;
137  fFreq = 120.0007547169;
138  fHelDelay=8;
139 
140  DBRequest list[]= {
141  // {"_hsign", &fSign, kInt, 0, 1},
142  {"helicity_delay", &fHelDelay, kInt, 0, 1},
143  {"helicity_freq", &fFreq, kDouble, 0, 1},
144  // {"helicity_seed", &fRingSeed_reported_initial, kInt, 0, 1},
145  // {"helicity_cycle", &fFirstCycle, kInt, 0, 1},
146  {0}
147  };
148 
149  gHcParms->LoadParmValues(list, "");
150 
151  fMAXBIT=30;
152 
153  fTIPeriod = 250000000.0/fFreq;
154 
155  // maximum of event in the pattern, for now we are working with quartets
156  // Int_t localpattern[4]={1,-1,-1,1};
157  // careful, the first value here should always +1
158  // for(int i=0;i<fQWEAKNPattern;i++)
159  // {
160  // fPatternSequence.push_back(localpattern[i]);
161  // }
162  HWPIN=kTRUE;
163 
164  fQuartet[0]=fQuartet[1]=fQuartet[2]=fQuartet[3]=0;
165 
167  // Set the seed for predicted reported and predicted actual
168  } else {
169  // Initialize mode to find quartets and then seed
170  }
171 
172  cout << "Helicity decoder initialized with frequency of " << fFreq
173  << " Hz and reporting delay of " << fHelDelay << " cycles." << endl;
174 
175  return kOK;
176 }
177 
178 //_____________________________________________________________________________
179 
181 {
182  THaDetector::MakePrefix();
183 }
184 //_____________________________________________________________________________
186 {
187  // Initialize global variables
188 
189  cout << "Called THcHelicity::DefineVariables with mode == "
190  << mode << endl;
191 
192  if( mode == kDefine && fIsSetup ) return kOK;
193  fIsSetup = ( mode == kDefine );
194 
195  // Define standard variables from base class
196  THaHelicityDet::DefineVariables( mode );
197 
198  const RVarDef var[] = {
199  { "nqrt", "position of cycle in quartet", "fnQrt" },
200  { "hel", "actual helicity for event", "fActualHelicity" },
201  { "helrep", "reported helicity for event", "fReportedHelicity" },
202  { "helpred", "predicted reported helicity for event", "fPredictedHelicity" },
203  { "mps", "In MPS blanking period", "fMPS"},
204  { "pcheck", "Period check", "fPeriodCheck"},
205  { "cycle", "Helicity Cycle", "fCycle"},
206  { "qrt", "Last cycle of quartet", "fQrt"},
207  { 0 }
208  };
209  cout << "Calling THcHelicity DefineVarsFromList" << endl;
210  return DefineVarsFromList( var, mode );
211 }
212 //_____________________________________________________________________________
213 
215 {
216 
217  cout<<" ++++++ THcHelicity::Print ++++++\n";
218 
219  cout<<" +++++++++++++++++++++++++++++++++++++\n";
220 
221  return;
222 }
223 
224 //_____________________________________________________________________________
225 Int_t THcHelicity::Begin( THaRunBase* )
226 {
228 
229  // fHisto[0] = new TH1F("hel.seed","hel.seed",32,-1.5,30.5);
230  // fHisto[1] = new TH1F("hel.error.code","hel.error.code",35,-1.5,33.5);
231 
232  return 0;
233 }
234 
235 //_____________________________________________________________________________
236 //void THcHelicity::FillHisto()
237 //{
238 // fHisto[0]->Fill(fRing_NSeed);
239 // fHisto[1]->Fill(fErrorCode);
240 // return;
241 //}
242 //_____________________________________________________________________________
244 {
245  // used as a control for the helciity computation
246  // 2^0: if the reported number of events in a pattern is larger than fQWEAKNPattern
247  // 2^1: if the offset between the ring reported value and TIR value is not fOffsetTIRvsRing
248  // 2^2: if the reported time in the ring is 0
249  // 2^3: if the predicted reported helicity doesn't match the reported helicity in the ring
250  // 2^4: if the helicity cannot be computed using the SetHelicity routine
251  // 2^5: if seed is being gathered
252 
253  if(fErrorCode==0)
254  fErrorCode=(1<<error);
255  // only one reported error at the time
256 
257  return;
258 }
259 
260 //_____________________________________________________________________________
262 {
263  // Clear event-by-event data
264 
265  THaHelicityDet::Clear(opt);
267  fEvtype = 0;
268 
269  fQrt=0;
270  fErrorCode=0;
271 
272  return;
273 }
274 //_____________________________________________________________________________
276 {
277  fglHelicityScaler = f;
279 }
280 
281 //_____________________________________________________________________________
283 {
284 
285  // Decode Helicity data.
286  // Return 1 if helicity was assigned, 0 if not, <0 if error.
287  evnum = evdata.GetEvNum();
288 
289  Int_t err = ReadData( evdata ); // from THcHelicityReader class
290  if( err ) {
291  Error( Here("THcHelicity::Decode"), "Error decoding helicity data." );
292  return err;
293  }
294 
295  fReportedHelicity = (fIsHelp?(fIsHelm?kUnknown:kPlus):(fIsHelm?kMinus:kUnknown));
296  fMPS = fIsMPS?1:0;
297  fQrt = fIsQrt?1:0; // Last of quartet
298 
299 #if 0
300  if(fglHelicityScaler) {
301  Int_t nhelev = fglHelicityScaler->GetNevents();
302  Int_t ncycles = fglHelicityScaler->GetNcycles();
303  if(nhelev >0) {
304  for(Int_t i=0;i<nhelev;i++) {
305  fScaleQuartet = (fHelicityHistory[i] & 2)!=0;
306  Int_t ispos = fHelicityHistory[i]&1;
307  if(fScaleQuartet) {
308  fScalerSeed = ((fScalerSeed<<1) | ispos) & 0x3FFFFFFF;
309  if(fNBits >= fMAXBIT+0) {
310  Int_t seedscan = fScalerSeed;
311  Int_t nbehind;
312  for(nbehind=0;nbehind<4;nbehind++) {
313  if(seedscan == fRingSeed_reported) {
314  if(nbehind>1) {
315  cout << "Scaler seed behind " << nbehind
316  << " quartets" << endl;
317  cout << "Ev seed " << bitset<32>(fRingSeed_reported) <<endl;
318  cout << "Scaler Seed " << bitset<32>(fScalerSeed) << endl;
319  }
320  break;
321  }
322  seedscan = RanBit30(seedscan);
323  }
324  if(nbehind>4) {
325  cout << "Scaler seed does not match" << endl;
326  cout << "Ev seed " << bitset<32>(fRingSeed_reported) <<endl;
327  cout << "Scaler Seed " << bitset<32>(fScalerSeed) << endl;
328  }
329  }
330  }
331  }
332  }
333  }
334 #endif
335 
336  if(fHelDelay == 0) { // If no delay actual=reported (but zero if in MPS)
338  return 0;
339  }
340 
341  if(fDisabled) {
342  fActualHelicity = kUnknown;
343  return 0;
344  }
345 
346  fEvNumCheck++;
347  Int_t evnum = evdata.GetEvNum();
348  if(fEvNumCheck!=evnum) {
349  cout << "THcHelicity: Missed " << evnum-fEvNumCheck << " events at event " << evnum << endl;
350  cout << " Disabling helicity decoding for rest of run." << endl;
351  cout << " Make sure \"RawDecode_master in cuts file accepts all physics events." <<endl;
352  fDisabled = kTRUE;
353  fActualHelicity = kUnknown;
354  return 0;
355  }
356 
357  fActualHelicity = -10.0;
358  if(fFirstEvProcessed) { // Normal processing
359  // cout << evnum << " " << fNCycle << " " << fIsMPS << " " << fFoundMPS << " " << fTITime << " "
360  // << fLastMPSTime << " " << fNBits << endl;
361  Int_t missed = 0;
362  // Double_t elapsed_time = (fTITime - fFirstEvTime)/250000000.0;
363  if(fIsMPS) {
364  fPeriodCheck = fmod(fTITime/(250000000.0/fFreq)-fPeriodCheckOffset,1.0);
365 
367  fActualHelicity = kUnknown;
368  fPredictedHelicity = kUnknown;
369  if(fFoundMPS) {
370  if(fRecommendedFreq < 0.0) {
371  if(TMath::Abs(fPeriodCheck-0.5) > 0.25) {
373  }
374  }
376  if(missed < 1) { // was <=1
378  fIsNewCycle = kTRUE;
379  fActualHelicity = kUnknown;
380  fPredictedHelicity = kUnknown;
381  } else {
382  fLastMPSTime = (fLastMPSTime + fTITime - missed*fTIPeriod)/2;
383  }
384  // If there is a skip, pass it off to next non MPS event
385  // Need to also check here for missed MPS's
386  // cout << "Found MPS" << endl;
387  // check for Nint((time-last)/period) > 1
388  } else {
389  fFoundMPS = kTRUE;
392  }
393  } else if (fFoundMPS) { //
394  if(fTITime - fLastMPSTime > fTIPeriod) { // We missed MPS periods
396  if(missed > 1) {
397  // cout << "Missed " << missed << " MPSes" << endl;
398  Int_t newNCycle = fNCycle + missed -1; // How many cycles really missed
399  Int_t quartets_missed = (newNCycle-fFirstCycle)/4 - (fNCycle-fFirstCycle)/4;
400  int quartetphase = (newNCycle-fFirstCycle)%4;
401  // cout << " " << fNCycle << " " << newNCycle << " " << fFirstCycle << " " << quartets_missed << " " << quartetphase << endl;
402  // cout << "Cycles " << fNCycle << " " << newNCycle << " " << fFirstCycle
403  // << " skipped " << quartets_missed << " quartets" << endl;
404  fNCycle = newNCycle;
405  // Need to reset fQuartet to reflect where we are based on the current
406  // reported helicity. So we don't fail quartet testing.
407  // But only do this if we are calibrated.
408  if(fNBits >= fMAXBIT+0) {
409 
410  for(Int_t i=0;i<quartets_missed;i++) { // Advance the seeds.
411  // cout << "Advancing seed A " << fNBits << endl;
414  }
415 
416  fQuartetStartHelicity = (fRingSeed_actual&1)?kPlus:kMinus;
418  fActualHelicity = (quartetphase==0||quartetphase==3)?
420  fPredictedHelicity = (quartetphase==0||quartetphase==3)?
422 
423  if (((fNCycle - fFirstCycle)%2)==1) {
425  fQuartet[1] = fQuartet[2] = -fQuartet[0];
426  } else {
428  fQuartet[2] = -fQuartet[1];
429  }
430  } else {
431  fActualHelicity = kUnknown;
433  fQuartet[1] = 0;
434  }
435  }
436  fLastMPSTime += missed*fTIPeriod;
437  fIsNewCycle = kTRUE;
439  } else { // No missed periods. Get helicities from rings
440  if(fNBits>=fMAXBIT+0) {
441  int quartetphase = (fNCycle-fFirstCycle)%4;
442  fQuartetStartHelicity = (fRingSeed_actual&1)?kPlus:kMinus;
444  fActualHelicity = (quartetphase==0||quartetphase==3)?
446  fPredictedHelicity = (quartetphase==0||quartetphase==3)?
448  } else {
449  fActualHelicity = 0;
450  }
451  }
452  if(fIsNewCycle) {
453  // cout << "Scaler Seed " << bitset<32>(fScalerSeed) << endl;
454  //Int_t predictedScalerSeed = RanBit30(fScalerSeed);
455  // cout << "Predct Seed " << bitset<32>(predictedScalerSeed) << endl;
456  //cout << "Event Seed " << bitset<32>(fRingSeed_reported) << endl;
457 
458  fQuartet[3]=fQuartet[2]; fQuartet[2]=fQuartet[1]; fQuartet[1]=fQuartet[0];
460  fNCycle++;
461  // cout << "XX: " << fNCycle << " " << fReportedHelicity << " " << fIsQrt <<endl;
462 
463  if(fIsQrt) { //
466  if(fHaveQRT) { // Should already have phase set
467  if((fNCycle-fFirstCycle)%4 != 0) {// Test if first in a quartet
468  fNQRTProblems++;
469  if(fNQRTProblems > 10) {
470  cout << "QRT Problem resetting" << endl;
471  fHaveQRT = kFALSE;
473  fNQRTProblems = 0;
474  } else {
475  cout << "Ignored " << fNQRTProblems << " problems" << endl;
476  }
477  } else {
478  fNQRTProblems = 0;
479  }
480  }
481  if(!fHaveQRT) {
482  fHaveQRT = kTRUE;
484 
485  fFirstCycle = fNCycle; //
487  fNLastQuartet = fNQuartet - 1; // Make sure LoadHelicity uses
488  fNBits = 0;
489  fNQRTProblems = 0;
490  cout << "Phase found from QRT signal" << endl;
491  cout << "fFirstcycle = " << fFirstCycle << endl;
492  }
493  } else {
494  if(fHaveQRT) { // Using qrt signal.
497  if((fNCycle-fFirstCycle)%4 == 0) { // Shouldn't happen
498  fNQRTProblems++;
499  if(fNQRTProblems > 10) {
500  cout << "Shouldn't happen, cycle=" << fNCycle << "/" << fFirstCycle << endl;
501  fHaveQRT = kFALSE; // False until a new QRT seen
502  fNBits = 0; // Reset
503  fNLastQuartet = fNQuartet; // Make sure LoadHelicity does not use
504  } else {
505  cout << "Ignored " << fNQRTProblems << " problems" << endl;
506  }
507  }
508  } else { // Presumable pre qrt signal data
509  if((fNCycle-fFirstCycle)%4 == 3) {// Test if last in a quartet
510  if((abs(fQuartet[0]+fQuartet[3]-fQuartet[1]-fQuartet[2])==4)) {
511  if(!fFoundQuartet) {
512  // fFirstCycle = fNCycle - 3;
513  cout << "Quartet potentially found, starting at cycle " << fFirstCycle
514  << endl;
516  fNLastQuartet = fNQuartet - 1; // Make sure LoadHelicity uses
518  }
519  } else {
520  if(fNCycle - fFirstCycle > 4) { // Not at start of run. Reset
521  cout << "Lost quartet sync at cycle " << fNCycle << endl;
522  cout << fQuartet[0] << " " << fQuartet[1] << " " << fQuartet[2] << " "
523  << fQuartet[3] << endl;
524  fFirstCycle += 4*((fNCycle-fFirstCycle)/4); // Update, but don't change phase
525  }
527  fNBits = 0;
528  cout << "Searching for first of a quartet at cycle " << " " << fFirstCycle
529  << endl;
530  cout << fQuartet[0] << " " << fQuartet[1] << " " << fQuartet[2] << " "
531  << fQuartet[3] << endl;
532  fFirstCycle++;
533  }
534  } else {
537  }
538  }
539  }
540  // Load the actual helicity. Calibrate if not calibrated.
541  fActualHelicity = kUnknown;
542  // Here if we know we missed some earlier in the quartet, we need
543  // to make sure we get here and call LoadHelicity for the missing
544  // Cycles, reducing the missed count for each extra loadhelicity
545  // call that we make.
549  // cout << fTITime/250000000.0 << " " << fNCycle << " " << fReportedHelicity << endl;
550  // cout << fNCycle << ": " << fReportedHelicity << " "
551  // << fPredictedHelicity << " " << fActualHelicity << endl;
552  }
553  // Ignore until a MPS Is found
554 
555  } else { // No MPS found yet
556  fActualHelicity = kUnknown;
557  }
558  } else {
559  cout << "Initializing" << endl;
561  fActualHelicity = kUnknown;
562  fPredictedHelicity = kUnknown;
565  fLastMPSTime = fTITime; // Not necessarily during the MPS
566  fNCycle = 0;
568  fFoundMPS = kFALSE;
571  fNBits = 0;
572  }
573 
574  // Some sanity checks
575  if(fActualHelicity < -5) {
576  cout << "Actual Helicity never got defined" << endl;
577  }
578  if(fNBits < fMAXBIT+0) {
579  if(fActualHelicity == -1 || fActualHelicity == 1) {
580  cout << "Helicity of " << fActualHelicity << " reported prematurely at cycle " << fNCycle << endl;
581  }
582  }
584  return 0;
585 }
586 //_____________________________________________________________________________
587 Int_t THcHelicity::End( THaRunBase* )
588 {
589  // End of run processing. Write histograms.
591 
592  // for( Int_t i = 0; i < NHIST; ++i )
593  // fHisto[i]->Write();
594 
595  if(fRecommendedFreq < 0.0) {
597  }
598  if(TMath::Abs(1-fRecommendedFreq/fFreq) >= 0.5e-6) {
599  cout << "------------- HELICITY DECODING ----------------------" << endl;
600  cout << "Actual helicity reversal frequency differs from \"helicity_freq\" value" << endl;
601  cout << "If there are helicity decoding errors beyond the start of the run, " << endl;
602  streamsize ss = cout.precision();
603  cout.precision(10);
604  cout << "try replacing helicity_freq value of " << fFreq << " with " << fRecommendedFreq << endl;
605  cout << "If that still gives helicity errors, try " << 0.9999999*fRecommendedFreq << endl;
606  cout.precision(ss);
607  cout << "------------------------------------------------------" << endl;
608  }
609 
610  return 0;
611 }
612 
613 //_____________________________________________________________________________
615 {
616  // Set debug level of this detector as well as the THcHelicityReader
617  // helper class.
618 
619  THaHelicityDet::SetDebug( level );
620  fQWEAKDebug = level;
621 }
622 
623 //_____________________________________________________________________________
624 void THcHelicity::LoadHelicity(Int_t reportedhelicity, Int_t cyclecount, Int_t missedcycles)
625 {
626  // static const char* const here = "THcHelicity::LoadHelicity";
627  int quartetphase = (cyclecount-fFirstCycle)%4;
628  fnQrt = quartetphase;
629 
630  // if(!fFixFirstCycle) {
631  if(fNQuartet - fNLastQuartet > 1) { // If we missed a quartet
632  if(fNBits< fMAXBIT+0) { // and we haven't gotten the seed, start over
633  cout << "fNBits = 0, missedcycles=" << missedcycles <<
634  " " << fNLastQuartet << " " << fNQuartet << endl;
635  fNBits = 0;
636  return;
637  }
638  }
639  // }
640  if(!fFoundQuartet) { // Wait until we have found quad phase before starting
641  return; // to calibrate
642  }
643  // LoadHelicity is called first event of each cycle.
644  // But only do it's thing if it is first cycle of quartet.
645  // Need to instead have it do it's thing on the first event of a quartet.
646  // But only for seed building. Current logic is OK once seed is found.
647  if(fNBits < fMAXBIT+0) {
648  if(fNQuartet != fNLastQuartet) {
649  // Sanity check fNQuartet == fNLastQuartet+1
650  if(fNBits == 0) {
651  cout << "Start calibrating at cycle " << cyclecount << endl;
652  fRingSeed_reported = 0;
653  }
654  // Do phase stuff right here
655  if((fReportedHelicity == kPlus && (quartetphase==0 || quartetphase == 3))
656  || (fReportedHelicity == kMinus && (quartetphase==1 || quartetphase == 2))) {
657  fRingSeed_reported = ((fRingSeed_reported<<1) | 1) & 0x3FFFFFFF;
658  // cout << " " << fNQuartet << " 1" << endl;
659  } else {
660  fRingSeed_reported = (fRingSeed_reported<<1) & 0x3FFFFFFF;
661  // cout << " " << fNQuartet << " 0" << endl;
662  }
663  fNBits++;
664  if(fReportedHelicity == kUnknown) {
665  fNBits = 0;
666  fRingSeed_reported = 0;
667  } else if (fNBits==fMAXBIT+0) {
668  cout << " Seed Found " << bitset<32>(fRingSeed_reported) << " at cycle " << cyclecount << " with first cycle " << fFirstCycle << endl;
669  if(fglHelicityScaler) {
670  cout << "Scaler Seed " << bitset<32>(fglHelicityScaler->GetReportedSeed()) << endl;
671  }
672  Int_t backseed = GetSeed30(fRingSeed_reported);
673  cout << "Seed at cycle " << fFirstCycle << " should be " << hex << backseed << dec << endl;
674  // Create the "actual seed"
676  for(Int_t i=0;i<fHelDelay/4; i++) {
678  }
679  fQuartetStartHelicity = (fRingSeed_actual&1)?kPlus:kMinus;
681  } else if (fglHelicityScaler && fNBits>2) { // Try the scalers
683  Int_t scalerseed = fglHelicityScaler->GetReportedSeed();
684  fRingSeed_reported = RanBit30(scalerseed);
685  cout << " -- Getting seed from scalers -- " << endl;
686  cout << " Seed Found " << bitset<32>(fRingSeed_reported) << " at cycle " << cyclecount << " with first cycle " << fFirstCycle << endl;
687  cout << "Scaler Seed " << bitset<32>(scalerseed) << endl;
688  // Create the "actual seed"
690  for(Int_t i=0;i<fHelDelay/4; i++) {
691  fRingSeed_actual = RanBit30(fRingSeed_actual);
692  }
693  fQuartetStartHelicity = (fRingSeed_actual&1)?kPlus:kMinus;
695  fNBits = fMAXBIT+0;
696  }
697  }
698  fActualHelicity = kUnknown;
699  } // Need to change this to build seed even when not at start of quartet
700  } else {
701  if(quartetphase == 0) {
702  // If quartetphase !=, the seeds will alread have been advanced
703  // except that we won't have made the initial
704  // cout << "Advancing seed B " << fNBits << endl;
707 
708  fActualHelicity = (fRingSeed_actual&1)?kPlus:kMinus;
709  fPredictedHelicity = (fRingSeed_reported&1)?kPlus:kMinus;
710  // if(fTITime/250000000.0 > 380.0) cout << fTITime/250000000.0 << " " << fNCycle << " " << hex <<
711  // fRingSeed_reported << " " << fRingSeed_actual << dec << endl;
713  cout << "Helicity prediction failed " << fReportedHelicity << " "
714  << fPredictedHelicity << " " << fActualHelicity << endl;
715  cout << bitset<32>(fRingSeed_reported) << " " << bitset<32>(fRingSeed_actual) << endl;
716  fNBits = 0; // Need to reaquire seed
717  fActualHelicity = kUnknown;
718  fPredictedHelicity = kUnknown;
719  }
722  }
723  fActualHelicity = (quartetphase==0||quartetphase==3)?
725  fPredictedHelicity = (quartetphase==0||quartetphase==3)?
727  }
728  return;
729 }
730 //_____________________________________________________________________________
732 {
733 
734  UInt_t bit7 = (ranseed & 0x00000040) != 0;
735  UInt_t bit28 = (ranseed & 0x08000000) != 0;
736  UInt_t bit29 = (ranseed & 0x10000000) != 0;
737  UInt_t bit30 = (ranseed & 0x20000000) != 0;
738 
739  UInt_t newbit = (bit30 ^ bit29 ^ bit28 ^ bit7) & 0x1;
740 
741 
742  if(ranseed<=0) {
743  if(fQWEAKDebug>1)
744  std::cerr<<"ranseed must be greater than zero!"<<"\n";
745 
746  newbit = 0;
747  }
748  ranseed = ( (ranseed<<1) | newbit ) & 0x3FFFFFFF;
749  //here ranseed is changed
750  if(fQWEAKDebug>1)
751  {
752  cout<< "THcHelicity::RanBit30, newbit="<<newbit<<"\n";
753  }
754 
755  return ranseed;
756 
757 }
758 //_____________________________________________________________________________
760 /* Back track the seed by 30 samples */
761 {
762 #if 1
763  Int_t seed = currentseed;
764  for(Int_t i=0;i<30;i++) {
765  UInt_t bit1 = (seed & 0x00000001) != 0;
766  UInt_t bit8 = (seed & 0x00000080) != 0;
767  UInt_t bit29 = (seed & 0x10000000) != 0;
768  UInt_t bit30 = (seed & 0x20000000) != 0;
769 
770  UInt_t newbit30 = (bit30 ^ bit29 ^ bit8 ^ bit1) & 0x1;
771  seed = (seed >> 1) | (newbit30<<29);
772  }
773 #else
774  Int_t bits = currentseed;
775  Int_t seed=0;
776  for(Int_t i=0;i<30;i++) {
777  Int_t val;
778  // XOR at virtual position 0 and 29
779  if(i==0) {
780  val = ((bits & (1<<(i)))!=0) ^ ((bits & (1<<(i+29)))!=0);
781  } else {
782  val = ((bits & (1<<(i)))!=0) ^ ((seed & (1<<(i-1)))!=0);
783  }
784  if(i<=1) {
785  val = ((bits & (1<<(1-i)))!=0) ^ val;
786  } else {
787  val = ((seed & (1<<(i-2)))!=0) ^ val;
788  }
789  if(i<=22) {
790  val = ((bits & (1<<(i-22)))!=0) ^ val;
791  } else {
792  val = ((seed & (1<<(i-23)))!=0) ^ val;
793  }
794  seed |= (val<<i);
795  }
796 #endif
797  return seed;
798 }
799 
801 
std::string GetName(const std::string &scope_name)
Bool_t fIsNewCycle
Definition: THcHelicity.h:74
Bool_t fHaveQRT
Definition: THcHelicity.h:81
Int_t fRingSeed_reported_initial
Definition: THcHelicity.h:49
Int_t fLastHelpCycle
Definition: THcHelicity.h:116
virtual void Clear(Option_t *opt="")
THcHelicityScaler * fglHelicityScaler
Definition: THcHelicity.h:114
Int_t fNQRTProblems
Definition: THcHelicity.h:82
const char Option_t
Int_t ReadDatabase(const char *dbfilename, const char *prefix, const TDatime &date, int debug_flag=0)
Int_t fMPS
Definition: THcHelicity.h:67
virtual EStatus Init(const TDatime &date)
Definition: THcHelicity.cxx:64
Double_t fCycle
Definition: THcHelicity.h:59
Event handler for Hall C helicity scalers.
Int_t fPredictedHelicity
Definition: THcHelicity.h:68
Bool_t fDisabled
Definition: THcHelicity.h:106
virtual Int_t * GetHelicityHistoryP()
UInt_t GetEvNum() const
Int_t fScaleQuartet
Definition: THcHelicity.h:117
virtual Bool_t IsSeedGood()
int Int_t
virtual void SetHelicityScaler(THcHelicityScaler *f)
STL namespace.
Int_t fQuartet[4]
Definition: THcHelicity.h:78
Bool_t fFirstEvProcessed
Definition: THcHelicity.h:61
Int_t fnQrt
Definition: THcHelicity.h:80
Short_t Abs(Short_t d)
virtual Int_t ReadData(const THaEvData &evdata)
virtual Int_t ReadDatabase(const TDatime &date)
virtual void Clear(Option_t *opt="")
Int_t fNCycle
Definition: THcHelicity.h:75
virtual Int_t DefineVariables(EMode mode=kDefine)
Int_t fQuadPattern[8]
Definition: THcHelicity.h:118
Determine the beam helicity for the current event.
Definition: THcHelicity.h:18
void Error(const char *location, const char *msgfmt,...)
Double_t fPeriodCheck
Definition: THcHelicity.h:57
Int_t fScalerSeed
Definition: THcHelicity.h:121
Int_t fNQuartet
Definition: THcHelicity.h:76
virtual void SetDebug(Int_t level)
virtual Int_t GetNcycles()
Bool_t fFoundMPS
Definition: THcHelicity.h:72
Int_t RanBit30(Int_t ranseed)
Double_t fPeriodCheckOffset
Definition: THcHelicity.h:58
Long64_t fLastMPSTime
Definition: THcHelicity.h:65
Int_t fMAXBIT
Definition: THcHelicity.h:91
void Setup(const char *name, const char *description)
Int_t fRingSeed_actual
Definition: THcHelicity.h:85
unsigned int UInt_t
std::string fKwPrefix
Definition: THcHelicity.h:41
double floor(double)
Int_t lastispos
Definition: THcHelicity.h:122
Long64_t fLastEvTime
Definition: THcHelicity.h:64
Bool_t HWPIN
Definition: THcHelicity.h:95
Bool_t fFoundQuartet
Definition: THcHelicity.h:73
Int_t fEvtype
Definition: THcHelicity.h:103
Int_t fQrt
Definition: THcHelicity.h:98
tuple list
Definition: SConscript.py:9
const Bool_t kFALSE
Int_t fReportedHelicity
Definition: THcHelicity.h:66
virtual Int_t GetReportedSeed()
Int_t fLastActualHelicity
Definition: THcHelicity.h:104
Int_t fHelDelay
Definition: THcHelicity.h:89
Int_t LoadParmValues(const DBRequest *list, const char *prefix="")
Retrieve parameter values from the parameter cache.
void SetErrorCode(Int_t error)
void LoadHelicity(Int_t reportedhelicity, Int_t cyclecount, Int_t missedcycles)
Int_t fActualHelicity
Definition: THcHelicity.h:69
Long64_t fFirstEvTime
Definition: THcHelicity.h:63
Double_t fFreq
Definition: THcHelicity.h:52
Int_t * fHelicityHistory
Definition: THcHelicity.h:115
Int_t fNBits
Definition: THcHelicity.h:79
Int_t fHelperHistory
Definition: THcHelicity.h:119
ClassImp(THcDCLookupTTDConv) THcDCLookupTTDConv
Int_t GetSeed30(Int_t currentseed)
virtual ~THcHelicity()
Definition: THcHelicity.cxx:54
Int_t fQuartetStartPredictedHelicity
Definition: THcHelicity.h:71
Int_t fNLastQuartet
Definition: THcHelicity.h:77
Double_t fErrorCode
Definition: THcHelicity.h:101
virtual void MakePrefix()
Int_t fFirstCycle
Definition: THcHelicity.h:50
Int_t fHelperQuartetHistory
Definition: THcHelicity.h:120
Int_t fQuartetStartHelicity
Definition: THcHelicity.h:70
R__EXTERN class THcParmList * gHcParms
Definition: THcGlobals.h:11
Double_t fTIPeriod
Definition: THcHelicity.h:55
Int_t fLastReportedHelicity
Definition: THcHelicity.h:62
virtual Int_t Decode(const THaEvData &evdata)
void PrintEvent(Int_t evtnum)
const Bool_t kTRUE
Int_t Nint(T x)
Bool_t fFixFirstCycle
Definition: THcHelicity.h:51
Double_t fRecommendedFreq
Definition: THcHelicity.h:53
virtual Int_t GetNevents()
Int_t fEvNumCheck
Definition: THcHelicity.h:105
Int_t fRingSeed_reported
Definition: THcHelicity.h:84