00001 #include <string.h>
00002 #include <stdio.h>
00003 #include <cstdlib>
00004
00005 #ifdef IS_REAL_L2 //in l2-ana environment
00006 #include "rtsLog.h"
00007 #include "../L2algoUtil/L2Histo.h"
00008 #include "../L2algoUtil/L2EmcDb.h"
00009 #else //full path needed for cvs'd code
00010 #include "StTriggerUtilities/L2Emulator/L2algoUtil/L2Histo.h"
00011 #include "StTriggerUtilities/L2Emulator/L2algoUtil/L2EmcDb.h"
00012 #endif
00013
00014
00015
00016 #include "L2VirtualAlgo2009.h"
00017
00018 L2VirtualAlgo2009::L2VirtualAlgo2009(const char* name, L2EmcDb* db, char* outDir, bool needbarrel, bool needendcap, int resOff) : mDb(db) {
00019 algoIsOkay=true;
00020 mxHA=0;
00021 mName1=name;
00022 mOutDir1=outDir;
00023 mNeeds_barrel=needbarrel;
00024 mNeeds_endcap=needendcap;
00025 mRunNumber=-1;
00026 mResultOffset=resOff;
00027
00028
00029 mEveStream_btow=globL2eventStream2009.get_btow();
00030 mEveStream_etow=globL2eventStream2009.get_etow();
00031
00032 setOflTrigID(0);
00033 mhN =new L2Histo(900,"total events. 0=anyInput 10=anyAccept 11=normalAccept 12=rndAccept",19);
00034 mhTc=new L2Histo(901,"L2 COMPUTE time per input event; x: COMPUTE time (CPU kTics); y: events ",180);
00035 mhTd=new L2Histo(902,"L2 DECISION time per input event; x: DECISION time (CPU kTics); y: events ",36);
00036 mhTcd=new L2Histo(903,"L2 COMP+DECI time per input event; x: COMP+DECIS time (CPU kTics); y: events ",180);
00037
00038 int mxRunDration=2000;
00039 mhRc= new L2Histo(905,"rate of COMPUTE; x: time in this run (seconds); y: rate (Hz)", mxRunDration);
00040 mhRd= new L2Histo(906,"rate of DECISION; x: time in this run (seconds); y: rate (Hz)", mxRunDration);
00041 mhRa= new L2Histo(907,"rate of ACCEPT; x: time in this run (seconds); y: rate (Hz)", mxRunDration);
00042
00043
00044
00045
00046 if (!(L2eventStream2009::mxToken == L2eventStream2009::tokenMask+1))
00047 {
00048 char err[200];
00049 sprintf(err,"Algo %s has failed consistency check '(L2eventStream2009::mxToken == L2eventStream2009::tokenMask+1)'",name);
00050 criticalError(err);
00051 }
00052 }
00053
00054
00055
00056 int
00057 L2VirtualAlgo2009::initRun( int runNo, int *rc_ints, float *rc_floats) {
00058 if(!algoIsOkay)
00059 {
00060 char err[100];
00061 sprintf(err,"%s is flagged as broken. Aborting init.",getName());
00062 criticalError(err);
00063 return -999;
00064 }
00065
00066 useDsmMask=false;
00067
00068
00069 if(mDb->getRun()!=runNo) return -700;
00070
00071 if(mRunNumber==runNo) {
00072 if (mLogFile) fprintf(mLogFile,"#L2-%s::initRun(%d)=ghost already initilized, Abort run\n",getName(), runNo);
00073 return -701;
00074 }
00075
00076
00077 mhN->reset();
00078 mhTc->reset();
00079 mhTd->reset();
00080 mhTcd->reset();
00081 mhRc->reset();
00082 mhRd->reset();
00083 mhRa->reset();
00084
00085
00086 unsigned int high,low;
00087 rdtsc_macro(low,high);
00088 mRunStartTicks=high; mRunStartTicks <<= 32; mRunStartTicks += low;
00089
00090 mRunNumber =runNo;
00091 mEventsInRun=0;
00092
00093 char Fname[1000];
00094 sprintf(Fname,"%s/run%d.l2%s.log",mOutDir1.c_str(),mRunNumber,getName());
00095
00096
00097 mLogFile = fopen(Fname,"w");
00098 if( mLogFile==0) printf(" L2-%s() UNABLE to open run summary log file, continue anyhow\n",getName());
00099
00100
00101 par_RndAcceptPrescale=0;
00102 mRndAcceptCounter=0;
00103
00104 int kBad=initRunUser( runNo, rc_ints, rc_floats);
00105
00106
00107
00108 mRandomAccept=false;
00109
00110
00111
00112
00113
00114 if (par_RndAcceptPrescale<0) par_RndAcceptPrescale=0;
00115 if (par_RndAcceptPrescale>0)
00116 mRndAcceptCounter=rand()%par_RndAcceptPrescale;
00117
00118
00119 if (mLogFile) {
00120 fprintf(mLogFile,"#L2-%s initRun() params checked for consistency, Error flag=0x%04x\n",getName(),kBad);
00121 }
00122
00123 if(kBad<0) {
00124 if (mLogFile) {
00125 fprintf(mLogFile,"#L2-%s initRun() ABORT due to internal logic\n",getName());
00126 fclose(mLogFile);
00127 }
00128 mRunNumber=-55;
00129 return kBad;
00130 }
00131
00132 if (mLogFile) {
00133 fprintf(mLogFile,"#L2-%s random accept counter started at %d\n",getName(),mRndAcceptCounter);
00134 fprintf(mLogFile,"#L2-%s initRun successful\n",getName());
00135
00136 #ifdef ADD_HARDCODED_DELAY
00137 fprintf(mLogFile,"#WARN: HARDCODED_DELAY in compute() & decision() is ON\n");
00138 #endif
00139
00140 }
00141
00142
00143
00144 return kBad;
00145 }
00146
00147
00148
00149 void
00150 L2VirtualAlgo2009::finishRun() {
00151
00152 if(mRunNumber<0) return;
00153 if(mLogFile)fprintf(mLogFile,"#L2-%s: finishRun(%d) called after %d seconds\n",getName(),mRunNumber ,mSecondsInRun);
00154
00155
00156
00157 char Fname[1000];
00158 sprintf(Fname,"%s/run%d.l2%s.hist.bin",mOutDir1.c_str(),mRunNumber,getName());
00159
00160 mHistFile = fopen(Fname,"w");
00161
00162
00163 if( mHistFile==0) {
00164 printf(" L2-%s: finishRun() UNABLE to open run summary log file, continue anyhow\n",getName());
00165 if (mLogFile)
00166 fprintf(mLogFile,"#L2-%s histos NOT saved, I/O error\n",getName());
00167 } else {
00168 finishRunUser();
00169 if (mLogFile)
00170 mhN->printCSV(mLogFile);
00171 int nh=finishCommonHistos();
00172 if (mLogFile)
00173 fprintf(mLogFile,"#L2-%s: %d histos saved to '%s'\n",getName(),nh,Fname);
00174 }
00175
00176 if (mLogFile && useDsmMask)
00177 {
00178 fprintf(mLogFile,"#L2-%s: %d DSM masks are used.\n",getName(),nmasks);
00179 for (int i=0;i<nmasks;i++)
00180 fprintf(mLogFile,"# Mask %d: 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x\n",
00181 i,DsmMask[i][0],DsmMask[i][1],DsmMask[i][2],DsmMask[i][3],DsmMask[i][4],
00182 DsmMask[i][5],DsmMask[i][6],DsmMask[i][7]);
00183 }
00184 mRunNumber=-2;
00185 for (int i=0; i<mxHA;i++) if(hA[i])hA[i]->reset();
00186
00187 if (mLogFile) {
00188 fclose(mLogFile);
00189 mLogFile=0;
00190 }
00191
00192 if ( mHistFile) {
00193 fclose(mHistFile);
00194 mHistFile=0;
00195 }
00196 }
00197
00198
00199
00200 int
00201 L2VirtualAlgo2009::finishCommonHistos() {
00202 int j;
00203 int nh=0;
00204 for(j=0;j<mxHA;j++) {
00205 if(hA[j]==0) continue;
00206 hA[j]->write(mHistFile);
00207 nh++;
00208 }
00209 const int nHt=3;
00210 L2Histo *hT[nHt]={mhTc,mhTd,mhTcd};
00211 const char *text[nHt]={"Compute ","Decision ","Deci+Comp"};
00212 int ih;
00213 for(ih=0;ih<nHt;ih++) {
00214 int iMax=-3, iFWHM=-4;
00215 hT[ih]->findMax( &iMax, &iFWHM);
00216
00217
00218 if (mLogFile){
00219 fprintf(mLogFile,"#L2:%s %s CPU/eve MPV %d kTicks, FWHM=%d, seen eve=%d\n",getName(),text[ih],iMax, iFWHM,mEventsInRun);
00220
00221 }
00222 if (mHistFile) {hT[ih]->write(mHistFile); nh++;}
00223 }
00224 if (mHistFile) {
00225 mhN->write(mHistFile); nh++;
00226 mhRc->write(mHistFile);nh++;
00227 mhRd->write(mHistFile);nh++;
00228 mhRa->write(mHistFile);nh++;
00229 }
00230 return nh;
00231 }
00232
00233
00234
00235 L2VirtualAlgo2009::~L2VirtualAlgo2009(){};
00236
00237
00238 int
00239 L2VirtualAlgo2009::readParams(const char *fileN, int mxPar, int *iPar, float *fPar) {
00240
00241
00242
00243
00244
00245 memset(iPar,0,mxPar*sizeof(int));
00246 memset(fPar,0,mxPar*sizeof(int));
00247 FILE *fd=fopen(fileN,"r");
00248 if(fd==0) { printf(" L2VirtualAlgo2009::readParams failed to open =%s=\n",fileN); return -2222;}
00249
00250 int nVal=0;
00251 int nInt=0, nFloat=0;
00252
00253 const int mx=1000;
00254 char buf[mx];
00255 int mode=0;
00256
00257 for(;;) {
00258 char * ret=fgets(buf,mx,fd);
00259
00260 if(ret==0) break;
00261 if(buf[0]==0) continue;
00262 if(buf[0]=='#') continue;
00263 if(buf[0]=='\n') continue;
00264
00265 if (mode==0 && strstr(buf,"INTS")) { mode=1; continue; }
00266 if (mode==1 && strstr(buf,"FLOATS")) { mode=2; continue; }
00267
00268 if(mode==1) {
00269 if(nInt>=mxPar) {nVal=-501; break;}
00270 int ret1=sscanf(buf,"%i",iPar+nInt);
00271 if(ret1!=1) {nVal=-100*mode -nInt; break;}
00272 nInt++; nVal++;
00273 }
00274 else if(mode==2) {
00275 if(nFloat>=mxPar) {nVal=-502; break;}
00276 int ret1=sscanf(buf,"%f",fPar+nFloat);
00277 if(ret1!=1) {nVal= -100*mode -nFloat; break;}
00278 nFloat++; nVal++;
00279 }
00280
00281 }
00282
00283 fclose(fd);
00284 printf(" L2VirtualAlgo2009::readParams %d from '%s'\n",nVal,fileN);
00285 return nVal;
00286 }
00287
00288
00289
00290 void
00291 L2VirtualAlgo2009::compute(int token){
00292
00293 computeStart();
00294 mhN->fill(1);
00295 token&=L2eventStream2009::tokenMask;
00296
00297 #ifdef ADD_HARDCODED_DELAY
00298
00299
00300
00301 for(int i=0;i<3*100;i++) { float x=i*i; x=x;}
00302 #endif
00303
00304 computeUser( token );
00305 computeStop( token);
00306
00307 }
00308
00309
00310 void
00311 L2VirtualAlgo2009::computeStart(){
00312
00313
00314 unsigned int high,low;
00315 rdtsc_macro(low,high);
00316
00317 mComputeTimeStart=low;
00318 unsigned long long ticks = high;
00319 ticks <<= 32;
00320 ticks += low;
00321
00322
00323 mSecondsInRun=(ticks- mRunStartTicks)/par_cpuTicksPerSecond;
00324
00325 mhRc->fill(mSecondsInRun);
00326
00327 mAccept=true;
00328 mEventsInRun++;
00329
00330 mhN->fill(0);
00331 }
00332
00333
00334 void
00335 L2VirtualAlgo2009::computeStop(int token){
00336
00337 rdtscl_macro(mComputeTimeStop);
00338 unsigned long xxx=mComputeTimeStop-mComputeTimeStart;
00339 mComputeTimeDiff[token]=xxx;
00340 int kTick=xxx/1000;
00341
00342 mhTc->fill(kTick);
00343 }
00344
00345
00346
00347 bool
00348 L2VirtualAlgo2009::decision(int token, bool barrel_is_in, bool endcap_is_in, int *myL2Result){
00349
00350
00351
00352
00353
00354 rdtscl_macro(mDecisionTimeStart);
00355 token&=L2eventStream2009::tokenMask;
00356 mDecisionTimeDiff=0;
00357
00358 mhRd->fill(mSecondsInRun);
00359
00360 #ifdef ADD_HARDCODED_DELAY
00361
00362
00363
00364 for(int i=0;i<3*100;i++) { float x=i*i; x=x;}
00365 #endif
00366
00367 mhN->fill(2);
00368
00369 if (par_RndAcceptPrescale>0)
00370 {
00371 mRndAcceptCounter=(mRndAcceptCounter+1)%par_RndAcceptPrescale;
00372 mRandomAccept=(mRndAcceptCounter==0);
00373 }
00374
00375
00376 if ( (!endcap_is_in && mNeeds_endcap) || (!barrel_is_in && mNeeds_barrel) )
00377 {
00378 mAccept=0;
00379 }
00380 else
00381 {
00382 mAccept=decisionUser(token, myL2Result+mResultOffset);
00383 }
00384
00385
00386
00387 if(mAccept || mRandomAccept) {
00388 mhN->fill(10);
00389 mhRa->fill(mSecondsInRun);
00390 }
00391 if(mRandomAccept)
00392 mhN->fill(12);
00393 if(mAccept)
00394 mhN->fill(11);
00395
00396
00397 rdtscl_macro(mDecisionTimeStop);
00398 mDecisionTimeDiff=mDecisionTimeStop-mDecisionTimeStart;
00399 int kTick=mDecisionTimeDiff/1000;
00400
00401
00402 mhTd->fill(kTick);
00403 kTick=(mDecisionTimeDiff+mComputeTimeDiff[token])/1000;
00404 mhTcd->fill(kTick);
00405 return (mAccept || mRandomAccept);
00406 }
00407
00408
00409
00410
00411
00412 void
00413 L2VirtualAlgo2009::printCalibratedData(int token){
00414
00415 int i;
00416 const int hitSize=mEveStream_btow[token].get_hitSize();
00417 printf("printCalibratedData-%s: ---BTOW ADC list--- size=%d\n",getName(),hitSize);
00418 const HitTower1 *hit=mEveStream_btow[token].get_hits();
00419 for(i=0;i< hitSize;i++,hit++) {
00420 int adc=hit->adc;
00421 int rdo=hit->rdo;
00422 float et=hit->et;
00423 float ene=hit->ene;
00424 printf(" btow: i=%2d rdo=%4d adc=%d et=%.3f ene=%.3f\n",i,rdo,adc,et,ene);
00425 }
00426 }
00427
00428
00429
00430
00431 void
00432 L2VirtualAlgo2009::criticalError(const char* message){
00433 algoIsOkay=false;
00434 #ifdef IS_REAL_L2
00435 LOG(CRIT,"%s",message,0,0,0,0);
00436 #else
00437 printf("CRITICAL MESSAGE: %s\n",message);
00438
00439 #endif
00440 return;
00441 }
00442
00443
00444
00445 bool L2VirtualAlgo2009::checkDsmMask(unsigned short *lastDSM)
00446 {
00447
00448
00449 if (!useDsmMask) return 1;
00450
00451 if (nmasks==0) return 1;
00452
00453
00454 bool isGood;
00455 for (int i=0;i<nmasks;i++)
00456 {
00457 isGood=true;
00458 for (int j=0;j<8 && isGood;j++)
00459 {
00460
00461
00462 if((swap_bytes(lastDSM[j]) & DsmMask[i][j]) != DsmMask[i][j]) isGood=false;
00463 }
00464 if (isGood) return 1;
00465 }
00466
00467 return 0;
00468 }
00469
00470 int L2VirtualAlgo2009::readDsmMask(const char *fileN)
00471 {
00472 for (int i=0;i<kMaximumNumberOfDsmMasks;i++)
00473 for (int j=0;j<8;j++)
00474 DsmMask[i][j]=0;
00475
00476 FILE *fd=fopen(fileN,"r");
00477 if(fd==0) {
00478 printf(" L2VirtualAlgo2009::readDsmMask failed to open =%s=. Assuming no mask.\n",fileN);
00479 return 0;
00480 useDsmMask=false;
00481 }
00482
00483 int n=0;
00484 nmasks=0;
00485
00486 const int mx=1000;
00487 char buf[mx];
00488
00489 for(;;) {
00490 char * ret=fgets(buf,mx,fd);
00491
00492 if(ret==0) break;
00493 if(buf[0]==0) continue;
00494 if(buf[0]=='#') continue;
00495 if(buf[0]=='\n') continue;
00496 if(nmasks>=kMaximumNumberOfDsmMasks) {printf(" L2VirtualAlgo2009::readDsmMask: Too many masks %s.\n",fileN); return -3333;}
00497 int ret1=sscanf(buf,"%hu",&(DsmMask[nmasks][n%8]));
00498 if(ret1!=1) {printf(" L2VirtualAlgo2009::readDsmMask: Problem reading %s.\n",fileN); return -4444;}
00499 n++;
00500 if (n%8==0) nmasks++;
00501 }
00502 fclose(fd);
00503 if (n%8!=0){printf(" L2VirtualAlgo2009::readDsmMask: Wrong number of arguments in %s (n=%d).\n",fileN,n); return -3333;}
00504 useDsmMask=true;
00505 return 0;
00506 }
00507
00508 unsigned short L2VirtualAlgo2009::swap_bytes(unsigned short in)
00509 {
00510 unsigned short out=0;
00511 unsigned char *a, *b;
00512
00513 a=(unsigned char*)(&in);
00514 b=(unsigned char*)(&out);
00515
00516 b[1]=a[0];
00517 b[0]=a[1];
00518 return out;
00519 }
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552