Hall A ROOT/C++ Analyzer (podd)
Loading...
Searching...
No Matches
THaQWEAKHelicity.cxx
Go to the documentation of this file.
1//*-- Author : Julie Roche, November 2010
2// this is a modified version of THaGOHelicity.C
4//
5// THaQWEAKHelicity
6//
7// Helicity of the beam from QWEAK electronics in delayed mode
8// +1 = plus, -1 = minus, 0 = unknown
9//
10// Also supports in-time mode with delay = 0
11//
13
14#include "THaQWEAKHelicity.h"
15#include "THaEvData.h"
16#include "TH1F.h"
17#include "TMath.h"
18#include <iostream>
19
20using namespace std;
21
22//_____________________________________________________________________________
23THaQWEAKHelicity::THaQWEAKHelicity( const char* name, const char* description,
24 THaApparatus* app ):
25 THaHelicityDet( name, description, app ),
26 fOffsetTIRvsRing(3), fQWEAKDelay(8), fMAXBIT(30),
27 fQWEAKNPattern(4), HWPIN(true), fQrt(1), fTSettle(0),fValidHel(false),
28 fHelicityLastTIR(0),fPatternLastTIR(0), fErrorCode(0), fRing_NSeed(0),
29 fRingU3plus(0),fRingU3minus(0),
30 fRingT3plus(0),fRingT3minus(0),
31 fRingT5plus(0),fRingT5minus(0),
32 fRingT10plus(0),fRingT10minus(0),
33 fRingTimeplus(0), fRingTimeminus(0),
34 fRingSeed_reported(0),fRingSeed_actual(0),
35 fRingPhase_reported(0),fRing_reported_polarity(0),
36 fRing_actual_polarity(0), fEvtype(-1), fHisto(NHIST, nullptr)
37{
38}
39
40//_____________________________________________________________________________
42 : fOffsetTIRvsRing(3), fQWEAKDelay(8), fMAXBIT(30),
43 fQWEAKNPattern(4), HWPIN(true), fQrt(1), fTSettle(0),fValidHel(false),
44 fHelicityLastTIR(0),fPatternLastTIR(0), fErrorCode(0), fRing_NSeed(0),
45 fRingU3plus(0),fRingU3minus(0),
46 fRingT3plus(0),fRingT3minus(0),
47 fRingT5plus(0),fRingT5minus(0),
48 fRingT10plus(0),fRingT10minus(0),
49 fRingTimeplus(0), fRingTimeminus(0),
50 fRingSeed_reported(0),fRingSeed_actual(0),
51 fRingPhase_reported(0),fRing_reported_polarity(0),
52 fRing_actual_polarity(0), fEvtype(-1), fHisto(NHIST, nullptr)
53{
54 // Default constructor for ROOT I/O
55}
56
57//_____________________________________________________________________________
59{
61
62 // for( Int_t i = 0; i < NHIST; ++i ) {
63 // delete fHisto[i];
64 // }
65}
66
67//_____________________________________________________________________________
69{
70 // Initialize global variables
71
72 // cout << "Called THaQWEAKHelicity::DefineVariables with mode == "
73 // << mode << endl;
74
75 // Define standard variables from base class
77 if( ret )
78 return ret;
79
80 const RVarDef var[] = {
81 { "qrt", "actual qrt for TIR event", "fQrt" },
82 { "hel", "actual helicity for TIR event", "fHelicity" },
83 { "tsettle", "TSettle for TIR event", "fTSettle"},
84 { "U3plus", "U3 plus", "fRingU3plus"},
85 { "U3minus", "U3 minus", "fRingU3minus"},
86 { "T3plus", "T3 plus", "fRingT3plus"},
87 { "T3minus", "T3 minus", "fRingT3minus"},
88 { "T5plus", "T5 plus", "fRingT5plus"},
89 { "T5minus", "T5 minus", "fRingT5minus"},
90 { "T10plus", "T10 plus", "fRingT10plus"},
91 { "T10minus", "T10 minus", "fRingT10minus"},
92 { "Timeminus","Time minus", "fRingTimeminus"},
93 { "Timeplus", "Time plus", "fRingTimeplus"},
94 { nullptr }
95 };
96 // cout << "now actually defining stuff, prefix = " << fPrefix << endl;
97 return DefineVarsFromList( var, mode );
98}
99//_____________________________________________________________________________
100
102{
103
104 cout<<" ++++++ THaQWEAKHelicity::Print ++++++\n";
105 cout << dec << "--> Data for spectrometer " << GetName() << endl;
106 cout << " evtype " << fEvtype<<endl;
107 cout << " event number ="<<evtnum<<endl;
108 cout << " == Input register data =="<<endl;
109 cout << " helicity="<<fHelicityTir<<" Pattern ="<<fPatternTir
110 <<" TSettle="<<fTSettleTir<<" TimeStamp="<<fTimeStampTir<<endl;
111 cout << " == Ring data =="<<endl;
112 UInt_t sumu3=0;
113 UInt_t sumt3=0;
114 UInt_t sumt5=0;
115 UInt_t sumt10=0;
116 UInt_t sumtime=0;
117
118 for (UInt_t i=0;i<fIRing;i++)
119 {
120 cout<<" iring="<< i<<" helicity="<<fHelicityRing[i]
121 <<" Pattern="<<fPatternRing[i]<<" timestamp="<<fTimeStampRing[i]
122 <<" T3="<<fT3Ring[i]<<" T5="<<fT5Ring[i]<<" T10="<<fT10Ring[i]
123 <<" U3="<<fU3Ring[i]
124 <<endl;
125 sumu3+=fU3Ring[i];
126 sumt3+=fT3Ring[i];
127 sumt5+=fT5Ring[i];
128 sumt10+=fT10Ring[i];
129 sumtime+=fTimeStampRing[i];
130 }
131
132 cout<<" == outputs ==\n";
133 cout<<" fQrt="<<fQrt<<" Helicity="<<fHelicity<<" TSettle="<<fTSettle<<endl;
134 cout<<" U3 plus="<<fRingU3plus<<" minus="<<fRingU3minus<<" sum u3="<<sumu3<<endl;
135 cout<<" T3 plus="<<fRingT3plus<<" minus="<<fRingT3minus<<" sum t3="<<sumt3<<endl;
136 cout<<" T5 plus="<<fRingT5plus<<" minus="<<fRingT5minus<<" sum t5="<<sumt5<<endl;
137 cout<<" T10 plus="<<fRingT10plus<<" minus="<<fRingT10minus<<" sum t10="<<sumt10<<endl;
138 cout<<" time plus="<<fRingTimeplus<<" minus="<<fRingTimeminus<<" sum time="<<sumtime<<endl;
139 cout<<" +++++++++++++++++++++++++++++++++++++\n";
140}
141
142//_____________________________________________________________________________
144{
145 // Read general HelicityDet database values (e.g. fSign)
147 if( st != kOK )
148 return st;
149
150 // Read QWEAK readout parameters (ROC addresses etc.)
152 date, fQWEAKDebug );
153 if( st != kOK )
154 return st;
155
156
157 // for now bypass reading the inputs from the database;
158 fMAXBIT=30;
160 fQWEAKDelay=8;
161 // maximum of event in the pattern, for now we are working with quartets
162 // careful, the first value here should always +1
163 fPatternSequence = {1,-1,-1,1};
164 HWPIN=true;
165
166 return kOK;
167}
168
169//_____________________________________________________________________________
171{
173
174 fHisto[0] = new TH1F("hel.seed","hel.seed",32,-1.5,30.5);
175 fHisto[1] = new TH1F("hel.error.code","hel.error.code",35,-1.5,33.5);
176
177 return 0;
178}
179
180//_____________________________________________________________________________
182{
183 fHisto[0]->Fill(fRing_NSeed);
184 fHisto[1]->Fill(fErrorCode);
185}
186//_____________________________________________________________________________
188{
189 // used as a control for the helciity computation
190 // 2^0: if the reported number of events in a pattern is larger than fQWEAKNPattern
191 // 2^1: if the offset between the ring reported value and TIR value is not fOffsetTIRvsRing
192 // 2^2: if the reported time in the ring is 0
193 // 2^3: if the predicted reported helicity doesn't match the reported helicity in the ring
194 // 2^4: if the helicity cannot be computed using the SetHelicity routine
195 // 2^5: if seed is being gathered
196
197 if(fErrorCode==0)
198 fErrorCode=(1<<error);
199 // only one reported error at the time
200}
201
202//_____________________________________________________________________________
204 // Clear event-by-event data
205
208 fEvtype = 0;
210
211 fQrt = 0;
212 fTSettle = 0;
213 fRingU3plus = 0;
214 fRingU3minus = 0;
215 fRingT3plus = 0;
216 fRingT3minus = 0;
217 fRingT5plus = 0;
218 fRingT5minus = 0;
219 fRingT10plus = 0;
220 fRingT10minus = 0;
221 fRingTimeplus = 0;
222 fRingTimeminus = 0;
223 fErrorCode = 0;
224}
225
226//_____________________________________________________________________________
228{
229
230 // Decode Helicity data.
231 // Return 1 if helicity was assigned, 0 if not, <0 if error.
232
233 Int_t err = ReadData( evdata ); // from THaQWEAKHelicityReader class
234 if( err ) {
235 Error( Here("THaQWEAKHelicity::Decode"), "Error decoding helicity data." );
236 return err;
237 }
238
239 fEvtype = evdata.GetEvType();
240 LoadHelicity(evdata.GetEvNum());
241 if(fQWEAKDebug>1)
242 PrintEvent(evdata.GetEvNum());
243 CheckTIRvsRing(evdata.GetEvNum());
244 if(fErrorCode==0)
245 fValidHel=true;
246 else
247 fValidHel=false;
248 FillHisto();
249
250 return 0;
251}
252//_____________________________________________________________________________
254{
255 // here one checks that the offset between the TIR helicity reports
256 // and the Ring report is as expected (fQWEAKOffset)
257 // This is a simplified comparison: ie not every TIR readings is
258 // compared to the Ring readings for example, and offset=3
259 // for simplicity the comparison only if the ring buffer contains at least
260 // fQWEAKOffset readings
261
262 static const char* const here = "THaQWEAKHelicity::CheckTIRvsRing";
263
265 {
266 // compare the two values (last TIR) and reading in the current ring
269 {
271 fRing_NSeed=0;
272 if(fQWEAKDebug>0)
273 {
274 cout<<here<<" BAD !! the offset between the helicity ring and the input register ";
275 cout << "is not what is expected: reset the seed !! event#" << eventnumber << "\n";
276 }
277 SetErrorCode(1);
278
279 if(fQWEAKDebug>1)
280 {
281 cout<<"=====================================\n";
282 cout<<here<<endl;
283 cout << " Event number =" << eventnumber << endl;
284 cout<<" fOffsetTIRvsRing ="<<fOffsetTIRvsRing;
285 cout<<" fHelicityLastTIR ="<<fHelicityLastTIR;
286 cout<<" fPatternLastTIR ="<<fPatternLastTIR;
287 cout<<" fIRing="<<fIRing<<endl;
288 cout<<"RING data: helicity="<<fHelicityRing[fOffsetTIRvsRing-1]
289 <<" pattern="<<fPatternRing[fOffsetTIRvsRing-1]<<endl;
290 }
291 }
292 }
295}
296
297//_____________________________________________________________________________
299{
300 // End of run processing. Write histograms.
302
303 for( Int_t i = 0; i < NHIST; ++i )
304 fHisto[i]->Write();
305
306 return 0;
307}
308
309//_____________________________________________________________________________
311{
312 // Set debug level of this detector as well as the THaQWEAKHelicityReader
313 // helper class.
314
316 fQWEAKDebug = level;
317}
318
319//_____________________________________________________________________________
321{
322 static const char* const here = "THaQWEAKHelicity::LoadHelicity";
323
324 for (UInt_t i=0;i<fIRing;i++)
325 {
326 //Check for the number of events between two Pattern signals
327 if(fPatternRing[i]==1)
328 {
329 // could add a check that the number of pattern is what is expected. EG 4 for a quartet
331 }
332 else
333 {
335 }
337 {
338 if(fQWEAKDebug>0)
339 cout << here << " Reset seed: The pattern has too many elements !! "
340 << "Should only go up to " << fQWEAKNPattern
341 << " but is now " << fRingPhase_reported
342 << " at event #=" << eventnumber
343 << endl;
344 fRing_NSeed=0;
345 SetErrorCode(0);
346 }
347
348 //Check that events in the ring is not empty, using the timestamp
349 if(fTimeStampRing[i]==0)
350 {
351 fRing_NSeed=0;
352 SetErrorCode(2);
353 }
354
355 // if seed has been gathered:
356 // check event by event that the seed make sense:
357 // fRing_polarity!=fHelcityRing[i]
358 // this should come before the section for the seed gathering::
359 // do not change this order
360 if(fRing_NSeed==fMAXBIT && fPatternRing[i]==1)
361 {
365 {
366 if(fQWEAKDebug>0)
367 cout<<here<<" Catastrophe !!"
368 <<" predicted helicity doesn't match reported helicity !!!"
369 <<" event #="<<eventnumber
370 <<endl;
371 if(fQWEAKDebug>1)
372 cout<<" iring="<<Form("%02d", i)
373 <<" predicted helicity="<<fRing_reported_polarity
374 <<" fHelicityRing["<<i<<"]="<<fHelicityRing[i]<<endl;
375 fRing_NSeed=0;
376 SetErrorCode(3);
377 }
378 }
379
380 // Here is the seed gathering if necessary
381 if(fRing_NSeed<fMAXBIT && fPatternRing[i]==1)
382 {
383 SetErrorCode(5);
385 ((fRingSeed_reported<<1)&0x3FFFFFFF)|fHelicityRing[i];
386 fRing_NSeed+=1;
387 if (fRing_NSeed==fMAXBIT)
388 {
390 UInt_t advance=0;
391 //take the delay into account
392 for(UInt_t j=0;j<fQWEAKDelay;j++)
393 {
394 advance+=1;
395 if( advance == fQWEAKNPattern)
396 {
398 advance=0;
399 }
400 }
401 }
402 }
403
404 //now compute helicity related quantities
405 EHelicity localhelicity = kUnknown;
407 {
409 if(localhelicity==kPlus)
410 {
416 }
417 else if(localhelicity==kMinus)
418 {
424 }
425 else
426 {
427 if(fQWEAKDebug>0)
428 cout<<here<<" TROUBLE !! Local helicity doesn't make sense"
429 <<" event #="<<eventnumber<<endl;
430 fRing_NSeed=0;
431 SetErrorCode(4);
432 }
433
434 }
435
436 if(fQWEAKDebug>1)
437 {
438 cout<<" iring="<<Form("%02d", i)
439 <<" hel,pat="
440 <<fHelicityRing[i]<<" ,"
441 <<fPatternRing[i]
442 <<" phase="<<fRingPhase_reported
443 <<" NSeed="<<fRing_NSeed
444 <<" Ring(pol reported="<<fRing_reported_polarity
445 <<", actual="<<fRing_actual_polarity
446 <<", actual hel="<<localhelicity
447 <<")"
448 <<endl;
449
450 }
451 }
452
453
454 // now go and get the true helicity for the event in the TIR
456 {
457 if(fTSettleTir==1)
458 {
460 fTSettle=1;
461 }
462 else
463 {
464 fTSettle=0;
465 UInt_t localfPhase=fRingPhase_reported;
466 UInt_t localfSeed=fRingSeed_actual;
467 UInt_t localfPolarity=fRing_actual_polarity;
468
469 for(UInt_t i=0; i<fOffsetTIRvsRing;i++)
470 {
471 localfPhase+=1;
472 if( localfPhase == fQWEAKNPattern)
473 {
474 localfPhase=0;
475 localfPolarity=RanBit30(localfSeed);
476 }
477 }
478 fHelicity=SetHelicity(localfPolarity,localfPhase);
479 if(fPatternTir==1)
480 fQrt=1;
481 else
482 fQrt=0;
484 {
485 if(fQWEAKDebug>0)
486 std::cout<<"TROUBLE !!! when predicting the actual helicity for the CODA "
487 <<" event #="<<eventnumber<<endl;
488 fRing_NSeed=0;
489 }
490 }
491 }
492 else
493 {
495 }
496}
497
498//_____________________________________________________________________________
501{
502 // here predicted_reported_helicity can have a value of 0 or 1
503 // fPatternSequence[fRingPhase_reported] can have a value of 1 or -1
504
506
507 Int_t select = static_cast<Int_t>(polarity) + fPatternSequence[phase];
508 if( select == -1 || select == 2 ) {
509 if( HWPIN )
510 localhel = kPlus;
511 else
512 localhel = kMinus;
513 } else if( select == 1 || select == 0 ) {
514 if( HWPIN )
515 localhel = kMinus;
516 else
517 localhel = kPlus;
518 }
519
520 // std::cout<<" ++++ THaQWEAKHelicity::SetHelicity \n";
521 // std::cout<<" actual ring polarity="<<polarity
522 // <<" fRingPhase_reported="<<fPatternSequence[phase]
523 // <<" HWP="<<HWPIN
524 // <<" select="<<select
525 // <<" Helicity="<<localhel<<endl;
526
527 return localhel;
528}
529
530//_____________________________________________________________________________
532{
533
534 bool bit7 = (ranseed & 0x00000040) != 0;
535 bool bit28 = (ranseed & 0x08000000) != 0;
536 bool bit29 = (ranseed & 0x10000000) != 0;
537 bool bit30 = (ranseed & 0x20000000) != 0;
538
539 UInt_t newbit = (bit30 ^ bit29 ^ bit28 ^ bit7) & 0x1;
540
541 if(ranseed<=0) {
542 if(fQWEAKDebug>1)
543 std::cerr<<"ranseed must be greater than zero!"<<"\n";
544
545 newbit = 0;
546 }
547 ranseed = ( (ranseed<<1) | newbit ) & 0x3FFFFFFF;
548 //here ranseed is changed
549 if( fQWEAKDebug > 1 ) {
550 cout << "THaQWEAKHelicity::RanBit30, newbit=" << newbit << "\n";
551 }
552
553 // Returns 0 or 1
554 return newbit;
555}
556
558
#define kOK
Definition BdataLoc.cxx:40
int Int_t
unsigned int UInt_t
const char Option_t
Option_t Option_t TPoint TPoint const char mode
char name[80]
static const char *const here
Definition THaVar.cxx:64
char * Form(const char *fmt,...)
virtual void SetDebug(Int_t level)
static Int_t DefineVarsFromList(const void *list, EType type, EMode mode, const char *def_prefix, const TObject *obj, const char *prefix, const char *here, const char *comment_subst="")
virtual const char * Here(const char *) const
const char * GetPrefix() const
UInt_t GetEvType() const
Definition THaEvData.h:53
UInt_t GetEvNum() const
Definition THaEvData.h:56
virtual void Clear(Option_t *opt="")
virtual Int_t ReadDatabase(const TDatime &date)
virtual const char * GetDBFileName() const
EHelicity fHelicity
virtual Int_t DefineVariables(EMode mode=kDefine)
UInt_t fTimeStampRing[kHelRingDepth]
UInt_t fPatternRing[kHelRingDepth]
UInt_t fT3Ring[kHelRingDepth]
UInt_t fHelicityRing[kHelRingDepth]
UInt_t fT10Ring[kHelRingDepth]
virtual void Clear(Option_t *opt="")
UInt_t fU3Ring[kHelRingDepth]
virtual Int_t ReadData(const THaEvData &evdata)
UInt_t fT5Ring[kHelRingDepth]
Int_t ReadDatabase(const char *dbfilename, const char *prefix, const TDatime &date, int debug_flag=0)
void PrintEvent(UInt_t evtnum)
THaHelicityDet::EHelicity SetHelicity(UInt_t polarity, UInt_t phase)
virtual void Clear(Option_t *opt="")
virtual Int_t Decode(const THaEvData &evdata)
virtual Int_t DefineVariables(EMode mode=kDefine)
void LoadHelicity(UInt_t eventnumber)
virtual Int_t ReadDatabase(const TDatime &date)
std::vector< Int_t > fPatternSequence
static const Int_t NHIST
UInt_t RanBit30(UInt_t &ranseed)
virtual void SetDebug(Int_t level)
void SetErrorCode(Int_t error)
std::vector< TH1F * > fHisto
virtual void FillHisto()
void CheckTIRvsRing(UInt_t eventnumber)
const char * GetName() const override
virtual Int_t Write(const char *name=nullptr, Int_t option=0, Int_t bufsize=0)
virtual void Error(const char *method, const char *msgfmt,...) const
STL namespace.
ClassImp(TPyArg)