StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
L2VirtualAlgo2012.cxx
1 #include <string.h>
2 #include <stdio.h>
3 #include <cstdlib>
4 
5 #include "fakeRtsLog.h"
6 
7 #ifdef IS_REAL_L2 //in l2-ana environment
8  #include "../L2algoUtil/L2Histo.h"
9  #include "../L2algoUtil/L2EmcDb2012.h"
10 #else //full path needed for cvs'd code
11  #include "StTriggerUtilities/L2Emulator/L2algoUtil/L2Histo.h"
12  #include "StTriggerUtilities/L2Emulator/L2algoUtil/L2EmcDb2012.h"
13 #endif
14 
15 //#define ADD_HARDCODED_DELAY // take it off for real on-line
16 
17 #include "L2VirtualAlgo2012.h"
18 //=============================================
19 L2VirtualAlgo2012::L2VirtualAlgo2012(const char* name, const char *uid, L2EmcDb2012* db, char* outDir, bool needbarrel, bool needendcap, int resOff) : mDb(db) {
20  algoIsOkay=true; //whether the algorithm is in a functional state. innocent until proven guilty.
21  mxHA=0;// initially no user defined histos
22  mName1=name;
23  mName1 = mName1 + "." + uid;
24  mOutDir1=outDir;
25  mNeeds_barrel=needbarrel;
26  mNeeds_endcap=needendcap;
27  mRunNumber=-1;
28  mResultOffset=resOff;
29 
30  // map L2event variables for _read_
31  mEveStream_btow=globL2eventStream2012.get_btow();
32  mEveStream_etow=globL2eventStream2012.get_etow();
33 
34  setOflTrigID(0); // relevant only for offline analysis
35  mhN =new L2Histo(900,"total events. 0=anyInput 10=anyAccept 11=normalAccept 12=rndAccept",19);
36  mhTc=new L2Histo(901,"L2 COMPUTE time per input event; x: COMPUTE time (CPU kTics); y: events ",180);
37  mhTd=new L2Histo(902,"L2 DECISION time per input event; x: DECISION time (CPU kTics); y: events ",36);
38  mhTcd=new L2Histo(903,"L2 COMP+DECI time per input event; x: COMP+DECIS time (CPU kTics); y: events ",180);
39 
40  int mxRunDration=2000;
41  mhRc= new L2Histo(905,"rate of COMPUTE; x: time in this run (seconds); y: rate (Hz)", mxRunDration);
42  mhRd= new L2Histo(906,"rate of DECISION; x: time in this run (seconds); y: rate (Hz)", mxRunDration);
43  mhRa= new L2Histo(907,"rate of ACCEPT; x: time in this run (seconds); y: rate (Hz)", mxRunDration);
44 
45  // consistency checks, should never fail
46 
47  if (!(L2eventStream2012::mxToken == L2eventStream2012::tokenMask+1))
48  {
49  char err[200];
50  sprintf(err,"Algo %s has failed consistency check '(L2eventStream2012::mxToken == L2eventStream2012::tokenMask+1)'",name);
51  criticalError(err);
52  }
53 }
54 
55 /*========================================
56  ======================================== */
57 int
58 L2VirtualAlgo2012::initRun( int runNo, int *rc_ints, float *rc_floats) {
59  if(!algoIsOkay)
60  {
61  char err[100];
62  sprintf(err,"%s is flagged as broken. Aborting init.",getName());
63  criticalError(err);
64  return -999;
65  }
66 
67  useDsmMask=false;
68 
69 
70  if(mDb->getRun()!=runNo) return -700; // L2EmcDb not initialized properly
71 
72  if(mRunNumber==runNo) {
73  if (mLogFile) fprintf(mLogFile,"#L2-%s::initRun(%d)=ghost already initilized, Abort run\n",getName(), runNo);
74  return -701;
75  }
76 
77  //clear VirtualAlgo histograms:
78  mhN->reset();
79  mhTc->reset();
80  mhTd->reset();
81  mhTcd->reset();
82  mhRc->reset();
83  mhRd->reset();
84  mhRa->reset();
85 
86 
87  unsigned int high,low;
88  rdtsc_macro(low,high); // needs also high to get tim in seconds
89  mRunStartTicks=high; mRunStartTicks <<= 32; mRunStartTicks += low;
90 
91  mRunNumber =runNo; // serves as a flag this run is initialized
92  mEventsInRun=0;
93 
94  char Fname[1000];
95  sprintf(Fname,"%s/run%d.l2%s.log",mOutDir1.c_str(),mRunNumber,getName());
96 
97  mLogFile = fopen(Fname,"w");
98  if( mLogFile==0) {
99  LOG(ERR," L2-%s() UNABLE to open run summary log file, continue anyhow (%s)",getName(),Fname);
100  }
101 
102  //set default for par_RndAcceptPrescale, just in case initRunUser() doesn't define it:
103  par_RndAcceptPrescale=0;//no random accepts.
104  mRndAcceptCounter=0;
105 
106  int kBad=initRunUser( runNo, rc_ints, rc_floats);
107 
108  //setup the random accept stuff:
109 
110  mRandomAccept=false; //initialize the mRandomAccept to false,
111  //this covers the case where the prescale=0. Note this is NOT a boolean of whether
112  //we are randomly accepting events, but just the marker for whether to accept the
113  //most recent event given.
114 
115  //par_RndAcceptPrescale is set in initRunUser(), but check range:
116  if (par_RndAcceptPrescale<0) par_RndAcceptPrescale=0;
117  if (par_RndAcceptPrescale>0)
118  mRndAcceptCounter=rand()%par_RndAcceptPrescale;
119 
120 
121  if (mLogFile) {
122  fprintf(mLogFile,"#L2-%s initRun() params checked for consistency, Error flag=0x%04x\n",getName(),kBad);
123  }
124 
125  if(kBad<0) {
126  if (mLogFile) {
127  fprintf(mLogFile,"#L2-%s initRun() ABORT due to internal logic\n",getName());
128  fclose(mLogFile);
129  }
130  mRunNumber=-55;
131  return kBad;
132  }
133 
134  if (mLogFile) {
135  fprintf(mLogFile,"#L2-%s random accept counter started at %d\n",getName(),mRndAcceptCounter);
136  fprintf(mLogFile,"#L2-%s initRun successful\n",getName());
137 
138 #ifdef ADD_HARDCODED_DELAY
139  fprintf(mLogFile,"#WARN: HARDCODED_DELAY in compute() & decision() is ON\n");
140 #endif
141 
142  }
143 
144  return kBad;
145 }
146 
147 /*========================================
148  ======================================== */
149 void
150 L2VirtualAlgo2012::finishRun() { /* called once at the end of the run */
151 
152  if(mRunNumber<0) return; // already finished
153  if(mLogFile)fprintf(mLogFile,"#L2-%s: finishRun(%d) called after %d seconds\n",getName(),mRunNumber ,mSecondsInRun);
154 
155 
156  // save run summary histos
157  char Fname[1000];
158  sprintf(Fname,"%s/run%d.l2%s.hist.bin",mOutDir1.c_str(),mRunNumber,getName());
159  mHistFile = fopen(Fname,"w");
160 
161 
162  if( mHistFile==0) {
163  LOG(ERR," L2-%s: finishRun() UNABLE to open run summary log file, continue anyhow (fn=%s)\n",getName(),Fname);
164  if (mLogFile)
165  fprintf(mLogFile,"#L2-%s histos NOT saved, I/O error\n",getName());
166  } else { // save histos
167  finishRunUser();
168  if (mLogFile)
169  mhN->printCSV(mLogFile);
170  int nh=finishCommonHistos();
171  if (mLogFile)
172  fprintf(mLogFile,"#L2-%s: %d histos saved to '%s'\n",getName(),nh,Fname);
173  }
174 
175  if (mLogFile && useDsmMask)
176  {
177  fprintf(mLogFile,"#L2-%s: %d DSM masks are used.\n",getName(),nmasks);
178  for (int i=0;i<nmasks;i++)
179  fprintf(mLogFile,"# Mask %d: 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x\n",
180  i,DsmMask[i][0],DsmMask[i][1],DsmMask[i][2],DsmMask[i][3],DsmMask[i][4],
181  DsmMask[i][5],DsmMask[i][6],DsmMask[i][7]);
182  }
183  mRunNumber=-2; // clear run #
184  for (int i=0; i<mxHA;i++) if(hA[i])hA[i]->reset();
185  /* close the output file if it is open */
186  if (mLogFile) {
187  fclose(mLogFile);
188  mLogFile=0;
189  }
190 
191  if ( mHistFile) {
192  fclose(mHistFile);
193  mHistFile=0;
194  }
195 }
196 
197 
198 //=============================================
199 int
200 L2VirtualAlgo2012::finishCommonHistos() {
201  int j;
202  int nh=0;
203  for(j=0;j<mxHA;j++) {
204  if(hA[j]==0) continue;
205  hA[j]->write(mHistFile);
206  nh++;
207  }
208  const int nHt=3;
209  L2Histo *hT[nHt]={mhTc,mhTd,mhTcd};
210  const char *text[nHt]={"Compute ","Decision ","Deci+Comp"};
211  int ih;
212  for(ih=0;ih<nHt;ih++) {
213  int iMax=-3, iFWHM=-4;
214  hT[ih]->findMax( &iMax, &iFWHM);
215 
216  if (mLogFile){
217  fprintf(mLogFile,"#L2:%s %s CPU/eve MPV %d kTicks, FWHM=%d, seen eve=%d\n",getName(),text[ih],iMax, iFWHM,mEventsInRun);
218  // hT[ih] ->print(0,mLogFile); // mhT->printCSV(mLogFile);
219  }
220  if (mHistFile) {hT[ih]->write(mHistFile); nh++;}
221  }
222  if (mHistFile) {
223  mhN->write(mHistFile); nh++;
224  mhRc->write(mHistFile);nh++;
225  mhRd->write(mHistFile);nh++;
226  mhRa->write(mHistFile);nh++;
227  }
228  return nh;
229 }
230 
231 //=============================================
232 
233 L2VirtualAlgo2012::~L2VirtualAlgo2012(){};
234 
235 //=============================================
236 int
237 L2VirtualAlgo2012::readParams(const char *fileN, int mxPar, int *iPar, float *fPar) {
238  /* return:
239  <0 : error in input
240  >=0 : # of valid params : int+float
241  */
242 
243  memset(iPar,0,mxPar*sizeof(int));
244  memset(fPar,0,mxPar*sizeof(int));
245  FILE *fd=fopen(fileN,"r");
246  if(fd==0) { LOG(ERR,"L2VirtualAlgo2012::readParams failed to open =%s=\n",fileN); return -2222;}
247 
248  int nVal=0; // sum of read in ints & floats
249  int nInt=0, nFloat=0; // # of read in values
250 
251  const int mx=1000;
252  char buf[mx];
253  int mode=0; // 1=int, 2=float
254 
255  for(;;) {
256  char * ret=fgets(buf,mx,fd);
257  if(ret==0) break;
258  if(buf[0]==0) continue;
259  if(buf[0]=='#') continue;
260  if(buf[0]=='\n') continue;
261 
262  if (mode==0 && strstr(buf,"INTS")) { mode=1; continue; }
263  if (mode==1 && strstr(buf,"FLOATS")) { mode=2; continue; }
264  if(mode==1) { // ints[]
265  if(nInt>=mxPar) {nVal=-501; break;} // too many int-params
266  int ret1=sscanf(buf,"%i",iPar+nInt);
267  if(ret1!=1) {nVal=-100*mode -nInt; break;} // wrong input file for this int-par
268  nInt++; nVal++;
269  }
270  else if(mode==2) { // floats[]
271  if(nFloat>=mxPar) {nVal=-502; break;} // too many float-params
272  int ret1=sscanf(buf,"%f",fPar+nFloat);
273  if(ret1!=1) {nVal= -100*mode -nFloat; break;} // wrong input file for this float-par
274  nFloat++; nVal++;
275  }
276 
277  }
278 
279  fclose(fd);
280  LOG(DBG,"L2VirtualAlgo2012::readParams %d from '%s'\n",nVal,fileN);
281  return nVal;
282 }
283 
284 
285 //=============================================
286 void
287 L2VirtualAlgo2012::compute(int token){
288  /* STRICT TIME BUDGET START ....*/
289  computeStart();
290  mhN->fill(1);
291  token&=L2eventStream2012::tokenMask; // only protect against bad token, Gerard's trick
292 
293 #ifdef ADD_HARDCODED_DELAY
294  /* for testing of histos,
295  adds 3kTicks delay, - to see sth in the spectra
296  even if algo is very fast */
297  for(int i=0;i<3*100;i++) { float x=i*i; x=x;}
298 #endif
299 
300  computeUser( token );
301  computeStop( token);
302 
303 }
304 
305 //=============================================
306 void
307 L2VirtualAlgo2012::computeStart(){
308 
309  /* STRICT TIME BUDGET START ....*/
310  unsigned int high,low;
311  rdtsc_macro(low,high); // needs also high to get tim in seconds
312 
313  mComputeTimeStart=low;
314  unsigned long long ticks = high;
315  ticks <<= 32;
316  ticks += low;
317 
318  // the line below costs ~100 ticks, wherase use of time(0) costs ~10,000 ticks
319  mSecondsInRun=(ticks- mRunStartTicks)/par_cpuTicksPerSecond;
320 
321  mhRc->fill(mSecondsInRun);
322 
323  mAccept=true; // by default accept every event
324  mEventsInRun++;
325 
326  mhN->fill(0);
327 }
328 
329 //=============================================
330 void
331 L2VirtualAlgo2012::computeStop(int token){
332 
333  rdtscl_macro(mComputeTimeStop);
334  unsigned long xxx=mComputeTimeStop-mComputeTimeStart;
335  mComputeTimeDiff[token]=xxx;
336  int kTick=xxx/1000;
337  mhTc->fill(kTick);
338 }
339 
340 
341 //=============================================
342 bool
343 L2VirtualAlgo2012::decision(int token, bool barrel_is_in, bool endcap_is_in, int *myL2Result){
344  /* STRICT TIME BUDGET START ....*/
345  /*
346  Chris doesn't want us to write out anything
347  during event processing ...
348  */
349 
350  LOG(DBG, "Decision...");
351 
352  rdtscl_macro(mDecisionTimeStart); //start timer
353  token&=L2eventStream2012::tokenMask; // only protect against bad token, Gerard's trick
354  mDecisionTimeDiff=0;
355 
356  mhRd->fill(mSecondsInRun);
357 
358 #ifdef ADD_HARDCODED_DELAY
359  /* for testing of histos,
360  adds 3kTicks delay, - to see sth in the spectra
361  even if algo is very fast */
362  for(int i=0;i<3*100;i++) { float x=i*i; x=x;}
363 #endif
364 
365  mhN->fill(2);
366 
367  if (par_RndAcceptPrescale>0)
368  {
369  mRndAcceptCounter=(mRndAcceptCounter+1)%par_RndAcceptPrescale;
370  mRandomAccept=(mRndAcceptCounter==0);
371  }
372 
373  //if a component is needed but not included, do not call decision(), set accept to 0.
374 
375  LOG(DBG, "bin %d needsb %d ee %d ne %d",
376  barrel_is_in, mNeeds_barrel, endcap_is_in, mNeeds_endcap);
377 
378  if ( (!endcap_is_in && mNeeds_endcap) || (!barrel_is_in && mNeeds_barrel) )
379  {
380  mAccept=0;
381  }
382  else
383  {
384  mAccept=decisionUser(token, myL2Result+mResultOffset);
385  }
386 
387  if(mAccept || mRandomAccept) {
388  mhN->fill(10); //Breakdown of how many events got to each stage. 10=any accept
389  mhRa->fill(mSecondsInRun);
390  }
391  if(mRandomAccept)
392  mhN->fill(12); //same. 12=random accept
393  if(mAccept)
394  mhN->fill(11); //same. 11=regular accept
395 
396 
397  rdtscl_macro(mDecisionTimeStop); //stop timer
398  mDecisionTimeDiff=mDecisionTimeStop-mDecisionTimeStart;
399  int kTick=mDecisionTimeDiff/1000;
400 
401  mhTd->fill(kTick);
402  kTick=(mDecisionTimeDiff+mComputeTimeDiff[token])/1000;
403  mhTcd->fill(kTick);
404  return (mAccept || mRandomAccept);
405 }
406 
407 
408 
409 /* ========================================
410  ======================================== */
411 void
412 L2VirtualAlgo2012::printCalibratedData(int token){ //
413  // now print always BARREL - fix it later
414  int i;
415  const int hitSize=mEveStream_btow[token].get_hitSize();
416  LOG(NOTE,"printCalibratedData-%s: ---BTOW ADC list--- size=%d\n",getName(),hitSize);
417  const HitTower1 *hit=mEveStream_btow[token].get_hits();
418  for(i=0;i< hitSize;i++,hit++) {
419  int adc=hit->adc;
420  int rdo=hit->rdo;
421  float et=hit->et;
422  float ene=hit->ene;
423  LOG(NOTE," btow: i=%2d rdo=%4d adc=%d et=%.3f ene=%.3f\n",i,rdo,adc,et,ene);
424  }
425 }
426 
427 
428 /* ========================================
429  ======================================== */
430 void
431 L2VirtualAlgo2012::criticalError(const char* message){
432  algoIsOkay=false;
433 #ifdef IS_REAL_L2
434  LOG(CRIT,"%s",message,0,0,0,0);
435 #else
436  LOG(CRIT,"CRITICAL MESSAGE: %s\n",message);
437  //asert(1==2);
438 #endif
439  return;
440 }
441 
442 
443 //three functions needed for the temporary hack for the old TCU:
444 bool L2VirtualAlgo2012::checkDsmMask(unsigned short *lastDSM)
445 {
446  if (!useDsmMask) return 1; //short circuit if we're not using a mask (ie new TCU is being used).
447  if (nmasks==0) return 1; //if we don't have any masks set up for some reason, return a 'yes'
448 
449  bool isGood;
450  for (int i=0;i<nmasks;i++)
451  {
452  isGood=true;
453  for (int j=0;j<8 && isGood;j++)
454  {
455  if((swap_bytes(lastDSM[j]) & DsmMask[i][j]) != DsmMask[i][j]) isGood=false;
456  }
457  if (isGood) return 1;
458  }
459  return 0; //we had masks and none of them matched, hence return 'no'.
460 }
461 
462 int L2VirtualAlgo2012::readDsmMask(const char *fileN)
463 {
464  for (int i=0;i<kMaximumNumberOfDsmMasks;i++)
465  for (int j=0;j<8;j++)
466  DsmMask[i][j]=0;
467 
468  FILE *fd=fopen(fileN,"r");
469  if(fd==0) {
470  LOG(ERR," L2VirtualAlgo2012::readDsmMask failed to open =%s=. Assuming no mask.\n",fileN);
471  return 0; //0=no error occurred.
472  useDsmMask=false;
473  }
474 
475  int n=0; // # of read in values
476  nmasks=0; //number of masks being used
477 
478  const int mx=1000;
479  char buf[mx];
480 
481  for(;;) {
482  char * ret=fgets(buf,mx,fd);
483  if(ret==0) break;
484  if(buf[0]==0) continue;
485  if(buf[0]=='#') continue;
486  if(buf[0]=='\n') continue;
487  if(nmasks>=kMaximumNumberOfDsmMasks) {LOG(ERR," L2VirtualAlgo2012::readDsmMask: Too many masks %s.\n",fileN); return -3333;}
488  int ret1=sscanf(buf,"%hu",&(DsmMask[nmasks][n%8]));
489  if(ret1!=1) {LOG(ERR," L2VirtualAlgo2012::readDsmMask: Problem reading %s.\n",fileN); return -4444;} // wrong input file for this int-par
490  n++;
491  if (n%8==0) nmasks++;
492  }
493  fclose(fd);
494  if (n%8!=0){LOG(ERR," L2VirtualAlgo2012::readDsmMask: Wrong number of arguments in %s (n=%d).\n",fileN,n); return -3333;}
495  useDsmMask=true;
496  return 0; //0=no error occurred
497 }
498 
499 unsigned short L2VirtualAlgo2012::swap_bytes(unsigned short in)
500 {
501  unsigned short out=0;
502  unsigned char *a, *b;
503 
504  a=(unsigned char*)(&in);
505  b=(unsigned char*)(&out);
506 
507  b[1]=a[0];
508  b[0]=a[1];
509  return out;
510 }
511 //ewnd of the three old TCU functions
512 
513 
514 
515 /******************************************************
516  $Log: L2VirtualAlgo2012.cxx,v $
517  Revision 1.6 2012/12/19 17:25:18 jml
518  logging
519 
520  Revision 1.5 2012/03/21 18:18:03 jml
521  got rid of printfs from 2012 files
522 
523  Revision 1.4 2011/10/19 15:58:06 jml
524  more compile offline
525 
526  Revision 1.3 2011/10/19 15:39:42 jml
527  2012
528 
529  Revision 1.2 2011/10/19 14:34:23 jml
530  added fakeRtsLog.h to turn log statements into printfs
531 
532  Revision 1.1 2011/10/18 15:11:41 jml
533  adding 2012 algorithms
534 
535  Revision 1.6 2011/04/02 20:35:51 pibero
536  Initialize mRunNumber to -1
537 
538  Revision 1.5 2010/04/18 06:05:32 pibero
539  Address compiler warnings.
540 
541  Revision 1.4 2010/04/17 05:01:27 pibero
542  Updates for Run 9 jet tree production
543 
544  Revision 1.6 2008/01/30 21:56:40 balewski
545  E+B high-enery-filter L2-algo fuly functional
546 
547  Revision 1.5 2008/01/30 00:47:15 balewski
548  Added L2-Etow-calib
549 
550  Revision 1.4 2008/01/18 23:29:12 balewski
551  now L2result is exported
552 
553  Revision 1.3 2008/01/17 23:15:51 balewski
554  bug in token-addressed memory fixed
555 
556  Revision 1.2 2008/01/16 23:32:33 balewski
557  toward token dependent compute()
558 
559 
560 
561 */