StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
L2jetAlgo2006.cxx
1 #include <stdio.h>
2 #include <assert.h>
3 #include <string.h>
4 #include <stdlib.h>
5 #include <time.h>
6 #include <math.h>
7 
8 /*********************************************************************
9  * $Id: L2jetAlgo2006.cxx,v 1.2 2009/11/19 15:48:45 balewski Exp $
10  * \author Jan Balewski, IUCF, 2006
11  *********************************************************************
12  * Descripion:
13  Reco of mono- & di-jets in L2 using BTOW+ETOW
14  depends on L2-DB class
15  *********************************************************************
16  */
17 
18 
19 
20 #ifdef IS_REAL_L2 //in l2-ana environment
21  #include "../L2algoUtil/L2EmcDb.h"
22  #include "../L2algoUtil/L2Histo.h"
23 #else
24  #include "StTriggerUtilities/L2Emulator/L2algoUtil/L2EmcDb.h"
25  #include "StTriggerUtilities/L2Emulator/L2algoUtil/L2Histo.h"
26 #endif
27 
28 #include "L2jetAlgo2006.h"
29 #include "L2jetResults2006.h" // note, there may be another copy of it in ofl-CVS - do not mix them up, JB
30 #include "Map_DeltaPhiJets.h"
31 
32 //=================================================
33 //=================================================
34 L2jetAlgo2006::L2jetAlgo2006(const char* name, L2EmcDb* db, char* outDir, int resOff)
35  : L2VirtualAlgo( name, db, outDir, resOff) {
36  /* called one per days
37  all memory allocation must be done here
38  */
39  par_maxADC=4095;
40  par_maxEt=60;
41  par_adcMask= (unsigned short) (-0x10); // to clear 4 LSF bits
42  par_pedOff=0x10/2; //WARN, must match 'par_adcMask'
43  createHisto();
44  run_number=-1;
45  printf("L2jetAlgo2006 instantiated, logPath='%s'\n",mOutDir);
46  eve_Jet[0]=new L2Jet;
47  eve_Jet[1]=new L2Jet;
48 }
49 
50 /*========================================
51  ======================================== */
52 bool
53 L2jetAlgo2006::paramsChanged( int *rc_ints, float *rc_floats) {
54  int i;
55  for(i=0;i<5;i++)
56  if(rc_ints[i]!=raw_ints[i]) goto foundProblem;
57 
58  for(i=0;i<5;i++)
59  if(fabs(rc_floats[i]-raw_floats[i])>0.00001) goto foundProblem;
60 
61  return false;
62 
63  foundProblem:
64  if (mLogFile) fprintf(mLogFile,"L2jet-ghost initRun - inconsistent params, ABORT initialization\n");
65  return true;
66 }
67 
68 /*========================================
69  ======================================== */
70 int
71 L2jetAlgo2006::initRun( int runNo, int *rc_ints, float *rc_floats) {
72 
73  // update DB if run # has changed
74  if(mDb->initRun(runNo)) return -7;
75  // DB must be initialized prior to lookup tables
76 
77  if(run_number==runNo) {
78  if (mLogFile) fprintf(mLogFile,"L2jet::initRun-%s(%d)=ghost already initilized, only check params\n",mName, runNo);
79  printf("L2jet::initRun-%s(%d)=ghost already initilized, only checking params\n",mName, runNo);
80  int ret= paramsChanged(rc_ints, rc_floats);
81  // 0=ok, 1=fatal problem
82  if(ret){
83  run_number=-77;
84  if (mLogFile) {
85  fprintf(mLogFile,"L2jet algorithm init: crashA in internal logic\n");
86  fclose(mLogFile);
87  }
88  return ret;
89  }
90  }
91 
92  // clear content of all histograms
93  int i;
94  for (i=0; i<mxHA;i++) if(hA[i])hA[i]->reset();
95 
96  /* .... clear content, set threshold @ max as default */
97  memset(db_btowThr, 0xFFFF,sizeof(db_btowThr));
98  memset(db_btowPedS, 0, sizeof(db_btowPedS));
99  memset(db_btowGainCorr, 0, sizeof(db_btowGainCorr));
100  memset(db_btowL2PhiBin, 0, sizeof(db_btowL2PhiBin));
101  memset(db_btowL2PatchBin,0, sizeof(db_btowL2PatchBin));
102 
103  memset(db_etowThr, 0xFFFF,sizeof(db_etowThr));
104  memset(db_etowPedS, 0 ,sizeof(db_etowPedS));
105  memset(db_etowGainCorr, 0 ,sizeof(db_etowGainCorr));
106  memset(db_etowL2PhiBin, 0 ,sizeof(db_etowL2PhiBin));
107  memset(db_etowL2PatchBin,0 ,sizeof(db_etowL2PatchBin));
108 
109  /* gain correction factor is mapped to 6 bits,
110  range: [5,60]
111  WARN: do NOT change 3 params below w/o understaning of
112  projection algo,JB
113  */
114 
115  int par_IgainCorrOne=30;
116  int par_IgainCorrMin=5;
117  int par_IgainCorrMax=60;
118 
119  run_startUnix=time(0);
120  run_number =runNo; // serves as a flag this run is initialized
121  raw_ints =rc_ints;
122  raw_floats =rc_floats;
123  run_nEventOneJet=run_nEventDiJet= run_nEventRnd=0;
124 
125  char Fname[1000];
126  sprintf(Fname,"%s/run%d.l2jet.out",mOutDir,run_number);
127  printf("L2jet::initRun-%s('%s') ...\n",mName,Fname);
128 
129  mEventsInRun=0;
130  mLogFile = fopen(Fname,"w");
131  if( mLogFile==0) printf(" L2jetAlgo2006() UNABLE to open run summary log file, continue anyhow\n");
132  // mLogFile = stdout; //tmp
133 
134  // unpack params from run control GUI
135  par_cutTag = rc_ints[0];
136  par_useBtowEast= (rc_ints[1]&1 )>0;
137  par_useBtowWest= (rc_ints[1]&2)>0;
138  par_useEndcap = rc_ints[2]&1;
139  int par_adcThr = rc_ints[3]; // needed only in initRun()
140  par_minPhiBinDiff=rc_ints[4];
141 
142  par_oneJetThr = rc_floats[0];
143  par_diJetThrHigh= rc_floats[1];
144  par_diJetThrLow = rc_floats[2];
145  par_rndAccProb = rc_floats[3];
146  par_dbg =(int)rc_floats[4];
147 
148  // set other hardcoded or calculated params
149  par_energyScale=par_maxADC*par_IgainCorrOne/par_maxEt;
150  // to monitor hot towers in E+B Emc
151  float monTwEtThr=2.0; // (GeV) Et threshold,WARN, edit histo title by hand
152  par_hotTwEtThr= (int)(monTwEtThr*par_energyScale); // now it is integer4 energy
153  // thres for rnd accept
154  par_rndAccThr= int(par_rndAccProb* RAND_MAX);
155  if(par_rndAccProb<0) {
156  par_rndAccThr=0;
157  par_rndAccProb=0.;
158  } else if (par_rndAccProb>0.9999) {
159  par_rndAccThr=RAND_MAX;
160  par_rndAccProb=1.0;
161  }
162  if (mLogFile) {
163  fprintf(mLogFile,"L2jet algorithm initRun(%d), compiled: %s , %s\n params:\n",run_number,__DATE__,__TIME__);
164  fprintf(mLogFile," - use BTOW: East=%d West=%d, Endcap=%d L2ResOffset=%d\n", par_useBtowEast, par_useBtowWest,par_useEndcap ,mResultOffset);
165  fprintf(mLogFile," - threshold: ADC-ped> %d \n", par_adcThr);
166  fprintf(mLogFile," - min phi opening angle Jet1<->Jet2: %d in L2phiBins\n",par_minPhiBinDiff);
167  fprintf(mLogFile," - diJet Et thrHigh= %.2f (GeV) thrLow= %.2f (GeV)\n", par_diJetThrHigh, par_diJetThrLow);
168  fprintf(mLogFile," - oneJet Et thr = %.2f (GeV) ; rndAccProb=%f; cutTag=%d \n",par_oneJetThr,par_rndAccProb,par_cutTag);
169  fprintf(mLogFile," - debug=%d, hot tower threshold: Et> %.1f GeV ( only monitoring)\n",par_dbg, monTwEtThr);
170  }
171 
172  // verify consistency of input params
173  int kBad=0;
174  kBad+=0x0001 * ( !par_useBtowEast & !par_useBtowWest & !par_useEndcap);
175  kBad+=0x0002 * (par_adcThr<par_pedOff);
176  kBad+=0x0004 * (par_adcThr>16);
177  kBad+=0x0008 * (par_minPhiBinDiff<5);
178  kBad+=0x0010 * (par_minPhiBinDiff>=15);
179  kBad+=0x0020 * (par_oneJetThr<3.);
180  kBad+=0x0040 * (par_oneJetThr>12.);
181  kBad+=0x0080 * (par_diJetThrLow<2.9);
182  kBad+=0x0100 * (par_diJetThrHigh<par_diJetThrLow);
183  kBad+=0x0200 * (par_diJetThrHigh>12.);
184  kBad+=0x0400 * (par_cutTag<=0 || par_cutTag>255);
185  kBad+=0x0800 * (par_rndAccProb<0. || par_rndAccProb>1.);
186  if (mLogFile) {
187  fprintf(mLogFile,"L2jet initRun() params checked for consistency, Error flag=0x%04x\n",kBad);
188  if(kBad) fprintf(mLogFile,"L2jet initRun() ABORT\n");
189  }
190 
191  if(kBad) {
192  run_number=-66;
193  if (mLogFile) {
194  fprintf(mLogFile,"L2jet algorithm init: crashB in internal logic\n");
195  fclose(mLogFile);
196  return kBad;
197  }
198  }
199 
200  char tit[100];
201  sprintf(tit,"# BTOW towers>ped+%d (input); x: # of towers/event",par_adcThr);
202  hA[47]->setTitle(tit);
203 
204  sprintf(tit,"# ETOW towers>ped+%d (input); x: # of towers/event",par_adcThr);
205  hA[48]->setTitle(tit);
206 
207  /* const float eta[mxEta]={1.95,1.855,1.765,1.675,1.59,1.51,1.435,1.365,1.3,1.235,1.17,1.115}; */
208 
209  /* the first 13 entries mark the bounds of the 12 eta Bins. 14th value is not used */
210  const float edgeEtaBinEtow[] = {
211  2.0 ,
212  1.9008 , 1.8065 , 1.7168 , 1.6317 , 1.5507 , 1.4738 ,
213  1.4007 , 1.3312 , 1.2651 , 1.2023 , 1.1427 , 1.086 ,
214  0.0
215  };
216 
217  const int mxEtaBinsE=12,mxEtaBinsB=40;
218  float idealGainEtow[mxEtaBinsE], idealGainBtow[mxEtaBinsB];
219  float coshEtow[mxEtaBinsE],coshBtow[mxEtaBinsB];
220 
221  for(i=0;i<mxEtaBinsE;i++ ){
222  float avrEta=(edgeEtaBinEtow[i]+edgeEtaBinEtow[i+1])/2.;
223  coshEtow[i]=cosh(avrEta);
224  idealGainEtow[i]=par_maxADC/par_maxEt/coshEtow[i];
225  // if (mLogFile && i%4==0) fprintf(mLogFile,"aim: ETow iEtaBin=%d eta=%.3f idealG=%.2f (GeV E_T), cosH=%.3f\n",i,avrEta, idealGainEtow[i], coshEtow[i]);
226  }
227 
228 
229  for(i=0;i<mxEtaBinsB;i++ ){
230  float avrEta=-0.975 +i*0.05; /* assume BTOW has fixed eta bin size */
231  coshBtow[i]=cosh(avrEta);
232  idealGainBtow[i]=par_maxADC/par_maxEt/coshBtow[i];
233  // if (mLogFile && i%4==0) fprintf(mLogFile,"aim: Btow iEtaBin=%2d eta=%.3f idealG=%.2f (GeV E_T), cosH=%.3f\n",i,avrEta, idealGainBtow[i], coshBtow[i]);
234  }
235 
236 
237  // rebuild local lookup tables
238 
239  int etowEtaBin2Patch[mxEtaBinsE]={14,14,13,13,12,12,11,11,11,10,10,10};
240 
241  int nB=0, nE=0; /* counts # of unmasekd towers */
242  int nBg=0, nEg=0; /* counts # of reasonable calibrated towers */
243 
244  for(i=0; i<EmcDbIndexMax; i++) {
245  const L2EmcDb::EmcCDbItem *x=mDb->getByIndex(i);
246  if(mDb->isEmpty(x)) continue; /* dropped not mapped channels */
247  if(x->fail) continue; /* dropped masked channels */
248  if(x->gain<=0) continue; /* dropped uncalibrated towers , tmp */
249  /* if(x->sec!=1) continue; tmp, to test patch mapping */
250 
251  /* WARN, calculate index to match RDO order in the ADC data banks */
252  int ietaP, iphiP;
253  if (mDb->isBTOW(x) ) {
254  /*....... B A R R E L .................*/
255  nB++;
256  if(x->eta<0 || x->eta>mxEtaBinsB) goto crashIt_1;
257  if(!par_useBtowEast && x->eta<=20) continue;
258  if(!par_useBtowWest && x->eta>=21) continue;
259  ietaP= (x->eta-1)/4; /* correct */
260  int iphiTw=(x->sec-1)*10 + x->sub-'a';
261  // allign in phi TP @ L2 w/ L0
262  iphiTw--;
263  if(iphiTw<0) iphiTw=119;
264  // now cr0x1e, mod1, subm2, is beginning of the first BTOW TP
265  iphiP= iphiTw/4 ; /* correct */
266  // if(ietaP==0 && iphiP==5)
267  //if( (iphiTw==21 || iphiTw==22) && x->eta<=4) printf("%s %s ietaP=%d iPhiP=%d cr0x%02x ch=%03d\n",x->name, x->tube,ietaP, iphiP,x->crate,x->chan);
268  int IgainCor=int(par_IgainCorrOne*idealGainBtow[x->eta-1]/x->gain);
269  //printf("%s IgainCor=%d\n",x->name,IgainCor);
270  /* gain outliers ignored */
271  if(IgainCor <par_IgainCorrMin) continue;
272  if(IgainCor >par_IgainCorrMax) continue;
273  db_btowGainCorr[x->rdo]=IgainCor;
274 
275  db_btowL2PhiBin[x->rdo]=iphiP;
276  db_btowL2PatchBin[x->rdo]=ietaP+ iphiP*cl2jetMaxEtaBins;
277  db_btowThr[x->rdo]=(int) (x->ped+par_adcThr);
278  db_btowPedS[x->rdo]=(unsigned short) (par_pedOff-x->ped);
279  nBg++;
280  } else if(mDb->isETOW(x) && par_useEndcap) {
281  /*....... E N D C A P ........................*/
282  nE++;
283  int iphiTw= (x->sec-1)*5 + x->sub-'A';
284  // allign in phi TP @ L2 w/ L0
285  iphiTw--;
286  if(iphiTw<0) iphiTw=59;
287  // now subsector 01TB is beginning of the first(==0) ETOW TP in phi
288  iphiP= iphiTw/2 ; /* correct */
289  if(x->eta<0 || x->eta>mxEtaBinsE) goto crashIt_1;
290  ietaP=etowEtaBin2Patch[x->eta-1];
291  //printf("%s %s ietaP=%d iPhiP=%d\n",x->name, x->tube,ietaP, iphiP);
292  int IgainCor=int(par_IgainCorrOne*idealGainEtow[x->eta-1]/x->gain);
293  // printf("%s IgainCor=%d\n",x->name,IgainCor);
294  /* gain outliers ignored */
295  if(IgainCor <par_IgainCorrMin) continue;
296  if(IgainCor >par_IgainCorrMax) continue;
297  db_etowGainCorr[x->rdo]=IgainCor;
298 
299  db_etowL2PhiBin[x->rdo]=iphiP;
300  db_etowL2PatchBin[x->rdo]=ietaP+ iphiP*cl2jetMaxEtaBins;
301  db_etowThr[x->rdo]=(int) (x->ped+par_adcThr);
302  db_etowPedS[x->rdo]=(unsigned short) (par_pedOff-x->ped);
303  nEg++;
304  }
305 
306  }
307 
308  if (mLogFile) {
309  fprintf(mLogFile,"L2jet algorithm: found working/calibrated: %d/%d=ETOW & %d/%d=BTOW, based on ASCII DB\n",nE,nEg,nB,nBg);
310  }
311 
312  return 0; //OK
313 
314  crashIt_1: /* fatal initialization error */
315  run_number=-55;
316  if (mLogFile) {
317  fprintf(mLogFile,"L2jet algorithm init: crashC in internal logic\n");
318  fclose(mLogFile);
319  }
320  return -6;
321 
322 }
323 
324 
325 /*========================================
326  ======================================== */
327 bool
328 L2jetAlgo2006::doEvent(int L0trg, int inpEveId, TrgDataType* trgData,
329  int bemcIn, unsigned short *bemcData,
330  int eemcIn, unsigned short *eemcData){
331  /* STRICT TIME BUDGET START ....*/
332  rdtscl_macro(mEveTimeStart);
333 
334  if(L0trg==1) hA[10]->fill(1);
335  else if(L0trg==2) hA[10]->fill(2);
336 
337  if(eve_ID!=inpEveId) {//UUUU
338  //.................... this event has NOT been processed
339 
340  /*
341  Chris doesn't want us to write anything out
342  during event processing ...
343  */
344 
345  eve_ID=inpEveId; // every events is processed only once
346  mEventsInRun++;
347  clearEvent(); /* price=13 kTicks */
348  int runTimeSec=time(0)- run_startUnix;
349  hA[10]->fill(0);
350  hA[12]->fill(runTimeSec);
351 
352  if(par_dbg>1) printf("\n......... in L2Jet_doEvent(ID=%d)... bIn=%d eIn=%d\n",eve_ID,bemcIn,eemcIn);
353 
354  if (bemcIn || eemcIn){//VVVV this algo has nothing to do w/o any Ecal data
355 
356  eve_TrigData=(TrgDataType* )trgData; /* internal copy of the pointer */
357 
358 
359  //===== step 1: unpack raw data blocks ==============
360 
361  int nBtowTw=0, nEtowTw=0;
362  /*......... BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB */
363  if(bemcIn==1 && (par_useBtowEast||par_useBtowWest) ) {
364  nBtowTw=projectAdc( bemcData, MaxBtowRdo,
365  db_btowThr, db_btowPedS, db_btowGainCorr,
366  db_btowL2PhiBin, db_btowL2PatchBin,
367  hA[20] );
368  }
369 
370  /*........... EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE */
371  if(eemcIn==1 && par_useEndcap ) {
372  nEtowTw=projectAdc( eemcData, 720,
373  db_etowThr, db_etowPedS, db_etowGainCorr,
374  db_etowL2PhiBin, db_etowL2PatchBin,
375  hA[30] );
376  }
377 
378  //===== step 2: scan phi projection of the whole ECAL for two peaks===
379  // total transverse energy in the whole calorimeter
380  int itotEne=scanPhi();
381  float totEneGeV=itotEne/par_energyScale;
382  int itotEneGeV=(int)totEneGeV;
383 
384  //===== step 3 : scan two eta projections for peak in phi ===
385  int iJ;
386  for(iJ=0; iJ< mxJ; iJ++) {
387  scanEta(iJ); // find eta location
388  weightedPhi(iJ); // find weighted phi
389  // auxiliary calculations
390  L2Jet *J=eve_Jet[iJ];
391  J->eneGeV=J->iene/par_energyScale;
392  J->phiRad=0.21*(6.0-J->fphiBin); // by construction can't exceed 1.3
393  // assert range
394  // this should be done by the lookup table , ok for now
395  while(J->phiRad<0) J->phiRad+=6.2832;
396  while(J->phiRad>6.2832) J->phiRad-=6.2832;
397  }
398 
399  if(eve_Jet[0]->eneGeV <eve_Jet[1]->eneGeV) {// swap jets fo E1>E2
400  L2Jet *Jx=eve_Jet[0];
401  eve_Jet[0]=eve_Jet[1];
402  eve_Jet[1]=Jx;
403  }
404 
405  if(par_dbg>2) printf("doEvent iphiBin1=%d iene1=%d , iphiBin2=%d iene2=%d\n",eve_Jet[0]->iphiBin,eve_Jet[0]->iene,eve_Jet[1]->iphiBin,eve_Jet[1]->iene);
406 
407  //====== step 4: make trigger decisions====
408  bool acceptDiJet=( eve_Jet[0]->eneGeV > par_diJetThrHigh) && ( eve_Jet[1]->eneGeV > par_diJetThrLow);
409  bool acceptOneJet=( eve_Jet[0]->eneGeV> par_oneJetThr) ;
410 
411  bool acceptRnd=rand()< par_rndAccThr;
412  mAccept=acceptDiJet || acceptOneJet || acceptRnd;
413 
414  //====== step 5: update various monitorig histos
415 
416  // histogramming reco Et1-Et2, no cuts
417  int iet1 =(int)eve_Jet[0]->eneGeV;
418  int iet2 =(int)eve_Jet[1]->eneGeV;
419  int ieta1=(int)eve_Jet[0]->fetaBin;
420  int ieta2=(int)eve_Jet[1]->fetaBin;
421  int iphi1=(int)eve_Jet[0]->fphiBin;
422  int iphi2=(int)eve_Jet[1]->fphiBin;
423 
424  hA[40]->fill(iet1,iet2);
425 
426  hA[41]->fill(ieta1,iphi1);
427  hA[42]->fill(ieta2,iphi2);
428  hA[43]->fill(iphi1,iphi2);
429  hA[44]->fill(iet1);
430  hA[45]->fill(iet2);
431  hA[46]->fill(itotEneGeV);
432  hA[47]->fill(nBtowTw);
433  hA[48]->fill(nEtowTw);
434 
435  // sivers delta zeta, the map is still worng
436  int kphi1=int(eve_Jet[0]->phiRad*10.);
437  int kphi2=int(eve_Jet[1]->phiRad*10.);
438  int idelZeta=map_DelPhiJets[kphi1*MxPhiRad10 + kphi2];
439 
440  if( mAccept) hA[10]->fill(8);
441 
442  if(acceptOneJet ){
443  hA[10]->fill(4);
444  run_nEventOneJet++;
445  hA[13]->fill(runTimeSec);
446  hA[50]->fill(iet1);
447  hA[51]->fill(ieta1,iphi1);
448  hA[52]->fill(ieta1);
449  hA[53]->fill(iphi1);
450  }
451 
452  if(acceptDiJet ){
453  hA[10]->fill(5);
454  run_nEventDiJet++;
455  hA[14]->fill(runTimeSec);
456  hA[60]->fill(iet1,iet2);
457  hA[61]->fill(ieta1,iphi1);
458  hA[62]->fill(ieta2,iphi2);
459  hA[63]->fill(iphi1,iphi2);
460  hA[64]->fill(iet1);
461  hA[65]->fill(iet2);
462  hA[66]->fill(ieta1);
463  hA[67]->fill(ieta2);
464  hA[68]->fill(iphi1);
465  hA[69]->fill(iphi2);
466  hA[70]->fill(idelZeta);
467  hA[71]->fill(ieta1,idelZeta);
468  hA[72]->fill(ieta1,ieta2);
469  hA[73]->fill((iphi1+iphi2)/2,idelZeta);
470  hA[74]->fill(itotEneGeV);
471  }
472  if(acceptRnd ){
473  hA[10]->fill(6);
474  run_nEventRnd++;
475  hA[15]->fill(runTimeSec);
476  }
477 
478 
479  //====== step 6: fill L2Result (except time)
480  L2jetResults2006 out; // all output bits lump together
481  memset(&out,0,sizeof(out)); // clear content
482 
483  out.int0.version=L2JET_RESULTS_VERSION;
484  out.int0.decision=
485  ( par_useBtowEast <<0 ) +
486  ( par_useBtowWest <<1 ) +
487  ( par_useEndcap <<2 ) +
488  ( (bemcIn>0) <<3 ) +
489  ( (eemcIn>0) <<4 ) +
490  ( acceptRnd <<5 ) +
491  ( acceptOneJet <<6 ) +
492  ( acceptDiJet <<7 ) ;
493  out.int0.cutTag=par_cutTag;
494 
495  out.int1.iTotEne=(unsigned short)(totEneGeV*100.); // now 1=10 MeV
496  out.int2.nBtowTw=nBtowTw;
497  out.int2.nEtowTw=nEtowTw;
498 
499  out.jet1.jPhi=(int)(eve_Jet[0]->phiRad*28.65); //so phi/deg=2*jPhi
500  out.jet1.jEta=(int)(eve_Jet[0]->fetaBin*10.);
501  out.jet1.iEne=(unsigned short)(eve_Jet[0]->eneGeV*100.); // now 1=10 MeV
502 
503  out.jet2.jPhi=(int)(eve_Jet[1]->phiRad*28.65);
504  out.jet2.jEta=(int)(eve_Jet[1]->fetaBin*10.);
505  out.jet2.iEne=(unsigned short)(eve_Jet[1]->eneGeV*100.); // now 1=10 MeV
506 
507  rdtscl_macro(mEveTimeStop);
508  mEveTimeDiff=mEveTimeStop-mEveTimeStart;
509  int kTick=mEveTimeDiff/1000;
510  // printf("jj=%f t1=%d t2=%d \n",mEveTimeDiff/1000.,mEveTimeStart,mEveTimeStop);
511  mhT->fill(kTick);
512 
513  out.int0.kTick= kTick>255 ? 255 : kTick;
514 
515  //calculate and match the check sum
516  out.int1.checkSum=-L2jetResults2006_doCheckSum(&out);
517  // unsigned char cSum=L2jetResults2006_doCheckSum(&out); printf("cSum2=%d\n",cSum);
518 
519  //===== step 7: write L2Result
520  unsigned int *outPlace=eve_TrigData->TrgSum.L2Result+mResultOffset;
521  memcpy(outPlace,&out,sizeof( L2jetResults2006));
522 
523  // dirty tests, clean it up before real use
524 
525  if(par_dbg){//WWWW
526  L2jetResults2006_print(&out);
527  printf(" phiRad1=%f phiRad2=%f \n",eve_Jet[0]->phiRad,eve_Jet[1]->phiRad);
528  printf("idelZeta=%d delZeta/deg=%.1f \n\n",idelZeta,idelZeta/31.416*180);
529 
530 
531  //tmp printouts of errors:
532  if( out.jet1.iEne+out.jet2.iEne > out.int1.iTotEne) {
533  printf("L2jet-fatal error, eve=%d, iEtot=%d < iEJ1=%d + iEJ2=%d, continue\n",inpEveId, out.int1.iTotEne,out.jet1.iEne,out.jet2.iEne);
534  }
535  if(iphi1==iphi2) {
536  printf("L2jet-fatal error,neveId=%d, phi1,2=%d,%d\n",mEventsInRun,iphi1,iphi2);
537  dumpPatchEneA();
538  }
539 
540  if( L2jetResults2006_doCheckSum(&out)) {
541  printf("L2jet-fatal error, wrong cSum=%d\n", L2jetResults2006_doCheckSum(&out));
542  L2jetResults2006_print(&out);
543  }
544  } // end of WWWW
545  }// end of VVVV (etow or btow has some data)
546  }// end of UUUU event processing
547 
548 
549  return mAccept;
550 }
551 
552 
553 /*========================================
554  ======================================== */
555 void
556 L2jetAlgo2006::finishRun() { /* called once at the end of the run */
557  if(run_number<0) return; // already finished
558  // save run summary histos
559  char Fname[1000];
560  sprintf(Fname,"%s/run%d.l2jet.hist.bin",mOutDir,run_number);
561  printf("L2jet::finishRun('%s') , save histo ...\n",Fname);
562  mHistFile = fopen(Fname,"w");
563 
564  if (mLogFile) {
565  fprintf(mLogFile,"L2-jet algorithm finishRun(%d)\n",run_number);
566  fprintf(mLogFile," - %d events seen by L2 di-jet\n",mEventsInRun);
567  fprintf(mLogFile," - accepted: rnd=%d oneJet=%d diJet=%d \n", run_nEventRnd, run_nEventOneJet, run_nEventDiJet);
568 
569  // print few basic histos
570 
571  hA[10]->printCSV(mLogFile); // event accumulated
572 
573  }
574  finishRunHisto(); // still needs current DB
575 
576  if( mHistFile==0) {
577  printf(" L2jetAlgo2006: finishRun() UNABLE to open run summary log file, continue anyhow\n");
578  if (mLogFile)
579  fprintf(mLogFile,"L2 di-jet histos NOT saved, I/O error\n");
580  } else { // save histos
581  int j;
582  int nh=0;
583  for(j=0;j<mxHA;j++) {
584  if(hA[j]==0) continue;
585  hA[j]->write(mHistFile);
586  nh++;
587  }
588  finishCommonHistos();
589  fclose(mHistFile);
590  mHistFile=0;
591  if (mLogFile)
592  fprintf(mLogFile,"L2 di-jet: %d histos saved to '%s'\n",nh,Fname);
593  }
594 
595  run_number=-2; // clear run #
596 
597  /* close the output file if it is open */
598  if (mLogFile && mLogFile!=stdout) {
599  fclose(mLogFile);
600  mLogFile=0;
601  }
602 
603 }
604 
605 
606 //=======================================
607 //=======================================
608 void
609 L2jetAlgo2006::createHisto() {
610  memset(hA,0,sizeof(hA));
611 
612  hA[10]=new L2Histo(10, (char*)"total event counter; x=cases",9);
613  hA[11]=new L2Histo(11, (char*)"L2 time used per input event; x: time (CPU kTics), range=100muSec; y: events ",160);
614 
615  int mxRunDration=2500;
616  hA[12]=new L2Histo(12, (char*)"rate of input events; x: time in this run (seconds); y: rate (Hz)", mxRunDration);
617 
618  hA[13]=new L2Histo(13, (char*)"rate of accepted one-Jet; x: time in this run (seconds); y: rate (Hz)", mxRunDration);
619  hA[14]=new L2Histo(14, (char*)"rate of accepted di-Jet ; x: time in this run (seconds); y: rate (Hz)", mxRunDration);
620  hA[15]=new L2Histo(15, (char*)"rate of random accepted ; x: time in this run (seconds); y: rate (Hz)", mxRunDration);
621 
622  // BTOW raw spectra
623  hA[20]=new L2Histo(20, (char*)"BTOW tower, Et>2.0 GeV (input); x: BTOW RDO index=chan*30+fiber; y: counts", 4800);
624  hA[21]=new L2Histo(21, (char*)"BTOW tower, Et>2.0 GeV (input); x: BTOW softID", 4800);
625  hA[22]=new L2Histo(22, (char*)"BTOW tower, Et>2.0 GeV (input); x: eta bin, [-1,+1]; y: phi bin ~sector",40,120);
626 
627  // ETOW raw spectra
628  hA[30]=new L2Histo(30, (char*)"ETOW tower, Et>2.0 GeV (input); x: ETOW RDO index=chan*6+fiber; y: counts", 720 );
629  hA[31]=new L2Histo(31, (char*)"ETOW tower, Et>2.0 GeV (input); x: i=chan+128*crate", 768);
630  hA[32]=new L2Histo(32, (char*)"ETOW tower, Et>2.0 GeV (input); x: 12 - Endcap etaBin ,[+1,+2]; y: phi bin ~sector",12,60);
631 
632  // Di-Jet raw yields
633  hA[40]=new L2Histo(40, (char*)"Et Jet1-Jet2 (input); x: Jet1 Et/GeV ; Jet2 Et/GeV",12,12);
634  hA[41]=new L2Histo(41, (char*)"diJet1 eta-phi (input); x: iEta [-1,+2] ; y: iPhi ~sector ",15,30);
635  hA[42]=new L2Histo(42, (char*)"diJet2 eta-phi (input); x: iEta [-1,+2] ; y: iPhi ~sector",15,30);
636 
637  hA[43]=new L2Histo(43, (char*)"diJet phi1-phi2 (input); x: iPhi1 ~sector ; y: iPhi2 ~sector ",30,30);
638 
639  hA[44]=new L2Histo(44, (char*)"Jet1 Et (input); x: Et (GeV)", 60);
640  hA[45]=new L2Histo(45, (char*)"Jet2 Et (input); x: Et (GeV)", 60);
641  hA[46]=new L2Histo(46, (char*)"total Et (input); x: Et (GeV)", 60);
642  hA[47]=new L2Histo(47, (char*)"# BTOW towers>thrXX (input); x: # of towers/event", 200);
643  hA[48]=new L2Histo(48, (char*)"# ETOW towers>thrXX (input); x: # of towers/event", 100);
644 
645  // ........accepted one-jet events
646  hA[50]=new L2Histo(50, (char*)"one-Jet Et (accepted); x: jet Et (GeV)", 60);
647  hA[51]=new L2Histo(51, (char*)"one-Jet eta-phi (accepted); x: iEta [-1,+2] ; y: iPhi ~sector ",15,30);
648  hA[52]=new L2Histo(52, (char*)"one-Jet eta (accepted); x: iEta [-1,+2]", 15);
649  hA[53]=new L2Histo(53, (char*)"one-Jet phi (accepted); x: iPhi ~sector", 30);
650 
651  // Di-Jet accepted
652  hA[60]=new L2Histo(60, (char*)"Et of Jet1 vs. Jet2 (accepted); x: Jet1/GeV ; Jet2/GeV",12,12);
653  hA[61]=new L2Histo(61, (char*)"diJet1 eta-phi (accepted); x: iEta [-1,+2] ; y: iPhi ~sector ",15,30);
654  hA[62]=new L2Histo(62, (char*)"diJet2 eta-phi (accepted); x: iEta [-1,+2] ; y: iPhi ~sector",15,30);
655 
656  hA[63]=new L2Histo(63, (char*)"diJet phi1-phi2 (accepted); x: iPhi1 ~sector ; y: iPhi2 ~sector ",30,30);
657 
658  hA[64]=new L2Histo(64, (char*)"diJet1 Et (accepted); x: Et (GeV)", 60);
659  hA[65]=new L2Histo(65, (char*)"diJet2 Et (accepted); x: Et (GeV)", 60);
660 
661  hA[66]=new L2Histo(66, (char*)"diJet1 eta (accepted); x: i Eta [-1,+2]", 15);
662  hA[67]=new L2Histo(67, (char*)"diJet2 eta (accepted); x: i Eta [-1,+2]", 15);
663  hA[68]=new L2Histo(68, (char*)"diJet1 phi (accepted); x: iPhi ~sector", 30);
664  hA[69]=new L2Histo(69, (char*)"diJet2 phi (accepted); x: iPhi ~sector", 30);
665  hA[70]=new L2Histo(70, (char*)"diJet delZeta (accepted); x: delta zeta (rad*10)", MxPhiRad10);
666  hA[71]=new L2Histo(71, (char*)"diJet delZeta vs. eta1 (accepted); x: iEta1 [-1,+2] ; y: delta zeta (rad*10)",15, MxPhiRad10);
667  hA[72]=new L2Histo(72, (char*)"diJet eta2 vs. eta1 (accepted); x: iEta1 [-1,+2] ;x: iEta2 [-1,+2] ",15,15);
668  hA[73]=new L2Histo(73, (char*)"diJet delZeta vs. avrPhi (accepted); x: (iphi1+iphi2)/2 (12 deg/bin); y: delta zeta (rad*10)",30, MxPhiRad10);
669  hA[74]=new L2Histo(74, (char*)"total Et diJet (accepted); x: Et (GeV)", 60);
670 
671 }
672 
673 //=======================================
674 //=======================================
675 void
676 L2jetAlgo2006::clearEvent(){
677  /* printf("clearEvent_L2jet() executed\n"); */
678 
679  eve_TrigData=0;
680  mAccept=false;
681  mEveTimeDiff=0;
682  memset(eve_patchEne,0,sizeof(eve_patchEne));
683  memset(eve_phiEne,0,sizeof(eve_phiEne));
684  eve_Jet[0]->clear();
685  eve_Jet[1]->clear();
686 }
687 
688 
689 
690 //=======================================
691 //=======================================
692 int
693 L2jetAlgo2006::projectAdc( unsigned short *rawAdc, int nRdo,
694  unsigned short *thr, unsigned short *pedS, unsigned short *gainCorr,
695  unsigned short *phiBin, unsigned short *patchBin,
696  L2Histo *hHot ){
697 
698  int tmpNused=0; /* counts mapped & used ADC channels */
699 
700  short rdo;
701  int adc,adc4;
702  for(rdo=0; rdo<nRdo; rdo++){
703  if(rawAdc[rdo]<thr[rdo])continue;
704  // adc=rawAdc[rdo]-ped[rdo]; // old, before drop of 4 LSB was introduced.
705  adc=(rawAdc[rdo]+pedS[rdo]) & par_adcMask ;
706  adc4=adc*gainCorr[rdo];
707  eve_patchEne[patchBin[rdo]]+=adc4;
708  eve_phiEne[phiBin[rdo]]+=adc4;
709  tmpNused++; /* drop it later */
710  // only monitoring
711  // if(par_dbg>3) printf("pro rdo=%d adc=%d nTw=%d\n",rdo,adc,tmpNused);
712  if(adc4 >par_hotTwEtThr) hHot->fill(rdo);
713  }
714 
715  return tmpNused;
716 }
717 
718 //=======================================
719 //=======================================
720 int
721 L2jetAlgo2006::scanPhi(){
722  /* build running sum for every 3 phi-bins:
723  - clone data in extra 2 bins to avoid 'if' statement for circular phi
724  - calculate running sum
725  - find absolute maximum
726  - find 2nd maximum seperated in phi
727  */
728 
729  int phiEneSum[cl2jetMaxPhiBins];
730  memset(phiEneSum,0,sizeof(phiEneSum));
731 
732  /* WARN: must match l2jet_par_mxPhiBin, provides 2 extra bins */
733  eve_phiEne[cl2jetMaxPhiBins+0]=eve_phiEne[0];
734  eve_phiEne[cl2jetMaxPhiBins+1]=eve_phiEne[1];
735 
736  int i;
737  int sum;
738  int sumMax1=0, iMax1=-1;
739  int sumTot=0;
740 
741  int *phiEneA=eve_phiEne;
742  for(i=0;i<cl2jetMaxPhiBins;i++,phiEneA++){
743  sumTot+=phiEneA[0];
744  sum=phiEneA[0]+phiEneA[1]+phiEneA[2];
745  phiEneSum[i]=sum;
746  if(sumMax1>sum) continue;
747  sumMax1=sum;
748  iMax1=i;
749  }
750 
751  if(par_dbg>2) printf("phiScan: sum1=%d, iphi1=%d\n",sumMax1,iMax1);
752  /* find second maximum in phi*/
753 
754  int sumMax2=0, iMax2=-1;
755  char doWrap=0;
756  int k1=iMax1-par_minPhiBinDiff;
757  int k2=iMax1+par_minPhiBinDiff;
758  if (k1<0) { k1+=cl2jetMaxPhiBins; doWrap+=1; }
759  if (k2>=cl2jetMaxPhiBins) { k2-=cl2jetMaxPhiBins; doWrap+=2; }
760 
761  if (!doWrap) { /* masking range does NOT wrap up */
762  for(i=0;i<cl2jetMaxPhiBins;i++){
763  /* printf("aa %d-%d =%d?%d -->%d\n",i,iMax1,abs(i-iMax1),l2jet_par_minPhiBdist,abs(i-iMax1)<l2jet_par_minPhiBdist); */
764  if(i>=k1 && i<=k2) continue;
765  if(sumMax2>phiEneSum[i]) continue;
766  sumMax2=phiEneSum[i];
767  iMax2=i;
768  }
769  } else { /* masking range WRAPS up */
770  for(i=k2;i<k1;i++){
771  /* printf("bc %d-%d =%d?%d -->%d\n",i,iMax1,abs(i-iMax1),l2jet_par_minPhiBdist,abs(i-iMax1)<l2jet_par_minPhiBdist); */
772  if(sumMax2>phiEneSum[i]) continue;
773  sumMax2=phiEneSum[i];
774  iMax2=i;
775  }
776  }
777  if(par_dbg>2) printf("phiScan: sum2=%d, iphi2=%d\n",sumMax2,iMax2);
778 
779 
780  eve_Jet[0]->iphiBin=iMax1;
781  eve_Jet[1]->iphiBin=iMax2;
782 
783  return sumTot;
784 
785 }
786 
787 
788 
789 //========================================
790 //========================================
791 void
792 L2jetAlgo2006::scanEta(int iJ){
793  L2Jet *J=eve_Jet[iJ];
794 
795  int iphi0=J->iphiBin;
796 
797  /* - sum energy vs. etaBin for selected 3 phi-bins:
798  - calculate running sum for every 3 eta-bins
799  - find absolute maximum for 3bin sum
800  - find energy weighted eta of the jet
801  */
802 
803  int eneA[cl2jetMaxEtaBins];
804  memset(eneA,0,sizeof(eneA));
805 
806  int sum;
807  int sumMax=1; // sth very small to avoid division by 0 if ECAL is empty
808  int iMax=0; // default to most East eta bin
809 
810  /* collaps 3 phi bins on eta-axis */
811  int ix,iy;
812  for(iy=0;iy<cl2jet_par_mxPhiBin;iy++) {
813  int jy=(iphi0+iy)%cl2jetMaxPhiBins; /* phi must wrap up */
814  int *patchEneA=eve_patchEne+(jy*cl2jetMaxEtaBins);
815  for(ix=0;ix<cl2jetMaxEtaBins;ix++,patchEneA++){
816  eneA[ix]+=*patchEneA;
817  }
818  }
819 
820  int *eneAp=eneA;
821  for(ix=0;ix<cl2jetMaxEtaBins-cl2jet_par_mxEtaBin+1;ix++,eneAp++) {
822  /* printf(" J1 ieta=%d E=%.2f\n", ix,eneA[0]/l2jet_par_energyScale);
823  printf(" E=%.2f\n",etaEneA[ix]/l2jet_par_energyScale); */
824  sum=eneAp[0]+eneAp[1]+eneAp[2];
825  // printf("ix=%d sum=%d sumMax=%d\n",ix,sum,sumMax);
826  if(sumMax>sum) continue;
827  sumMax=sum;
828  iMax=ix;
829  }
830 
831  // calculate center of gravity
832  int sumX=0;
833  for(ix=iMax;ix<iMax+cl2jet_par_mxEtaBin;ix++){
834  sumX+=ix*eneA[ix];
835  }
836  float fetaBin=0.5+1.*sumX/sumMax;
837 
838 
839  if(par_dbg>2){
840  if(par_dbg>3) {
841  printf("scanEta iphi0=%d\n eta profile:\n L2eta-bin energy\n",iphi0);
842  for(ix=0;ix<cl2jetMaxEtaBins;ix++){
843  printf("%d %d\n",ix,eneA[ix]);
844  }
845  }
846  printf("scanEta: sum=%d, ietaLeft=%d\n",sumMax,iMax);
847  printf("sumX=%d fetaBinmax=%.1f \n",sumX,fetaBin);
848  }
849 
850  J->fetaBin=fetaBin;
851  J->iene=sumMax;
852  J->ietaBin=iMax;
853 }
854 
855 //========================================
856 //========================================
857 void
858 L2jetAlgo2006:: dumpPatchEneA(){
859  // dump L2 array with energy
860  int ix,iy;
861  for(iy=0;iy<cl2jetMaxPhiBins;iy++) {
862  int *patchEneA=eve_patchEne+(iy*cl2jetMaxEtaBins);// phi bins are consecutive
863 
864  for(ix=0;ix<cl2jetMaxEtaBins;ix++,patchEneA++){
865  printf(" %6d",*patchEneA);
866  }
867  printf(" iPhi=%d\n",iy);
868  }
869 
870 }
871 
872 //========================================
873 //========================================
874 void
875 L2jetAlgo2006::weightedPhi(int iJ){
876  L2Jet *J=eve_Jet[iJ];
877 
878 
879  // empty calo protection
880  if(J->iene<=1) { J->fphiBin=J->iphiBin+.333; return;}
881 
882  int iphi0=J->iphiBin;
883  int ieta0=J->ietaBin;
884 
885  /*
886  - find energy weighted phi of the jet
887  - if phi>360 it wraps phi over
888  */
889  // printf("weightedPhi() inp: iphi0=%d ieta0=%d\n",iphi0, ieta0);
890  int sum=1, sumY=0; // make sum non zero so it never fails
891  int sum1;//wrk variable
892 
893  int ix,iy;
894  // pick 3x3 eta-phi patch and calculate weighted phi==Y
895  for(iy=iphi0;iy<iphi0+cl2jet_par_mxPhiBin;iy++) {
896  int jy=iy % cl2jetMaxPhiBins; /* iphi must wrap up */
897  int *patchEneA=eve_patchEne+(jy*cl2jetMaxEtaBins);// phi bins are consecutive
898 #if 0
899  for(ix=0;ix<cl2jetMaxEtaBins;ix++){
900  printf(" %6d",patchEneA[ix]);
901  }
902  printf(" iy=%d \n",iy);
903 #endif
904 
905  sum1=0;
906  for(ix=ieta0;ix<ieta0+cl2jet_par_mxEtaBin;ix++){
907  sum1+=patchEneA[ix];
908  }
909  sum+=sum1; // do it again, coul dbe passed from scanEta
910  sumY+=sum1*iy;
911  //printf("jy=%d sym1=%d sum=%d sumY=%d\n",jy,sum1, sum,sumY);
912  }
913 
914  float fphiBinMax=0.5 + 1.*sumY/sum;
915  if( fphiBinMax>cl2jetMaxPhiBins) fphiBinMax-=cl2jetMaxPhiBins;
916  if(par_dbg>2) printf("weightedPhi() sum=%d sumY=%d fphiBin=%.2f\n",sum,sumY, fphiBinMax);
917  J->fphiBin=fphiBinMax;
918 }
919 
920 //=======================================
921 //=======================================
922 void
923 L2jetAlgo2006::finishRunHisto(){
924  // auxialiary operations on histograms at the end of the run
925 
926  const int *data20=hA[20]->getData();
927  const int *data30=hA[30]->getData();
928 
929  int bHotSum=1,bHotId=-1;
930  int eHotSum=1;
931 
932  const L2EmcDb::EmcCDbItem *xE=mDb->getByIndex(402), *xB=mDb->getByIndex(402);
933  int i;
934  for(i=0; i<EmcDbIndexMax; i++) {
935  const L2EmcDb::EmcCDbItem *x=mDb->getByIndex(i);
936  if(mDb->isEmpty(x)) continue;
937  if (mDb->isBTOW(x) ) {
938  int softId=atoi(x->tube+2);
939  int ieta= (x->eta-1);
940  int iphi= (x->sec-1)*10 + x->sub-'a' ;
941  //mDb->printItem(x); printf("softID=%d\n",softId);
942  hA[21]->fillW(softId,data20[x->rdo]);
943  hA[22]->fillW(ieta, iphi,data20[x->rdo]);
944  if(bHotSum<data20[x->rdo]) {
945  bHotSum=data20[x->rdo];
946  bHotId=softId;
947  xB=x;
948  }
949  }// end of BTOW
950  else if (mDb->isETOW(x) ) {
951  int ihard=x->chan+(x->crate-1)*128;
952  int ieta= 12-x->eta;
953  int iphi= (x->sec-1)*5 + x->sub-'A' ;
954  hA[31]->fillW(ihard,data30[x->rdo]);
955  hA[32]->fillW(ieta, iphi,data30[x->rdo]);
956  if(eHotSum<data30[x->rdo]) {
957  eHotSum=data30[x->rdo];
958  xE=x;
959  }
960 
961  }// end of BTOW
962  }
963  if (mLogFile){
964  fprintf(mLogFile,"L2jet::finishRun()\n");
965  fprintf(mLogFile,"#BTOW_hot tower _candidate_ (bHotSum=%d) :, softID %d , crate %d , chan %d , name %s\n",bHotSum,bHotId,xB->crate,xB->chan,xB->name);
966  fprintf(mLogFile,"#ETOW_hot tower _candidate_ (eHotSum=%d) :, name %s , crate %d , chan %d\n",eHotSum,xE->name,xE->crate,xE->chan);
967  }
968 
969 
970 }
971 
972 
973 /**********************************************************************
974  $Log: L2jetAlgo2006.cxx,v $
975  Revision 1.2 2009/11/19 15:48:45 balewski
976  add (char*) to many strings to make SL5 happ, few other adjustments
977 
978  Revision 1.1 2007/11/19 22:18:27 balewski
979  most L2algos provide triggerID's
980 
981  Revision 1.8 2007/11/14 03:58:14 balewski
982  cleanup of common timing measurement
983 
984  Revision 1.7 2007/11/13 23:06:07 balewski
985  toward more unified L2-algos
986 
987  Revision 1.6 2007/11/13 00:12:36 balewski
988  added offline triggerID, take1
989 
990  Revision 1.5 2007/11/08 04:02:31 balewski
991  run on l2ana as well
992 
993  Revision 1.4 2007/11/02 17:43:08 balewski
994  cleanup & it started to work w/ L2upsilon
995 
996  Revision 1.3 2007/11/02 03:03:47 balewski
997  modified L2VirtualAlgo
998 
999  Revision 1.2 2007/10/25 02:07:02 balewski
1000  added L2upsilon & binary event dump
1001 
1002  Revision 1.1 2007/10/11 00:33:19 balewski
1003  L2algo added
1004 
1005  Revision 1.5 2006/03/28 19:46:49 balewski
1006  ver16b, in l2new
1007 
1008  Revision 1.4 2006/03/11 17:08:33 balewski
1009  now CVS comments should work
1010 
1011 */
1012 
1013