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