]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ANALYSIS/TenderSupplies/AliEMCALTenderSupply.cxx
8f17c44cad7f3030c63d41b4ed78f1910d229ed7
[u/mrichter/AliRoot.git] / ANALYSIS / TenderSupplies / AliEMCALTenderSupply.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
16
17 ///////////////////////////////////////////////////////////////////////////////
18 //                                                                           //
19 //  EMCAL tender, apply corrections to EMCAl clusters                        //
20 //  and do track matching.                                                   //
21 //  Author: Deepa Thomas (Utrecht University)                                // 
22 //                                                                           //
23 ///////////////////////////////////////////////////////////////////////////////
24
25 #include <TROOT.h>
26 #include <TFile.h>
27 #include <TTree.h>
28 #include <TInterpreter.h>
29 #include <TObjArray.h>
30 #include <TClonesArray.h>
31 #include <TGeoGlobalMagField.h>
32 #include <AliLog.h>
33 #include <AliESDEvent.h>
34 #include <AliAnalysisManager.h>
35 #include <AliTender.h>
36 #include "AliOADBContainer.h"
37 #include "AliCDBManager.h"
38 #include "AliCDBStorage.h"
39 #include "AliCDBEntry.h"
40 #include "AliMagF.h"
41 #include "AliESDCaloCluster.h"
42 #include "AliEMCALTenderSupply.h"
43 #include "AliEMCALGeometry.h"
44 #include "AliEMCALRecoUtils.h"
45 #include "AliEMCALClusterizer.h"
46 #include "AliEMCALRecParam.h"
47 #include "AliEMCALRecPoint.h"
48 #include "AliEMCALAfterBurnerUF.h"
49 #include "AliEMCALClusterizerNxN.h"
50 #include "AliEMCALClusterizerv1.h"
51 #include "AliEMCALClusterizerv2.h"
52 #include "AliEMCALDigit.h"
53 #include "AliEMCALRecParam.h"
54
55 ClassImp(AliEMCALTenderSupply)
56
57 AliEMCALTenderSupply::AliEMCALTenderSupply() :
58 AliTenderSupply()
59 ,fEMCALGeo(0x0)
60 ,fEMCALGeoName("EMCAL_COMPLETEV1")
61 ,fEMCALRecoUtils(0)
62 ,fConfigName("")
63 ,fDebugLevel(0)
64 ,fNonLinearFunc(-1) 
65 ,fNonLinearThreshold(-1)
66 ,fReCalibCluster(kFALSE)
67 ,fUpdateCell(kFALSE)  
68 ,fCalibrateEnergy(kFALSE)
69 ,fCalibrateTime(kFALSE)
70 ,fDoNonLinearity(kFALSE)
71 ,fBadCellRemove(kFALSE)
72 ,fRejectExoticCells(kFALSE)
73 ,fRejectExoticClusters(kFALSE)
74 ,fClusterBadChannelCheck(kFALSE)
75 ,fRecalClusPos(kFALSE)
76 ,fFiducial(kFALSE) 
77 ,fNCellsFromEMCALBorder(-1)
78 ,fRecalDistToBadChannels(kFALSE)
79 ,fRecalShowerShape(kFALSE)
80 ,fInputTree(0)
81 ,fInputFile(0)
82 ,fFilepass(0) 
83 ,fMass(-1)
84 ,fStep(-1)
85 ,fCutEtaPhiSum(kTRUE)
86 ,fCutEtaPhiSeparate(kFALSE)
87 ,fRcut(-1)
88 ,fEtacut(-1)
89 ,fPhicut(-1)
90 ,fBasePath("")
91 ,fReClusterize(kFALSE)
92 ,fClusterizer(0)
93 ,fGeomMatrixSet(kFALSE)
94 ,fLoadGeomMatrices(kFALSE)
95 ,fRecParam(0x0)
96 ,fDoTrackMatch(kFALSE)
97 ,fDoUpdateOnly(kFALSE)
98 ,fUnfolder(0)
99 ,fDigitsArr(0)
100 ,fClusterArr(0)
101 ,fMisalignSurvey(kdefault)  
102 ,fExoticCellFraction(-1)
103 ,fExoticCellDiffTime(-1)
104 ,fExoticCellMinAmplitude(-1)
105 {
106   // Default constructor.
107   for(Int_t i = 0; i < 10; i++) fEMCALMatrix[i] = 0 ;
108 }
109
110 //_____________________________________________________
111 AliEMCALTenderSupply::AliEMCALTenderSupply(const char *name, const AliTender *tender) :
112 AliTenderSupply(name,tender)
113 ,fEMCALGeo(0x0)
114 ,fEMCALGeoName("EMCAL_COMPLETEV1")
115 ,fEMCALRecoUtils(0)
116 ,fConfigName("")
117 ,fDebugLevel(0)
118 ,fNonLinearFunc(-1) 
119 ,fNonLinearThreshold(-1)        
120 ,fReCalibCluster(kFALSE)  
121 ,fUpdateCell(kFALSE)  
122 ,fCalibrateEnergy(kFALSE)
123 ,fCalibrateTime(kFALSE)
124 ,fDoNonLinearity(kFALSE)
125 ,fBadCellRemove(kFALSE)
126 ,fRejectExoticCells(kFALSE)
127 ,fRejectExoticClusters(kFALSE)
128 ,fClusterBadChannelCheck(kFALSE)
129 ,fRecalClusPos(kFALSE)
130 ,fFiducial(kFALSE) 
131 ,fNCellsFromEMCALBorder(-1)  
132 ,fRecalDistToBadChannels(kFALSE)  
133 ,fRecalShowerShape(kFALSE)
134 ,fInputTree(0)  
135 ,fInputFile(0)
136 ,fFilepass(0) 
137 ,fMass(-1)
138 ,fStep(-1)
139 ,fCutEtaPhiSum(kTRUE)
140 ,fCutEtaPhiSeparate(kFALSE)
141 ,fRcut(-1)  
142 ,fEtacut(-1)  
143 ,fPhicut(-1)  
144 ,fBasePath("")
145 ,fReClusterize(kFALSE)
146 ,fClusterizer(0)
147 ,fGeomMatrixSet(kFALSE)
148 ,fLoadGeomMatrices(kFALSE)
149 ,fRecParam(0x0)
150 ,fDoTrackMatch(kFALSE)
151 ,fDoUpdateOnly(kFALSE)
152 ,fUnfolder(0)
153 ,fDigitsArr(0)
154 ,fClusterArr(0)
155 ,fMisalignSurvey(kdefault)  
156 ,fExoticCellFraction(-1)
157 ,fExoticCellDiffTime(-1)
158 ,fExoticCellMinAmplitude(-1)
159 {
160   // Named constructor
161   
162   for(Int_t i = 0; i < 10; i++) fEMCALMatrix[i] = 0 ;
163   fEMCALRecoUtils  = new AliEMCALRecoUtils;
164   fDigitsArr       = new TClonesArray("AliEMCALDigit",1000);
165 }
166
167 //_____________________________________________________
168 AliEMCALTenderSupply::~AliEMCALTenderSupply()
169 {
170   //Destructor
171   
172   delete fEMCALRecoUtils;
173   delete fRecParam;
174   delete fUnfolder;
175   if (!fClusterizer) {
176     fDigitsArr->Clear("C");
177     delete fDigitsArr; 
178   } else {
179     delete fClusterizer;
180     fDigitsArr = 0;
181   }
182 }
183
184 //_____________________________________________________
185 void AliEMCALTenderSupply::Init()
186 {
187   // Initialise EMCAL tender.
188
189   if (fDebugLevel>0) 
190     AliInfo("Init EMCAL Tender supply"); 
191   
192   if (fConfigName.Length()>0 && gROOT->LoadMacro(fConfigName) >=0) {
193     AliDebug(1, Form("Loading settings from macro %s", fConfigName.Data()));
194     AliEMCALTenderSupply *tender = (AliEMCALTenderSupply*)gInterpreter->ProcessLine("ConfigEMCALTenderSupply()");
195     fDebugLevel             = tender->fDebugLevel;
196     fEMCALGeoName           = tender->fEMCALGeoName; 
197     fEMCALRecoUtils         = tender->fEMCALRecoUtils; 
198     fConfigName             = tender->fConfigName;
199     fNonLinearFunc          = tender->fNonLinearFunc;
200     fNonLinearThreshold     = tender->fNonLinearThreshold;
201     fReCalibCluster         = tender->fReCalibCluster;
202     fUpdateCell             = tender->fUpdateCell;
203     fRecalClusPos           = tender->fRecalClusPos;
204     fCalibrateEnergy        = tender->fCalibrateEnergy;
205     fCalibrateTime          = tender->fCalibrateTime;
206     fFiducial               = tender->fFiducial;
207     fNCellsFromEMCALBorder  = tender->fNCellsFromEMCALBorder;
208     fRecalDistToBadChannels = tender->fRecalDistToBadChannels;    
209     fRecalShowerShape       = tender->fRecalShowerShape;
210     fClusterBadChannelCheck = tender->fClusterBadChannelCheck;
211     fBadCellRemove          = tender->fBadCellRemove;
212     fRejectExoticCells      = tender->fRejectExoticCells;
213     fRejectExoticClusters   = tender->fRejectExoticClusters;
214     fMass                   = tender->fMass;
215     fStep                   = tender->fStep;
216     fCutEtaPhiSum           = tender->fCutEtaPhiSum;
217     fCutEtaPhiSeparate      = tender->fCutEtaPhiSeparate;
218     fRcut                   = tender->fRcut;
219     fEtacut                 = tender->fEtacut;
220     fPhicut                 = tender->fPhicut;
221     fReClusterize           = tender->fReClusterize;
222     fLoadGeomMatrices       = tender->fLoadGeomMatrices;
223     fRecParam               = tender->fRecParam;
224     fDoNonLinearity         = tender->fDoNonLinearity;
225     fDoTrackMatch           = tender->fDoTrackMatch;
226     fDoUpdateOnly           = tender->fDoUpdateOnly;
227     fMisalignSurvey         = tender->fMisalignSurvey;
228     fExoticCellFraction     = tender->fExoticCellFraction;
229     fExoticCellDiffTime     = tender->fExoticCellDiffTime;
230     fExoticCellMinAmplitude = tender->fExoticCellMinAmplitude;
231
232     for(Int_t i = 0; i < 10; i++) 
233       fEMCALMatrix[i] = tender->fEMCALMatrix[i] ;
234   }
235
236   // Init geometry  
237   fEMCALGeo = AliEMCALGeometry::GetInstance(fEMCALGeoName) ;
238   
239   // Initialising non-linearity parameters
240   if( fNonLinearThreshold != -1 )
241     fEMCALRecoUtils->SetNonLinearityThreshold(fNonLinearThreshold);
242   if( fNonLinearFunc != -1 )
243     fEMCALRecoUtils->SetNonLinearityFunction(fNonLinearFunc);
244
245   // missalignment function
246   fEMCALRecoUtils->SetPositionAlgorithm(AliEMCALRecoUtils::kPosTowerGlobal);
247
248   // fiducial cut
249   // do not do the eta0 fiducial cut
250   if( fNCellsFromEMCALBorder != -1 )
251     fEMCALRecoUtils->SetNumberOfCellsFromEMCALBorder(fNCellsFromEMCALBorder);
252   fEMCALRecoUtils->SwitchOnNoFiducialBorderInEMCALEta0();
253     
254   // exotic cell rejection
255   if( fExoticCellFraction != -1 )
256     fEMCALRecoUtils->SetExoticCellFractionCut( fExoticCellFraction );
257   if( fExoticCellDiffTime != -1 )
258     fEMCALRecoUtils->SetExoticCellDiffTimeCut( fExoticCellDiffTime );
259   if( fExoticCellMinAmplitude != -1 )
260     fEMCALRecoUtils->SetExoticCellMinAmplitudeCut( fExoticCellMinAmplitude );
261
262   // Setting track matching parameters ... mass, step size and residual cut
263   if( fMass != -1 )
264     fEMCALRecoUtils->SetMass(fMass);
265   if( fStep != -1 )
266     fEMCALRecoUtils->SetStep(fStep);
267   
268   // spatial cut based on separate eta/phi or common processing
269   if(fCutEtaPhiSum){ 
270     fEMCALRecoUtils->SwitchOnCutEtaPhiSum(); 
271     if( fRcut != -1 )
272       fEMCALRecoUtils->SetCutR(fRcut);
273   } else if (fCutEtaPhiSeparate) {
274     fEMCALRecoUtils->SwitchOnCutEtaPhiSeparate();
275     if( fEtacut != -1 )
276       fEMCALRecoUtils->SetCutEta(fEtacut);
277     if( fPhicut != -1 )
278       fEMCALRecoUtils->SetCutPhi(fPhicut);
279   }
280 }
281
282 //_____________________________________________________
283 void AliEMCALTenderSupply::ProcessEvent()
284 {
285   // Event loop.
286   
287   AliESDEvent *event = fTender->GetEvent();
288   if (!event) {
289     AliError("ESD event ptr = 0, returning");
290     return;
291   }
292   
293   // Initialising parameters once per run number
294   if (fTender->RunChanged()){ 
295
296     // initiate default reco params if not supplied by user
297     if (!fRecParam)
298       InitRecParam();
299
300     // get pass
301     GetPass();
302
303     // define what recalib parameters are needed for various switches
304     // this is based on implementation in AliEMCALRecoUtils
305     Bool_t needBadChannels = fBadCellRemove   | fClusterBadChannelCheck | fRecalDistToBadChannels | fReClusterize;
306     Bool_t needRecalib     = fCalibrateEnergy | fReClusterize;
307     Bool_t needTimecalib   = fCalibrateTime   | fReClusterize;
308     Bool_t needMisalign    = fRecalClusPos    | fReClusterize;
309     Bool_t needClusterizer = fReClusterize;
310
311     // Init bad channels
312     if( needBadChannels )
313     {
314       Int_t fInitBC = InitBadChannels();
315       if (fInitBC==0)
316       {
317         AliError("InitBadChannels returned false, returning");
318         return;
319       }
320       if (fInitBC==1)
321       {
322         AliInfo("InitBadChannels OK");
323       }
324       if (fInitBC>1)
325       {
326         AliInfo(Form("No external hot channel set: %d - %s", event->GetRunNumber(), fFilepass.Data()));
327       }
328     }
329
330     // init recalibration factors
331     if( needRecalib ) 
332     { 
333       Int_t fInitRecalib = InitRecalib();
334       if (fInitRecalib==0)
335       {
336         AliError("InitRecalib returned false, returning");
337         return;
338       }
339       if (fInitRecalib==1)
340       {
341         AliInfo("InitRecalib OK");
342       }
343       if (fInitRecalib>1)
344       {
345         AliInfo(Form("No recalibration available: %d - %s", event->GetRunNumber(), fFilepass.Data()));
346         fReCalibCluster = kFALSE;
347       }
348     }
349     
350     // init time calibration
351     if( needTimecalib )
352     {
353       Int_t initTC = InitTimeCalibration();
354       if ( !initTC ) 
355       {
356         AliError("InitTimeCalibration returned false, returning");
357         return;
358       }
359       if (initTC==1)
360       {
361         AliInfo("InitTimeCalib OK");
362       }
363       if( initTC > 1 )
364       {
365         AliInfo(Form("No external time calibration set: %d - %s", event->GetRunNumber(), fFilepass.Data()));
366       }
367     }
368
369     // init misalignment matrix
370     if( needMisalign ) 
371     { 
372       if (!InitMisalignMatrix()) {
373         
374         AliError("InitMisalignmentMatrix returned false, returning");
375         return;
376       }
377       else
378         AliInfo("InitMisalignMatrix OK");
379     }
380     
381     // init clusterizer
382     if( needClusterizer ) 
383     {
384       if (!InitClusterization()) 
385       {
386         AliError("InitClusterization returned false, returning");
387         return;
388       }
389       else
390         AliInfo("InitClusterization OK");
391     }
392     
393     if(fDebugLevel>1) 
394       fEMCALRecoUtils->Print("");
395   }
396   
397   // disable implied switches -------------------------------------------------
398   // AliEMCALRecoUtils or clusterizer functions alredy include some
399   // recalibration so based on those implied callibration te switches
400   // here are disabled to avoid duplication
401     
402   // clusterizer does cluster energy recalibration, position recomputation
403   // and shower shape
404   if( fReClusterize )
405   {
406     fReCalibCluster   = kFALSE;
407     fRecalClusPos     = kFALSE;
408     fRecalShowerShape = kFALSE;
409   }
410   
411   // CONFIGURE THE RECO UTILS -------------------------------------------------
412   // configure the reco utils
413   // this option does energy recalibration
414   if( fCalibrateEnergy )
415     fEMCALRecoUtils->SwitchOnRecalibration();
416   else
417     fEMCALRecoUtils->SwitchOffRecalibration();
418   
419   // allows time calibration
420   if( fCalibrateTime )
421     fEMCALRecoUtils->SwitchOnTimeRecalibration();
422   else
423     fEMCALRecoUtils->SwitchOffTimeRecalibration();
424
425   // allows to zero bad cells
426   if( fBadCellRemove )
427     fEMCALRecoUtils->SwitchOnBadChannelsRemoval();
428   else
429     fEMCALRecoUtils->SwitchOffBadChannelsRemoval();
430   
431   // distance to bad channel recalibration
432   if( fRecalDistToBadChannels )
433     fEMCALRecoUtils->SwitchOnDistToBadChannelRecalculation();
434   else
435     fEMCALRecoUtils->SwitchOffDistToBadChannelRecalculation();
436
437   // exclude exotic cells
438   if( fRejectExoticCells )
439     fEMCALRecoUtils->SwitchOnRejectExoticCell();
440   else
441     fEMCALRecoUtils->SwitchOffRejectExoticCell();
442   
443   // exclude clusters with exotic cells
444   if( fRejectExoticClusters )
445     fEMCALRecoUtils->SwitchOnRejectExoticCluster();
446   else
447     fEMCALRecoUtils->SwitchOffRejectExoticCluster();
448
449   // TODO: not implemented switches
450   // SwitchOnClusterEnergySmearing
451   // SwitchOnRunDepCorrection
452
453   // START PROCESSING ---------------------------------------------------------
454   // Test if cells present
455   AliESDCaloCells *cells= event->GetEMCALCells();
456   if (cells->GetNumberOfCells()<=0) 
457   {
458     if(fDebugLevel>1) 
459       AliWarning(Form("Number of EMCAL cells = %d, returning", cells->GetNumberOfCells()));
460     return;
461   }
462   
463   if (fDebugLevel>2)
464     AliInfo(Form("Re-calibrate cluster %d\n",fReCalibCluster));
465
466   // mark the cells not recalibrated in case of selected
467   // time, energy recalibration or bad channel removal
468   if( fCalibrateEnergy || fCalibrateTime || fBadCellRemove )
469     fEMCALRecoUtils->ResetCellsCalibrated();
470   
471   // CELL RECALIBRATION -------------------------------------------------------
472   // cell objects will be updated
473   // the cell calibrations are also processed locally any time those are needed
474   // in case that the cell objects are not to be updated here for later use
475   if( fUpdateCell )
476   {
477     // do the update
478     // includes exotic cell check in the UpdateCells function - is not provided
479     // by the reco utils
480     UpdateCells();
481
482     // switch off recalibrations so those are not done multiple times
483     // this is just for safety, the recalibrated flag of cell object
484     // should not allow for farther processing anyways
485     fEMCALRecoUtils->SwitchOffRecalibration();
486     fEMCALRecoUtils->SwitchOffTimeRecalibration();  
487   
488     if (fDoUpdateOnly)
489       return;
490   }
491
492   // RECLUSTERIZATION ---------------------------------------------------------
493   if (fReClusterize)
494   {
495     FillDigitsArray();
496     Clusterize();
497     UpdateClusters();
498   }
499   
500   // Store good clusters
501   TClonesArray *clusArr = dynamic_cast<TClonesArray*>(event->FindListObject("caloClusters"));
502   if (!clusArr) 
503     clusArr = dynamic_cast<TClonesArray*>(event->FindListObject("CaloClusters"));
504   if (!clusArr) {
505     AliWarning(Form("No cluster array, number of cells in event = %d, returning", cells->GetNumberOfCells()));
506     return;
507   }
508
509   // PROCESS SINGLE CLUSTER RECALIBRATION -------------------------------------
510   // now go through clusters one by one and process separate correction
511   // as those were defined or not
512   Int_t nclusters = clusArr->GetEntriesFast();
513   for (Int_t icluster=0; icluster < nclusters; ++icluster) 
514   { 
515     AliVCluster *clust = static_cast<AliVCluster*>(clusArr->At(icluster));
516     if (!clust) 
517       continue;
518     if  (!clust->IsEMCAL()) 
519       continue;
520
521     // REMOVE CLUSTERS WITH BAD CELLS -----------------------------
522     if( fClusterBadChannelCheck )
523     {
524       // careful, the the ClusterContainsBadChannel is dependent on
525       // SwitchOnBadChannelsRemoval, switching it ON automatically
526       // and returning to original value after processing
527       Bool_t badRemoval = fEMCALRecoUtils->IsBadChannelsRemovalSwitchedOn();
528       fEMCALRecoUtils->SwitchOnBadChannelsRemoval();
529       
530       Bool_t badResult = fEMCALRecoUtils->ClusterContainsBadChannel(fEMCALGeo, clust->GetCellsAbsId(), clust->GetNCells());
531
532       // switch the bad channels removal back
533       if( ! badRemoval )
534         fEMCALRecoUtils->SwitchOffBadChannelsRemoval();
535       
536       if( badResult )
537       {
538         delete clusArr->RemoveAt(icluster);
539         continue; //TODO is it really needed to remove it? Or should we flag it?
540       }
541     }
542     
543     // REMOVE EXOTIC CLUSTERS -------------------------------------
544     // does process local cell recalibration energy and time without replacing
545     // the global cell values, in case of no cell recalib done yet
546     if( fRejectExoticClusters )
547     {
548       // careful, the IsExoticCluster is dependent on
549       // SwitchOnRejectExoticCell, switching it ON automatically
550       // and returning to original value after processing
551       Bool_t exRemoval = fEMCALRecoUtils->IsRejectExoticCell();
552       fEMCALRecoUtils->SwitchOnRejectExoticCell();
553
554       // get bunch crossing
555       Int_t bunchCrossNo = fTender->GetEvent()->GetBunchCrossNumber();
556
557       Bool_t exResult = fEMCALRecoUtils->IsExoticCluster(clust, cells, bunchCrossNo );
558
559       // switch the exotic channels removal back
560       if( ! exRemoval )
561         fEMCALRecoUtils->SwitchOffRejectExoticCell();
562       
563       if( exResult )
564       {
565         delete clusArr->RemoveAt(icluster);
566         continue; //TODO is it really needed to remove it? Or should we flag it?
567       }
568     }
569     
570     // FIDUCIAL CUT -----------------------------------------------
571     if (fFiducial)
572     {
573       // depends on SetNumberOfCellsFromEMCALBorder
574       // SwitchOnNoFiducialBorderInEMCALEta0
575       if (!fEMCALRecoUtils->CheckCellFiducialRegion(fEMCALGeo, clust, cells)){
576         delete clusArr->RemoveAt(icluster);
577         continue; //TODO it would be nice to store the distance
578       }
579     }
580     
581     // CLUSTER ENERGY ---------------------------------------------
582     // does process local cell recalibration energy and time without replacing
583     // the global cell values, in case of no cell recalib done yet
584     if( fReCalibCluster ) 
585       fEMCALRecoUtils->RecalibrateClusterEnergy(fEMCALGeo, clust, cells);
586
587     // CLUSTER POSITION -------------------------------------------
588     // does process local cell energy recalibration, if enabled and cells
589     // not calibratied yet
590     if( fRecalClusPos ) 
591       fEMCALRecoUtils->RecalculateClusterPosition(fEMCALGeo, cells, clust);
592     
593     // SHOWER SHAPE -----------------------------------------------
594     if( fRecalShowerShape )
595       fEMCALRecoUtils->RecalculateClusterShowerShapeParameters(fEMCALGeo, cells, clust);  
596
597     // NONLINEARITY -----------------------------------------------
598     if( fDoNonLinearity )
599     {
600       Float_t correctedEnergy = fEMCALRecoUtils->CorrectClusterEnergyLinearity(clust);
601       clust->SetE(correctedEnergy);
602     }
603
604     // DISTANCE TO BAD CHANNELS -----------------------------------
605     if( fRecalDistToBadChannels )
606       fEMCALRecoUtils->RecalculateClusterDistanceToBadChannel(fEMCALGeo, cells, clust);  
607   }
608
609   clusArr->Compress();
610
611   if (!fDoTrackMatch)
612     return;
613
614   // TRACK MATCHING -----------------------------------------------------------
615   if (!TGeoGlobalMagField::Instance()->GetField()) 
616   {
617     event->InitMagneticField();
618   }
619   
620   fEMCALRecoUtils->FindMatches(event,0x0,fEMCALGeo);
621   fEMCALRecoUtils->SetClusterMatchedToTrack(event);
622   fEMCALRecoUtils->SetTracksMatchedToCluster(event);
623 }
624
625 //_____________________________________________________
626 Bool_t AliEMCALTenderSupply::InitMisalignMatrix()
627 {
628   // Initialising misalignment matrices
629   
630   AliESDEvent *event = fTender->GetEvent();
631   if (!event) 
632     return kFALSE;
633   
634   if (fGeomMatrixSet) 
635   {
636     AliInfo("Misalignment matrix already set");  
637     return kTRUE;
638   }
639   
640   if (fDebugLevel>0) 
641     AliInfo("Initialising misalignment matrix");  
642   
643   if (fLoadGeomMatrices) {
644     for(Int_t mod=0; mod < fEMCALGeo->GetNumberOfSuperModules(); ++mod)
645     {
646       if (fEMCALMatrix[mod]){
647         if(fDebugLevel > 2) 
648           fEMCALMatrix[mod]->Print();
649         fEMCALGeo->SetMisalMatrix(fEMCALMatrix[mod],mod);  
650       }
651     }
652     fGeomMatrixSet = kTRUE;
653     return kTRUE;
654   }
655   
656   Int_t runGM = event->GetRunNumber();
657   TObjArray *mobj = 0;
658
659  if(fMisalignSurvey == kdefault)
660  { //take default alignment corresponding to run no
661     AliOADBContainer emcalgeoCont(Form("emcal"));
662     emcalgeoCont.InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALlocal2master.root",Form("AliEMCALgeo"));
663     mobj=(TObjArray*)emcalgeoCont.GetObject(runGM,"EmcalMatrices");
664  }
665
666  if(fMisalignSurvey == kSurveybyS)
667  { //take alignment at sector level
668   if (runGM <= 140000) { //2010 data
669     AliOADBContainer emcalgeoCont(Form("emcal2010"));
670     emcalgeoCont.InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALlocal2master.root",Form("AliEMCALgeo"));
671     mobj=(TObjArray*)emcalgeoCont.GetObject(100,"survey10");
672     
673   } else if (runGM>140000)
674   { // 2011 LHC11a pass1 data
675     AliOADBContainer emcalgeoCont(Form("emcal2011"));
676     emcalgeoCont.InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALlocal2master.root",Form("AliEMCALgeo"));
677     mobj=(TObjArray*)emcalgeoCont.GetObject(100,"survey11byS");      
678   }
679  }
680
681  if(fMisalignSurvey == kSurveybyM)
682  { //take alignment at module level
683   if (runGM <= 140000) { //2010 data
684     AliOADBContainer emcalgeoCont(Form("emcal2010"));
685     emcalgeoCont.InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALlocal2master.root",Form("AliEMCALgeo"));
686     mobj=(TObjArray*)emcalgeoCont.GetObject(100,"survey10");
687     
688   } else if (runGM>140000) 
689   { // 2011 LHC11a pass1 data
690     AliOADBContainer emcalgeoCont(Form("emcal2011"));
691     emcalgeoCont.InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALlocal2master.root",Form("AliEMCALgeo"));
692     mobj=(TObjArray*)emcalgeoCont.GetObject(100,"survey11byM");      
693   }
694  }
695
696   if(!mobj)
697   {
698     AliFatal("Geometry matrix array not found");
699     return kFALSE;
700   }
701   
702  for(Int_t mod=0; mod < (fEMCALGeo->GetEMCGeometry())->GetNumberOfSuperModules(); mod++)
703  {
704    fEMCALMatrix[mod] = (TGeoHMatrix*) mobj->At(mod);
705    fEMCALGeo->SetMisalMatrix(fEMCALMatrix[mod],mod); 
706    fEMCALMatrix[mod]->Print();
707  }
708   
709   return kTRUE;
710 }
711
712 //_____________________________________________________
713 Int_t AliEMCALTenderSupply::InitBadChannels()
714 {
715   // Initialising bad channel maps
716   AliESDEvent *event = fTender->GetEvent();
717   if (!event) 
718     return 0;
719   
720   if (fDebugLevel>0) 
721     AliInfo("Initialising Bad channel map");
722   
723   // init default maps first
724   if( !fEMCALRecoUtils->GetEMCALBadChannelStatusMapArray() )
725     fEMCALRecoUtils->InitEMCALBadChannelStatusMap() ;
726   
727   Int_t runBC = event->GetRunNumber();
728   
729   AliOADBContainer *contBC = new AliOADBContainer("");
730   if (fBasePath!="")
731   { //if fBasePath specified in the ->SetBasePath()
732     if (fDebugLevel>0) AliInfo(Form("Loading Bad Channels OADB from given path %s",fBasePath.Data()));
733     
734     TFile *fbad=new TFile(Form("%s/EMCALBadChannels.root",fBasePath.Data()),"read");
735     if (!fbad || fbad->IsZombie())
736     {
737       AliFatal(Form("EMCALBadChannels.root was not found in the path provided: %s",fBasePath.Data()));
738       return 0;
739     }  
740     
741     if (fbad) delete fbad;
742     
743     contBC->InitFromFile(Form("%s/EMCALBadChannels.root",fBasePath.Data()),"AliEMCALBadChannels");    
744   } 
745   else 
746   { // Else choose the one in the $ALICE_ROOT directory
747     if (fDebugLevel>0) AliInfo("Loading Bad Channels OADB from $ALICE_ROOT/OADB/EMCAL");
748     
749     TFile *fbad=new TFile("$ALICE_ROOT/OADB/EMCAL/EMCALBadChannels.root","read");
750     if (!fbad || fbad->IsZombie())
751     {
752       AliFatal("$ALICE_ROOT/OADB/EMCAL/EMCALBadChannels.root was not found");
753       return 0;
754     }  
755       
756     if (fbad) delete fbad;
757     
758     contBC->InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALBadChannels.root","AliEMCALBadChannels"); 
759   }
760   
761   TObjArray *arrayBC=(TObjArray*)contBC->GetObject(runBC);
762   if (!arrayBC)
763   {
764     AliError(Form("No external hot channel set for run number: %d", runBC));
765     return 2; 
766   }
767   
768   TObjArray *arrayBCpass=(TObjArray*)arrayBC->FindObject(fFilepass); // Here, it looks for a specific pass
769   if (!arrayBCpass)
770   {
771     AliError(Form("No external hot channel set for: %d -%s", runBC,fFilepass.Data()));
772     return 2; 
773   }
774
775   if (fDebugLevel>0) arrayBCpass->Print();
776
777   Int_t sms = fEMCALGeo->GetEMCGeometry()->GetNumberOfSuperModules();
778   for (Int_t i=0; i<sms; ++i) 
779   {
780     TH2I *h = fEMCALRecoUtils->GetEMCALChannelStatusMap(i);
781     if (h)
782       delete h;
783     h=(TH2I*)arrayBCpass->FindObject(Form("EMCALBadChannelMap_Mod%d",i));
784
785     if (!h) 
786     {
787       AliError(Form("Can not get EMCALBadChannelMap_Mod%d",i));
788       continue;
789     }
790     h->SetDirectory(0);
791     fEMCALRecoUtils->SetEMCALChannelStatusMap(i,h);
792   }
793   return 1;  
794 }
795
796 //_____________________________________________________
797 Int_t AliEMCALTenderSupply::InitRecalib()
798 {
799   // Initialising recalibration factors.
800   
801   AliESDEvent *event = fTender->GetEvent();
802   if (!event) 
803     return 0;
804   
805   if (fDebugLevel>0) 
806     AliInfo("Initialising recalibration factors");
807   
808   // init default maps first
809   if( !fEMCALRecoUtils->GetEMCALRecalibrationFactorsArray() )
810     fEMCALRecoUtils->InitEMCALRecalibrationFactors() ;
811
812   Int_t runRC = event->GetRunNumber();
813       
814   AliOADBContainer *contRF=new AliOADBContainer("");
815   if (fBasePath!="") 
816   { //if fBasePath specified in the ->SetBasePath()
817     if (fDebugLevel>0)  AliInfo(Form("Loading Recalib OADB from given path %s",fBasePath.Data()));
818     
819     TFile *fRecalib= new TFile(Form("%s/EMCALRecalib.root",fBasePath.Data()),"read");
820     if (!fRecalib || fRecalib->IsZombie()) 
821     {
822       AliFatal(Form("EMCALRecalib.root not found in %s",fBasePath.Data()));
823       return 0;
824     }
825     
826     if (fRecalib) delete fRecalib;
827     
828     contRF->InitFromFile(Form("%s/EMCALRecalib.root",fBasePath.Data()),"AliEMCALRecalib");
829   }
830     else
831     { // Else choose the one in the $ALICE_ROOT directory
832       if (fDebugLevel>0)  AliInfo("Loading Recalib OADB from $ALICE_ROOT/OADB/EMCAL");
833       
834       TFile *fRecalib= new TFile("$ALICE_ROOT/OADB/EMCAL/EMCALRecalib.root","read");
835       if (!fRecalib || fRecalib->IsZombie()) 
836       {
837         AliFatal("$ALICE_ROOT/OADB/EMCAL/EMCALRecalib.root was not found");
838         return 0;
839       }
840       
841       if (fRecalib) delete fRecalib;
842       
843       contRF->InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALRecalib.root","AliEMCALRecalib");     
844     }
845
846   TObjArray *recal=(TObjArray*)contRF->GetObject(runRC); //GetObject(int runnumber)
847   if (!recal)
848   {
849     AliError(Form("No Objects for run: %d",runRC));
850     return 2;
851   } 
852
853   TObjArray *recalpass=(TObjArray*)recal->FindObject(fFilepass);
854   if (!recalpass)
855   {
856     AliError(Form("No Objects for run: %d - %s",runRC,fFilepass.Data()));
857     return 2;
858   }
859
860   TObjArray *recalib=(TObjArray*)recalpass->FindObject("Recalib");
861   if (!recalib)
862   {
863     AliError(Form("No Recalib histos found for  %d - %s",runRC,fFilepass.Data())); 
864     return 2;
865   }
866
867   if (fDebugLevel>0) recalib->Print();
868
869   Int_t sms = fEMCALGeo->GetEMCGeometry()->GetNumberOfSuperModules();
870   for (Int_t i=0; i<sms; ++i) 
871   {
872     TH2F *h = fEMCALRecoUtils->GetEMCALChannelRecalibrationFactors(i);
873     if (h)
874       delete h;
875     h = (TH2F*)recalib->FindObject(Form("EMCALRecalFactors_SM%d",i));
876     if (!h) 
877     {
878       AliError(Form("Could not load EMCALRecalFactors_SM%d",i));
879       continue;
880     }
881     h->SetDirectory(0);
882     fEMCALRecoUtils->SetEMCALChannelRecalibrationFactors(i,h);
883   }
884   return 1;
885 }
886
887 //_____________________________________________________
888 Int_t AliEMCALTenderSupply::InitTimeCalibration()
889 {
890   // Initialising bad channel maps
891   AliESDEvent *event = fTender->GetEvent();
892   if (!event) 
893     return 0;
894   
895   if (fDebugLevel>0) 
896     AliInfo("Initialising time calibration map");
897   
898   // init default maps first
899   if( !fEMCALRecoUtils->GetEMCALTimeRecalibrationFactorsArray() )
900     fEMCALRecoUtils->InitEMCALTimeRecalibrationFactors() ;
901
902   Int_t runBC = event->GetRunNumber();
903   
904   AliOADBContainer *contBC = new AliOADBContainer("");
905   if (fBasePath!="")
906   { //if fBasePath specified in the ->SetBasePath()
907     if (fDebugLevel>0) AliInfo(Form("Loading time calibration OADB from given path %s",fBasePath.Data()));
908     
909     TFile *fbad=new TFile(Form("%s/EMCALTimeCalib.root",fBasePath.Data()),"read");
910     if (!fbad || fbad->IsZombie())
911     {
912       AliFatal(Form("EMCALTimeCalib.root was not found in the path provided: %s",fBasePath.Data()));
913       return 0;
914     }  
915     
916     if (fbad) delete fbad;
917     
918     contBC->InitFromFile(Form("%s/EMCALTimeCalib.root",fBasePath.Data()),"AliEMCALTimeCalib");    
919   } 
920   else 
921   { // Else choose the one in the $ALICE_ROOT directory
922     if (fDebugLevel>0) AliInfo("Loading time calibration OADB from $ALICE_ROOT/OADB/EMCAL");
923     
924     TFile *fbad=new TFile("$ALICE_ROOT/OADB/EMCAL/EMCALTimeCalib.root","read");
925     if (!fbad || fbad->IsZombie())
926     {
927       AliFatal("$ALICE_ROOT/OADB/EMCAL/EMCALTimeCalib.root was not found");
928       return 0;
929     }  
930       
931     if (fbad) delete fbad;
932     
933     contBC->InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALTimeCalib.root","AliEMCALTimeCalib"); 
934   }
935   
936   TObjArray *arrayBC=(TObjArray*)contBC->GetObject(runBC);
937   if (!arrayBC)
938   {
939     AliError(Form("No external time calibration set for run number: %d", runBC));
940     return 2; 
941   }
942   
943   TObjArray *arrayBCpass=(TObjArray*)arrayBC->FindObject(fFilepass); // Here, it looks for a specific pass
944   if (!arrayBCpass)
945   {
946     AliError(Form("No external time calibration set for: %d -%s", runBC,fFilepass.Data()));
947     return 2; 
948   }
949
950   if (fDebugLevel>0) arrayBCpass->Print();
951
952   for( Int_t i = 0; i < 4; i++ )
953   {
954     TH1F *h = fEMCALRecoUtils->GetEMCALChannelTimeRecalibrationFactors( i );
955     if( h )
956       delete h;
957     
958     h = (TH1F*)arrayBCpass->FindObject(Form("hAllTimeAvBC%d",i));
959     
960     if (!h)
961     {
962       AliError(Form("Can not get hAllTimeAvBC%d",i));
963       continue;
964     }
965     h->SetDirectory(0);
966     fEMCALRecoUtils->SetEMCALChannelTimeRecalibrationFactors(i,h);
967   }
968   return 1;  
969 }
970
971 //_____________________________________________________
972 void AliEMCALTenderSupply::UpdateCells()
973 {
974   //Remove bad cells from the cell list
975   //Recalibrate energy and time cells 
976   //This is required for later reclusterization
977
978   AliESDCaloCells *cells = fTender->GetEvent()->GetEMCALCells();
979   Int_t bunchCrossNo = fTender->GetEvent()->GetBunchCrossNumber();
980
981   fEMCALRecoUtils->RecalibrateCells(cells, bunchCrossNo); 
982   
983   // remove exotic cells - loop through cells and zero the exotic ones
984   // just like with bad cell rejection in reco utils (inside RecalibrateCells)
985   if( fRejectExoticCells )
986   {
987     Int_t    absId  =-1;
988     Bool_t   isExot = kFALSE;
989   
990     // loop through cells
991     Int_t nEMcell  = cells->GetNumberOfCells() ;  
992     for (Int_t iCell = 0; iCell < nEMcell; iCell++) 
993     { 
994       absId  = cells->GetCellNumber(iCell);
995     
996       isExot = fEMCALRecoUtils->IsExoticCell( absId, cells, bunchCrossNo ); 
997       // zero if exotic
998       if( isExot )
999         cells->SetCell( iCell, absId, 0.0, 0.0 );
1000     } // cell loop
1001   } // reject exotic cells
1002
1003   cells->Sort();
1004 }
1005
1006 //_____________________________________________________
1007 void AliEMCALTenderSupply::InitRecParam()
1008 {
1009   // Initalize the reconstructor parameters
1010   // Depending on the data type, different type of clusterizer
1011   
1012   if (fDebugLevel>0) 
1013     AliInfo("Initialize the recParam");
1014
1015   fRecParam = new AliEMCALRecParam;
1016   const AliESDRun *run = fTender->GetEvent()->GetESDRun();
1017   TString bt(run->GetBeamType());
1018   if (bt=="A-A") 
1019   {
1020     fRecParam->SetClusterizerFlag(AliEMCALRecParam::kClusterizerv2);
1021     fRecParam->SetClusteringThreshold(0.100);
1022     fRecParam->SetMinECut(0.050);
1023   } 
1024   else 
1025   {
1026     fRecParam->SetClusterizerFlag(AliEMCALRecParam::kClusterizerv1);
1027     fRecParam->SetClusteringThreshold(0.100);
1028     fRecParam->SetMinECut(0.050);
1029   }
1030 }
1031
1032 //_____________________________________________________
1033 Bool_t AliEMCALTenderSupply::InitClusterization()
1034 {
1035   // Initialing clusterization/unfolding algorithm and set all the needed parameters.
1036   
1037   AliESDEvent *event = fTender->GetEvent();
1038   if (!event) 
1039     return kFALSE;
1040   
1041   if (fDebugLevel>0) 
1042     AliInfo(Form("Initialising reclustering parameters: Clusterizer type: %d",fRecParam->GetClusterizerFlag()));
1043   
1044   //---setup clusterizer
1045   delete fClusterizer;
1046   if     (fRecParam->GetClusterizerFlag() == AliEMCALRecParam::kClusterizerv1)
1047     fClusterizer = new AliEMCALClusterizerv1 (fEMCALGeo);
1048   else if (fRecParam->GetClusterizerFlag() == AliEMCALRecParam::kClusterizerv2) 
1049     fClusterizer = new AliEMCALClusterizerv2(fEMCALGeo);
1050   else if (fRecParam->GetClusterizerFlag() == AliEMCALRecParam::kClusterizerNxN) 
1051   {
1052     AliEMCALClusterizerNxN *clusterizer = new AliEMCALClusterizerNxN(fEMCALGeo);
1053     clusterizer->SetNRowDiff(fRecParam->GetNRowDiff());
1054     clusterizer->SetNColDiff(fRecParam->GetNColDiff());
1055     fClusterizer = clusterizer;
1056   } 
1057   else 
1058   {
1059     AliFatal(Form("Clusterizer < %d > not available", fRecParam->GetClusterizerFlag()));
1060     return kFALSE;
1061   }
1062   
1063   // Set the clustering parameters
1064   fClusterizer->SetECAClusteringThreshold( fRecParam->GetClusteringThreshold() );
1065   fClusterizer->SetECALogWeight          ( fRecParam->GetW0()                  );
1066   fClusterizer->SetMinECut               ( fRecParam->GetMinECut()             );    
1067   fClusterizer->SetUnfolding             ( fRecParam->GetUnfold()              );
1068   fClusterizer->SetECALocalMaxCut        ( fRecParam->GetLocMaxCut()           );
1069   fClusterizer->SetTimeCut               ( fRecParam->GetTimeCut()             );
1070   fClusterizer->SetTimeMin               ( fRecParam->GetTimeMin()             );
1071   fClusterizer->SetTimeMax               ( fRecParam->GetTimeMax()             );
1072   fClusterizer->SetInputCalibrated       ( kTRUE                               );
1073   fClusterizer->SetJustClusters          ( kTRUE                               );  
1074   
1075   // In case of unfolding after clusterization is requested, set the corresponding parameters
1076   if (fRecParam->GetUnfold()) 
1077   {
1078     for (Int_t i = 0; i < 8; ++i) 
1079     {
1080       fClusterizer->SetSSPars(i, fRecParam->GetSSPars(i));
1081     }
1082     for (Int_t i = 0; i < 3; ++i)
1083     {
1084       fClusterizer->SetPar5  (i, fRecParam->GetPar5(i));
1085       fClusterizer->SetPar6  (i, fRecParam->GetPar6(i));
1086     }
1087     fClusterizer->InitClusterUnfolding();
1088   }
1089   
1090   fClusterizer->SetDigitsArr(fDigitsArr);
1091   fClusterizer->SetOutput(0);
1092   fClusterArr = const_cast<TObjArray *>(fClusterizer->GetRecPoints());
1093   return kTRUE;
1094 }
1095
1096 //_____________________________________________________
1097 void AliEMCALTenderSupply::FillDigitsArray()
1098 {
1099   // Fill digits from cells to a TClonesArray.
1100   
1101   AliESDEvent *event = fTender->GetEvent();
1102   if (!event)
1103     return;
1104   
1105   fDigitsArr->Clear("C");
1106   AliESDCaloCells *cells = event->GetEMCALCells();
1107   Int_t ncells = cells->GetNumberOfCells();
1108   for (Int_t icell = 0, idigit = 0; icell < ncells; ++icell) 
1109   {
1110     Double_t cellAmplitude=0, cellTime=0;
1111     Short_t  cellNumber=0;
1112
1113     if (cells->GetCell(icell, cellNumber, cellAmplitude, cellTime) != kTRUE)
1114       break;
1115
1116     // Do not add if already too low (some cells set to 0 if bad channels)
1117     if (cellAmplitude < fRecParam->GetMinECut() ) 
1118       continue;
1119
1120     // If requested, do not include exotic cells
1121    if (fEMCALRecoUtils->IsExoticCell(cellNumber,cells,event->GetBunchCrossNumber())) 
1122       continue;
1123         
1124     AliEMCALDigit *digit = static_cast<AliEMCALDigit*>(fDigitsArr->New(idigit));
1125     digit->SetId(cellNumber);
1126     digit->SetTime(cellTime);
1127     digit->SetTimeR(cellTime);
1128     digit->SetIndexInList(idigit);
1129     digit->SetType(AliEMCALDigit::kHG);
1130     digit->SetAmplitude(cellAmplitude);
1131     idigit++;
1132   }
1133 }
1134
1135 //_____________________________________________________
1136 void AliEMCALTenderSupply::Clusterize()
1137 {
1138   // Clusterize.
1139   
1140   fClusterizer->Digits2Clusters("");
1141 }
1142
1143 //_____________________________________________________
1144 void AliEMCALTenderSupply::UpdateClusters()
1145 {
1146   // Update ESD cluster list.
1147   
1148   AliESDEvent *event = fTender->GetEvent();
1149   if (!event)
1150     return;
1151   
1152   TClonesArray *clus = dynamic_cast<TClonesArray*>(event->FindListObject("caloClusters"));
1153   if (!clus) 
1154     clus = dynamic_cast<TClonesArray*>(event->FindListObject("CaloClusters"));
1155   if (!clus) 
1156   {
1157     AliError(" Null pointer to calo clusters array, returning");
1158     return;
1159   }
1160   
1161   Int_t nents = clus->GetEntriesFast();
1162   for (Int_t i=0; i < nents; ++i) 
1163   {
1164     AliESDCaloCluster *c = static_cast<AliESDCaloCluster*>(clus->At(i));
1165     if (!c)
1166       continue;
1167     if (c->IsEMCAL())
1168       delete clus->RemoveAt(i);
1169   }
1170   
1171   clus->Compress();
1172   
1173   RecPoints2Clusters(clus);
1174   
1175 }
1176
1177 //_____________________________________________________
1178 void AliEMCALTenderSupply::RecPoints2Clusters(TClonesArray *clus)
1179 {
1180   // Convert AliEMCALRecoPoints to AliESDCaloClusters.
1181   // Cluster energy, global position, cells and their amplitude fractions are restored.
1182   
1183   AliESDEvent *event = fTender->GetEvent();
1184   if (!event)
1185     return;
1186
1187   Int_t ncls = fClusterArr->GetEntriesFast();
1188   for(Int_t i=0, nout=clus->GetEntriesFast(); i < ncls; ++i) 
1189   {
1190     AliEMCALRecPoint *recpoint = static_cast<AliEMCALRecPoint*>(fClusterArr->At(i));
1191     
1192     Int_t ncellsTrue = 0;
1193     const Int_t ncells = recpoint->GetMultiplicity();
1194     UShort_t   absIds[ncells];  
1195     Double32_t ratios[ncells];
1196     Int_t *dlist = recpoint->GetDigitsList();
1197     Float_t *elist = recpoint->GetEnergiesList();
1198     for (Int_t c = 0; c < ncells; ++c) 
1199     {
1200       AliEMCALDigit *digit = static_cast<AliEMCALDigit*>(fDigitsArr->At(dlist[c]));
1201       absIds[ncellsTrue] = digit->GetId();
1202       ratios[ncellsTrue] = elist[c]/digit->GetAmplitude();
1203       if (ratios[ncellsTrue] < 0.001) 
1204         continue;
1205       ++ncellsTrue;
1206     }
1207     
1208     if (ncellsTrue < 1) 
1209     {
1210       AliWarning("Skipping cluster with no cells");
1211       continue;
1212     }
1213     
1214     // calculate new cluster position
1215     TVector3 gpos;
1216     recpoint->GetGlobalPosition(gpos);
1217     Float_t g[3];
1218     gpos.GetXYZ(g);
1219     
1220     AliESDCaloCluster *c = static_cast<AliESDCaloCluster*>(clus->New(nout++));
1221     c->SetID(nout-1); 
1222     c->SetType(AliVCluster::kEMCALClusterv1);
1223     c->SetE(recpoint->GetEnergy());
1224     c->SetPosition(g);
1225     c->SetNCells(ncellsTrue);
1226     c->SetDispersion(recpoint->GetDispersion());
1227     c->SetEmcCpvDistance(-1);            //not yet implemented
1228     c->SetChi2(-1);                      //not yet implemented
1229     c->SetTOF(recpoint->GetTime()) ;     //time-of-flight
1230     c->SetNExMax(recpoint->GetNExMax()); //number of local maxima
1231     Float_t elipAxis[2];
1232     recpoint->GetElipsAxis(elipAxis);
1233     c->SetM02(elipAxis[0]*elipAxis[0]) ;
1234     c->SetM20(elipAxis[1]*elipAxis[1]) ;
1235     AliESDCaloCluster *cesd = static_cast<AliESDCaloCluster*>(c);
1236     cesd->SetCellsAbsId(absIds);
1237     cesd->SetCellsAmplitudeFraction(ratios);
1238   }
1239 }
1240
1241 //_____________________________________________________
1242 void AliEMCALTenderSupply::GetPass()
1243 {
1244   // Get passx from filename.
1245   
1246   AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
1247   fInputTree = mgr->GetTree();
1248   
1249   if (!fInputTree) 
1250   {
1251     AliError("Pointer to tree = 0, returning");
1252     return;
1253   }
1254   
1255   fInputFile = fInputTree->GetCurrentFile();
1256   if (!fInputFile) {
1257     AliError("Null pointer input file, returning");
1258     return;
1259   }
1260   
1261   TString fname(fInputFile->GetName());
1262   if      (fname.Contains("pass1")) fFilepass = TString("pass1");
1263   else if (fname.Contains("pass2")) fFilepass = TString("pass2");
1264   else if (fname.Contains("pass3")) fFilepass = TString("pass3");
1265   else 
1266   {
1267     AliError(Form("Pass number string not found: %s", fname.Data()));
1268     return;            
1269   }
1270 }
1271