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