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