Added class to read reconstruction parameters from OCDB (Yuri)
[u/mrichter/AliRoot.git] / EMCAL / AliEMCALTrigger.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15 /* $Id$ */
16
17 //_________________________________________________________________________  
18 //
19 //  Class for trigger analysis.
20 //  Digits are grouped in TRU's  (Trigger Units). A TRU consists of 384 
21 //  cells ordered fNTRUPhi x fNTRUEta. The algorithm searches all possible 2x2 
22 //  and nxn (n is a multiple of 2) cell combinations per each TRU,  adding the 
23 //  digits amplitude and finding the maximum. If found, look if it is isolated.
24 //  Maxima are transformed in ADC time samples. Each time bin is compared to the trigger 
25 //  threshold until it is larger and then, triggers are set. Thresholds need to be fixed.  
26 //  Thresholds need to be fixed. Last 2 modules are half size in Phi, I considered 
27 //  that the number of TRU is maintained for the last modules but decision not taken. 
28 //  If different, then this must be changed. 
29 //  Usage:
30 //
31 //  //Inside the event loop
32 //  AliEMCALTrigger *tr = new AliEMCALTrigger();//Init Trigger
33 //  tr->SetL0Threshold(100); //Arbitrary threshold values
34 //  tr->SetL1JetLowPtThreshold(1000);
35 //  tr->SetL1JetMediumPtThreshold(10000);
36 //  tr->SetL1JetHighPtThreshold(20000);
37 //  ...
38 //  tr->Trigger(); //Execute Trigger
39 //  tr->Print(""); //Print results
40 //
41 //*-- Author: Gustavo Conesa & Yves Schutz (IFIC, CERN) 
42 //////////////////////////////////////////////////////////////////////////////
43
44
45 // --- ROOT system ---
46
47 // --- ALIROOT system ---
48 #include "AliRun.h" 
49 #include "AliRunLoader.h" 
50 #include "AliTriggerInput.h"
51 #include "AliEMCAL.h" 
52 #include "AliEMCALLoader.h" 
53 #include "AliEMCALDigit.h"
54 #include "AliEMCALTrigger.h" 
55 #include "AliEMCALGeometry.h"
56 #include "AliEMCALRawUtils.h"
57
58 ClassImp(AliEMCALTrigger)
59
60 //______________________________________________________________________
61 AliEMCALTrigger::AliEMCALTrigger()
62   : AliTriggerDetector(), fGeom(0),
63     f2x2MaxAmp(-1), f2x2CellPhi(-1),  f2x2CellEta(-1),
64     f2x2SM(0),
65     fnxnMaxAmp(-1), fnxnCellPhi(-1),  fnxnCellEta(-1),
66     fnxnSM(0),
67     fADCValuesHighnxn(0),fADCValuesLownxn(0),
68     fADCValuesHigh2x2(0),fADCValuesLow2x2(0),
69     fDigitsList(0),
70     fL0Threshold(100),fL1JetLowPtThreshold(200),
71     fL1JetMediumPtThreshold(500), fL1JetHighPtThreshold(1000),
72     fPatchSize(1),  fIsolPatchSize(1), 
73     f2x2AmpOutOfPatch(-1), fnxnAmpOutOfPatch(-1), 
74     f2x2AmpOutOfPatchThres(100000),  fnxnAmpOutOfPatchThres(100000), 
75     fIs2x2Isol(kFALSE), fIsnxnIsol(kFALSE),  
76     fSimulation(kTRUE), fIsolateInSuperModule(kTRUE)
77 {
78   //ctor 
79   fADCValuesHighnxn = 0x0; //new Int_t[fTimeBins];
80   fADCValuesLownxn  = 0x0; //new Int_t[fTimeBins];
81   fADCValuesHigh2x2 = 0x0; //new Int_t[fTimeBins];
82   fADCValuesLow2x2  = 0x0; //new Int_t[fTimeBins];
83
84   SetName("EMCAL");
85   CreateInputs();
86    
87    //Print("") ; 
88 }
89
90
91
92 //____________________________________________________________________________
93 AliEMCALTrigger::AliEMCALTrigger(const AliEMCALTrigger & trig) 
94   : AliTriggerDetector(trig),
95     fGeom(trig.fGeom),
96     f2x2MaxAmp(trig.f2x2MaxAmp), 
97     f2x2CellPhi(trig.f2x2CellPhi),  
98     f2x2CellEta(trig.f2x2CellEta),
99     f2x2SM(trig.f2x2SM),
100     fnxnMaxAmp(trig.fnxnMaxAmp), 
101     fnxnCellPhi(trig.fnxnCellPhi),  
102     fnxnCellEta(trig.fnxnCellEta),
103     fnxnSM(trig.fnxnSM),
104     fADCValuesHighnxn(trig.fADCValuesHighnxn),
105     fADCValuesLownxn(trig.fADCValuesLownxn),
106     fADCValuesHigh2x2(trig.fADCValuesHigh2x2),
107     fADCValuesLow2x2(trig.fADCValuesLow2x2),
108     fDigitsList(trig.fDigitsList),
109     fL0Threshold(trig.fL0Threshold),
110     fL1JetLowPtThreshold(trig.fL1JetLowPtThreshold),
111     fL1JetMediumPtThreshold(trig.fL1JetMediumPtThreshold), 
112     fL1JetHighPtThreshold(trig.fL1JetHighPtThreshold),
113     fPatchSize(trig.fPatchSize),
114     fIsolPatchSize(trig.fIsolPatchSize), 
115     f2x2AmpOutOfPatch(trig.f2x2AmpOutOfPatch), 
116     fnxnAmpOutOfPatch(trig.fnxnAmpOutOfPatch), 
117     f2x2AmpOutOfPatchThres(trig.f2x2AmpOutOfPatchThres),  
118     fnxnAmpOutOfPatchThres(trig.fnxnAmpOutOfPatchThres), 
119     fIs2x2Isol(trig.fIs2x2Isol),
120     fIsnxnIsol(trig.fIsnxnIsol),  
121     fSimulation(trig.fSimulation),
122     fIsolateInSuperModule(trig.fIsolateInSuperModule)
123 {
124   // cpy ctor
125 }
126
127 AliEMCALTrigger::~AliEMCALTrigger() {
128   delete [] fADCValuesHighnxn; 
129   delete [] fADCValuesLownxn;
130   delete [] fADCValuesHigh2x2;
131   delete [] fADCValuesLow2x2;
132 }
133
134 //----------------------------------------------------------------------
135 void AliEMCALTrigger::CreateInputs()
136 {
137    // inputs 
138    
139    // Do not create inputs again!!
140    if( fInputs.GetEntriesFast() > 0 ) return;
141    
142    fInputs.AddLast( new AliTriggerInput( "EMCAL_L0",       "EMCAL L0", 0x02 ) );
143    fInputs.AddLast( new AliTriggerInput( "EMCAL_JetHPt_L1","EMCAL Jet High Pt L1",   0x04 ) );
144    fInputs.AddLast( new AliTriggerInput( "EMCAL_JetMPt_L1","EMCAL Jet Medium Pt L1", 0x08 ) );
145    fInputs.AddLast( new AliTriggerInput( "EMCAL_JetLPt_L1","EMCAL Jet Low Pt L1",    0x016 ) );
146  
147 }
148
149 //____________________________________________________________________________
150 Bool_t AliEMCALTrigger::IsPatchIsolated(Int_t iPatchType, const TClonesArray * ampmatrixes, const Int_t iSM, const Int_t mtru, const Float_t maxamp, const Int_t maxphi, const Int_t maxeta) {
151
152   //Calculate if the maximum patch found is isolated, find amplitude around maximum (2x2 or nxn) patch, 
153   //inside isolation patch . iPatchType = 0 means calculation for 2x2 patch, 
154   //iPatchType = 1 means calculation for nxn patch.
155   //In the next table there is an example of the different options of patch size and isolation patch size:
156   //                                                                                 Patch Size (fPatchSize)
157   //                                                             0                          1                                  2
158   //          fIsolPatchSize                 2x2 (not overlap)   4x4 (overlapped)        6x6(overlapped) ...
159   //                   1                                       4x4                      8x8                              10x10
160   //                   2                                       6x6                     12x12                           14x14    
161   //                   3                                       8x8                     16x16                           18x18
162                           
163   Bool_t b = kFALSE;
164   Float_t amp = 0;
165  
166   //Get matrix of TRU or Module with maximum amplitude patch.
167   Int_t itru = mtru + iSM * fGeom->GetNTRU(); //number of tru, min 0 max 8*5.
168   TMatrixD * ampmatrix   = 0x0;
169   Int_t colborder = 0;
170   Int_t rowborder = 0;
171   
172   if(fIsolateInSuperModule){
173     ampmatrix = dynamic_cast<TMatrixD *>(ampmatrixes->At(iSM)) ;
174     rowborder = fGeom->GetNPhi()*2; 
175     colborder = fGeom->GetNZ()*2;
176     AliDebug(2,"Isolate trigger in Module");
177   }
178   else{
179     ampmatrix = dynamic_cast<TMatrixD *>(ampmatrixes->At(itru)) ;
180     rowborder = fGeom->GetNCellsInTRUPhi();
181     colborder = fGeom->GetNCellsInTRUEta();
182     AliDebug(2,"Isolate trigger in TRU");
183   }
184   
185   //Define patch cells
186   Int_t isolcells   = fIsolPatchSize*(1+iPatchType);
187   Int_t ipatchcells = 2*(1+fPatchSize*iPatchType);
188   Int_t minrow      = maxphi - isolcells;
189   Int_t mincol      = maxeta - isolcells;
190   Int_t maxrow      = maxphi + isolcells + ipatchcells;
191   Int_t maxcol      = maxeta + isolcells + ipatchcells;
192
193   if (minrow < 0)
194     minrow = 0;
195   if (mincol < 0)
196     mincol = 0;
197   if (maxrow > rowborder)
198     maxrow = rowborder;
199   if (maxcol > colborder)
200     maxcol = colborder;
201   
202   AliDebug(2,Form("Number of added Isol Cells %d, Patch Size %d",isolcells, ipatchcells));
203   AliDebug(2,Form("Patch: minrow %d, maxrow %d, mincol %d, maxcol %d",minrow,maxrow,mincol,maxcol));
204   
205   //Add amplitudes in all isolation patch
206   for(Int_t irow = minrow ; irow <  maxrow; irow ++)
207     for(Int_t icol = mincol ; icol < maxcol ; icol ++)
208       amp += (*ampmatrix)(irow,icol);
209   
210   AliDebug(2,Form("Type %d, Maximum amplitude %f, patch+isol square %f",iPatchType, maxamp, amp));
211
212   if(amp < maxamp){
213     AliError(Form("Bad sum: Type %d, Maximum amplitude %f, patch+isol square %f",iPatchType, maxamp, amp));
214     return kFALSE;
215   }
216   else
217     amp-=maxamp; //Calculate energy in isolation patch that do not comes from maximum patch.
218   
219   AliDebug(2, Form("Maximum amplitude %f, Out of patch %f",maxamp, amp));
220
221   //Fill isolation amplitude data member and say if patch is isolated.
222   if(iPatchType == 0){ //2x2 case
223     f2x2AmpOutOfPatch = amp;   
224     if(amp < f2x2AmpOutOfPatchThres)
225       b=kTRUE;
226   }
227   else  if(iPatchType == 1){ //nxn case
228     fnxnAmpOutOfPatch = amp;   
229     if(amp < fnxnAmpOutOfPatchThres)
230       b=kTRUE;
231   }
232
233   return b;
234
235 }
236
237 //____________________________________________________________________________
238 void AliEMCALTrigger::MakeSlidingCell(const TClonesArray * amptrus, const TClonesArray * timeRtrus, const Int_t isupermod,TMatrixD &ampmax2, TMatrixD &ampmaxn){
239   
240   //Sums energy of all possible 2x2 (L0) and nxn (L1) cells per each TRU. 
241   //Fast signal in the experiment is given by 2x2 cells, 
242   //for this reason we loop inside the TRU cells by 2. 
243
244   //Declare and initialize variables
245   Int_t nCellsPhi  = fGeom->GetNCellsInTRUPhi();
246   if(isupermod > 9)
247     nCellsPhi =  nCellsPhi / 2 ; //Half size SM. Not Final.
248   // 12(tow)*2(cell)/1 TRU, cells in Phi in one TRU
249   Int_t nCellsEta  = fGeom->GetNCellsInTRUEta();
250   Int_t nTRU  = fGeom->GetNTRU();
251   // 24(mod)*2(tower)/3 TRU, cells in Eta in one TRU
252   //Int_t nTRU          = geom->GeNTRU();//3 TRU per super module
253
254   Float_t amp2 = 0 ;
255   Float_t ampn = 0 ; 
256   for(Int_t i = 0; i < 4; i++){
257     for(Int_t j = 0; j < nTRU; j++){
258       ampmax2(i,j) = -1;
259       ampmaxn(i,j) = -1;
260     }
261   }
262
263   //Create matrix that will contain 2x2 amplitude sums
264   //used to calculate the nxn sums
265   TMatrixD tru2x2(nCellsPhi/2,nCellsEta/2) ;
266   for(Int_t i = 0; i < nCellsPhi/2; i++)
267     for(Int_t j = 0; j < nCellsEta/2; j++)
268       tru2x2(i,j) = -1;
269   
270   //Loop over all TRUS in a supermodule
271   for(Int_t itru = 0 + isupermod * nTRU ; itru < (isupermod+1)*nTRU ; itru++) {
272     TMatrixD * amptru   = dynamic_cast<TMatrixD *>(amptrus->At(itru)) ;
273     TMatrixD * timeRtru = dynamic_cast<TMatrixD *>(timeRtrus->At(itru)) ;
274     Int_t mtru = itru-isupermod*nTRU ; //Number of TRU in Supermodule
275    
276     //Sliding 2x2, add 2x2 amplitudes (NOT OVERLAP)
277     for(Int_t irow = 0 ; irow <  nCellsPhi; irow += 2){ 
278       for(Int_t icol = 0 ; icol < nCellsEta ; icol += 2){
279         amp2 = (*amptru)(irow,icol)+(*amptru)(irow+1,icol)+
280           (*amptru)(irow,icol+1)+(*amptru)(irow+1,icol+1);
281
282         //Fill matrix with added 2x2 cells for use in nxn sums
283         tru2x2(irow/2,icol/2) = amp2 ;
284         //Select 2x2 maximum sums to select L0 
285         if(amp2 > ampmax2(0,mtru)){
286           ampmax2(0,mtru) = amp2 ; 
287           ampmax2(1,mtru) = irow;
288           ampmax2(2,mtru) = icol;
289         }
290       }
291     }
292     
293     //Find most recent time in the selected 2x2 cell
294     ampmax2(3,mtru) = 1 ;
295     Int_t row2 =  static_cast <Int_t> (ampmax2(1,mtru));
296     Int_t col2 =  static_cast <Int_t> (ampmax2(2,mtru));
297     for(Int_t i = 0; i<2; i++){
298       for(Int_t j = 0; j<2; j++){
299         if((*amptru)(row2+i,col2+j) > 0 &&  (*timeRtru)(row2+i,col2+j)> 0){       
300           if((*timeRtru)(row2+i,col2+j) <  ampmax2(3,mtru)  )
301             ampmax2(3,mtru) =  (*timeRtru)(row2+i,col2+j);
302         }
303       }
304     }
305
306     //Sliding nxn, add nxn amplitudes  (OVERLAP)
307     if(fPatchSize > 0){
308       for(Int_t irow = 0 ; irow <  nCellsPhi/2; irow++){ 
309         for(Int_t icol = 0 ; icol < nCellsEta/2 ; icol++){
310           ampn = 0;
311           if( (irow+fPatchSize) < nCellsPhi/2 && (icol+fPatchSize) < nCellsEta/2){//Avoid exit the TRU
312             for(Int_t i = 0 ; i <= fPatchSize ; i++)
313               for(Int_t j = 0 ; j <= fPatchSize ; j++)
314                 ampn += tru2x2(irow+i,icol+j);
315             //Select nxn maximum sums to select L1 
316             if(ampn > ampmaxn(0,mtru)){
317               ampmaxn(0,mtru) = ampn ; 
318               ampmaxn(1,mtru) = irow*2;
319               ampmaxn(2,mtru) = icol*2;
320             }
321           }
322         }
323       }
324       
325       //Find most recent time in selected nxn cell
326       ampmaxn(3,mtru) = 1 ;
327       Int_t rown =  static_cast <Int_t> (ampmaxn(1,mtru));
328       Int_t coln =  static_cast <Int_t> (ampmaxn(2,mtru));
329       for(Int_t i = 0; i<4*fPatchSize; i++){
330         for(Int_t j = 0; j<4*fPatchSize; j++){
331           if( (rown+i) < nCellsPhi && (coln+j) < nCellsEta){//Avoid exit the TRU
332             if((*amptru)(rown+i,coln+j) > 0 &&  (*timeRtru)(rown+i,coln+j)> 0){
333               if((*timeRtru)(rown+i,coln+j) <  ampmaxn(3,mtru)  )
334                 ampmaxn(3,mtru) =  (*timeRtru)(rown+i,coln+j);
335             }
336           }
337         }
338       }
339     }
340     else {  
341         ampmaxn(0,mtru) =  ampmax2(0,mtru); 
342         ampmaxn(1,mtru) =  ampmax2(1,mtru);
343         ampmaxn(2,mtru) =  ampmax2(2,mtru);
344         ampmaxn(3,mtru) =  ampmax2(3,mtru);
345       }
346   }
347 }
348
349 //____________________________________________________________________________
350 void AliEMCALTrigger::Print(const Option_t * opt) const 
351 {
352   
353   //Prints main parameters
354   
355   if(! opt)
356     return;
357   AliTriggerInput* in = 0x0 ;
358
359   printf( "             Maximum Amplitude after Sliding Cell, \n") ; 
360   printf( "               -2x2 cells sum (not overlapped): %10.2f, in Super Module %d\n",
361           f2x2MaxAmp,f2x2SM) ; 
362   printf( "               -2x2 from row %d to row %d and from column %d to column %d\n", f2x2CellPhi, f2x2CellPhi+2, f2x2CellEta, f2x2CellEta+2) ; 
363   printf( "               -2x2 Isolation Patch %d x %d, Amplitude out of 2x2 patch is %f, threshold %f, Isolated? %d \n", 
364           2*fIsolPatchSize+2, 2*fIsolPatchSize+2,  f2x2AmpOutOfPatch,  f2x2AmpOutOfPatchThres,static_cast<Int_t> (fIs2x2Isol)) ; 
365   if(fPatchSize > 0){
366     printf( "             Patch Size, n x n: %d x %d cells\n",2*(fPatchSize+1), 2*(fPatchSize+1));
367     printf( "               -nxn cells sum (overlapped)    : %10.2f, in Super Module %d\n",
368             fnxnMaxAmp,fnxnSM) ; 
369     printf( "               -nxn from row %d to row %d and from column %d to column %d\n", fnxnCellPhi, fnxnCellPhi+4*fPatchSize, fnxnCellEta, fnxnCellEta+4*fPatchSize) ; 
370     printf( "               -nxn Isolation Patch %d x %d, Amplitude out of nxn patch is %f, threshold %f, Isolated? %d \n", 
371             4*fIsolPatchSize+2*(fPatchSize+1),4*fIsolPatchSize+2*(fPatchSize+1) ,  fnxnAmpOutOfPatch,  fnxnAmpOutOfPatchThres,static_cast<Int_t> (fIsnxnIsol) ) ; 
372   }
373   
374   printf( "             Isolate in SuperModule? %d\n",  
375           fIsolateInSuperModule) ;  
376
377   printf( "             Threshold for LO %10.2f\n", 
378           fL0Threshold) ;  
379   in = (AliTriggerInput*)fInputs.FindObject( "EMCAL_L0" );
380   if(in->GetValue())
381     printf( "             *** EMCAL LO is set ***\n") ; 
382   
383   printf( "             Jet Low Pt Threshold for L1 %10.2f\n", 
384           fL1JetLowPtThreshold) ;
385   in = (AliTriggerInput*)fInputs.FindObject( "EMCAL_JetLPt_L1" );
386   if(in->GetValue())
387     printf( "             *** EMCAL Jet Low Pt for L1 is set ***\n") ;
388
389   printf( "             Jet Medium Pt Threshold for L1 %10.2f\n", 
390           fL1JetMediumPtThreshold) ;  
391   in = (AliTriggerInput*) fInputs.FindObject( "EMCAL_JetMPt_L1" );
392   if(in->GetValue())
393     printf( "             *** EMCAL Jet Medium Pt for L1 is set ***\n") ;
394
395   printf( "             Jet High Pt Threshold for L1 %10.2f\n", 
396           fL1JetHighPtThreshold) ;  
397   in = (AliTriggerInput*) fInputs.FindObject( "EMCAL_JetHPt_L1" );
398   if(in->GetValue())
399     printf( "             *** EMCAL Jet High Pt for L1 is set ***\n") ;
400
401 }
402
403 //____________________________________________________________________________
404 void AliEMCALTrigger::SetTriggers(const TClonesArray * ampmatrix,const Int_t iSM, 
405                                   const TMatrixD &ampmax2, 
406                                   const TMatrixD &ampmaxn)  
407 {
408
409   //Checks the 2x2 and nxn maximum amplitude per each TRU and 
410   //compares with the different L0 and L1 triggers thresholds
411   Float_t max2[] = {-1,-1,-1,-1} ;
412   Float_t maxn[] = {-1,-1,-1,-1} ;
413   Int_t   mtru2  = -1 ;
414   Int_t   mtrun  = -1 ;
415
416   Int_t nTRU = fGeom->GetNTRU();
417
418   //Find maximum summed amplitude of all the TRU 
419   //in a Super Module
420     for(Int_t i = 0 ; i < nTRU ; i++){
421       if(max2[0] < ampmax2(0,i) ){
422         max2[0] =  ampmax2(0,i) ; // 2x2 summed max amplitude
423         max2[1] =  ampmax2(1,i) ; // corresponding phi position in TRU
424         max2[2] =  ampmax2(2,i) ; // corresponding eta position in TRU
425         max2[3] =  ampmax2(3,i) ; // corresponding most recent time
426         mtru2   = i ;
427       }
428       if(maxn[0] < ampmaxn(0,i) ){
429         maxn[0] =  ampmaxn(0,i) ; // nxn summed max amplitude
430         maxn[1] =  ampmaxn(1,i) ; // corresponding phi position in TRU
431         maxn[2] =  ampmaxn(2,i) ; // corresponding eta position in TRU
432         maxn[3] =  ampmaxn(3,i) ; // corresponding most recent time
433         mtrun   = i ;
434       }
435     }
436
437   //--------Set max amplitude if larger than in other Super Modules------------
438   Float_t maxtimeR2 = -1 ;
439   Float_t maxtimeRn = -1 ;
440   static AliEMCALRawUtils rawUtil;
441   Int_t nTimeBins = rawUtil.GetRawFormatTimeBins() ;
442
443   //Set max of 2x2 amplitudes and select L0 trigger
444   if(max2[0] > f2x2MaxAmp ){
445     f2x2MaxAmp  = max2[0] ;
446     f2x2SM      = iSM ;
447     maxtimeR2   = max2[3] ;
448     fGeom->GetCellPhiEtaIndexInSModuleFromTRUIndex(mtru2, 
449                                                   static_cast<Int_t>(max2[1]),
450                                                   static_cast<Int_t>(max2[2]),
451                                                   f2x2CellPhi,f2x2CellEta) ;
452     
453     //Isolated patch?
454     if(fIsolateInSuperModule)
455       fIs2x2Isol =  IsPatchIsolated(0, ampmatrix, iSM, mtru2,  f2x2MaxAmp, f2x2CellPhi,f2x2CellEta) ;
456     else
457       fIs2x2Isol =  IsPatchIsolated(0, ampmatrix, iSM, mtru2,  f2x2MaxAmp,  static_cast<Int_t>(max2[1]), static_cast<Int_t>(max2[2])) ;
458
459     //Transform digit amplitude in Raw Samples
460     if (fADCValuesLow2x2 == 0) {
461       fADCValuesLow2x2  = new Int_t[nTimeBins];
462       fADCValuesHigh2x2 = new Int_t[nTimeBins];
463     }
464     rawUtil.RawSampledResponse(maxtimeR2, f2x2MaxAmp, fADCValuesHigh2x2, fADCValuesLow2x2) ; 
465     
466     //Set Trigger Inputs, compare ADC time bins until threshold is attained
467     //Set L0
468     for(Int_t i = 0 ; i < nTimeBins ; i++){
469       if(fADCValuesHigh2x2[i] >= fL0Threshold          || fADCValuesLow2x2[i] >= fL0Threshold){
470         SetInput("EMCAL_L0") ;
471         break;
472       }
473     }
474   }
475   
476   //------------Set max of nxn amplitudes and select L1 trigger---------
477   if(maxn[0] > fnxnMaxAmp ){
478     fnxnMaxAmp  = maxn[0] ;
479     fnxnSM      = iSM ;
480     maxtimeRn   = maxn[3] ;
481     fGeom->GetCellPhiEtaIndexInSModuleFromTRUIndex(mtrun, 
482                                                   static_cast<Int_t>(maxn[1]),
483                                                   static_cast<Int_t>(maxn[2]),
484                                                   fnxnCellPhi,fnxnCellEta) ; 
485     
486     //Isolated patch?
487     if(fIsolateInSuperModule)
488       fIsnxnIsol =  IsPatchIsolated(1, ampmatrix, iSM, mtrun,  fnxnMaxAmp, fnxnCellPhi, fnxnCellEta) ;
489     else
490       fIsnxnIsol =  IsPatchIsolated(1, ampmatrix, iSM, mtrun,  fnxnMaxAmp,  static_cast<Int_t>(maxn[1]), static_cast<Int_t>(maxn[2])) ;
491     
492     //Transform digit amplitude in Raw Samples
493     if (fADCValuesLownxn == 0) {
494       fADCValuesHighnxn = new Int_t[nTimeBins];
495       fADCValuesLownxn  = new Int_t[nTimeBins];
496     }
497     rawUtil.RawSampledResponse(maxtimeRn, fnxnMaxAmp, fADCValuesHighnxn, fADCValuesLownxn) ;
498     
499     //Set Trigger Inputs, compare ADC time bins until threshold is attained
500     //SetL1 Low
501     for(Int_t i = 0 ; i < nTimeBins ; i++){
502       if(fADCValuesHighnxn[i] >= fL1JetLowPtThreshold  || fADCValuesLownxn[i] >= fL1JetLowPtThreshold){
503         SetInput("EMCAL_JetLPt_L1") ;
504         break; 
505       }
506     }
507     
508     //SetL1 Medium
509     for(Int_t i = 0 ; i < nTimeBins ; i++){
510       if(fADCValuesHighnxn[i] >= fL1JetMediumPtThreshold || fADCValuesLownxn[i] >= fL1JetMediumPtThreshold){
511         SetInput("EMCAL_JetMPt_L1") ;
512         break;
513       }
514     }
515     
516     //SetL1 High
517     for(Int_t i = 0 ; i < nTimeBins ; i++){
518       if(fADCValuesHighnxn[i] >= fL1JetHighPtThreshold || fADCValuesLownxn[i] >= fL1JetHighPtThreshold){
519         SetInput("EMCAL_JetHPt_L1") ;
520         break;
521       }
522     }
523   } 
524 }
525
526 //____________________________________________________________________________
527 void AliEMCALTrigger::FillTRU(const TClonesArray * digits, TClonesArray * ampmatrix, TClonesArray * ampmatrixsmod, TClonesArray * timeRmatrix) {
528
529 //  Orders digits ampitudes list in fNTRU TRUs (384 cells) per supermodule. 
530 //  Each TRU is a TMatrixD, and they are kept in TClonesArrays. The number of 
531 //  TRU in phi is fNTRUPhi, and the number of TRU in eta is fNTRUEta.
532 //  Last 2 modules are half size in Phi, I considered that the number of TRU
533 //  is maintained for the last modules but decision not taken. If different, 
534 //  then this must be changed. Also fill a matrix with all amplitudes in supermodule for isolation studies. 
535  
536   //Initilize and declare variables
537   //List of TRU matrices initialized to 0.
538   Int_t nPhi = fGeom->GetNPhi();
539   Int_t nZ = fGeom->GetNZ();
540   Int_t nTRU = fGeom->GetNTRU();
541   Int_t nTRUPhi = fGeom->GetNTRUPhi();
542   Int_t nCellsPhi  = fGeom->GetNCellsInTRUPhi();
543   Int_t nCellsPhi2 = fGeom->GetNCellsInTRUPhi();
544   Int_t nCellsEta  = fGeom->GetNCellsInTRUEta();
545
546   Int_t id       = -1; 
547   Float_t amp    = -1;
548   Float_t timeR  = -1;
549   Int_t iSupMod  = -1;
550   Int_t nModule  = -1;
551   Int_t nIphi    = -1;
552   Int_t nIeta    = -1;
553   Int_t iphi     = -1;
554   Int_t ieta     = -1;
555
556   //List of TRU matrices initialized to 0.
557   Int_t nSup = fGeom->GetNumberOfSuperModules();
558   for(Int_t k = 0; k < nTRU*nSup; k++){
559     TMatrixD amptrus(nCellsPhi,nCellsEta) ;
560     TMatrixD timeRtrus(nCellsPhi,nCellsEta) ;
561     // Do we need to initialise? I think TMatrixD does it by itself...
562     for(Int_t i = 0; i < nCellsPhi; i++){
563       for(Int_t j = 0; j < nCellsEta; j++){
564         amptrus(i,j) = 0.0;
565         timeRtrus(i,j) = 0.0;
566       }
567     }
568     new((*ampmatrix)[k])   TMatrixD(amptrus) ;
569     new((*timeRmatrix)[k]) TMatrixD(timeRtrus) ; 
570   }
571   
572   //List of Modules matrices initialized to 0.
573   for(Int_t k = 0; k < nSup ; k++){
574     TMatrixD  ampsmods( nPhi*2, nZ*2) ;
575     for(Int_t i = 0; i <  nPhi*2; i++){
576       for(Int_t j = 0; j < nZ*2; j++){
577         ampsmods(i,j)   = 0.0;
578       }
579     }
580     new((*ampmatrixsmod)[k])   TMatrixD(ampsmods) ;
581   }
582
583   AliEMCALDigit * dig ;
584   
585   //Digits loop to fill TRU matrices with amplitudes.
586   for(Int_t idig = 0 ; idig < digits->GetEntriesFast() ; idig++){
587     
588     dig = dynamic_cast<AliEMCALDigit *>(digits->At(idig)) ;
589     amp    = dig->GetAmp() ;   // Energy of the digit (arbitrary units)
590     id     = dig->GetId() ;    // Id label of the cell
591     timeR  = dig->GetTimeR() ; // Earliest time of the digit
592    
593     //Get eta and phi cell position in supermodule
594     Bool_t bCell = fGeom->GetCellIndex(id, iSupMod, nModule, nIphi, nIeta) ;
595     if(!bCell)
596       Error("FillTRU","Wrong cell id number") ;
597     
598     fGeom->GetCellPhiEtaIndexInSModule(iSupMod,nModule,nIphi, nIeta,iphi,ieta);
599
600     //Check to which TRU in the supermodule belongs the cell. 
601     //Supermodules are divided in a TRU matrix of dimension 
602     //(fNTRUPhi,fNTRUEta).
603     //Each TRU is a cell matrix of dimension (nCellsPhi,nCellsEta)
604
605     //First calculate the row and column in the supermodule 
606     //of the TRU to which the cell belongs.
607     Int_t col   = ieta/nCellsEta; 
608     Int_t row   = iphi/nCellsPhi; 
609     if(iSupMod > 9)
610       row   = iphi/nCellsPhi2; 
611     //Calculate label number of the TRU
612     Int_t itru  = row + col*nTRUPhi + iSupMod*nTRU ;  
613  
614     //Fill TRU matrix with cell values
615     TMatrixD * amptrus   = dynamic_cast<TMatrixD *>(ampmatrix->At(itru)) ;
616     TMatrixD * timeRtrus = dynamic_cast<TMatrixD *>(timeRmatrix->At(itru)) ;
617
618     //Calculate row and column of the cell inside the TRU with number itru
619     Int_t irow = iphi - row *  nCellsPhi;
620     if(iSupMod > 9)
621       irow = iphi - row *  nCellsPhi2;
622     Int_t icol = ieta - col *  nCellsEta;
623     
624     (*amptrus)(irow,icol) = amp ;
625     (*timeRtrus)(irow,icol) = timeR ;
626     
627     //####################SUPERMODULE MATRIX ##################
628     TMatrixD * ampsmods   = dynamic_cast<TMatrixD *>(ampmatrixsmod->At(iSupMod)) ;
629     (*ampsmods)(iphi,ieta)   = amp ;
630     
631   }
632 }
633 //____________________________________________________________________________
634 void AliEMCALTrigger::Trigger() 
635 {
636   //Main Method to select triggers.
637   AliRunLoader *runLoader = AliRunLoader::GetRunLoader();
638   AliEMCALLoader *emcalLoader = dynamic_cast<AliEMCALLoader*>
639     (runLoader->GetDetectorLoader("EMCAL"));
640  
641   //Load EMCAL Geometry
642   if (runLoader->GetAliRun() && runLoader->GetAliRun()->GetDetector("EMCAL"))
643     fGeom = dynamic_cast<AliEMCAL*>(runLoader->GetAliRun()->GetDetector("EMCAL"))->GetGeometry();
644   if (fGeom == 0)
645     fGeom = AliEMCALGeometry::GetInstance(AliEMCALGeometry::GetDefaulGeometryName());
646
647   if (fGeom==0)
648     AliFatal("Did not get geometry from EMCALLoader");
649   
650   //Define parameters
651   Int_t nSuperModules = fGeom->GetNumberOfSuperModules() ; //12 SM in EMCAL
652   Int_t nTRU       = fGeom->GetNTRU();    //3 TRU per super module
653
654   //Intialize data members each time the trigger is called in event loop
655   f2x2MaxAmp = -1; f2x2CellPhi = -1;  f2x2CellEta = -1;
656   fnxnMaxAmp = -1; fnxnCellPhi = -1;  fnxnCellEta = -1;
657
658   //Take the digits list if simulation
659   if(fSimulation){
660     runLoader->LoadDigits("EMCAL");
661     fDigitsList = emcalLoader->Digits() ;
662   }
663   if(!fDigitsList)
664     AliFatal("Digits not found !") ;
665   
666   //Take the digits list 
667   
668   //Fill TRU Matrix  
669   TClonesArray * amptrus   = new TClonesArray("TMatrixD",1000);
670   TClonesArray * ampsmods  = new TClonesArray("TMatrixD",1000);
671   TClonesArray * timeRtrus = new TClonesArray("TMatrixD",1000);
672   
673   FillTRU(fDigitsList, amptrus, ampsmods, timeRtrus) ;
674
675   //Do Cell Sliding and select Trigger
676   //Initialize varible that will contain maximum amplitudes and 
677   //its corresponding cell position in eta and phi, and time.
678   TMatrixD ampmax2(4,nTRU) ;
679   TMatrixD ampmaxn(4,nTRU) ;
680   
681   for(Int_t iSM = 0 ; iSM < nSuperModules ; iSM++) {
682     //Do 2x2 and nxn sums, select maximums. 
683     MakeSlidingCell(amptrus, timeRtrus, iSM, ampmax2, ampmaxn);
684     
685     //Set the trigger
686     if(fIsolateInSuperModule)
687       SetTriggers(ampsmods,iSM,ampmax2,ampmaxn) ;
688     if(!fIsolateInSuperModule)
689       SetTriggers(amptrus,iSM,ampmax2,ampmaxn) ;
690   }
691   
692   amptrus->Delete();
693   delete amptrus; amptrus = 0;
694   ampsmods->Delete();
695   delete ampsmods; ampsmods = 0;
696   timeRtrus->Delete();
697   delete timeRtrus; timeRtrus = 0;
698   //Print();
699
700 }