]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ANALYSIS/TenderSupplies/AliEMCALTenderSupply.cxx
Merge branch 'master' into TPCdev
[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 //  EMCAL tender, apply corrections to EMCAL clusters and do track matching. //
19 //                                                                           //
20 //  Author: Deepa Thomas (Utrecht University)                                // 
21 //  Later mods/rewrite: Jiri Kral (University of Jyvaskyla)                  //
22 //  S. Aiola, C. Loizides : Make it work for AODs                            //
23 //                                                                           //
24 ///////////////////////////////////////////////////////////////////////////////
25
26 #include <TROOT.h>
27 #include <TFile.h>
28 #include <TTree.h>
29 #include <TInterpreter.h>
30 #include <TObjArray.h>
31 #include <TClonesArray.h>
32 #include <TGeoGlobalMagField.h>
33 #include "AliEMCALAfterBurnerUF.h"
34 #include "AliEMCALClusterizer.h"
35 #include "AliEMCALClusterizerNxN.h"
36 #include "AliEMCALClusterizerv1.h"
37 #include "AliEMCALClusterizerv2.h"
38 #include "AliEMCALDigit.h"
39 #include "AliEMCALGeometry.h"
40 #include "AliEMCALRecParam.h"
41 #include "AliEMCALRecParam.h"
42 #include "AliEMCALRecPoint.h"
43 #include "AliEMCALRecoUtils.h"
44 #include "AliEMCALTenderSupply.h"
45 #include "AliESDCaloCluster.h"
46 #include "AliMagF.h"
47 #include "AliOADBContainer.h"
48 #include "AliAODEvent.h"
49 #include "AliAnalysisManager.h"
50 #include "AliESDEvent.h"
51 #include "AliLog.h"
52 #include "AliTender.h"
53 #include "AliAODMCParticle.h"
54
55 ClassImp(AliEMCALTenderSupply)
56
57 AliEMCALTenderSupply::AliEMCALTenderSupply() :
58 AliTenderSupply()
59 ,fTask(0)
60 ,fRun(0)
61 ,fEMCALGeo(0x0)
62 ,fEMCALGeoName("")
63 ,fEMCALRecoUtils(0)
64 ,fConfigName("")
65 ,fDebugLevel(0)
66 ,fNonLinearFunc(-1) 
67 ,fNonLinearThreshold(-1)
68 ,fReCalibCluster(kFALSE)
69 ,fUpdateCell(kFALSE)  
70 ,fCalibrateEnergy(kFALSE)
71 ,fCalibrateTime(kFALSE)
72 ,fCalibrateTimeParamAvailable(kFALSE)
73 ,fDoNonLinearity(kFALSE)
74 ,fBadCellRemove(kFALSE)
75 ,fRejectExoticCells(kFALSE)
76 ,fRejectExoticClusters(kFALSE)
77 ,fClusterBadChannelCheck(kFALSE)
78 ,fRecalClusPos(kFALSE)
79 ,fFiducial(kFALSE) 
80 ,fNCellsFromEMCALBorder(-1)
81 ,fRecalDistToBadChannels(kFALSE)
82 ,fRecalShowerShape(kFALSE)
83 ,fInputTree(0)
84 ,fInputFile(0)
85 ,fGetPassFromFileName(kTRUE)
86 ,fFilepass(0) 
87 ,fMass(-1)
88 ,fStep(-1)
89 ,fCutEtaPhiSum(kTRUE)
90 ,fCutEtaPhiSeparate(kFALSE)
91 ,fRcut(-1)
92 ,fEtacut(-1)
93 ,fPhicut(-1)
94 ,fBasePath("")
95 ,fReClusterize(kFALSE)
96 ,fClusterizer(0)
97 ,fGeomMatrixSet(kFALSE)
98 ,fLoadGeomMatrices(kFALSE)
99 ,fRecParam(0x0)
100 ,fDoTrackMatch(kFALSE)
101 ,fDoUpdateOnly(kFALSE)
102 ,fUnfolder(0)
103 ,fDigitsArr(0)
104 ,fClusterArr(0)
105 ,fMisalignSurvey(kdefault)  
106 ,fExoticCellFraction(-1)
107 ,fExoticCellDiffTime(-1)
108 ,fExoticCellMinAmplitude(-1)
109 ,fSetCellMCLabelFromCluster(0)
110 ,fTempClusterArr(0)
111 ,fRemapMCLabelForAODs(0)
112
113 {
114   // Default constructor.
115
116   for(Int_t i = 0; i < 12;    i++) fEMCALMatrix[i]      = 0 ;
117   for(Int_t j = 0; j < 12672; j++) fOrgClusterCellId[j] = -1;
118 }
119
120 //_____________________________________________________
121 AliEMCALTenderSupply::AliEMCALTenderSupply(const char *name, const AliTender *tender) :
122 AliTenderSupply(name,tender)
123 ,fTask(0)
124 ,fRun(0)
125 ,fEMCALGeo(0x0)
126 ,fEMCALGeoName("")
127 ,fEMCALRecoUtils(0)
128 ,fConfigName("")
129 ,fDebugLevel(0)
130 ,fNonLinearFunc(-1) 
131 ,fNonLinearThreshold(-1)        
132 ,fReCalibCluster(kFALSE)  
133 ,fUpdateCell(kFALSE)  
134 ,fCalibrateEnergy(kFALSE)
135 ,fCalibrateTime(kFALSE)
136 ,fCalibrateTimeParamAvailable(kFALSE)
137 ,fDoNonLinearity(kFALSE)
138 ,fBadCellRemove(kFALSE)
139 ,fRejectExoticCells(kFALSE)
140 ,fRejectExoticClusters(kFALSE)
141 ,fClusterBadChannelCheck(kFALSE)
142 ,fRecalClusPos(kFALSE)
143 ,fFiducial(kFALSE) 
144 ,fNCellsFromEMCALBorder(-1)  
145 ,fRecalDistToBadChannels(kFALSE)  
146 ,fRecalShowerShape(kFALSE)
147 ,fInputTree(0)  
148 ,fInputFile(0)
149 ,fGetPassFromFileName(kTRUE)
150 ,fFilepass("") 
151 ,fMass(-1)
152 ,fStep(-1)
153 ,fCutEtaPhiSum(kTRUE)
154 ,fCutEtaPhiSeparate(kFALSE)
155 ,fRcut(-1)  
156 ,fEtacut(-1)  
157 ,fPhicut(-1)  
158 ,fBasePath("")
159 ,fReClusterize(kFALSE)
160 ,fClusterizer(0)
161 ,fGeomMatrixSet(kFALSE)
162 ,fLoadGeomMatrices(kFALSE)
163 ,fRecParam(0x0)
164 ,fDoTrackMatch(kFALSE)
165 ,fDoUpdateOnly(kFALSE)
166 ,fUnfolder(0)
167 ,fDigitsArr(0)
168 ,fClusterArr(0)
169 ,fMisalignSurvey(kdefault)  
170 ,fExoticCellFraction(-1)
171 ,fExoticCellDiffTime(-1)
172 ,fExoticCellMinAmplitude(-1)
173 ,fSetCellMCLabelFromCluster(0)
174 ,fTempClusterArr(0)
175 ,fRemapMCLabelForAODs(0)
176
177 {
178   // Named constructor
179   
180   for(Int_t i = 0; i < 12;    i++) fEMCALMatrix[i]      = 0 ;
181   for(Int_t j = 0; j < 12672; j++) fOrgClusterCellId[j] = -1;
182 }
183
184 //_____________________________________________________
185 AliEMCALTenderSupply::AliEMCALTenderSupply(const char *name, AliAnalysisTaskSE *task) :
186 AliTenderSupply(name)
187 ,fTask(task)
188 ,fRun(0)
189 ,fEMCALGeo(0x0)
190 ,fEMCALGeoName("")
191 ,fEMCALRecoUtils(0)
192 ,fConfigName("")
193 ,fDebugLevel(0)
194 ,fNonLinearFunc(-1) 
195 ,fNonLinearThreshold(-1)        
196 ,fReCalibCluster(kFALSE)  
197 ,fUpdateCell(kFALSE)  
198 ,fCalibrateEnergy(kFALSE)
199 ,fCalibrateTime(kFALSE)
200 ,fCalibrateTimeParamAvailable(kFALSE)
201 ,fDoNonLinearity(kFALSE)
202 ,fBadCellRemove(kFALSE)
203 ,fRejectExoticCells(kFALSE)
204 ,fRejectExoticClusters(kFALSE)
205 ,fClusterBadChannelCheck(kFALSE)
206 ,fRecalClusPos(kFALSE)
207 ,fFiducial(kFALSE) 
208 ,fNCellsFromEMCALBorder(-1)  
209 ,fRecalDistToBadChannels(kFALSE)  
210 ,fRecalShowerShape(kFALSE)
211 ,fInputTree(0)  
212 ,fInputFile(0)
213 ,fGetPassFromFileName(kTRUE)
214 ,fFilepass("") 
215 ,fMass(-1)
216 ,fStep(-1)
217 ,fCutEtaPhiSum(kTRUE)
218 ,fCutEtaPhiSeparate(kFALSE)
219 ,fRcut(-1)  
220 ,fEtacut(-1)  
221 ,fPhicut(-1)  
222 ,fBasePath("")
223 ,fReClusterize(kFALSE)
224 ,fClusterizer(0)
225 ,fGeomMatrixSet(kFALSE)
226 ,fLoadGeomMatrices(kFALSE)
227 ,fRecParam(0x0)
228 ,fDoTrackMatch(kFALSE)
229 ,fDoUpdateOnly(kFALSE)
230 ,fUnfolder(0)
231 ,fDigitsArr(0)
232 ,fClusterArr(0)
233 ,fMisalignSurvey(kdefault)  
234 ,fExoticCellFraction(-1)
235 ,fExoticCellDiffTime(-1)
236 ,fExoticCellMinAmplitude(-1)
237 ,fSetCellMCLabelFromCluster(0)
238 ,fTempClusterArr(0)
239 ,fRemapMCLabelForAODs(0)
240 {
241   // Named constructor.
242   
243   for(Int_t i = 0; i < 12;    i++) fEMCALMatrix[i]      = 0 ;
244   for(Int_t j = 0; j < 12672; j++) fOrgClusterCellId[j] = -1;
245 }
246
247 //_____________________________________________________
248 AliEMCALTenderSupply::~AliEMCALTenderSupply()
249 {
250   //Destructor
251
252   if (!AliAnalysisManager::GetAnalysisManager())  return;  
253
254   if (!AliAnalysisManager::GetAnalysisManager()->IsProofMode()) 
255   {
256     delete fEMCALRecoUtils;
257     delete fRecParam;
258     delete fUnfolder;
259     
260     if (!fClusterizer) 
261     {
262       if (fDigitsArr) 
263       { 
264         fDigitsArr->Clear("C");
265         delete fDigitsArr; 
266       }
267     } 
268     else 
269     {
270       delete fClusterizer;
271       fDigitsArr = 0;
272     }
273   }
274 }
275
276 //_____________________________________________________
277 void AliEMCALTenderSupply::SetDefaults()
278 {
279   // Set default settings.
280
281   SwitchOnBadCellRemove();
282   SwitchOnExoticCellRemove();
283   SwitchOnCalibrateEnergy();
284   SwitchOnCalibrateTime();
285   SwitchOnUpdateCell();
286   SwitchOnReclustering();
287   SwitchOnClusterBadChannelCheck();
288   SwitchOnClusterExoticChannelCheck();
289   SwitchOnTrackMatch();
290 }
291
292 //_____________________________________________________
293 Bool_t AliEMCALTenderSupply::RunChanged() const
294 {
295   // Get run number.
296
297   return (fTender && fTender->RunChanged()) || (fTask && fRun != fTask->InputEvent()->GetRunNumber()); 
298 }
299
300 //_____________________________________________________
301 void AliEMCALTenderSupply::Init()
302 {
303   // Initialise EMCAL tender.
304
305   if (fDebugLevel>0) 
306     AliWarning("Init EMCAL Tender supply"); 
307   
308   if (fConfigName.Length()>0 && gROOT->LoadMacro(fConfigName) >=0) {
309     AliDebug(1, Form("Loading settings from macro %s", fConfigName.Data()));
310     AliEMCALTenderSupply *tender = (AliEMCALTenderSupply*)gInterpreter->ProcessLine("ConfigEMCALTenderSupply()");
311     fDebugLevel             = tender->fDebugLevel;
312     fEMCALGeoName           = tender->fEMCALGeoName; 
313     fEMCALRecoUtils         = tender->fEMCALRecoUtils; 
314     fConfigName             = tender->fConfigName;
315     fNonLinearFunc          = tender->fNonLinearFunc;
316     fNonLinearThreshold     = tender->fNonLinearThreshold;
317     fReCalibCluster         = tender->fReCalibCluster;
318     fUpdateCell             = tender->fUpdateCell;
319     fRecalClusPos           = tender->fRecalClusPos;
320     fCalibrateEnergy        = tender->fCalibrateEnergy;
321     fCalibrateTime          = tender->fCalibrateTime;
322     fCalibrateTimeParamAvailable = tender->fCalibrateTimeParamAvailable;
323     fFiducial               = tender->fFiducial;
324     fNCellsFromEMCALBorder  = tender->fNCellsFromEMCALBorder;
325     fRecalDistToBadChannels = tender->fRecalDistToBadChannels;    
326     fRecalShowerShape       = tender->fRecalShowerShape;
327     fClusterBadChannelCheck = tender->fClusterBadChannelCheck;
328     fBadCellRemove          = tender->fBadCellRemove;
329     fRejectExoticCells      = tender->fRejectExoticCells;
330     fRejectExoticClusters   = tender->fRejectExoticClusters;
331     fMass                   = tender->fMass;
332     fStep                   = tender->fStep;
333     fCutEtaPhiSum           = tender->fCutEtaPhiSum;
334     fCutEtaPhiSeparate      = tender->fCutEtaPhiSeparate;
335     fRcut                   = tender->fRcut;
336     fEtacut                 = tender->fEtacut;
337     fPhicut                 = tender->fPhicut;
338     fReClusterize           = tender->fReClusterize;
339     fLoadGeomMatrices       = tender->fLoadGeomMatrices;
340     fRecParam               = tender->fRecParam;
341     fDoNonLinearity         = tender->fDoNonLinearity;
342     fDoTrackMatch           = tender->fDoTrackMatch;
343     fDoUpdateOnly           = tender->fDoUpdateOnly;
344     fMisalignSurvey         = tender->fMisalignSurvey;
345     fExoticCellFraction     = tender->fExoticCellFraction;
346     fExoticCellDiffTime     = tender->fExoticCellDiffTime;
347     fExoticCellMinAmplitude = tender->fExoticCellMinAmplitude;
348
349     for(Int_t i = 0; i < 12; i++) 
350       fEMCALMatrix[i] = tender->fEMCALMatrix[i] ;
351   }
352   
353   if (fDebugLevel>0){
354     AliInfo( "Emcal Tender settings: ======================================" ); 
355     AliInfo( "------------ Switches --------------------------" ); 
356     AliInfo( Form( "BadCellRemove : %d", fBadCellRemove )); 
357     AliInfo( Form( "ExoticCellRemove : %d", fRejectExoticCells )); 
358     AliInfo( Form( "CalibrateEnergy : %d", fCalibrateEnergy )); 
359     AliInfo( Form( "CalibrateTime : %d", fCalibrateTime )); 
360     AliInfo( Form( "UpdateCell : %d", fUpdateCell )); 
361     AliInfo( Form( "DoUpdateOnly : %d", fDoUpdateOnly )); 
362     AliInfo( Form( "Reclustering : %d", fReClusterize )); 
363     AliInfo( Form( "ClusterBadChannelCheck : %d", fClusterBadChannelCheck )); 
364     AliInfo( Form( "ClusterExoticChannelCheck : %d", fRejectExoticClusters )); 
365     AliInfo( Form( "CellFiducialRegion : %d", fFiducial )); 
366     AliInfo( Form( "ReCalibrateCluster : %d", fReCalibCluster )); 
367     AliInfo( Form( "RecalculateClusPos : %d", fRecalClusPos )); 
368     AliInfo( Form( "RecalShowerShape : %d", fRecalShowerShape )); 
369     AliInfo( Form( "NonLinearityCorrection : %d", fDoNonLinearity )); 
370     AliInfo( Form( "RecalDistBadChannel : %d", fRecalDistToBadChannels )); 
371     AliInfo( Form( "TrackMatch : %d", fDoTrackMatch )); 
372     AliInfo( "------------ Variables -------------------------" ); 
373     AliInfo( Form( "DebugLevel : %d", fDebugLevel )); 
374     AliInfo( Form( "BasePath : %s", fBasePath.Data() )); 
375     AliInfo( Form( "ConfigFileName : %s", fConfigName.Data() )); 
376     AliInfo( Form( "EMCALGeometryName : %s", fEMCALGeoName.Data() )); 
377     AliInfo( Form( "NonLinearityFunction : %d", fNonLinearFunc )); 
378     AliInfo( Form( "NonLinearityThreshold : %d", fNonLinearThreshold )); 
379     AliInfo( Form( "MisalignmentMatrixSurvey : %d", fMisalignSurvey )); 
380     AliInfo( Form( "NumberOfCellsFromEMCALBorder : %d", fNCellsFromEMCALBorder )); 
381     AliInfo( Form( "RCut : %f", fRcut )); 
382     AliInfo( Form( "Mass : %f", fMass )); 
383     AliInfo( Form( "Step : %f", fStep )); 
384     AliInfo( Form( "EtaCut : %f", fEtacut )); 
385     AliInfo( Form( "PhiCut : %f", fPhicut )); 
386     AliInfo( Form( "ExoticCellFraction : %f", fExoticCellFraction )); 
387     AliInfo( Form( "ExoticCellDiffTime : %f", fExoticCellDiffTime )); 
388     AliInfo( Form( "ExoticCellMinAmplitude : %f", fExoticCellMinAmplitude )); 
389     AliInfo( "=============================================================" ); 
390   }
391
392   // init reco utils
393   
394   if(!fEMCALRecoUtils)
395     fEMCALRecoUtils  = new AliEMCALRecoUtils;
396
397   // init geometry if requested
398   if (fEMCALGeoName.Length()>0) 
399     fEMCALGeo = AliEMCALGeometry::GetInstance(fEMCALGeoName) ;
400
401   // digits array
402   fDigitsArr       = new TClonesArray("AliEMCALDigit",1000);
403
404   // initialising non-linearity parameters
405   if( fNonLinearThreshold != -1 )
406     fEMCALRecoUtils->SetNonLinearityThreshold(fNonLinearThreshold);
407   if( fNonLinearFunc != -1 )
408     fEMCALRecoUtils->SetNonLinearityFunction(fNonLinearFunc);
409
410   // missalignment function
411   fEMCALRecoUtils->SetPositionAlgorithm(AliEMCALRecoUtils::kPosTowerGlobal);
412
413   // fiducial cut
414   // do not do the eta0 fiducial cut
415   if( fNCellsFromEMCALBorder != -1 )
416     fEMCALRecoUtils->SetNumberOfCellsFromEMCALBorder(fNCellsFromEMCALBorder);
417   fEMCALRecoUtils->SwitchOnNoFiducialBorderInEMCALEta0();
418     
419   // exotic cell rejection
420   if( fExoticCellFraction != -1 )
421     fEMCALRecoUtils->SetExoticCellFractionCut( fExoticCellFraction );
422   if( fExoticCellDiffTime != -1 )
423     fEMCALRecoUtils->SetExoticCellDiffTimeCut( fExoticCellDiffTime );
424   if( fExoticCellMinAmplitude != -1 )
425     fEMCALRecoUtils->SetExoticCellMinAmplitudeCut( fExoticCellMinAmplitude );
426
427   // setting track matching parameters ... mass, step size and residual cut
428   if( fMass != -1 )
429     fEMCALRecoUtils->SetMass(fMass);
430   if( fStep != -1 )
431     fEMCALRecoUtils->SetStep(fStep);
432   
433   // spatial cut based on separate eta/phi or common processing
434   if(fCutEtaPhiSum){ 
435     fEMCALRecoUtils->SwitchOnCutEtaPhiSum(); 
436     if( fRcut != -1 )
437       fEMCALRecoUtils->SetCutR(fRcut);
438   } else if (fCutEtaPhiSeparate) {
439     fEMCALRecoUtils->SwitchOnCutEtaPhiSeparate();
440     if( fEtacut != -1 )
441       fEMCALRecoUtils->SetCutEta(fEtacut);
442     if( fPhicut != -1 )
443       fEMCALRecoUtils->SetCutPhi(fPhicut);
444   }
445 }
446
447 //_____________________________________________________
448 AliVEvent* AliEMCALTenderSupply::GetEvent()
449 {
450   // Return the event pointer.
451   
452   if (fTender) {
453     return fTender->GetEvent();
454   }
455   else if (fTask) {
456     return fTask->InputEvent();
457   }
458   
459   return 0;
460 }
461
462 //_____________________________________________________
463 void AliEMCALTenderSupply::ProcessEvent()
464 {
465   // Event loop.
466   
467   AliVEvent *event = GetEvent();
468
469   if (!event) {
470     AliError("Event ptr = 0, returning");
471     return;
472   }
473   
474  // Initialising parameters once per run number
475   if (RunChanged()) { 
476
477     AliWarning( "Run changed, initializing parameters" );
478     fRun = event->GetRunNumber();
479
480     // init geometry if not already done
481     if (fEMCALGeoName.Length()==0) {
482       fEMCALGeoName = "EMCAL_FIRSTYEARV1";
483       if (fRun>139517) {
484         fEMCALGeoName = "EMCAL_COMPLETEV1";
485       } 
486       if (fRun>170593) {
487         fEMCALGeoName = "EMCAL_COMPLETE12SMV1";
488       }
489       fEMCALGeo = AliEMCALGeometry::GetInstance(fEMCALGeoName);
490       if (!fEMCALGeo) {
491         AliFatal(Form("Can not create geometry: %s", fEMCALGeoName.Data()));
492         return;
493       }
494     } 
495
496     // get pass
497     if (fGetPassFromFileName)
498       GetPass();
499
500     // define what recalib parameters are needed for various switches
501     // this is based on implementation in AliEMCALRecoUtils
502     Bool_t needRecoParam   = fReClusterize;
503     Bool_t needBadChannels = fBadCellRemove   | fClusterBadChannelCheck | fRecalDistToBadChannels | fReClusterize;
504     Bool_t needRecalib     = fCalibrateEnergy | fReClusterize;
505     Bool_t needTimecalib   = fCalibrateTime   | fReClusterize;
506     Bool_t needMisalign    = fRecalClusPos    | fReClusterize;
507     Bool_t needClusterizer = fReClusterize;
508
509     // init bad channels
510     if( needBadChannels ){
511       Int_t fInitBC = InitBadChannels();
512       if (fInitBC==0)
513         AliError("InitBadChannels returned false, returning");
514       if (fInitBC==1)
515         AliWarning("InitBadChannels OK");
516       if (fInitBC>1)
517         AliWarning(Form("No external hot channel set: %d - %s", event->GetRunNumber(), fFilepass.Data()));
518     }
519
520     // init recalibration factors
521     if( needRecalib ) 
522     { 
523       Int_t fInitRecalib = InitRecalib();
524       if (fInitRecalib==0)
525         AliError("InitRecalib returned false, returning");
526       if (fInitRecalib==1)
527         AliWarning("InitRecalib OK");
528       if (fInitRecalib>1)
529         AliWarning(Form("No recalibration available: %d - %s", event->GetRunNumber(), fFilepass.Data()));
530       
531       Int_t fInitRunDepRecalib = InitRunDepRecalib();
532       if (fInitRunDepRecalib==0)
533         AliError("InitrunDepRecalib returned false, returning");
534       if (fInitRunDepRecalib==1)
535         AliWarning("InitRecalib OK");
536       if (fInitRunDepRecalib>1)
537         AliWarning(Form("No Temperature recalibration available: %d - %s", event->GetRunNumber(), fFilepass.Data()));
538       
539     }
540     
541     // init time calibration
542     if( needTimecalib ) {
543       Int_t initTC = InitTimeCalibration();
544       if ( !initTC ) 
545         AliError("InitTimeCalibration returned false, returning");
546       if (initTC==1) {
547         fCalibrateTimeParamAvailable = kTRUE;
548         AliWarning("InitTimeCalib OK");
549       }
550       if( initTC > 1 )
551         AliWarning(Form("No external time calibration set: %d - %s", event->GetRunNumber(), fFilepass.Data()));
552     }
553
554     // init misalignment matrix
555     if( needMisalign ) { 
556       if (!InitMisalignMatrix())
557         AliError("InitMisalignmentMatrix returned false, returning");
558       else
559         AliWarning("InitMisalignMatrix OK");
560     }
561     
562     // initiate reco params with some defaults
563     // will not overwrite, if those have been provided by user
564     if( needRecoParam ) {
565       Int_t initRC = InitRecParam();
566       
567       if( initRC == 0 )
568         AliInfo("Defaults reco params loaded.");
569       if( initRC > 1 )
570         AliWarning("User defined reco params.");
571     }
572     
573     // init clusterizer
574     if( needClusterizer ) {
575       if (!InitClusterization()) 
576         AliError("InitClusterization returned false, returning");
577       else
578         AliWarning("InitClusterization OK");
579     }
580     
581     if(fDebugLevel>1) 
582       fEMCALRecoUtils->Print("");
583   }
584   
585   // disable implied switches -------------------------------------------------
586   // AliEMCALRecoUtils or clusterizer functions alredy include some
587   // recalibration so based on those implied callibration te switches
588   // here are disabled to avoid duplication
589     
590   // clusterizer does cluster energy recalibration, position recomputation
591   // and shower shape
592   if( fReClusterize ){
593     fReCalibCluster   = kFALSE;
594     fRecalClusPos     = kFALSE;
595     fRecalShowerShape = kFALSE;
596   }
597   
598   // CONFIGURE THE RECO UTILS -------------------------------------------------
599   // configure the reco utils
600   // this option does energy recalibration
601   if( fCalibrateEnergy )
602     fEMCALRecoUtils->SwitchOnRecalibration();
603   else
604     fEMCALRecoUtils->SwitchOffRecalibration();
605   
606   // allows time calibration
607   if( fCalibrateTime )
608     fEMCALRecoUtils->SwitchOnTimeRecalibration();
609   else
610     fEMCALRecoUtils->SwitchOffTimeRecalibration();
611
612   // allows to zero bad cells
613   if( fBadCellRemove )
614     fEMCALRecoUtils->SwitchOnBadChannelsRemoval();
615   else
616     fEMCALRecoUtils->SwitchOffBadChannelsRemoval();
617   
618   // distance to bad channel recalibration
619   if( fRecalDistToBadChannels )
620     fEMCALRecoUtils->SwitchOnDistToBadChannelRecalculation();
621   else
622     fEMCALRecoUtils->SwitchOffDistToBadChannelRecalculation();
623
624   // exclude exotic cells
625   if( fRejectExoticCells )
626     fEMCALRecoUtils->SwitchOnRejectExoticCell();
627   else
628     fEMCALRecoUtils->SwitchOffRejectExoticCell();
629   
630   // exclude clusters with exotic cells
631   if( fRejectExoticClusters )
632     fEMCALRecoUtils->SwitchOnRejectExoticCluster();
633   else
634     fEMCALRecoUtils->SwitchOffRejectExoticCluster();
635
636   // TODO: not implemented switches
637   // SwitchOnClusterEnergySmearing
638   // SwitchOnRunDepCorrection
639
640   // START PROCESSING ---------------------------------------------------------
641   // Test if cells present
642   AliVCaloCells *cells= event->GetEMCALCells();
643   if (cells->GetNumberOfCells()<=0) 
644   {
645     if(fDebugLevel>1) 
646       AliWarning(Form("Number of EMCAL cells = %d, returning", cells->GetNumberOfCells()));
647     return;
648   }
649   
650   if (fDebugLevel>2)
651     AliInfo(Form("Re-calibrate cluster %d\n",fReCalibCluster));
652
653   // mark the cells not recalibrated in case of selected
654   // time, energy recalibration or bad channel removal
655   if( fCalibrateEnergy || fCalibrateTime || fBadCellRemove )
656     fEMCALRecoUtils->ResetCellsCalibrated();
657   
658  // CELL RECALIBRATION -------------------------------------------------------
659   // cell objects will be updated
660   // the cell calibrations are also processed locally any time those are needed
661   // in case that the cell objects are not to be updated here for later use
662   if( fUpdateCell )
663   {
664     // do the update
665     // includes exotic cell check in the UpdateCells function - is not provided
666     // by the reco utils
667     UpdateCells();
668
669     // switch off recalibrations so those are not done multiple times
670     // this is just for safety, the recalibrated flag of cell object
671     // should not allow for farther processing anyways
672     fEMCALRecoUtils->SwitchOffRecalibration();
673     fEMCALRecoUtils->SwitchOffTimeRecalibration();  
674   
675     if (fDoUpdateOnly)
676       return;
677   }
678
679   // RECLUSTERIZATION ---------------------------------------------------------
680   if (fReClusterize)
681   {
682     FillDigitsArray();
683     Clusterize();
684     UpdateClusters();
685   }
686
687   // Store good clusters
688   TClonesArray *clusArr = dynamic_cast<TClonesArray*>(event->FindListObject("caloClusters"));
689   if (!clusArr) 
690     clusArr = dynamic_cast<TClonesArray*>(event->FindListObject("CaloClusters"));
691   if (!clusArr) {
692     AliWarning(Form("No cluster array, number of cells in event = %d, returning", cells->GetNumberOfCells()));
693     return;
694   }
695
696   // PROCESS SINGLE CLUSTER RECALIBRATION -------------------------------------
697   // now go through clusters one by one and process separate correction
698   // as those were defined or not
699   Int_t nclusters = clusArr->GetEntriesFast();
700   for (Int_t icluster=0; icluster < nclusters; ++icluster) 
701   { 
702     AliVCluster *clust = static_cast<AliVCluster*>(clusArr->At(icluster));
703     if (!clust) 
704       continue;
705     if  (!clust->IsEMCAL()) 
706       continue;
707
708     // REMOVE CLUSTERS WITH BAD CELLS -----------------------------
709     if( fClusterBadChannelCheck )
710     {
711       // careful, the the ClusterContainsBadChannel is dependent on
712       // SwitchOnBadChannelsRemoval, switching it ON automatically
713       // and returning to original value after processing
714       Bool_t badRemoval = fEMCALRecoUtils->IsBadChannelsRemovalSwitchedOn();
715       fEMCALRecoUtils->SwitchOnBadChannelsRemoval();
716       
717       Bool_t badResult = fEMCALRecoUtils->ClusterContainsBadChannel(fEMCALGeo, clust->GetCellsAbsId(), clust->GetNCells());
718
719       // switch the bad channels removal back
720       if( ! badRemoval )
721         fEMCALRecoUtils->SwitchOffBadChannelsRemoval();
722       
723       if( badResult )
724       {
725         delete clusArr->RemoveAt(icluster);
726         continue; //TODO is it really needed to remove it? Or should we flag it?
727       }
728     }
729     
730     // REMOVE EXOTIC CLUSTERS -------------------------------------
731     // does process local cell recalibration energy and time without replacing
732     // the global cell values, in case of no cell recalib done yet
733     if( fRejectExoticClusters )
734     {
735       // careful, the IsExoticCluster is dependent on
736       // SwitchOnRejectExoticCell, switching it ON automatically
737       // and returning to original value after processing
738       Bool_t exRemoval = fEMCALRecoUtils->IsRejectExoticCell();
739       fEMCALRecoUtils->SwitchOnRejectExoticCell();
740
741       // get bunch crossing
742       Int_t bunchCrossNo = event->GetBunchCrossNumber();
743
744       Bool_t exResult = fEMCALRecoUtils->IsExoticCluster(clust, cells, bunchCrossNo );
745
746       // switch the exotic channels removal back
747       if( ! exRemoval )
748         fEMCALRecoUtils->SwitchOffRejectExoticCell();
749       
750       if( exResult )
751       {
752         delete clusArr->RemoveAt(icluster);
753         continue; //TODO is it really needed to remove it? Or should we flag it?
754       }
755     }
756     
757     // FIDUCIAL CUT -----------------------------------------------
758     if (fFiducial)
759     {
760       // depends on SetNumberOfCellsFromEMCALBorder
761       // SwitchOnNoFiducialBorderInEMCALEta0
762       if (!fEMCALRecoUtils->CheckCellFiducialRegion(fEMCALGeo, clust, cells)){
763         delete clusArr->RemoveAt(icluster);
764         continue; //TODO it would be nice to store the distance
765       }
766     }
767     
768     // CLUSTER ENERGY ---------------------------------------------
769     // does process local cell recalibration energy and time without replacing
770     // the global cell values, in case of no cell recalib done yet
771     if( fReCalibCluster ) {
772       fEMCALRecoUtils->RecalibrateClusterEnergy(fEMCALGeo, clust, cells);
773       if (clust->E() < 1e-9) {
774         delete clusArr->RemoveAt(icluster);
775         continue;
776       }
777     }
778     
779     // CLUSTER POSITION -------------------------------------------
780     // does process local cell energy recalibration, if enabled and cells
781     // not calibrated yet
782     if( fRecalClusPos ) 
783       fEMCALRecoUtils->RecalculateClusterPosition(fEMCALGeo, cells, clust);
784     
785     // SHOWER SHAPE -----------------------------------------------
786     if( fRecalShowerShape )
787       fEMCALRecoUtils->RecalculateClusterShowerShapeParameters(fEMCALGeo, cells, clust);  
788
789     // NONLINEARITY -----------------------------------------------
790     if( fDoNonLinearity )
791     {
792       Float_t correctedEnergy = fEMCALRecoUtils->CorrectClusterEnergyLinearity(clust);
793       clust->SetE(correctedEnergy);
794     }
795
796     // DISTANCE TO BAD CHANNELS -----------------------------------
797     if( fRecalDistToBadChannels )
798       fEMCALRecoUtils->RecalculateClusterDistanceToBadChannel(fEMCALGeo, cells, clust);  
799   }
800
801   clusArr->Compress();
802
803   if (!fDoTrackMatch)
804     return;
805
806   // TRACK MATCHING -----------------------------------------------------------
807   if (!TGeoGlobalMagField::Instance()->GetField()) {
808     AliESDEvent *esd = dynamic_cast<AliESDEvent*>(event);
809     if (esd)
810       esd->InitMagneticField();
811     else {
812       AliAODEvent *aod = dynamic_cast<AliAODEvent*>(event);
813       Double_t curSol = 30000*aod->GetMagneticField()/5.00668;
814       Double_t curDip = 6000 *aod->GetMuonMagFieldScale();
815       AliMagF *field  = AliMagF::CreateFieldMap(curSol,curDip);
816       TGeoGlobalMagField::Instance()->SetField(field);
817     }
818   }
819
820   fEMCALRecoUtils->FindMatches(event,0x0,fEMCALGeo);
821   fEMCALRecoUtils->SetClusterMatchedToTrack(event);
822   fEMCALRecoUtils->SetTracksMatchedToCluster(event);
823 }
824
825 //_____________________________________________________
826 Bool_t AliEMCALTenderSupply::InitMisalignMatrix()
827 {
828   // Initialising misalignment matrices
829
830   AliVEvent *event = GetEvent();
831   
832   if (!event) 
833     return kFALSE;
834   
835   if (fGeomMatrixSet) 
836   {
837     AliInfo("Misalignment matrix already set");  
838     return kTRUE;
839   }
840   
841   if (fDebugLevel>0) 
842     AliInfo("Initialising misalignment matrix");  
843   
844   if (fLoadGeomMatrices) {
845     for(Int_t mod=0; mod < fEMCALGeo->GetNumberOfSuperModules(); ++mod)
846     {
847       if (fEMCALMatrix[mod]){
848         if(fDebugLevel > 2) 
849           fEMCALMatrix[mod]->Print();
850         fEMCALGeo->SetMisalMatrix(fEMCALMatrix[mod],mod);  
851       }
852     }
853     fGeomMatrixSet = kTRUE;
854     return kTRUE;
855   }
856   
857   Int_t runGM = event->GetRunNumber();
858   TObjArray *mobj = 0;
859
860   if(fMisalignSurvey == kdefault)
861   { //take default alignment corresponding to run no
862     AliOADBContainer emcalgeoCont(Form("emcal"));
863     emcalgeoCont.InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALlocal2master.root",Form("AliEMCALgeo"));
864     mobj=(TObjArray*)emcalgeoCont.GetObject(runGM,"EmcalMatrices");
865   }
866   
867   if(fMisalignSurvey == kSurveybyS)
868   { //take alignment at sector level
869     if (runGM <= 140000) { //2010 data
870       AliOADBContainer emcalgeoCont(Form("emcal2010"));
871       emcalgeoCont.InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALlocal2master.root",Form("AliEMCALgeo"));
872       mobj=(TObjArray*)emcalgeoCont.GetObject(100,"survey10");
873     } 
874     else if (runGM>140000)
875     { // 2011 LHC11a pass1 data
876       AliOADBContainer emcalgeoCont(Form("emcal2011"));
877       emcalgeoCont.InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALlocal2master.root",Form("AliEMCALgeo"));
878       mobj=(TObjArray*)emcalgeoCont.GetObject(100,"survey11byS");      
879     }
880   }
881
882   if(fMisalignSurvey == kSurveybyM)
883   { //take alignment at module level
884     if (runGM <= 140000) { //2010 data
885       AliOADBContainer emcalgeoCont(Form("emcal2010"));
886       emcalgeoCont.InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALlocal2master.root",Form("AliEMCALgeo"));
887       mobj=(TObjArray*)emcalgeoCont.GetObject(100,"survey10");
888     } 
889     else if (runGM>140000) 
890     { // 2011 LHC11a pass1 data
891       AliOADBContainer emcalgeoCont(Form("emcal2011"));
892       emcalgeoCont.InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALlocal2master.root",Form("AliEMCALgeo"));
893       mobj=(TObjArray*)emcalgeoCont.GetObject(100,"survey11byM");      
894     }
895   }
896
897   if(!mobj)
898   {
899     AliFatal("Geometry matrix array not found");
900     return kFALSE;
901   }
902   
903   for(Int_t mod=0; mod < (fEMCALGeo->GetEMCGeometry())->GetNumberOfSuperModules(); mod++)
904   {
905     fEMCALMatrix[mod] = (TGeoHMatrix*) mobj->At(mod);
906     fEMCALGeo->SetMisalMatrix(fEMCALMatrix[mod],mod); 
907     fEMCALMatrix[mod]->Print();
908   }
909   
910   return kTRUE;
911 }
912
913 //_____________________________________________________
914 Int_t AliEMCALTenderSupply::InitBadChannels()
915 {
916   // Initialising bad channel maps
917
918   AliVEvent *event = GetEvent();
919
920   if (!event) 
921     return 0;
922   
923   if (fDebugLevel>0) 
924     AliInfo("Initialising Bad channel map");
925   
926   // init default maps first
927   if( !fEMCALRecoUtils->GetEMCALBadChannelStatusMapArray() )
928     fEMCALRecoUtils->InitEMCALBadChannelStatusMap() ;
929   
930   Int_t runBC = event->GetRunNumber();
931   
932   AliOADBContainer *contBC = new AliOADBContainer("");
933   if (fBasePath!="")
934   { //if fBasePath specified in the ->SetBasePath()
935     if (fDebugLevel>0) AliInfo(Form("Loading Bad Channels OADB from given path %s",fBasePath.Data()));
936     
937     TFile *fbad=new TFile(Form("%s/EMCALBadChannels.root",fBasePath.Data()),"read");
938     if (!fbad || fbad->IsZombie())
939     {
940       AliFatal(Form("EMCALBadChannels.root was not found in the path provided: %s",fBasePath.Data()));
941       return 0;
942     }  
943     
944     if (fbad) delete fbad;
945     
946     contBC->InitFromFile(Form("%s/EMCALBadChannels.root",fBasePath.Data()),"AliEMCALBadChannels");    
947   } 
948   else 
949   { // Else choose the one in the $ALICE_ROOT directory
950     if (fDebugLevel>0) AliInfo("Loading Bad Channels OADB from $ALICE_ROOT/OADB/EMCAL");
951     
952     TFile *fbad=new TFile("$ALICE_ROOT/OADB/EMCAL/EMCALBadChannels.root","read");
953     if (!fbad || fbad->IsZombie())
954     {
955       AliFatal("$ALICE_ROOT/OADB/EMCAL/EMCALBadChannels.root was not found");
956       return 0;
957     }  
958       
959     if (fbad) delete fbad;
960     
961     contBC->InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALBadChannels.root","AliEMCALBadChannels"); 
962   }
963   
964   TObjArray *arrayBC=(TObjArray*)contBC->GetObject(runBC);
965   if (!arrayBC)
966   {
967     AliError(Form("No external hot channel set for run number: %d", runBC));
968     return 2; 
969   }
970
971   Int_t sms = fEMCALGeo->GetEMCGeometry()->GetNumberOfSuperModules();
972   for (Int_t i=0; i<sms; ++i) 
973   {
974     TH2I *h = fEMCALRecoUtils->GetEMCALChannelStatusMap(i);
975     if (h)
976       delete h;
977     h=(TH2I*)arrayBC->FindObject(Form("EMCALBadChannelMap_Mod%d",i));
978
979     if (!h) 
980     {
981       AliError(Form("Can not get EMCALBadChannelMap_Mod%d",i));
982       continue;
983     }
984     h->SetDirectory(0);
985     fEMCALRecoUtils->SetEMCALChannelStatusMap(i,h);
986   }
987   return 1;  
988 }
989
990 //_____________________________________________________
991 Int_t AliEMCALTenderSupply::InitRecalib()
992 {
993   // Initialising recalibration factors.
994   
995   AliVEvent *event = GetEvent();
996
997   if (!event) 
998     return 0;
999   
1000   if (fDebugLevel>0) 
1001     AliInfo("Initialising recalibration factors");
1002   
1003   // init default maps first
1004   if( !fEMCALRecoUtils->GetEMCALRecalibrationFactorsArray() )
1005     fEMCALRecoUtils->InitEMCALRecalibrationFactors() ;
1006
1007   Int_t runRC = event->GetRunNumber();
1008       
1009   AliOADBContainer *contRF=new AliOADBContainer("");
1010   if (fBasePath!="") 
1011   { //if fBasePath specified in the ->SetBasePath()
1012     if (fDebugLevel>0)  AliInfo(Form("Loading Recalib OADB from given path %s",fBasePath.Data()));
1013     
1014     TFile *fRecalib= new TFile(Form("%s/EMCALRecalib.root",fBasePath.Data()),"read");
1015     if (!fRecalib || fRecalib->IsZombie()) 
1016     {
1017       AliFatal(Form("EMCALRecalib.root not found in %s",fBasePath.Data()));
1018       return 0;
1019     }
1020     
1021     if (fRecalib) delete fRecalib;
1022     
1023     contRF->InitFromFile(Form("%s/EMCALRecalib.root",fBasePath.Data()),"AliEMCALRecalib");
1024   }
1025   else
1026   { // Else choose the one in the $ALICE_ROOT directory
1027     if (fDebugLevel>0)  AliInfo("Loading Recalib OADB from $ALICE_ROOT/OADB/EMCAL");
1028     
1029     TFile *fRecalib= new TFile("$ALICE_ROOT/OADB/EMCAL/EMCALRecalib.root","read");
1030     if (!fRecalib || fRecalib->IsZombie()) 
1031     {
1032       AliFatal("$ALICE_ROOT/OADB/EMCAL/EMCALRecalib.root was not found");
1033       return 0;
1034     }
1035     
1036     if (fRecalib) delete fRecalib;
1037       
1038     contRF->InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALRecalib.root","AliEMCALRecalib");     
1039   }
1040
1041   TObjArray *recal=(TObjArray*)contRF->GetObject(runRC);
1042   if (!recal)
1043   {
1044     AliError(Form("No Objects for run: %d",runRC));
1045     return 2;
1046   } 
1047
1048   TObjArray *recalpass=(TObjArray*)recal->FindObject(fFilepass);
1049   if (!recalpass)
1050   {
1051     AliError(Form("No Objects for run: %d - %s",runRC,fFilepass.Data()));
1052     return 2;
1053   }
1054
1055   TObjArray *recalib=(TObjArray*)recalpass->FindObject("Recalib");
1056   if (!recalib)
1057   {
1058     AliError(Form("No Recalib histos found for  %d - %s",runRC,fFilepass.Data())); 
1059     return 2;
1060   }
1061
1062   if (fDebugLevel>0) recalib->Print();
1063
1064   Int_t sms = fEMCALGeo->GetEMCGeometry()->GetNumberOfSuperModules();
1065   for (Int_t i=0; i<sms; ++i) 
1066   {
1067     TH2F *h = fEMCALRecoUtils->GetEMCALChannelRecalibrationFactors(i);
1068     if (h)
1069       delete h;
1070     h = (TH2F*)recalib->FindObject(Form("EMCALRecalFactors_SM%d",i));
1071     if (!h) 
1072     {
1073       AliError(Form("Could not load EMCALRecalFactors_SM%d",i));
1074       continue;
1075     }
1076     h->SetDirectory(0);
1077     fEMCALRecoUtils->SetEMCALChannelRecalibrationFactors(i,h);
1078   }
1079   return 1;
1080 }
1081
1082 //_____________________________________________________
1083 Int_t AliEMCALTenderSupply::InitRunDepRecalib()
1084 {
1085   // Initialising recalibration factors.
1086   
1087   AliVEvent *event = GetEvent();
1088   
1089   if (!event) 
1090     return 0;
1091   
1092   if (fDebugLevel>0) 
1093     AliInfo("Initialising recalibration factors");
1094   
1095   // init default maps first
1096   if( !fEMCALRecoUtils->GetEMCALRecalibrationFactorsArray() )
1097     fEMCALRecoUtils->InitEMCALRecalibrationFactors() ;
1098   
1099   Int_t runRC = event->GetRunNumber();
1100   
1101   AliOADBContainer *contRF=new AliOADBContainer("");
1102   if (fBasePath!="") 
1103   { //if fBasePath specified in the ->SetBasePath()
1104     if (fDebugLevel>0)  AliInfo(Form("Loading Recalib OADB from given path %s",fBasePath.Data()));
1105     
1106     TFile *fRunDepRecalib= new TFile(Form("%s/EMCALTemperatureCorrCalib.root",fBasePath.Data()),"read");
1107     if (!fRunDepRecalib || fRunDepRecalib->IsZombie()) 
1108     {
1109       AliFatal(Form("EMCALTemperatureCorrCalib.root not found in %s",fBasePath.Data()));
1110       return 0;
1111     }
1112     
1113     if (fRunDepRecalib) delete fRunDepRecalib;
1114     
1115     contRF->InitFromFile(Form("%s/EMCALTemperatureCorrCalib.root",fBasePath.Data()),"AliEMCALRunDepTempCalibCorrections");
1116   }
1117   else
1118   { // Else choose the one in the $ALICE_ROOT directory
1119     if (fDebugLevel>0)  AliInfo("Loading Recalib OADB from $ALICE_ROOT/OADB/EMCAL");
1120     
1121     TFile *fRunDepRecalib= new TFile("$ALICE_ROOT/OADB/EMCAL/EMCALTemperatureCorrCalib.root","read");
1122     if (!fRunDepRecalib || fRunDepRecalib->IsZombie()) 
1123     {
1124       AliFatal("$ALICE_ROOT/OADB/EMCAL/EMCALTemperatureCorrCalib.root was not found");
1125       return 0;
1126     }
1127     
1128     if (fRunDepRecalib) delete fRunDepRecalib;
1129     
1130     contRF->InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALTemperatureCorrCalib.root","AliEMCALRunDepTempCalibCorrections");     
1131   }
1132   
1133   TH1S *rundeprecal=(TH1S*)contRF->GetObject(runRC);
1134   if (!rundeprecal)
1135   {
1136     AliWarning(Form("No TemperatureCorrCalib Objects for run: %d",runRC));
1137     // let's get the closest runnumber instead then..
1138     Int_t lower = 0;
1139     Int_t ic = 0;
1140     Int_t maxEntry = contRF->GetNumberOfEntries();
1141
1142     while ( (ic < maxEntry) && (contRF->UpperLimit(ic) < runRC) ) {
1143       lower = ic;
1144       ic++; 
1145     }
1146
1147     Int_t closest = lower;
1148     if ( (ic<maxEntry) && 
1149          (contRF->LowerLimit(ic)-runRC) < (runRC - contRF->UpperLimit(lower)) ) {
1150          closest = ic;
1151     }
1152
1153     AliWarning(Form("TemperatureCorrCalib Objects found closest id %d from run: %d", closest, contRF->LowerLimit(closest)));
1154     rundeprecal = (TH1S*) contRF->GetObjectByIndex(closest);  
1155   } 
1156   
1157   if (fDebugLevel>0) rundeprecal->Print();
1158   
1159   Int_t nSM = fEMCALGeo->GetEMCGeometry()->GetNumberOfSuperModules();
1160   
1161   for (Int_t ism=0; ism<nSM; ++ism) 
1162   {        
1163     for (Int_t icol=0; icol<48; ++icol) 
1164     {        
1165       for (Int_t irow=0; irow<24; ++irow) 
1166       {
1167         Float_t factor = fEMCALRecoUtils->GetEMCALChannelRecalibrationFactor(ism,icol,irow);
1168         
1169         Int_t absID = fEMCALGeo->GetAbsCellIdFromCellIndexes(ism, irow, icol); // original calibration factor
1170         factor *= rundeprecal->GetBinContent(absID) / 10000. ; // correction dependent on T
1171
1172         fEMCALRecoUtils->SetEMCALChannelRecalibrationFactor(ism,icol,irow,factor);
1173       } // columns
1174     } // rows 
1175   } // SM loop
1176   
1177   return 1;
1178 }
1179
1180
1181 //_____________________________________________________
1182 Int_t AliEMCALTenderSupply::InitTimeCalibration()
1183 {
1184   // Initialising bad channel maps
1185   AliVEvent *event = GetEvent();
1186
1187   if (!event) 
1188     return 0;
1189   
1190   if (fDebugLevel>0) 
1191     AliInfo("Initialising time calibration map");
1192   
1193   // init default maps first
1194   if ( !fEMCALRecoUtils->GetEMCALTimeRecalibrationFactorsArray() )
1195     fEMCALRecoUtils->InitEMCALTimeRecalibrationFactors() ;
1196
1197   Int_t runBC = event->GetRunNumber();
1198   
1199   AliOADBContainer *contBC = new AliOADBContainer("");
1200   if (fBasePath!="")
1201   { //if fBasePath specified in the ->SetBasePath()
1202     if (fDebugLevel>0) AliInfo(Form("Loading time calibration OADB from given path %s",fBasePath.Data()));
1203     
1204     TFile *fbad=new TFile(Form("%s/EMCALTimeCalib.root",fBasePath.Data()),"read");
1205     if (!fbad || fbad->IsZombie())
1206     {
1207       AliFatal(Form("EMCALTimeCalib.root was not found in the path provided: %s",fBasePath.Data()));
1208       return 0;
1209     }  
1210     
1211     if (fbad) delete fbad;
1212     
1213     contBC->InitFromFile(Form("%s/EMCALTimeCalib.root",fBasePath.Data()),"AliEMCALTimeCalib");    
1214   } 
1215   else 
1216   { // Else choose the one in the $ALICE_ROOT directory
1217     if (fDebugLevel>0) AliInfo("Loading time calibration OADB from $ALICE_ROOT/OADB/EMCAL");
1218     
1219     TFile *fbad=new TFile("$ALICE_ROOT/OADB/EMCAL/EMCALTimeCalib.root","read");
1220     if (!fbad || fbad->IsZombie())
1221     {
1222       AliFatal("$ALICE_ROOT/OADB/EMCAL/EMCALTimeCalib.root was not found");
1223       return 0;
1224     }  
1225       
1226     if (fbad) delete fbad;
1227     
1228     contBC->InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALTimeCalib.root","AliEMCALTimeCalib"); 
1229   }
1230   
1231   TObjArray *arrayBC=(TObjArray*)contBC->GetObject(runBC);
1232   if (!arrayBC)
1233   {
1234     AliError(Form("No external time calibration set for run number: %d", runBC));
1235     return 2; 
1236   }
1237   
1238   // Here, it looks for a specific pass
1239   TString pass = fFilepass;
1240   if(fFilepass=="calo_spc") pass ="pass1";
1241   TObjArray *arrayBCpass=(TObjArray*)arrayBC->FindObject(pass);
1242   if (!arrayBCpass)
1243   {
1244     AliError(Form("No external time calibration set for: %d -%s", runBC,pass.Data()));
1245     return 2; 
1246   }
1247
1248   if (fDebugLevel>0) arrayBCpass->Print();
1249
1250   for( Int_t i = 0; i < 4; i++ )
1251   {
1252     TH1F *h = fEMCALRecoUtils->GetEMCALChannelTimeRecalibrationFactors( i );
1253     if( h )
1254       delete h;
1255     
1256     h = (TH1F*)arrayBCpass->FindObject(Form("hAllTimeAvBC%d",i));
1257     
1258     if (!h)
1259     {
1260       AliError(Form("Can not get hAllTimeAvBC%d",i));
1261       continue;
1262     }
1263     h->SetDirectory(0);
1264     fEMCALRecoUtils->SetEMCALChannelTimeRecalibrationFactors(i,h);
1265   }
1266   return 1;  
1267 }
1268
1269 //_____________________________________________________
1270 void AliEMCALTenderSupply::UpdateCells()
1271 {
1272   //Remove bad cells from the cell list
1273   //Recalibrate energy and time cells 
1274   //This is required for later reclusterization
1275
1276   AliVEvent *event = GetEvent();
1277
1278   if(!event) return ;
1279   
1280   AliVCaloCells *cells = event->GetEMCALCells();
1281   Int_t bunchCrossNo = event->GetBunchCrossNumber();
1282
1283   fEMCALRecoUtils->RecalibrateCells(cells, bunchCrossNo); 
1284   
1285   // remove exotic cells - loop through cells and zero the exotic ones
1286   // just like with bad cell rejection in reco utils (inside RecalibrateCells)
1287   if( fRejectExoticCells )
1288   {
1289     Short_t  absId  =-1;
1290     Double_t ecell = 0;
1291     Double_t tcell = 0;
1292     Double_t efrac = 0;
1293     Int_t  mclabel = -1;
1294     Bool_t   isExot = kFALSE;
1295   
1296     // loop through cells
1297     Int_t nEMcell  = cells->GetNumberOfCells() ;  
1298     for (Int_t iCell = 0; iCell < nEMcell; iCell++) 
1299     { 
1300       cells->GetCell( iCell, absId, ecell, tcell, mclabel, efrac );
1301     
1302       isExot = fEMCALRecoUtils->IsExoticCell( absId, cells, bunchCrossNo ); 
1303       // zero if exotic
1304       if( isExot )
1305         cells->SetCell( iCell, absId, 0.0, -1.0, mclabel, efrac );
1306     } // cell loop
1307   } // reject exotic cells
1308
1309   cells->Sort();
1310 }
1311
1312 //_____________________________________________________
1313 TString AliEMCALTenderSupply::GetBeamType()
1314 {
1315   // Get beam type : pp-AA-pA
1316   // ESDs have it directly, AODs get it from hardcoded run number ranges
1317   
1318   AliVEvent *event = GetEvent();
1319
1320   if (!event) { 
1321     AliError("Couldn't retrieve event!");
1322     return "";
1323   }
1324
1325   TString beamType;
1326
1327   AliESDEvent *esd = dynamic_cast<AliESDEvent*>(event);
1328   if (esd) {
1329     const AliESDRun *run = esd->GetESDRun();
1330     beamType = run->GetBeamType();
1331   }
1332   else
1333   {
1334     Int_t runNumber = event->GetRunNumber();
1335     if ((runNumber >= 136851 && runNumber <= 139517)  // LHC10h
1336   || (runNumber >= 166529 && runNumber <= 170593))  // LHC11h
1337     {
1338       beamType = "A-A";
1339     }
1340     else 
1341     {
1342       beamType = "p-p";
1343     }
1344   }
1345
1346   return beamType;    
1347 }
1348
1349 //_____________________________________________________
1350 Int_t AliEMCALTenderSupply::InitRecParam()
1351 {
1352   // Init reco params if not yet exist (probably shipped by the user already)
1353
1354   if( fRecParam != 0 )
1355     return 2;
1356
1357   TString beamType = GetBeamType();
1358
1359   // set some default reco params
1360   fRecParam = new AliEMCALRecParam();
1361   fRecParam->SetClusteringThreshold(0.100);
1362   fRecParam->SetMinECut(0.050);
1363   
1364   if(!fCalibrateTimeParamAvailable){
1365     fRecParam->SetTimeCut(250*1.e-9);
1366     fRecParam->SetTimeMin(425*1.e-9);
1367     fRecParam->SetTimeMax(825*1.e-9);
1368   }
1369   else {
1370     fRecParam->SetTimeCut(100*1.e-9);
1371     fRecParam->SetTimeMin(-50*1.e-9);
1372     fRecParam->SetTimeMax( 50*1.e-9);
1373   }
1374   
1375   if ( beamType == "A-A") {
1376     fRecParam->SetClusterizerFlag(AliEMCALRecParam::kClusterizerv2);
1377   } 
1378   else {
1379     fRecParam->SetClusterizerFlag(AliEMCALRecParam::kClusterizerv1);
1380   }
1381
1382   return 0;
1383 }
1384
1385 //_____________________________________________________
1386 Bool_t AliEMCALTenderSupply::InitClusterization()
1387 {
1388   // Initialing clusterization/unfolding algorithm and set all the needed parameters.
1389   
1390   AliVEvent *event = GetEvent();
1391
1392   if (!event) 
1393     return kFALSE;
1394   
1395   if (fDebugLevel>0) 
1396     AliInfo(Form("Initialising reclustering parameters: Clusterizer type: %d",fRecParam->GetClusterizerFlag()));
1397   
1398   //---setup clusterizer
1399   if (fClusterizer) {
1400     // avoid deleting fDigitsArr
1401     fClusterizer->SetDigitsArr(0);
1402     delete fClusterizer;
1403     fClusterizer = 0;
1404   }
1405   if     (fRecParam->GetClusterizerFlag() == AliEMCALRecParam::kClusterizerv1)
1406     fClusterizer = new AliEMCALClusterizerv1 (fEMCALGeo);
1407   else if (fRecParam->GetClusterizerFlag() == AliEMCALRecParam::kClusterizerv2) 
1408     fClusterizer = new AliEMCALClusterizerv2(fEMCALGeo);
1409   else if (fRecParam->GetClusterizerFlag() == AliEMCALRecParam::kClusterizerNxN) 
1410   {
1411     AliEMCALClusterizerNxN *clusterizer = new AliEMCALClusterizerNxN(fEMCALGeo);
1412     clusterizer->SetNRowDiff(fRecParam->GetNRowDiff());
1413     clusterizer->SetNColDiff(fRecParam->GetNColDiff());
1414     fClusterizer = clusterizer;
1415   } 
1416   else 
1417   {
1418     AliFatal(Form("Clusterizer < %d > not available", fRecParam->GetClusterizerFlag()));
1419     return kFALSE;
1420   }
1421   
1422   // Set the clustering parameters
1423   fClusterizer->SetECAClusteringThreshold( fRecParam->GetClusteringThreshold() );
1424   fClusterizer->SetECALogWeight          ( fRecParam->GetW0()                  );
1425   fClusterizer->SetMinECut               ( fRecParam->GetMinECut()             );    
1426   fClusterizer->SetUnfolding             ( fRecParam->GetUnfold()              );
1427   fClusterizer->SetECALocalMaxCut        ( fRecParam->GetLocMaxCut()           );
1428   fClusterizer->SetTimeCut               ( fRecParam->GetTimeCut()             );
1429   fClusterizer->SetTimeMin               ( fRecParam->GetTimeMin()             );
1430   fClusterizer->SetTimeMax               ( fRecParam->GetTimeMax()             );
1431   fClusterizer->SetInputCalibrated       ( kTRUE                               );
1432   fClusterizer->SetJustClusters          ( kTRUE                               );  
1433   
1434   // In case of unfolding after clusterization is requested, set the corresponding parameters
1435   if (fRecParam->GetUnfold()) 
1436   {
1437     for (Int_t i = 0; i < 8; ++i) 
1438     {
1439       fClusterizer->SetSSPars(i, fRecParam->GetSSPars(i));
1440     }
1441     for (Int_t i = 0; i < 3; ++i)
1442     {
1443       fClusterizer->SetPar5  (i, fRecParam->GetPar5(i));
1444       fClusterizer->SetPar6  (i, fRecParam->GetPar6(i));
1445     }
1446     fClusterizer->InitClusterUnfolding();
1447   }
1448   
1449   fClusterizer->SetDigitsArr(fDigitsArr);
1450   fClusterizer->SetOutput(0);
1451   fClusterArr = const_cast<TObjArray *>(fClusterizer->GetRecPoints());
1452   return kTRUE;
1453 }
1454
1455 //_____________________________________________________
1456 void AliEMCALTenderSupply::FillDigitsArray()
1457 {
1458   // Fill digits from cells to a TClonesArray.
1459   
1460   AliVEvent *event = GetEvent();
1461
1462  if (!event)
1463     return;
1464     
1465   // In case of MC productions done before aliroot tag v5-02-Rev09
1466   // assing the cluster label to all the cells belonging to this cluster
1467   // very rough
1468   Int_t cellLabels[12672];
1469   if(fSetCellMCLabelFromCluster)
1470   {
1471     for (Int_t i = 0; i < 12672; i++)
1472     {
1473       cellLabels       [i] = 0 ;
1474       fOrgClusterCellId[i] =-1 ;
1475     }
1476     
1477     Int_t nClusters = event->GetNumberOfCaloClusters();
1478     for (Int_t i = 0; i < nClusters; i++)
1479     {
1480       AliVCluster *clus =  event->GetCaloCluster(i);
1481       
1482       if(!clus) continue;
1483       
1484       if(!clus->IsEMCAL()) continue ;
1485       
1486       Int_t      label = clus->GetLabel();
1487       UShort_t * index = clus->GetCellsAbsId() ;
1488       
1489       for(Int_t icell=0; icell < clus->GetNCells(); icell++ )
1490       {
1491         cellLabels       [index[icell]] = label;
1492         fOrgClusterCellId[index[icell]] = i ; // index of the original cluster
1493       }
1494     }// cluster loop
1495   }
1496
1497   fDigitsArr->Clear("C");
1498   AliVCaloCells *cells = event->GetEMCALCells();
1499   Int_t ncells = cells->GetNumberOfCells();
1500   for (Int_t icell = 0, idigit = 0; icell < ncells; ++icell) 
1501   {
1502     Double_t cellAmplitude=0, cellTime=0, efrac = 0;
1503     Short_t  cellNumber=0;
1504     Int_t mcLabel=-1;
1505
1506     if (cells->GetCell(icell, cellNumber, cellAmplitude, cellTime, mcLabel, efrac) != kTRUE)
1507       break;
1508
1509     // Do not add if energy already too low (some cells set to 0 if bad channels)
1510     if (cellAmplitude < fRecParam->GetMinECut())
1511       continue;
1512
1513     // If requested, do not include exotic cells
1514    if (fEMCALRecoUtils->IsExoticCell(cellNumber,cells,event->GetBunchCrossNumber())) 
1515       continue;
1516     
1517     if     ( fSetCellMCLabelFromCluster ) mcLabel = cellLabels[cellNumber];
1518     else if( fRemapMCLabelForAODs       ) RemapMCLabelForAODs(mcLabel);
1519     
1520     if (mcLabel > 0 && efrac < 1e-6) efrac = 1;
1521     
1522     new((*fDigitsArr)[idigit]) AliEMCALDigit(mcLabel, mcLabel, cellNumber,
1523                                              (Float_t)cellAmplitude, (Float_t)cellTime,
1524                                              AliEMCALDigit::kHG,idigit, 0, 0, efrac*cellAmplitude);
1525     idigit++;
1526   }
1527 }
1528
1529 //_____________________________________________________
1530 void AliEMCALTenderSupply::Clusterize()
1531 {
1532   // Clusterize.
1533   
1534   fClusterizer->Digits2Clusters("");
1535 }
1536
1537 //_____________________________________________________
1538 void AliEMCALTenderSupply::UpdateClusters()
1539 {
1540   // Update ESD cluster list.
1541   
1542   AliVEvent *event = GetEvent();
1543
1544   if (!event)
1545     return;
1546   
1547   TClonesArray *clus = dynamic_cast<TClonesArray*>(event->FindListObject("caloClusters"));
1548   if (!clus) 
1549     clus = dynamic_cast<TClonesArray*>(event->FindListObject("CaloClusters"));
1550   if (!clus) 
1551   {
1552     AliError(" Null pointer to calo clusters array, returning");
1553     return;
1554   }
1555     
1556   // Before destroying the orignal list, assign to the rec points the MC labels
1557   // of the original clusters, if requested
1558   if( fSetCellMCLabelFromCluster == 2 ) SetClustersMCLabelFromOriginalClusters() ;
1559
1560   Int_t nents = clus->GetEntriesFast();
1561   for (Int_t i=0; i < nents; ++i) 
1562   {
1563     AliVCluster *c = dynamic_cast<AliVCluster*>(clus->At(i));
1564     if (!c)
1565       continue;
1566     if (c->IsEMCAL())
1567     {
1568       delete clus->RemoveAt(i);
1569     }
1570   }
1571   
1572   clus->Compress();
1573   
1574   RecPoints2Clusters(clus);
1575 }
1576
1577 //_____________________________________________________
1578 void AliEMCALTenderSupply::RecPoints2Clusters(TClonesArray *clus)
1579 {
1580   // Convert AliEMCALRecoPoints to AliESDCaloClusters/AliAODCaloClusters.
1581   // Cluster energy, global position, cells and their amplitude fractions are restored.
1582   
1583   AliVEvent *event = GetEvent();
1584
1585   if (!event)
1586     return;
1587
1588   Int_t ncls = fClusterArr->GetEntriesFast();
1589   for(Int_t i=0, nout=clus->GetEntriesFast(); i < ncls; ++i) 
1590   {
1591     AliEMCALRecPoint *recpoint = static_cast<AliEMCALRecPoint*>(fClusterArr->At(i));
1592     
1593     Int_t ncellsTrue = 0;
1594     const Int_t ncells = recpoint->GetMultiplicity();
1595     UShort_t   absIds[ncells];  
1596     Double32_t ratios[ncells];
1597     Int_t *dlist = recpoint->GetDigitsList();
1598     Float_t *elist = recpoint->GetEnergiesList();
1599     for (Int_t c = 0; c < ncells; ++c) 
1600     {
1601       AliEMCALDigit *digit = static_cast<AliEMCALDigit*>(fDigitsArr->At(dlist[c]));
1602       absIds[ncellsTrue] = digit->GetId();
1603       ratios[ncellsTrue] = elist[c]/digit->GetAmplitude();
1604       if (ratios[ncellsTrue] < 0.001) 
1605         continue;
1606       ++ncellsTrue;
1607     }
1608     
1609     if (ncellsTrue < 1) 
1610     {
1611       AliWarning("Skipping cluster with no cells");
1612       continue;
1613     }
1614     
1615     // calculate new cluster position
1616     TVector3 gpos;
1617     recpoint->GetGlobalPosition(gpos);
1618     Float_t g[3];
1619     gpos.GetXYZ(g);
1620     
1621     AliVCluster *c = static_cast<AliVCluster*>(clus->New(nout++));
1622     c->SetID(nout-1); 
1623     c->SetType(AliVCluster::kEMCALClusterv1);
1624     c->SetE(recpoint->GetEnergy());
1625     c->SetPosition(g);
1626     c->SetNCells(ncellsTrue);
1627     c->SetDispersion(recpoint->GetDispersion());
1628     c->SetEmcCpvDistance(-1);            //not yet implemented
1629     c->SetChi2(-1);                      //not yet implemented
1630     c->SetTOF(recpoint->GetTime()) ;     //time-of-flight
1631     c->SetNExMax(recpoint->GetNExMax()); //number of local maxima
1632     Float_t elipAxis[2];
1633     recpoint->GetElipsAxis(elipAxis);
1634     c->SetM02(elipAxis[0]*elipAxis[0]) ;
1635     c->SetM20(elipAxis[1]*elipAxis[1]) ;
1636     c->SetCellsAbsId(absIds);
1637     c->SetCellsAmplitudeFraction(ratios);
1638
1639     //MC labels
1640     Int_t  parentMult = 0;
1641     Int_t *parentList = recpoint->GetParents(parentMult);
1642     if (parentMult > 0) c->SetLabel(parentList, parentMult);
1643
1644   }
1645 }
1646
1647 //___________________________________________________________
1648 void AliEMCALTenderSupply::RemapMCLabelForAODs(Int_t & label)
1649 {
1650   // MC label for Cells not remapped after ESD filtering, do it here.
1651   
1652   if(label < 0) return ;
1653   
1654   AliAODEvent  * evt = dynamic_cast<AliAODEvent*> (GetEvent()) ;
1655   if(!evt) return ;
1656   
1657   TClonesArray * arr = dynamic_cast<TClonesArray*>(evt->FindListObject("mcparticles")) ;
1658   if(!arr) return ;
1659   
1660   if(label < arr->GetEntriesFast())
1661   {
1662     AliAODMCParticle * particle = dynamic_cast<AliAODMCParticle *>(arr->At(label));
1663     if(!particle) return ;
1664     
1665     if(label == particle->Label()) return ; // label already OK
1666   }
1667   
1668   // loop on the particles list and check if there is one with the same label
1669   for(Int_t ind = 0; ind < arr->GetEntriesFast(); ind++ )
1670   {
1671     AliAODMCParticle * particle = dynamic_cast<AliAODMCParticle *>(arr->At(ind));
1672     if(!particle) continue ;
1673     
1674     if(label == particle->Label())
1675     {
1676       label = ind;
1677       return;
1678     }
1679   }
1680   
1681   label = -1;
1682   
1683 }
1684
1685 //_____________________________________________________________________________________________
1686 void AliEMCALTenderSupply::SetClustersMCLabelFromOriginalClusters()
1687 {
1688   // Get the original clusters that contribute to the new rec point cluster,
1689   // assign the labels of such clusters to the new rec point cluster.
1690   // Only approximatedly valid  when output are V1 clusters, or input/output clusterizer
1691   // are the same handle with care
1692   // Copy from same method in AliAnalysisTaskEMCALClusterize, but here modify the recpoint and
1693   // not the output calocluster
1694   
1695   Int_t ncls = fClusterArr->GetEntriesFast();
1696   for(Int_t irp=0; irp < ncls; ++irp)
1697   {
1698     TArrayI clArray(300) ; //Weird if more than a few clusters are in the origin ...
1699     clArray.Reset();
1700     Int_t nClu = 0;
1701     Int_t nLabTotOrg = 0;
1702     Float_t emax = -1;
1703     Int_t idMax = -1;
1704     
1705     AliEMCALRecPoint *clus = static_cast<AliEMCALRecPoint*>(fClusterArr->At(irp));
1706     
1707     //Find the clusters that originally had the cells
1708     const Int_t ncells = clus->GetMultiplicity();
1709     Int_t *digList     = clus->GetDigitsList();
1710     
1711     for ( Int_t iLoopCell = 0 ; iLoopCell < ncells ; iLoopCell++ )
1712     {
1713       AliEMCALDigit *digit = static_cast<AliEMCALDigit*>(fDigitsArr->At(digList[iLoopCell]));
1714       Int_t idCell = digit->GetId();
1715
1716       if(idCell>=0)
1717       {
1718         Int_t idCluster = fOrgClusterCellId[idCell];
1719         Bool_t set = kTRUE;
1720         for(Int_t icl =0; icl < nClu; icl++)
1721         {
1722           if(((Int_t)clArray.GetAt(icl))==-1 ) continue;
1723           if( idCluster == ((Int_t)clArray.GetAt(icl)) ) set = kFALSE;
1724         }
1725         if( set && idCluster >= 0)
1726         {
1727           clArray.SetAt(idCluster,nClu++);
1728           nLabTotOrg+=(GetEvent()->GetCaloCluster(idCluster))->GetNLabels();
1729                     
1730           //Search highest E cluster
1731           AliVCluster * clOrg = GetEvent()->GetCaloCluster(idCluster);
1732           if(emax < clOrg->E())
1733           {
1734             emax  = clOrg->E();
1735             idMax = idCluster;
1736           }
1737         }
1738       }
1739     }// cell loop
1740         
1741     // Put the first in the list the cluster with highest energy
1742     if(idMax != ((Int_t)clArray.GetAt(0))) // Max not at first position
1743     {
1744       Int_t maxIndex = -1;
1745       Int_t firstCluster = ((Int_t)clArray.GetAt(0));
1746       for ( Int_t iLoopCluster = 0 ; iLoopCluster < nClu ; iLoopCluster++ )
1747       {
1748         if(idMax == ((Int_t)clArray.GetAt(iLoopCluster))) maxIndex = iLoopCluster;
1749       }
1750       
1751       if(firstCluster >=0 && idMax >=0)
1752       {
1753         clArray.SetAt(idMax,0);
1754         clArray.SetAt(firstCluster,maxIndex);
1755       }
1756     }
1757     
1758     // Get the labels list in the original clusters, assign all to the new cluster
1759     TArrayI clMCArray(nLabTotOrg) ;
1760     clMCArray.Reset();
1761     
1762     Int_t nLabTot = 0;
1763     for ( Int_t iLoopCluster = 0 ; iLoopCluster < nClu ; iLoopCluster++ )
1764     {
1765       Int_t idCluster = (Int_t) clArray.GetAt(iLoopCluster);
1766       AliVCluster * clOrg = GetEvent()->GetCaloCluster(idCluster);
1767       Int_t nLab = clOrg->GetNLabels();
1768       
1769       for ( Int_t iLab = 0 ; iLab < nLab ; iLab++ )
1770       {
1771         Int_t lab = clOrg->GetLabelAt(iLab) ;
1772         if(lab>=0)
1773         {
1774           Bool_t set = kTRUE;
1775           for(Int_t iLabTot =0; iLabTot < nLabTot; iLabTot++)
1776           {
1777             if( lab == ((Int_t)clMCArray.GetAt(iLabTot)) ) set = kFALSE;
1778           }
1779           if( set ) clMCArray.SetAt(lab,nLabTot++);
1780         }
1781       }
1782     }// cluster loop
1783     
1784     // Set the final list of labels to rec point
1785     
1786     Int_t *labels = new Int_t[nLabTot];
1787     for(Int_t il = 0; il < nLabTot; il++) labels[il] = clMCArray.GetArray()[il];
1788     clus->SetParents(nLabTot,labels);
1789     
1790   } // rec point array
1791 }
1792
1793
1794 //_____________________________________________________
1795 void AliEMCALTenderSupply::GetPass()
1796 {
1797   // Get passx from filename
1798   
1799   AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
1800   fInputTree = mgr->GetTree();
1801   
1802   if (!fInputTree) 
1803   {
1804     AliError("Pointer to tree = 0, returning");
1805     return;
1806   }
1807   
1808   fInputFile = fInputTree->GetCurrentFile();
1809   if (!fInputFile) {
1810     AliError("Null pointer input file, returning");
1811     return;
1812   }
1813   
1814   TString fname(fInputFile->GetName());
1815   if      (fname.Contains("pass1")) fFilepass = TString("pass1");
1816   else if (fname.Contains("pass2")) fFilepass = TString("pass2");
1817   else if (fname.Contains("pass3")) fFilepass = TString("pass3");
1818   else if (fname.Contains("pass4")) fFilepass = TString("pass4");
1819   else if (fname.Contains("pass5")) fFilepass = TString("pass5");
1820   else if (fname.Contains("LHC11c") &&
1821            fname.Contains("spc_calo")) fFilepass = TString("spc_calo");
1822   else if (fname.Contains("calo") || fname.Contains("high_lumi"))
1823
1824   {
1825     //printf("AliEMCALTenderSupply::GetPass() - Path contains <calo> or <high-lumi>, set as <pass1>\n");
1826     fFilepass = TString("pass1");
1827   }
1828   else
1829   {
1830     AliError(Form("Pass number string not found: %s", fname.Data()));
1831     return;            
1832   }
1833 }