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