Hall C ROOT/C++ Analyzer (hcana)
THcScalerEvtHandler.cxx
Go to the documentation of this file.
1 
36 #include "THaEvtTypeHandler.h"
37 #include "THcScalerEvtHandler.h"
38 #include "GenScaler.h"
39 #include "Scaler3800.h"
40 #include "Scaler3801.h"
41 #include "Scaler1151.h"
42 #include "Scaler560.h"
43 #include "Scaler9001.h"
44 #include "Scaler9250.h"
45 #include "THaCodaData.h"
46 #include "THaEvData.h"
47 #include "THcParmList.h"
48 #include "THcGlobals.h"
49 #include "THaGlobals.h"
50 #include "TNamed.h"
51 #include "TMath.h"
52 #include "TString.h"
53 #include "TROOT.h"
54 #include <cstring>
55 #include <cstdio>
56 #include <cstdlib>
57 #include <iostream>
58 #include <sstream>
59 #include <map>
60 #include <iterator>
61 #include "THaVarList.h"
62 #include "VarDef.h"
63 #include "Helper.h"
64 
65 using namespace std;
66 using namespace Decoder;
67 
68 static const UInt_t ICOUNT = 1;
69 static const UInt_t IRATE = 2;
70 static const UInt_t ICURRENT = 3;
71 static const UInt_t ICHARGE = 4;
72 static const UInt_t ITIME = 5;
73 static const UInt_t ICUT = 6;
74 static const UInt_t MAXCHAN = 32;
75 static const UInt_t defaultDT = 4;
76 
77 THcScalerEvtHandler::THcScalerEvtHandler(const char *name, const char* description)
78  : THaEvtTypeHandler(name,description),
79  fBCM_Gain(0), fBCM_Offset(0), fBCM_SatOffset(0), fBCM_SatQuadratic(0), fBCM_delta_charge(0),
80  evcount(0), evcountR(0.0), ifound(0), fNormIdx(-1),
81  fNormSlot(-1),
82  dvars(0),dvars_prev_read(0), dvarsFirst(0), fScalerTree(0), fUseFirstEvent(kTRUE),
83  fOnlySyncEvents(kFALSE), fOnlyBanks(kFALSE), fDelayedType(-1),
84  fClockChan(-1), fLastClock(0), fClockOverflows(0)
85 {
86  fRocSet.clear();
87  fModuleSet.clear();
88  scal_prev_read.clear();
89  scal_present_read.clear();
90  scal_overflows.clear();
91 }
92 
94 {
95  // The tree object is owned by ROOT since it gets associated wth the output
96  // file, so DO NOT delete it here.
97  if (!TROOT::Initialized()) {
98  delete fScalerTree;
99  }
100  Podd::DeleteContainer(scalers);
101  Podd::DeleteContainer(scalerloc);
102  delete [] dvars_prev_read;
103  delete [] dvars;
104  delete [] dvarsFirst;
105  delete [] fBCM_Gain;
106  delete [] fBCM_Offset;
107  delete [] fBCM_SatOffset;
108  delete [] fBCM_SatQuadratic;
109  delete [] fBCM_delta_charge;
110 
111  for( vector<UInt_t*>::iterator it = fDelayedEvents.begin();
112  it != fDelayedEvents.end(); ++it )
113  delete [] *it;
114  fDelayedEvents.clear();
115 }
116 
118 {
119  // Process any delayed events in order received
120 
121  cout << "THcScalerEvtHandler::End Analyzing " << fDelayedEvents.size() << " delayed scaler events" << endl;
122  for(std::vector<UInt_t*>::iterator it = fDelayedEvents.begin();
123  it != fDelayedEvents.end(); ++it) {
124  UInt_t* rdata = *it;
125  AnalyzeBuffer(rdata,kFALSE);
126  }
127  if (fDebugFile) *fDebugFile << "scaler tree ptr "<<fScalerTree<<endl;
128  evNumber += 1;
130  if (fScalerTree) fScalerTree->Fill();
131 
132  for( vector<UInt_t*>::iterator it = fDelayedEvents.begin();
133  it != fDelayedEvents.end(); ++it )
134  delete [] *it;
135  fDelayedEvents.clear();
136 
137  if (fScalerTree) fScalerTree->Write();
138  return 0;
139 }
140 
141 
143 {
144  char prefix[2];
145  prefix[0]='g';
146  prefix[1]='\0';
147  fNumBCMs = 0;
148  DBRequest list[]={
149  {"NumBCMs",&fNumBCMs, kInt, 0, 1},
150  {0}
151  };
152  gHcParms->LoadParmValues((DBRequest*)&list, prefix);
153  //cout << " NUmber of BCMs = " << fNumBCMs << endl;
154  //
155  if(fNumBCMs > 0) {
156  fBCM_Gain = new Double_t[fNumBCMs];
161  string bcm_namelist;
162  DBRequest list2[]={
163  {"BCM_Gain", fBCM_Gain, kDouble, (UInt_t) fNumBCMs},
164  {"BCM_Offset", fBCM_Offset, kDouble,(UInt_t) fNumBCMs},
165  {"BCM_SatQuadratic", fBCM_SatQuadratic, kDouble,(UInt_t) fNumBCMs,1},
166  {"BCM_SatOffset", fBCM_SatOffset, kDouble,(UInt_t) fNumBCMs,1},
167  {"BCM_Names", &bcm_namelist, kString},
168  {"BCM_Current_threshold", &fbcm_Current_Threshold, kDouble,0, 1},
169  {"BCM_Current_threshold_index", &fbcm_Current_Threshold_Index, kInt,0,1},
170  {0}
171  };
174  for(Int_t i=0;i<fNumBCMs;i++) {
175  fBCM_SatOffset[i]=0.;
176  fBCM_SatQuadratic[i]=0.;
177  }
178  gHcParms->LoadParmValues((DBRequest*)&list2, prefix);
179  vector<string> bcm_names = Podd::vsplit(bcm_namelist);
180  for(Int_t i=0;i<fNumBCMs;i++) {
181  fBCM_Name.push_back(bcm_names[i]+".scal");
182  fBCM_delta_charge[i]=0.;
183  }
184  }
185  fTotalTime=0.;
186  fPrevTotalTime=0.;
187  fDeltaTime=-1.;
188  //
189  //
190  return kOK;
191 }
201  fDelayedType = evtype;
202 }
203 
205 {
206  Int_t lfirst=1;
207 
208  if(evdata->GetEvNum() > 0) {
209  evNumber=evdata->GetEvNum();
211  }
212  if ( !IsMyEvent(evdata->GetEvType()) ) return -1;
213 
214  if (fDebugFile) {
215  *fDebugFile << endl << "---------------------------------- "<<endl<<endl;
216  *fDebugFile << "\nEnter THcScalerEvtHandler for fName = "<<fName<<endl;
217  EvDump(evdata);
218  }
219 
220  if (lfirst && !fScalerTree) {
221 
222 
223  lfirst = 0; // Can't do this in Init for some reason
224 
225  TString sname1 = "TS";
226  TString sname2 = sname1 + fName;
227  TString sname3 = fName + " Scaler Data";
228 
229  if (fDebugFile) {
230  *fDebugFile << "\nAnalyze 1st time for fName = "<<fName<<endl;
231  *fDebugFile << sname2 << " " <<sname3<<endl;
232  }
233 
234  fScalerTree = new TTree(sname2.Data(),sname3.Data());
235  fScalerTree->SetAutoSave(200000000);
236 
237  TString name, tinfo;
238 
239  name = "evcount";
240  tinfo = name + "/D";
241  fScalerTree->Branch(name.Data(), &evcountR, tinfo.Data(), 4000);
242 
243  name = "evNumber";
244  tinfo = name + "/D";
245  fScalerTree->Branch(name.Data(), &evNumberR, tinfo.Data(), 4000);
246 
247  for (size_t i = 0; i < scalerloc.size(); i++) {
248  name = scalerloc[i]->name;
249  tinfo = name + "/D";
250  fScalerTree->Branch(name.Data(), &dvars[i], tinfo.Data(), 4000);
251  }
252 
253  } // if (lfirst && !fScalerTree)
254 
255  UInt_t *rdata = (UInt_t*) evdata->GetRawDataBuffer();
256 
257  if( (Int_t)evdata->GetEvType() == fDelayedType) { // Save this event for processing later
258  UInt_t evlen = evdata->GetEvLength();
259 
260  UInt_t *datacopy = new UInt_t[evlen];
261  fDelayedEvents.push_back(datacopy);
262  memcpy(datacopy,rdata,evlen*sizeof(UInt_t));
263  return 1;
264  } else { // A normal event
265  if (fDebugFile) *fDebugFile<<"\n\nTHcScalerEvtHandler :: Debugging event type "<<dec<<evdata->GetEvType()<< " event num = " << evdata->GetEvNum() << endl<<endl;
266  Int_t ret;
267  if((ret=AnalyzeBuffer(rdata,fOnlySyncEvents))) {
268  if (fDebugFile) *fDebugFile << "scaler tree ptr "<<fScalerTree<<endl;
269  if (fScalerTree) fScalerTree->Fill();
270  }
271  return ret;
272 
273  }
274 
275 }
277 {
278 
279  // Parse the data, load local data arrays.
280  UInt_t *p = (UInt_t*) rdata;
281 
282  UInt_t *plast = p+*p; // Index to last word in the bank
283 
284  ifound=0;
285  while(p<plast) {
286  p++; // point to header
287  if (fDebugFile) {
288  *fDebugFile << "Bank: " << hex << *p << dec << " len: " << *(p-1) << endl;
289  }
290  if((*p & 0xff00) == 0x1000) { // Bank Containing banks
291  p++; // Now pointing to a bank in the bank
292  } else if (((*p & 0xff00) == 0x100) && (*p != 0xC0000100)) {
293  // Bank containing integers. Look for scalers
294  // This is either ROC bank containing integers or
295  // a bank within a ROC containing data from modules of a single type
296  // Look for scaler data
297  // Assume that very first word is a scaler header
298  // At any point in the bank where the word is not a matching
299  // header, we stop.
300  UInt_t tag = (*p>>16) & 0xffff;
301  UInt_t num = (*p) & 0xff;
302  UInt_t *pnext = p+*(p-1); // Next bank
303  p++; // First data word
304 
305  // Skip over banks that can't contain scalers
306  // If SetOnlyBanks(kTRUE) called, fRocSet will be empty
307  // so only bank tags matching module types will be considered.
308  if(fModuleSet.find(tag)!=fModuleSet.end()) {
309  if(onlysync && num==0) {
310  ifound = 0;
311  return 0;
312  }
313  } else if (fRocSet.find(tag)==fRocSet.end()) {
314  p = pnext; // Fall through to end of the above else if
315  }
316 
317  // Look for normalization scaler module first.
318  if(fNormIdx >= 0) {
319  UInt_t *psave = p;
320  while(p < pnext) {
321  if(scalers[fNormIdx]->IsSlot(*p)) {
322  scalers[fNormIdx]->Decode(p);
323  ifound = 1;
324  break;
325  }
326  p += scalers[fNormIdx]->GetNumChan() + 1;
327  }
328  p = psave;
329  }
330  while(p < pnext) {
331  Int_t nskip = 0;
332  if(fDebugFile) {
333  *fDebugFile << "Scaler Header: " << hex << *p << dec;
334  }
335  for(size_t j=0; j<scalers.size(); j++) {
336  if(scalers[j]->IsSlot(*p)) {
337  nskip = scalers[j]->GetNumChan() + 1;
338  if((Int_t) j != fNormIdx) {
339  if(fDebugFile) {
340  *fDebugFile << " found (" << j << ") skip " << nskip << endl;
341  }
342  scalers[j]->Decode(p);
343  ifound = 1;
344  }
345  break;
346  }
347  }
348  if(nskip == 0) {
349  if(fDebugFile) {
350  *fDebugFile << endl;
351  }
352  break; // Didn't find a matching header
353  }
354  p = p + nskip;
355  }
356  p = pnext;
357  } else {
358  p = p+*(p-1); // Skip to next bank
359  }
360  }
361 
362  if (fDebugFile) {
363  *fDebugFile << "Finished with decoding. "<<endl;
364  *fDebugFile << " Found flag = "<<ifound<<endl;
365  }
366 
367  // HMS has headers which are different from SOS, but both are
368  // event type 0 and come here. If you found no headers, return.
369 
370  if (!ifound) return 0;
371 
372  // The correspondance between dvars and the scaler and the channel
373  // will be driven by a scaler.map file -- later
374  Double_t scal_current=0;
375  UInt_t thisClock = scalers[fNormIdx]->GetData(fClockChan);
376  if(thisClock < fLastClock) { // Count clock scaler wrap arounds
377  fClockOverflows++;
378  }
380  fLastClock = thisClock;
382  if (fDeltaTime==0) {
383  cout << " ******************* Severe Warning ****************************" << endl;
384  cout << " In THcScalerEvtHandler have found fDeltaTime is zero !! " << endl;
385  cout << " ******************* Alert DAQ experts ****************************" << endl;
386  }
387  fPrevTotalTime=fTotalTime;
388  Int_t nscal=0;
389  for (size_t i = 0; i < scalerloc.size(); i++) {
390  size_t ivar = scalerloc[i]->ivar;
391  size_t idx = scalerloc[i]->index;
392  size_t ichan = scalerloc[i]->ichan;
393  if (evcount==0) {
394  if (fDebugFile) *fDebugFile << "Debug dvarsFirst "<<i<<" "<<ivar<<" "<<idx<<" "<<ichan<<endl;
395  if ((ivar < scalerloc.size()) &&
396  (idx < scalers.size()) &&
397  (ichan < MAXCHAN)){
398  if(fUseFirstEvent){
399  if (scalerloc[ivar]->ikind == ICOUNT){
400  UInt_t scaldata = scalers[idx]->GetData(ichan);
401  dvars[ivar] = scaldata;
402  scal_present_read.push_back(scaldata);
403  scal_prev_read.push_back(0);
404  scal_overflows.push_back(0);
405  dvarsFirst[ivar] = 0.0;
406  }
407  if (scalerloc[ivar]->ikind == ITIME){
408  dvars[ivar] =fTotalTime;
409  dvarsFirst[ivar] = 0;
410  }
411  if (scalerloc[ivar]->ikind == IRATE) {
412  dvars[ivar] = (scalers[idx]->GetData(ichan))/fDeltaTime;
413  dvarsFirst[ivar] = dvars[ivar];
414  //printf("%s %f\n",scalerloc[ivar]->name.Data(),scalers[idx]->GetRate(ichan)); //checks
415  }
416  if(scalerloc[ivar]->ikind == ICURRENT || scalerloc[ivar]->ikind == ICHARGE){
417  Int_t bcm_ind=-1;
418  for(Int_t itemp =0; itemp<fNumBCMs;itemp++)
419  {
420  size_t match = string(scalerloc[ivar]->name.Data()).find(string(fBCM_Name[itemp]));
421  if (match!=string::npos)
422  {
423  bcm_ind=itemp;
424  }
425  }
426  if (scalerloc[ivar]->ikind == ICURRENT) {
427  dvars[ivar]=0.;
428  if (bcm_ind != -1) {
429  dvars[ivar]=((scalers[idx]->GetData(ichan))/fDeltaTime-fBCM_Offset[bcm_ind])/fBCM_Gain[bcm_ind];
430  dvars[ivar]=dvars[ivar]+fBCM_SatQuadratic[bcm_ind]*TMath::Power(TMath::Max(dvars[ivar]-fBCM_SatOffset[bcm_ind],0.0),2.0);
431 
432  }
433  if (bcm_ind == fbcm_Current_Threshold_Index) scal_current= dvars[ivar];
434  }
435  if (scalerloc[ivar]->ikind == ICHARGE) {
436  if (bcm_ind != -1) {
437  Double_t cur_temp=((scalers[idx]->GetData(ichan))/fDeltaTime-fBCM_Offset[bcm_ind])/fBCM_Gain[bcm_ind];
438  cur_temp=cur_temp+fBCM_SatQuadratic[bcm_ind]*TMath::Power(TMath::Max(cur_temp-fBCM_SatOffset[bcm_ind],0.0),2.0);
439  fBCM_delta_charge[bcm_ind]=fDeltaTime*cur_temp;
440  dvars[ivar]+=fBCM_delta_charge[bcm_ind];
441  }
442  }
443  // printf("1st event %i index %i fBCMname %s scalerloc %s offset %f gain %f computed %f\n",evcount, bcm_ind, fBCM_Name[bcm_ind],scalerloc[ivar]->name.Data(),fBCM_Offset[bcm_ind],fBCM_Gain[bcm_ind],dvars[ivar]);
444  }
445 
446  if (fDebugFile) *fDebugFile << " dvarsFirst "<<scalerloc[ivar]->ikind<<" "<<dvarsFirst[ivar]<<endl;
447 
448  } else { //ifnotusefirstevent
449  if (scalerloc[ivar]->ikind == ICOUNT) {
450  dvarsFirst[ivar] = scalers[idx]->GetData(ichan) ;
451  scal_present_read.push_back(dvarsFirst[ivar]);
452  scal_prev_read.push_back(0);
453  }
454  if (scalerloc[ivar]->ikind == ITIME){
455  dvarsFirst[ivar] = fTotalTime;
456  }
457  if (scalerloc[ivar]->ikind == IRATE) {
458  dvarsFirst[ivar] = (scalers[idx]->GetData(ichan))/fDeltaTime;
459  //printf("%s %f\n",scalerloc[ivar]->name.Data(),scalers[idx]->GetRate(ichan)); //checks
460  }
461  if(scalerloc[ivar]->ikind == ICURRENT || scalerloc[ivar]->ikind == ICHARGE)
462  {
463  Int_t bcm_ind=-1;
464  for(Int_t itemp =0; itemp<fNumBCMs;itemp++)
465  {
466  size_t match = string(scalerloc[ivar]->name.Data()).find(string(fBCM_Name[itemp]));
467  if (match!=string::npos)
468  {
469  bcm_ind=itemp;
470  }
471  }
472  if (scalerloc[ivar]->ikind == ICURRENT) {
473  dvarsFirst[ivar]=0.0;
474  if (bcm_ind != -1) {
475  dvarsFirst[ivar]=((scalers[idx]->GetData(ichan))/fDeltaTime-fBCM_Offset[bcm_ind])/fBCM_Gain[bcm_ind];
476  dvarsFirst[ivar]=dvarsFirst[ivar]+fBCM_SatQuadratic[bcm_ind]*TMath::Power(TMath::Max(dvars[ivar]-fBCM_SatOffset[bcm_ind],0.0),2.);
477  }
478  if (bcm_ind == fbcm_Current_Threshold_Index) scal_current= dvarsFirst[ivar];
479  }
480  if (scalerloc[ivar]->ikind == ICHARGE) {
481  if (bcm_ind != -1) {
482  Double_t cur_temp=((scalers[idx]->GetData(ichan))/fDeltaTime-fBCM_Offset[bcm_ind])/fBCM_Gain[bcm_ind];
483  cur_temp=cur_temp+fBCM_SatQuadratic[bcm_ind]*TMath::Power(TMath::Max(cur_temp-fBCM_SatOffset[bcm_ind],0.0),2.);
484  fBCM_delta_charge[bcm_ind]=fDeltaTime*cur_temp;
485  dvarsFirst[ivar]+=fBCM_delta_charge[bcm_ind];
486  }
487  }
488  }
489  if (fDebugFile) *fDebugFile << " dvarsFirst "<<scalerloc[ivar]->ikind<<" "<<dvarsFirst[ivar]<<endl;
490  }
491  }
492  else {
493  cout << "THcScalerEvtHandler:: ERROR:: incorrect index "<<ivar<<" "<<idx<<" "<<ichan<<endl;
494  }
495  }else{ // evcount != 0
496  if (fDebugFile) *fDebugFile << "Debug dvars "<<i<<" "<<ivar<<" "<<idx<<" "<<ichan<<endl;
497  if ((ivar < scalerloc.size()) &&
498  (idx < scalers.size()) &&
499  (ichan < MAXCHAN)) {
500  if (scalerloc[ivar]->ikind == ICOUNT) {
501  UInt_t scaldata = scalers[idx]->GetData(ichan);
502  if(scaldata < scal_prev_read[nscal]) {
503  scal_overflows[nscal]++;
504  }
505  dvars[ivar] = scaldata + (1+((Double_t)kMaxUInt))*scal_overflows[nscal]
506  -dvarsFirst[ivar];
507  scal_present_read[nscal]=scaldata;
508  nscal++;
509  }
510  if (scalerloc[ivar]->ikind == ITIME) {
511  dvars[ivar] = fTotalTime;
512  }
513  if (scalerloc[ivar]->ikind == IRATE) {
514  UInt_t scaldata = scalers[idx]->GetData(ichan);
515  UInt_t diff;
516  if(scaldata < scal_prev_read[nscal-1]) {
517  diff = (kMaxUInt-(scal_prev_read[nscal-1] - 1)) + scaldata;
518  } else {
519  diff = scaldata - scal_prev_read[nscal-1];
520  }
521  dvars[ivar] = diff/fDeltaTime;
522  // printf("%s %f\n",scalerloc[ivar]->name.Data(),scalers[idx]->GetRate(ichan));//checks
523  }
524  if(scalerloc[ivar]->ikind == ICURRENT || scalerloc[ivar]->ikind == ICHARGE)
525  {
526  Int_t bcm_ind=-1;
527  for(Int_t itemp =0; itemp<fNumBCMs;itemp++)
528  {
529  size_t match = string(scalerloc[ivar]->name.Data()).find(string(fBCM_Name[itemp]));
530  if (match!=string::npos)
531  {
532  bcm_ind=itemp;
533  }
534  }
535  if (scalerloc[ivar]->ikind == ICURRENT) {
536  dvars[ivar]=0;
537  if (bcm_ind != -1) {
538  UInt_t scaldata = scalers[idx]->GetData(ichan);
539  UInt_t diff;
540  if(scaldata < scal_prev_read[nscal-1]) {
541  diff = (kMaxUInt-(scal_prev_read[nscal-1] - 1)) + scaldata;
542  } else {
543  diff = scaldata - scal_prev_read[nscal-1];
544  }
545  dvars[ivar]=0.;
546  if (fDeltaTime>0) {
547  Double_t cur_temp=(diff/fDeltaTime-fBCM_Offset[bcm_ind])/fBCM_Gain[bcm_ind];
548  cur_temp=cur_temp+fBCM_SatQuadratic[bcm_ind]*TMath::Power(TMath::Max(cur_temp-fBCM_SatOffset[bcm_ind],0.0),2.);
549 
550  dvars[ivar]=cur_temp;
551  }
552  }
553  if (bcm_ind == fbcm_Current_Threshold_Index) scal_current= dvars[ivar];
554  }
555  if (scalerloc[ivar]->ikind == ICHARGE) {
556  if (bcm_ind != -1) {
557  UInt_t scaldata = scalers[idx]->GetData(ichan);
558  UInt_t diff;
559  if(scaldata < scal_prev_read[nscal-1]) {
560  diff = (kMaxUInt-(scal_prev_read[nscal-1] - 1)) + scaldata;
561  } else {
562  diff = scaldata - scal_prev_read[nscal-1];
563  }
564  fBCM_delta_charge[bcm_ind]=0;
565  if (fDeltaTime>0) {
566  Double_t cur_temp=(diff/fDeltaTime-fBCM_Offset[bcm_ind])/fBCM_Gain[bcm_ind];
567  cur_temp=cur_temp+fBCM_SatQuadratic[bcm_ind]*TMath::Power(TMath::Max(cur_temp-fBCM_SatOffset[bcm_ind],0.0),2.);
568  fBCM_delta_charge[bcm_ind]=fDeltaTime*cur_temp;
569  }
570  dvars[ivar]+=fBCM_delta_charge[bcm_ind];
571  }
572  }
573  // printf("event %i index %i fBCMname %s scalerloc %s offset %f gain %f computed %f\n",evcount, bcm_ind, fBCM_Name[bcm_ind],scalerloc[ivar]->name.Data(),fBCM_Offset[bcm_ind],fBCM_Gain[bcm_ind],dvars[ivar]);
574  }
575  if (fDebugFile) *fDebugFile << " dvars "<<scalerloc[ivar]->ikind<<" "<<dvars[ivar]<<endl;
576  } else {
577  cout << "THcScalerEvtHandler:: ERROR:: incorrect index "<<ivar<<" "<<idx<<" "<<ichan<<endl;
578  }
579  }
580 
581  }
582  //
583  for (size_t i = 0; i < scalerloc.size(); i++) {
584  size_t ivar = scalerloc[i]->ivar;
585  size_t idx = scalerloc[i]->index;
586  size_t ichan = scalerloc[i]->ichan;
587  if (scalerloc[ivar]->ikind == ICUT+ICOUNT){
588  UInt_t scaldata = scalers[idx]->GetData(ichan);
589  if ( scal_current > fbcm_Current_Threshold) {
590  UInt_t diff;
591  if(scaldata < dvars_prev_read[ivar]) {
592  diff = (kMaxUInt-(dvars_prev_read[ivar] - 1)) + scaldata;
593  } else {
594  diff = scaldata - dvars_prev_read[ivar];
595  }
596  dvars[ivar] += diff;
597  }
598  dvars_prev_read[ivar] = scaldata;
599  }
600  if (scalerloc[ivar]->ikind == ICUT+ICHARGE){
601  Int_t bcm_ind=-1;
602  for(Int_t itemp =0; itemp<fNumBCMs;itemp++)
603  {
604  size_t match = string(scalerloc[ivar]->name.Data()).find(string(fBCM_Name[itemp]));
605  if (match!=string::npos)
606  {
607  bcm_ind=itemp;
608  }
609  }
610  if ( scal_current > fbcm_Current_Threshold && bcm_ind != -1) {
611  dvars[ivar] += fBCM_delta_charge[bcm_ind];
612  }
613  }
614  if (scalerloc[ivar]->ikind == ICUT+ITIME){
615  if ( scal_current > fbcm_Current_Threshold) {
616  dvars[ivar] += fDeltaTime;
617  }
618  }
619  }
620  //
621  evcount = evcount + 1;
622  evcountR = evcount;
623  //
624  for (size_t j=0; j<scal_prev_read.size(); j++) scal_prev_read[j]=scal_present_read[j];
625  //
626  for (size_t j=0; j<scalers.size(); j++) scalers[j]->Clear("");
627 
628  return 1;
629 }
630 
631 
632 THaAnalysisObject::EStatus THcScalerEvtHandler::Init(const TDatime& date)
633 {
634  //
635  ReadDatabase(date);
636  const int LEN = 200;
637  char cbuf[LEN];
638 
639  fStatus = kOK;
640  fNormIdx = -1;
641 
642  for( vector<UInt_t*>::iterator it = fDelayedEvents.begin();
643  it != fDelayedEvents.end(); ++it )
644  delete [] *it;
645  fDelayedEvents.clear();
646 
647  cout << "Howdy ! We are initializing THcScalerEvtHandler !! name = "
648  << fName << endl;
649 
650  if(eventtypes.size()==0) {
651  eventtypes.push_back(0); // Default Event Type
652  }
653 
654  TString dfile;
655  dfile = fName + "scaler.txt";
656 
657 // Parse the map file which defines what scalers exist and the global variables.
658 
659  TString sname0 = "Scalevt";
660  TString sname;
661  sname = fName+sname0;
662 
663  FILE *fi = Podd::OpenDBFile(sname.Data(), date);
664  if ( !fi ) {
665  cout << "Cannot find db file for "<<fName<<" scaler event handler"<<endl;
666  return kFileError;
667  }
668 
669  size_t minus1 = -1;
670  size_t pos1;
671  string scomment = "#";
672  string svariable = "variable";
673  string smap = "map";
674  vector<string> dbline;
675 
676  while( fgets(cbuf, LEN, fi) != NULL) {
677  std::string sin(cbuf);
678  std::string sinput(sin.substr(0,sin.find_first_of("#")));
679  if (fDebugFile) *fDebugFile << "string input "<<sinput<<endl;
680  dbline = Podd::vsplit(sinput);
681  if (dbline.size() > 0) {
682  pos1 = FindNoCase(dbline[0],scomment);
683  if (pos1 != minus1) continue;
684  pos1 = FindNoCase(dbline[0],svariable);
685  if (pos1 != minus1 && dbline.size()>4) {
686  string sdesc = "";
687  for (size_t j=5; j<dbline.size(); j++) sdesc = sdesc+" "+dbline[j];
688  UInt_t islot = atoi(dbline[1].c_str());
689  UInt_t ichan = atoi(dbline[2].c_str());
690  UInt_t ikind = atoi(dbline[3].c_str());
691  if (fDebugFile)
692  *fDebugFile << "add var "<<dbline[1]<<" desc = "<<sdesc<<" islot= "<<islot<<" "<<ichan<<" "<<ikind<<endl;
693  TString tsname(dbline[4].c_str());
694  TString tsdesc(sdesc.c_str());
695  AddVars(tsname,tsdesc,islot,ichan,ikind);
696  // add extra scaler which is cut on the current
697  if (ikind == ICOUNT ||ikind == ITIME ||ikind == ICHARGE ) {
698  tsname=tsname+"Cut";
699  AddVars(tsname,tsdesc,islot,ichan,ICUT+ikind);
700  }
701  }
702  pos1 = FindNoCase(dbline[0],smap);
703  if (fDebugFile) *fDebugFile << "map ? "<<dbline[0]<<" "<<smap<<" "<<pos1<<" "<<dbline.size()<<endl;
704  if (pos1 != minus1 && dbline.size()>6) {
705  Int_t imodel, icrate, islot, inorm;
706  UInt_t header, mask;
707  char cdum[20];
708  sscanf(sinput.c_str(),"%s %d %d %d %x %x %d \n",cdum,&imodel,&icrate,&islot, &header, &mask, &inorm);
709  if ((fNormSlot >= 0) && (fNormSlot != inorm)) cout << "THcScalerEvtHandler::WARN: contradictory norm slot "<<fNormSlot<<" "<<inorm<<endl;
710  fNormSlot = inorm; // slot number used for normalization. This variable is not used but is checked.
711  Int_t clkchan = -1;
712  Double_t clkfreq = 1;
713  if (dbline.size()>8) {
714  clkchan = atoi(dbline[7].c_str());
715  clkfreq = 1.0*atoi(dbline[8].c_str());
716  fClockChan=clkchan;
717  fClockFreq=clkfreq;
718  }
719  if (fDebugFile) {
720  *fDebugFile << "map line "<<dec<<imodel<<" "<<icrate<<" "<<islot<<endl;
721  *fDebugFile <<" header 0x"<<hex<<header<<" 0x"<<mask<<dec<<" "<<inorm<<" "<<clkchan<<" "<<clkfreq<<endl;
722  }
723  switch (imodel) {
724  case 560:
725  scalers.push_back(new Scaler560(icrate, islot));
726  if(!fOnlyBanks) fRocSet.insert(icrate);
727  fModuleSet.insert(imodel);
728  break;
729  case 1151:
730  scalers.push_back(new Scaler1151(icrate, islot));
731  if(!fOnlyBanks) fRocSet.insert(icrate);
732  fModuleSet.insert(imodel);
733  break;
734  case 3800:
735  scalers.push_back(new Scaler3800(icrate, islot));
736  if(!fOnlyBanks) fRocSet.insert(icrate);
737  fModuleSet.insert(imodel);
738  break;
739  case 3801:
740  scalers.push_back(new Scaler3801(icrate, islot));
741  if(!fOnlyBanks) fRocSet.insert(icrate);
742  fModuleSet.insert(imodel);
743  break;
744  case 9001: // TI Scalers
745  scalers.push_back(new Scaler9001(icrate, islot));
746  if(!fOnlyBanks) fRocSet.insert(icrate);
747  fModuleSet.insert(imodel);
748  break;
749  case 9250: // FADC250 Scalers
750  scalers.push_back(new Scaler9250(icrate, islot));
751  if(!fOnlyBanks) fRocSet.insert(icrate);
752  fModuleSet.insert(imodel);
753  break;
754  }
755  if (scalers.size() > 0) {
756  UInt_t idx = scalers.size()-1;
757  // Headers must be unique over whole event, not
758  // just within a ROC
759  scalers[idx]->SetHeader(header, mask);
760 // The normalization slot has the clock in it, so we automatically recognize it.
761 // fNormIdx is the index in scaler[] and
762 // fNormSlot is the slot#, checked for consistency
763  if (clkchan >= 0) {
764  scalers[idx]->SetClock(defaultDT, clkchan, clkfreq);
765  cout << "Setting scaler clock ... channel = "<<clkchan<<" ... freq = "<<clkfreq<<endl;
766  if (fDebugFile) *fDebugFile <<"Setting scaler clock ... channel = "<<clkchan<<" ... freq = "<<clkfreq<<endl;
767  fNormIdx = idx;
768  if (islot != fNormSlot) cout << "THcScalerEvtHandler:: WARN: contradictory norm slot ! "<<islot<<endl;
769 
770  }
771  }
772  }
773  }
774  }
775  // can't compare UInt_t to Int_t (compiler warning), so do this
776  nscalers=0;
777  for (size_t i=0; i<scalers.size(); i++) nscalers++;
778  // need to do LoadNormScaler after scalers created and if fNormIdx found
779  if (fDebugFile) *fDebugFile <<"fNormIdx = "<<fNormIdx<<endl;
780  if ((fNormIdx >= 0) && fNormIdx < nscalers) {
781  for (Int_t i = 0; i < nscalers; i++) {
782  if (i==fNormIdx) continue;
783  scalers[i]->LoadNormScaler(scalers[fNormIdx]);
784  }
785  }
786 
787 #ifdef HARDCODED
788  // This code is superseded by the parsing of a map file above. It's another way ...
789  if (fName == "Left") {
790  AddVars("TSbcmu1", "BCM x1 counts", 1, 4, ICOUNT);
791  AddVars("TSbcmu1r","BCM x1 rate", 1, 4, IRATE);
792  AddVars("TSbcmu3", "BCM u3 counts", 1, 5, ICOUNT);
793  AddVars("TSbcmu3r", "BCM u3 rate", 1, 5, IRATE);
794  } else {
795  AddVars("TSbcmu1", "BCM x1 counts", 0, 4, ICOUNT);
796  AddVars("TSbcmu1r","BCM x1 rate", 0, 4, IRATE);
797  AddVars("TSbcmu3", "BCM u3 counts", 0, 5, ICOUNT);
798  AddVars("TSbcmu3r", "BCM u3 rate", 0, 5, IRATE);
799  }
800 #endif
801 
802 
803  DefVars();
804 
805 #ifdef HARDCODED
806  // This code is superseded by the parsing of a map file above. It's another way ...
807  if (fName == "Left") {
808  scalers.push_back(new Scaler1151(1,0));
809  scalers.push_back(new Scaler3800(1,1));
810  scalers.push_back(new Scaler3800(1,2));
811  scalers.push_back(new Scaler3800(1,3));
812  scalers[0]->SetHeader(0xabc00000, 0xffff0000);
813  scalers[1]->SetHeader(0xabc10000, 0xffff0000);
814  scalers[2]->SetHeader(0xabc20000, 0xffff0000);
815  scalers[3]->SetHeader(0xabc30000, 0xffff0000);
816  scalers[0]->LoadNormScaler(scalers[1]);
817  scalers[1]->SetClock(4, 7, 1024);
818  scalers[2]->LoadNormScaler(scalers[1]);
819  scalers[3]->LoadNormScaler(scalers[1]);
820  } else {
821  scalers.push_back(new Scaler3800(2,0));
822  scalers.push_back(new Scaler3800(2,0));
823  scalers.push_back(new Scaler1151(2,1));
824  scalers.push_back(new Scaler1151(2,2));
825  scalers[0]->SetHeader(0xceb00000, 0xffff0000);
826  scalers[1]->SetHeader(0xceb10000, 0xffff0000);
827  scalers[2]->SetHeader(0xceb20000, 0xffff0000);
828  scalers[3]->SetHeader(0xceb30000, 0xffff0000);
829  scalers[0]->SetClock(4, 7, 1024);
830  scalers[1]->LoadNormScaler(scalers[0]);
831  scalers[2]->LoadNormScaler(scalers[0]);
832  scalers[3]->LoadNormScaler(scalers[0]);
833  }
834 #endif
835 
836  // Verify that the slots are not defined twice
837  for (UInt_t i1=0; i1 < scalers.size()-1; i1++) {
838  for (UInt_t i2=i1+1; i2 < scalers.size(); i2++) {
839  if (scalers[i1]->GetSlot()==scalers[i2]->GetSlot())
840  cout << "THcScalerEvtHandler:: WARN: same slot defined twice"<<endl;
841  }
842  }
843  // Identify indices of scalers[] vector to variables.
844  for (UInt_t i=0; i < scalers.size(); i++) {
845  for (UInt_t j = 0; j < scalerloc.size(); j++) {
846  if (scalerloc[j]->islot==static_cast<UInt_t>(scalers[i]->GetSlot()))
847  scalerloc[j]->index = i;
848  }
849  }
850 
851  if(fDebugFile) *fDebugFile << "THcScalerEvtHandler:: Name of scaler bank "<<fName<<endl;
852  for (size_t i=0; i<scalers.size(); i++) {
853  if(fDebugFile) {
854  *fDebugFile << "Scaler # "<<i<<endl;
855  scalers[i]->SetDebugFile(fDebugFile);
856  scalers[i]->DebugPrint(fDebugFile);
857  }
858  }
859 
860 
861  //
862  return kOK;
863 }
864 
866  UInt_t ichan, UInt_t ikind)
867 {
868  // need to add fName here to make it a unique variable. (Left vs Right HRS, for example)
869  TString name1 = fName + name;
870  TString desc1 = fName + desc;
871  // We don't yet know the correspondence between index of scalers[] and slots.
872  // Will put that in later.
873  scalerloc.push_back( new HCScalerLoc(name1, desc1, 0, islot, ichan, ikind,
874  scalerloc.size()) );
875 }
876 
878 {
879  // called after AddVars has finished being called.
880  Nvars = scalerloc.size();
881  if (Nvars == 0) return;
882  dvars_prev_read = new UInt_t[Nvars]; // dvars_prev_read is a member of this class
883  dvars = new Double_t[Nvars]; // dvars is a member of this class
884  dvarsFirst = new Double_t[Nvars]; // dvarsFirst is a member of this class
885  memset(dvars, 0, Nvars*sizeof(Double_t));
886  memset(dvars_prev_read, 0, Nvars*sizeof(UInt_t));
887  memset(dvarsFirst, 0, Nvars*sizeof(Double_t));
888  if (gHaVars) {
889  if(fDebugFile) *fDebugFile << "THcScalerEVtHandler:: Have gHaVars "<<gHaVars<<endl;
890  } else {
891  cout << "No gHaVars ?! Well, that's a problem !!"<<endl;
892  return;
893  }
894  if(fDebugFile) *fDebugFile << "THcScalerEvtHandler:: scalerloc size "<<scalerloc.size()<<endl;
895  const Int_t* count = 0;
896  for (size_t i = 0; i < scalerloc.size(); i++) {
897  gHaVars->DefineByType(scalerloc[i]->name.Data(), scalerloc[i]->description.Data(),
898  &dvars[i], kDouble, count);
899  //gHaVars->DefineByType(scalerloc[i]->name.Data(), scalerloc[i]->description.Data(),
900  // &dvarsFirst[i], kDouble, count);
901  }
902 }
903 
904 size_t THcScalerEvtHandler::FindNoCase(const string& sdata, const string& skey)
905 {
906  // Find iterator of word "sdata" where "skey" starts. Case insensitive.
907  string sdatalc, skeylc;
908  sdatalc = ""; skeylc = "";
909  for (string::const_iterator p =
910  sdata.begin(); p != sdata.end(); ++p) {
911  sdatalc += tolower(*p);
912  }
913  for (string::const_iterator p =
914  skey.begin(); p != skey.end(); ++p) {
915  skeylc += tolower(*p);
916  }
917  if (sdatalc.find(skeylc,0) == string::npos) return -1;
918  return sdatalc.find(skeylc,0);
919 };
920 
const UInt_t kMaxUInt
static const UInt_t ICURRENT
virtual Int_t Fill()
std::vector< HCScalerLoc * > scalerloc
virtual void SetAutoSave(Long64_t autos=-300000000)
std::set< UInt_t > fModuleSet
UInt_t GetEvNum() const
static const UInt_t ITIME
static const UInt_t ICHARGE
int Int_t
bool Bool_t
std::vector< std::string > fBCM_Name
STL namespace.
std::vector< Decoder::GenScaler * > scalers
virtual Int_t ReadDatabase(const TDatime &date)
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
std::vector< UInt_t * > fDelayedEvents
virtual void SetDelayedType(int evtype)
const char * Data() const
static Bool_t Initialized()
void AddVars(TString name, TString desc, UInt_t iscal, UInt_t ichan, UInt_t ikind)
static const UInt_t ICOUNT
std::vector< UInt_t > scal_prev_read
static const UInt_t ICUT
static const UInt_t MAXCHAN
UInt_t GetEvLength() const
double sin(double)
std::vector< UInt_t > scal_present_read
const UInt_t * GetRawDataBuffer() const
virtual Int_t Write(const char *name=0, Int_t option=0, Int_t bufsize=0)
static const UInt_t IRATE
static const UInt_t defaultDT
unsigned int UInt_t
std::vector< UInt_t > scal_overflows
const std::string sname
tuple list
Definition: SConscript.py:9
const Bool_t kFALSE
THcScalerEvtHandler(const char *, const char *)
static size_t FindNoCase(const std::string &sdata, const std::string &skey)
virtual EStatus Init(const TDatime &run_time)
Int_t LoadParmValues(const DBRequest *list, const char *prefix="")
Retrieve parameter values from the parameter cache.
double Double_t
UInt_t GetEvType() const
ClassImp(THcDCLookupTTDConv) THcDCLookupTTDConv
virtual Int_t Branch(TCollection *list, Int_t bufsize=32000, Int_t splitlevel=99, const char *name="")
Event handler for Hall C scalers.
virtual Int_t End(THaRunBase *r=0)
Short_t Max(Short_t a, Short_t b)
std::set< UInt_t > fRocSet
R__EXTERN class THcParmList * gHcParms
Definition: THcGlobals.h:11
Int_t Analyze(THaEvData *evdata)
const Bool_t kTRUE
char name[80]
Int_t AnalyzeBuffer(UInt_t *rdata, Bool_t onlysync)