1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
17 ///////////////////////////////////////////////////////////////////////////////
19 // EMCAL tender, apply corrections to EMCAL clusters //
20 // and do track matching. //
21 // Author: Deepa Thomas (Utrecht University) //
23 ///////////////////////////////////////////////////////////////////////////////
28 #include <TInterpreter.h>
29 #include <TObjArray.h>
30 #include <TClonesArray.h>
31 #include <TGeoGlobalMagField.h>
33 #include <AliESDEvent.h>
34 #include <AliAnalysisManager.h>
35 #include <AliTender.h>
36 #include "AliOADBContainer.h"
37 #include "AliCDBManager.h"
38 #include "AliCDBStorage.h"
39 #include "AliCDBEntry.h"
41 #include "AliESDCaloCluster.h"
42 #include "AliEMCALTenderSupply.h"
43 #include "AliEMCALGeometry.h"
44 #include "AliEMCALRecoUtils.h"
45 #include "AliEMCALClusterizer.h"
46 #include "AliEMCALRecParam.h"
47 #include "AliEMCALRecPoint.h"
48 #include "AliEMCALAfterBurnerUF.h"
49 #include "AliEMCALClusterizerNxN.h"
50 #include "AliEMCALClusterizerv1.h"
51 #include "AliEMCALClusterizerv2.h"
52 #include "AliEMCALDigit.h"
53 #include "AliEMCALRecParam.h"
55 ClassImp(AliEMCALTenderSupply)
57 AliEMCALTenderSupply::AliEMCALTenderSupply() :
60 ,fEMCALGeoName("EMCAL_COMPLETEV1")
65 ,fNonLinearThreshold(-1)
66 ,fReCalibCluster(kFALSE)
68 ,fCalibrateEnergy(kFALSE)
69 ,fCalibrateTime(kFALSE)
70 ,fDoNonLinearity(kFALSE)
71 ,fBadCellRemove(kFALSE)
72 ,fRejectExoticCells(kFALSE)
73 ,fRejectExoticClusters(kFALSE)
74 ,fClusterBadChannelCheck(kFALSE)
75 ,fRecalClusPos(kFALSE)
77 ,fNCellsFromEMCALBorder(-1)
78 ,fRecalDistToBadChannels(kFALSE)
79 ,fRecalShowerShape(kFALSE)
86 ,fCutEtaPhiSeparate(kFALSE)
91 ,fReClusterize(kFALSE)
93 ,fGeomMatrixSet(kFALSE)
94 ,fLoadGeomMatrices(kFALSE)
96 ,fDoTrackMatch(kFALSE)
97 ,fDoUpdateOnly(kFALSE)
101 ,fMisalignSurvey(kdefault)
102 ,fExoticCellFraction(-1)
103 ,fExoticCellDiffTime(-1)
104 ,fExoticCellMinAmplitude(-1)
106 // Default constructor.
107 for(Int_t i = 0; i < 10; i++) fEMCALMatrix[i] = 0 ;
108 fEMCALRecoUtils = new AliEMCALRecoUtils;
111 //_____________________________________________________
112 AliEMCALTenderSupply::AliEMCALTenderSupply(const char *name, const AliTender *tender) :
113 AliTenderSupply(name,tender)
115 ,fEMCALGeoName("EMCAL_COMPLETEV1")
120 ,fNonLinearThreshold(-1)
121 ,fReCalibCluster(kFALSE)
123 ,fCalibrateEnergy(kFALSE)
124 ,fCalibrateTime(kFALSE)
125 ,fDoNonLinearity(kFALSE)
126 ,fBadCellRemove(kFALSE)
127 ,fRejectExoticCells(kFALSE)
128 ,fRejectExoticClusters(kFALSE)
129 ,fClusterBadChannelCheck(kFALSE)
130 ,fRecalClusPos(kFALSE)
132 ,fNCellsFromEMCALBorder(-1)
133 ,fRecalDistToBadChannels(kFALSE)
134 ,fRecalShowerShape(kFALSE)
140 ,fCutEtaPhiSum(kTRUE)
141 ,fCutEtaPhiSeparate(kFALSE)
146 ,fReClusterize(kFALSE)
148 ,fGeomMatrixSet(kFALSE)
149 ,fLoadGeomMatrices(kFALSE)
151 ,fDoTrackMatch(kFALSE)
152 ,fDoUpdateOnly(kFALSE)
156 ,fMisalignSurvey(kdefault)
157 ,fExoticCellFraction(-1)
158 ,fExoticCellDiffTime(-1)
159 ,fExoticCellMinAmplitude(-1)
163 for(Int_t i = 0; i < 10; i++) fEMCALMatrix[i] = 0 ;
164 fEMCALRecoUtils = new AliEMCALRecoUtils;
167 //_____________________________________________________
168 AliEMCALTenderSupply::~AliEMCALTenderSupply()
172 delete fEMCALRecoUtils;
176 fDigitsArr->Clear("C");
184 //_____________________________________________________
185 void AliEMCALTenderSupply::Init()
187 // Initialise EMCAL tender.
190 AliWarning("Init EMCAL Tender supply");
192 if (fConfigName.Length()>0 && gROOT->LoadMacro(fConfigName) >=0) {
193 AliDebug(1, Form("Loading settings from macro %s", fConfigName.Data()));
194 AliEMCALTenderSupply *tender = (AliEMCALTenderSupply*)gInterpreter->ProcessLine("ConfigEMCALTenderSupply()");
195 fDebugLevel = tender->fDebugLevel;
196 fEMCALGeoName = tender->fEMCALGeoName;
197 fEMCALRecoUtils = tender->fEMCALRecoUtils;
198 fConfigName = tender->fConfigName;
199 fNonLinearFunc = tender->fNonLinearFunc;
200 fNonLinearThreshold = tender->fNonLinearThreshold;
201 fReCalibCluster = tender->fReCalibCluster;
202 fUpdateCell = tender->fUpdateCell;
203 fRecalClusPos = tender->fRecalClusPos;
204 fCalibrateEnergy = tender->fCalibrateEnergy;
205 fCalibrateTime = tender->fCalibrateTime;
206 fFiducial = tender->fFiducial;
207 fNCellsFromEMCALBorder = tender->fNCellsFromEMCALBorder;
208 fRecalDistToBadChannels = tender->fRecalDistToBadChannels;
209 fRecalShowerShape = tender->fRecalShowerShape;
210 fClusterBadChannelCheck = tender->fClusterBadChannelCheck;
211 fBadCellRemove = tender->fBadCellRemove;
212 fRejectExoticCells = tender->fRejectExoticCells;
213 fRejectExoticClusters = tender->fRejectExoticClusters;
214 fMass = tender->fMass;
215 fStep = tender->fStep;
216 fCutEtaPhiSum = tender->fCutEtaPhiSum;
217 fCutEtaPhiSeparate = tender->fCutEtaPhiSeparate;
218 fRcut = tender->fRcut;
219 fEtacut = tender->fEtacut;
220 fPhicut = tender->fPhicut;
221 fReClusterize = tender->fReClusterize;
222 fLoadGeomMatrices = tender->fLoadGeomMatrices;
223 fRecParam = tender->fRecParam;
224 fDoNonLinearity = tender->fDoNonLinearity;
225 fDoTrackMatch = tender->fDoTrackMatch;
226 fDoUpdateOnly = tender->fDoUpdateOnly;
227 fMisalignSurvey = tender->fMisalignSurvey;
228 fExoticCellFraction = tender->fExoticCellFraction;
229 fExoticCellDiffTime = tender->fExoticCellDiffTime;
230 fExoticCellMinAmplitude = tender->fExoticCellMinAmplitude;
232 for(Int_t i = 0; i < 10; i++)
233 fEMCALMatrix[i] = tender->fEMCALMatrix[i] ;
237 AliInfo( "Emcal Tender settings: ======================================" );
238 AliInfo( "------------ Switches --------------------------" );
239 AliInfo( Form( "BadCellRemove : %d", fBadCellRemove ));
240 AliInfo( Form( "ExoticCellRemove : %d", fRejectExoticCells ));
241 AliInfo( Form( "CalibrateEnergy : %d", fCalibrateEnergy ));
242 AliInfo( Form( "CalibrateTime : %d", fCalibrateTime ));
243 AliInfo( Form( "UpdateCell : %d", fUpdateCell ));
244 AliInfo( Form( "DoUpdateOnly : %d", fDoUpdateOnly ));
245 AliInfo( Form( "Reclustering : %d", fReClusterize ));
246 AliInfo( Form( "ClusterBadChannelCheck : %d", fClusterBadChannelCheck ));
247 AliInfo( Form( "ClusterExoticChannelCheck : %d", fRejectExoticClusters ));
248 AliInfo( Form( "CellFiducialRegion : %d", fFiducial ));
249 AliInfo( Form( "ReCalibrateCluster : %d", fReCalibCluster ));
250 AliInfo( Form( "RecalculateClusPos : %d", fRecalClusPos ));
251 AliInfo( Form( "RecalShowerShape : %d", fRecalShowerShape ));
252 AliInfo( Form( "NonLinearityCorrection : %d", fDoNonLinearity ));
253 AliInfo( Form( "RecalDistBadChannel : %d", fRecalDistToBadChannels ));
254 AliInfo( Form( "TrackMatch : %d", fDoTrackMatch ));
255 AliInfo( "------------ Variables -------------------------" );
256 AliInfo( Form( "DebugLevel : %d", fDebugLevel ));
257 AliInfo( Form( "BasePath : %s", fBasePath.Data() ));
258 AliInfo( Form( "ConfigFileName : %s", fConfigName.Data() ));
259 AliInfo( Form( "EMCALGeometryName : %s", fEMCALGeoName.Data() ));
260 AliInfo( Form( "NonLinearityFunction : %d", fNonLinearFunc ));
261 AliInfo( Form( "NonLinearityThreshold : %d", fNonLinearThreshold ));
262 AliInfo( Form( "MisalignmentMatrixSurvey : %d", fMisalignSurvey ));
263 AliInfo( Form( "NumberOfCellsFromEMCALBorder : %d", fNCellsFromEMCALBorder ));
264 AliInfo( Form( "RCut : %f", fRcut ));
265 AliInfo( Form( "Mass : %f", fMass ));
266 AliInfo( Form( "Step : %f", fStep ));
267 AliInfo( Form( "EtaCut : %f", fEtacut ));
268 AliInfo( Form( "PhiCut : %f", fPhicut ));
269 AliInfo( Form( "ExoticCellFraction : %f", fExoticCellFraction ));
270 AliInfo( Form( "ExoticCellDiffTime : %f", fExoticCellDiffTime ));
271 AliInfo( Form( "ExoticCellMinAmplitude : %f", fExoticCellMinAmplitude ));
272 AliInfo( "=============================================================" );
276 fEMCALGeo = AliEMCALGeometry::GetInstance(fEMCALGeoName) ;
279 fDigitsArr = new TClonesArray("AliEMCALDigit",1000);
281 // Initialising non-linearity parameters
282 if( fNonLinearThreshold != -1 )
283 fEMCALRecoUtils->SetNonLinearityThreshold(fNonLinearThreshold);
284 if( fNonLinearFunc != -1 )
285 fEMCALRecoUtils->SetNonLinearityFunction(fNonLinearFunc);
287 // missalignment function
288 fEMCALRecoUtils->SetPositionAlgorithm(AliEMCALRecoUtils::kPosTowerGlobal);
291 // do not do the eta0 fiducial cut
292 if( fNCellsFromEMCALBorder != -1 )
293 fEMCALRecoUtils->SetNumberOfCellsFromEMCALBorder(fNCellsFromEMCALBorder);
294 fEMCALRecoUtils->SwitchOnNoFiducialBorderInEMCALEta0();
296 // exotic cell rejection
297 if( fExoticCellFraction != -1 )
298 fEMCALRecoUtils->SetExoticCellFractionCut( fExoticCellFraction );
299 if( fExoticCellDiffTime != -1 )
300 fEMCALRecoUtils->SetExoticCellDiffTimeCut( fExoticCellDiffTime );
301 if( fExoticCellMinAmplitude != -1 )
302 fEMCALRecoUtils->SetExoticCellMinAmplitudeCut( fExoticCellMinAmplitude );
304 // Setting track matching parameters ... mass, step size and residual cut
306 fEMCALRecoUtils->SetMass(fMass);
308 fEMCALRecoUtils->SetStep(fStep);
310 // spatial cut based on separate eta/phi or common processing
312 fEMCALRecoUtils->SwitchOnCutEtaPhiSum();
314 fEMCALRecoUtils->SetCutR(fRcut);
315 } else if (fCutEtaPhiSeparate) {
316 fEMCALRecoUtils->SwitchOnCutEtaPhiSeparate();
318 fEMCALRecoUtils->SetCutEta(fEtacut);
320 fEMCALRecoUtils->SetCutPhi(fPhicut);
324 //_____________________________________________________
325 void AliEMCALTenderSupply::ProcessEvent()
329 AliESDEvent *event = fTender->GetEvent();
331 AliError("ESD event ptr = 0, returning");
335 // Initialising parameters once per run number
336 if (fTender->RunChanged()){
338 // initiate default reco params if not supplied by user
345 // define what recalib parameters are needed for various switches
346 // this is based on implementation in AliEMCALRecoUtils
347 Bool_t needBadChannels = fBadCellRemove | fClusterBadChannelCheck | fRecalDistToBadChannels | fReClusterize;
348 Bool_t needRecalib = fCalibrateEnergy | fReClusterize;
349 Bool_t needTimecalib = fCalibrateTime | fReClusterize;
350 Bool_t needMisalign = fRecalClusPos | fReClusterize;
351 Bool_t needClusterizer = fReClusterize;
354 if( needBadChannels )
356 Int_t fInitBC = InitBadChannels();
359 AliError("InitBadChannels returned false, returning");
364 AliWarning("InitBadChannels OK");
368 AliWarning(Form("No external hot channel set: %d - %s", event->GetRunNumber(), fFilepass.Data()));
372 // init recalibration factors
375 Int_t fInitRecalib = InitRecalib();
378 AliError("InitRecalib returned false, returning");
383 AliWarning("InitRecalib OK");
387 AliWarning(Form("No recalibration available: %d - %s", event->GetRunNumber(), fFilepass.Data()));
388 fReCalibCluster = kFALSE;
392 // init time calibration
395 Int_t initTC = InitTimeCalibration();
398 AliError("InitTimeCalibration returned false, returning");
403 AliWarning("InitTimeCalib OK");
407 AliWarning(Form("No external time calibration set: %d - %s", event->GetRunNumber(), fFilepass.Data()));
411 // init misalignment matrix
414 if (!InitMisalignMatrix()) {
416 AliError("InitMisalignmentMatrix returned false, returning");
420 AliWarning("InitMisalignMatrix OK");
424 if( needClusterizer )
426 if (!InitClusterization())
428 AliError("InitClusterization returned false, returning");
432 AliWarning("InitClusterization OK");
436 fEMCALRecoUtils->Print("");
439 // disable implied switches -------------------------------------------------
440 // AliEMCALRecoUtils or clusterizer functions alredy include some
441 // recalibration so based on those implied callibration te switches
442 // here are disabled to avoid duplication
444 // clusterizer does cluster energy recalibration, position recomputation
448 fReCalibCluster = kFALSE;
449 fRecalClusPos = kFALSE;
450 fRecalShowerShape = kFALSE;
453 // CONFIGURE THE RECO UTILS -------------------------------------------------
454 // configure the reco utils
455 // this option does energy recalibration
456 if( fCalibrateEnergy )
457 fEMCALRecoUtils->SwitchOnRecalibration();
459 fEMCALRecoUtils->SwitchOffRecalibration();
461 // allows time calibration
463 fEMCALRecoUtils->SwitchOnTimeRecalibration();
465 fEMCALRecoUtils->SwitchOffTimeRecalibration();
467 // allows to zero bad cells
469 fEMCALRecoUtils->SwitchOnBadChannelsRemoval();
471 fEMCALRecoUtils->SwitchOffBadChannelsRemoval();
473 // distance to bad channel recalibration
474 if( fRecalDistToBadChannels )
475 fEMCALRecoUtils->SwitchOnDistToBadChannelRecalculation();
477 fEMCALRecoUtils->SwitchOffDistToBadChannelRecalculation();
479 // exclude exotic cells
480 if( fRejectExoticCells )
481 fEMCALRecoUtils->SwitchOnRejectExoticCell();
483 fEMCALRecoUtils->SwitchOffRejectExoticCell();
485 // exclude clusters with exotic cells
486 if( fRejectExoticClusters )
487 fEMCALRecoUtils->SwitchOnRejectExoticCluster();
489 fEMCALRecoUtils->SwitchOffRejectExoticCluster();
491 // TODO: not implemented switches
492 // SwitchOnClusterEnergySmearing
493 // SwitchOnRunDepCorrection
495 // START PROCESSING ---------------------------------------------------------
496 // Test if cells present
497 AliESDCaloCells *cells= event->GetEMCALCells();
498 if (cells->GetNumberOfCells()<=0)
501 AliWarning(Form("Number of EMCAL cells = %d, returning", cells->GetNumberOfCells()));
506 AliInfo(Form("Re-calibrate cluster %d\n",fReCalibCluster));
508 // mark the cells not recalibrated in case of selected
509 // time, energy recalibration or bad channel removal
510 if( fCalibrateEnergy || fCalibrateTime || fBadCellRemove )
511 fEMCALRecoUtils->ResetCellsCalibrated();
513 // CELL RECALIBRATION -------------------------------------------------------
514 // cell objects will be updated
515 // the cell calibrations are also processed locally any time those are needed
516 // in case that the cell objects are not to be updated here for later use
520 // includes exotic cell check in the UpdateCells function - is not provided
524 // switch off recalibrations so those are not done multiple times
525 // this is just for safety, the recalibrated flag of cell object
526 // should not allow for farther processing anyways
527 fEMCALRecoUtils->SwitchOffRecalibration();
528 fEMCALRecoUtils->SwitchOffTimeRecalibration();
534 // RECLUSTERIZATION ---------------------------------------------------------
542 // Store good clusters
543 TClonesArray *clusArr = dynamic_cast<TClonesArray*>(event->FindListObject("caloClusters"));
545 clusArr = dynamic_cast<TClonesArray*>(event->FindListObject("CaloClusters"));
547 AliWarning(Form("No cluster array, number of cells in event = %d, returning", cells->GetNumberOfCells()));
551 // PROCESS SINGLE CLUSTER RECALIBRATION -------------------------------------
552 // now go through clusters one by one and process separate correction
553 // as those were defined or not
554 Int_t nclusters = clusArr->GetEntriesFast();
555 for (Int_t icluster=0; icluster < nclusters; ++icluster)
557 AliVCluster *clust = static_cast<AliVCluster*>(clusArr->At(icluster));
560 if (!clust->IsEMCAL())
563 // REMOVE CLUSTERS WITH BAD CELLS -----------------------------
564 if( fClusterBadChannelCheck )
566 // careful, the the ClusterContainsBadChannel is dependent on
567 // SwitchOnBadChannelsRemoval, switching it ON automatically
568 // and returning to original value after processing
569 Bool_t badRemoval = fEMCALRecoUtils->IsBadChannelsRemovalSwitchedOn();
570 fEMCALRecoUtils->SwitchOnBadChannelsRemoval();
572 Bool_t badResult = fEMCALRecoUtils->ClusterContainsBadChannel(fEMCALGeo, clust->GetCellsAbsId(), clust->GetNCells());
574 // switch the bad channels removal back
576 fEMCALRecoUtils->SwitchOffBadChannelsRemoval();
580 delete clusArr->RemoveAt(icluster);
581 continue; //TODO is it really needed to remove it? Or should we flag it?
585 // REMOVE EXOTIC CLUSTERS -------------------------------------
586 // does process local cell recalibration energy and time without replacing
587 // the global cell values, in case of no cell recalib done yet
588 if( fRejectExoticClusters )
590 // careful, the IsExoticCluster is dependent on
591 // SwitchOnRejectExoticCell, switching it ON automatically
592 // and returning to original value after processing
593 Bool_t exRemoval = fEMCALRecoUtils->IsRejectExoticCell();
594 fEMCALRecoUtils->SwitchOnRejectExoticCell();
596 // get bunch crossing
597 Int_t bunchCrossNo = fTender->GetEvent()->GetBunchCrossNumber();
599 Bool_t exResult = fEMCALRecoUtils->IsExoticCluster(clust, cells, bunchCrossNo );
601 // switch the exotic channels removal back
603 fEMCALRecoUtils->SwitchOffRejectExoticCell();
607 delete clusArr->RemoveAt(icluster);
608 continue; //TODO is it really needed to remove it? Or should we flag it?
612 // FIDUCIAL CUT -----------------------------------------------
615 // depends on SetNumberOfCellsFromEMCALBorder
616 // SwitchOnNoFiducialBorderInEMCALEta0
617 if (!fEMCALRecoUtils->CheckCellFiducialRegion(fEMCALGeo, clust, cells)){
618 delete clusArr->RemoveAt(icluster);
619 continue; //TODO it would be nice to store the distance
623 // CLUSTER ENERGY ---------------------------------------------
624 // does process local cell recalibration energy and time without replacing
625 // the global cell values, in case of no cell recalib done yet
626 if( fReCalibCluster )
627 fEMCALRecoUtils->RecalibrateClusterEnergy(fEMCALGeo, clust, cells);
629 // CLUSTER POSITION -------------------------------------------
630 // does process local cell energy recalibration, if enabled and cells
631 // not calibratied yet
633 fEMCALRecoUtils->RecalculateClusterPosition(fEMCALGeo, cells, clust);
635 // SHOWER SHAPE -----------------------------------------------
636 if( fRecalShowerShape )
637 fEMCALRecoUtils->RecalculateClusterShowerShapeParameters(fEMCALGeo, cells, clust);
639 // NONLINEARITY -----------------------------------------------
640 if( fDoNonLinearity )
642 Float_t correctedEnergy = fEMCALRecoUtils->CorrectClusterEnergyLinearity(clust);
643 clust->SetE(correctedEnergy);
646 // DISTANCE TO BAD CHANNELS -----------------------------------
647 if( fRecalDistToBadChannels )
648 fEMCALRecoUtils->RecalculateClusterDistanceToBadChannel(fEMCALGeo, cells, clust);
656 // TRACK MATCHING -----------------------------------------------------------
657 if (!TGeoGlobalMagField::Instance()->GetField())
659 event->InitMagneticField();
662 fEMCALRecoUtils->FindMatches(event,0x0,fEMCALGeo);
663 fEMCALRecoUtils->SetClusterMatchedToTrack(event);
664 fEMCALRecoUtils->SetTracksMatchedToCluster(event);
667 //_____________________________________________________
668 Bool_t AliEMCALTenderSupply::InitMisalignMatrix()
670 // Initialising misalignment matrices
672 AliESDEvent *event = fTender->GetEvent();
678 AliInfo("Misalignment matrix already set");
683 AliInfo("Initialising misalignment matrix");
685 if (fLoadGeomMatrices) {
686 for(Int_t mod=0; mod < fEMCALGeo->GetNumberOfSuperModules(); ++mod)
688 if (fEMCALMatrix[mod]){
690 fEMCALMatrix[mod]->Print();
691 fEMCALGeo->SetMisalMatrix(fEMCALMatrix[mod],mod);
694 fGeomMatrixSet = kTRUE;
698 Int_t runGM = event->GetRunNumber();
701 if(fMisalignSurvey == kdefault)
702 { //take default alignment corresponding to run no
703 AliOADBContainer emcalgeoCont(Form("emcal"));
704 emcalgeoCont.InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALlocal2master.root",Form("AliEMCALgeo"));
705 mobj=(TObjArray*)emcalgeoCont.GetObject(runGM,"EmcalMatrices");
708 if(fMisalignSurvey == kSurveybyS)
709 { //take alignment at sector level
710 if (runGM <= 140000) { //2010 data
711 AliOADBContainer emcalgeoCont(Form("emcal2010"));
712 emcalgeoCont.InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALlocal2master.root",Form("AliEMCALgeo"));
713 mobj=(TObjArray*)emcalgeoCont.GetObject(100,"survey10");
715 } else if (runGM>140000)
716 { // 2011 LHC11a pass1 data
717 AliOADBContainer emcalgeoCont(Form("emcal2011"));
718 emcalgeoCont.InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALlocal2master.root",Form("AliEMCALgeo"));
719 mobj=(TObjArray*)emcalgeoCont.GetObject(100,"survey11byS");
723 if(fMisalignSurvey == kSurveybyM)
724 { //take alignment at module level
725 if (runGM <= 140000) { //2010 data
726 AliOADBContainer emcalgeoCont(Form("emcal2010"));
727 emcalgeoCont.InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALlocal2master.root",Form("AliEMCALgeo"));
728 mobj=(TObjArray*)emcalgeoCont.GetObject(100,"survey10");
730 } else if (runGM>140000)
731 { // 2011 LHC11a pass1 data
732 AliOADBContainer emcalgeoCont(Form("emcal2011"));
733 emcalgeoCont.InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALlocal2master.root",Form("AliEMCALgeo"));
734 mobj=(TObjArray*)emcalgeoCont.GetObject(100,"survey11byM");
740 AliFatal("Geometry matrix array not found");
744 for(Int_t mod=0; mod < (fEMCALGeo->GetEMCGeometry())->GetNumberOfSuperModules(); mod++)
746 fEMCALMatrix[mod] = (TGeoHMatrix*) mobj->At(mod);
747 fEMCALGeo->SetMisalMatrix(fEMCALMatrix[mod],mod);
748 fEMCALMatrix[mod]->Print();
754 //_____________________________________________________
755 Int_t AliEMCALTenderSupply::InitBadChannels()
757 // Initialising bad channel maps
758 AliESDEvent *event = fTender->GetEvent();
763 AliInfo("Initialising Bad channel map");
765 // init default maps first
766 if( !fEMCALRecoUtils->GetEMCALBadChannelStatusMapArray() )
767 fEMCALRecoUtils->InitEMCALBadChannelStatusMap() ;
769 Int_t runBC = event->GetRunNumber();
771 AliOADBContainer *contBC = new AliOADBContainer("");
773 { //if fBasePath specified in the ->SetBasePath()
774 if (fDebugLevel>0) AliInfo(Form("Loading Bad Channels OADB from given path %s",fBasePath.Data()));
776 TFile *fbad=new TFile(Form("%s/EMCALBadChannels.root",fBasePath.Data()),"read");
777 if (!fbad || fbad->IsZombie())
779 AliFatal(Form("EMCALBadChannels.root was not found in the path provided: %s",fBasePath.Data()));
783 if (fbad) delete fbad;
785 contBC->InitFromFile(Form("%s/EMCALBadChannels.root",fBasePath.Data()),"AliEMCALBadChannels");
788 { // Else choose the one in the $ALICE_ROOT directory
789 if (fDebugLevel>0) AliInfo("Loading Bad Channels OADB from $ALICE_ROOT/OADB/EMCAL");
791 TFile *fbad=new TFile("$ALICE_ROOT/OADB/EMCAL/EMCALBadChannels.root","read");
792 if (!fbad || fbad->IsZombie())
794 AliFatal("$ALICE_ROOT/OADB/EMCAL/EMCALBadChannels.root was not found");
798 if (fbad) delete fbad;
800 contBC->InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALBadChannels.root","AliEMCALBadChannels");
803 TObjArray *arrayBC=(TObjArray*)contBC->GetObject(runBC);
806 AliError(Form("No external hot channel set for run number: %d", runBC));
810 TObjArray *arrayBCpass=(TObjArray*)arrayBC->FindObject(fFilepass); // Here, it looks for a specific pass
813 AliError(Form("No external hot channel set for: %d -%s", runBC,fFilepass.Data()));
817 if (fDebugLevel>0) arrayBCpass->Print();
819 Int_t sms = fEMCALGeo->GetEMCGeometry()->GetNumberOfSuperModules();
820 for (Int_t i=0; i<sms; ++i)
822 TH2I *h = fEMCALRecoUtils->GetEMCALChannelStatusMap(i);
825 h=(TH2I*)arrayBCpass->FindObject(Form("EMCALBadChannelMap_Mod%d",i));
829 AliError(Form("Can not get EMCALBadChannelMap_Mod%d",i));
833 fEMCALRecoUtils->SetEMCALChannelStatusMap(i,h);
838 //_____________________________________________________
839 Int_t AliEMCALTenderSupply::InitRecalib()
841 // Initialising recalibration factors.
843 AliESDEvent *event = fTender->GetEvent();
848 AliInfo("Initialising recalibration factors");
850 // init default maps first
851 if( !fEMCALRecoUtils->GetEMCALRecalibrationFactorsArray() )
852 fEMCALRecoUtils->InitEMCALRecalibrationFactors() ;
854 Int_t runRC = event->GetRunNumber();
856 AliOADBContainer *contRF=new AliOADBContainer("");
858 { //if fBasePath specified in the ->SetBasePath()
859 if (fDebugLevel>0) AliInfo(Form("Loading Recalib OADB from given path %s",fBasePath.Data()));
861 TFile *fRecalib= new TFile(Form("%s/EMCALRecalib.root",fBasePath.Data()),"read");
862 if (!fRecalib || fRecalib->IsZombie())
864 AliFatal(Form("EMCALRecalib.root not found in %s",fBasePath.Data()));
868 if (fRecalib) delete fRecalib;
870 contRF->InitFromFile(Form("%s/EMCALRecalib.root",fBasePath.Data()),"AliEMCALRecalib");
873 { // Else choose the one in the $ALICE_ROOT directory
874 if (fDebugLevel>0) AliInfo("Loading Recalib OADB from $ALICE_ROOT/OADB/EMCAL");
876 TFile *fRecalib= new TFile("$ALICE_ROOT/OADB/EMCAL/EMCALRecalib.root","read");
877 if (!fRecalib || fRecalib->IsZombie())
879 AliFatal("$ALICE_ROOT/OADB/EMCAL/EMCALRecalib.root was not found");
883 if (fRecalib) delete fRecalib;
885 contRF->InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALRecalib.root","AliEMCALRecalib");
888 TObjArray *recal=(TObjArray*)contRF->GetObject(runRC); //GetObject(int runnumber)
891 AliError(Form("No Objects for run: %d",runRC));
895 TObjArray *recalpass=(TObjArray*)recal->FindObject(fFilepass);
898 AliError(Form("No Objects for run: %d - %s",runRC,fFilepass.Data()));
902 TObjArray *recalib=(TObjArray*)recalpass->FindObject("Recalib");
905 AliError(Form("No Recalib histos found for %d - %s",runRC,fFilepass.Data()));
909 if (fDebugLevel>0) recalib->Print();
911 Int_t sms = fEMCALGeo->GetEMCGeometry()->GetNumberOfSuperModules();
912 for (Int_t i=0; i<sms; ++i)
914 TH2F *h = fEMCALRecoUtils->GetEMCALChannelRecalibrationFactors(i);
917 h = (TH2F*)recalib->FindObject(Form("EMCALRecalFactors_SM%d",i));
920 AliError(Form("Could not load EMCALRecalFactors_SM%d",i));
924 fEMCALRecoUtils->SetEMCALChannelRecalibrationFactors(i,h);
929 //_____________________________________________________
930 Int_t AliEMCALTenderSupply::InitTimeCalibration()
932 // Initialising bad channel maps
933 AliESDEvent *event = fTender->GetEvent();
938 AliInfo("Initialising time calibration map");
940 // init default maps first
941 if( !fEMCALRecoUtils->GetEMCALTimeRecalibrationFactorsArray() )
942 fEMCALRecoUtils->InitEMCALTimeRecalibrationFactors() ;
944 Int_t runBC = event->GetRunNumber();
946 AliOADBContainer *contBC = new AliOADBContainer("");
948 { //if fBasePath specified in the ->SetBasePath()
949 if (fDebugLevel>0) AliInfo(Form("Loading time calibration OADB from given path %s",fBasePath.Data()));
951 TFile *fbad=new TFile(Form("%s/EMCALTimeCalib.root",fBasePath.Data()),"read");
952 if (!fbad || fbad->IsZombie())
954 AliFatal(Form("EMCALTimeCalib.root was not found in the path provided: %s",fBasePath.Data()));
958 if (fbad) delete fbad;
960 contBC->InitFromFile(Form("%s/EMCALTimeCalib.root",fBasePath.Data()),"AliEMCALTimeCalib");
963 { // Else choose the one in the $ALICE_ROOT directory
964 if (fDebugLevel>0) AliInfo("Loading time calibration OADB from $ALICE_ROOT/OADB/EMCAL");
966 TFile *fbad=new TFile("$ALICE_ROOT/OADB/EMCAL/EMCALTimeCalib.root","read");
967 if (!fbad || fbad->IsZombie())
969 AliFatal("$ALICE_ROOT/OADB/EMCAL/EMCALTimeCalib.root was not found");
973 if (fbad) delete fbad;
975 contBC->InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALTimeCalib.root","AliEMCALTimeCalib");
978 TObjArray *arrayBC=(TObjArray*)contBC->GetObject(runBC);
981 AliError(Form("No external time calibration set for run number: %d", runBC));
985 TObjArray *arrayBCpass=(TObjArray*)arrayBC->FindObject(fFilepass); // Here, it looks for a specific pass
988 AliError(Form("No external time calibration set for: %d -%s", runBC,fFilepass.Data()));
992 if (fDebugLevel>0) arrayBCpass->Print();
994 for( Int_t i = 0; i < 4; i++ )
996 TH1F *h = fEMCALRecoUtils->GetEMCALChannelTimeRecalibrationFactors( i );
1000 h = (TH1F*)arrayBCpass->FindObject(Form("hAllTimeAvBC%d",i));
1004 AliError(Form("Can not get hAllTimeAvBC%d",i));
1008 fEMCALRecoUtils->SetEMCALChannelTimeRecalibrationFactors(i,h);
1013 //_____________________________________________________
1014 void AliEMCALTenderSupply::UpdateCells()
1016 //Remove bad cells from the cell list
1017 //Recalibrate energy and time cells
1018 //This is required for later reclusterization
1020 AliESDCaloCells *cells = fTender->GetEvent()->GetEMCALCells();
1021 Int_t bunchCrossNo = fTender->GetEvent()->GetBunchCrossNumber();
1023 fEMCALRecoUtils->RecalibrateCells(cells, bunchCrossNo);
1025 // remove exotic cells - loop through cells and zero the exotic ones
1026 // just like with bad cell rejection in reco utils (inside RecalibrateCells)
1027 if( fRejectExoticCells )
1030 Bool_t isExot = kFALSE;
1032 // loop through cells
1033 Int_t nEMcell = cells->GetNumberOfCells() ;
1034 for (Int_t iCell = 0; iCell < nEMcell; iCell++)
1036 absId = cells->GetCellNumber(iCell);
1038 isExot = fEMCALRecoUtils->IsExoticCell( absId, cells, bunchCrossNo );
1041 cells->SetCell( iCell, absId, 0.0, 0.0 );
1043 } // reject exotic cells
1048 //_____________________________________________________
1049 void AliEMCALTenderSupply::InitRecParam()
1051 // Initalize the reconstructor parameters
1052 // Depending on the data type, different type of clusterizer
1055 AliInfo("Initialize the recParam");
1057 fRecParam = new AliEMCALRecParam;
1058 const AliESDRun *run = fTender->GetEvent()->GetESDRun();
1059 TString bt(run->GetBeamType());
1062 fRecParam->SetClusterizerFlag(AliEMCALRecParam::kClusterizerv2);
1063 fRecParam->SetClusteringThreshold(0.100);
1064 fRecParam->SetMinECut(0.050);
1068 fRecParam->SetClusterizerFlag(AliEMCALRecParam::kClusterizerv1);
1069 fRecParam->SetClusteringThreshold(0.100);
1070 fRecParam->SetMinECut(0.050);
1074 //_____________________________________________________
1075 Bool_t AliEMCALTenderSupply::InitClusterization()
1077 // Initialing clusterization/unfolding algorithm and set all the needed parameters.
1079 AliESDEvent *event = fTender->GetEvent();
1084 AliInfo(Form("Initialising reclustering parameters: Clusterizer type: %d",fRecParam->GetClusterizerFlag()));
1086 //---setup clusterizer
1087 delete fClusterizer;
1088 if (fRecParam->GetClusterizerFlag() == AliEMCALRecParam::kClusterizerv1)
1089 fClusterizer = new AliEMCALClusterizerv1 (fEMCALGeo);
1090 else if (fRecParam->GetClusterizerFlag() == AliEMCALRecParam::kClusterizerv2)
1091 fClusterizer = new AliEMCALClusterizerv2(fEMCALGeo);
1092 else if (fRecParam->GetClusterizerFlag() == AliEMCALRecParam::kClusterizerNxN)
1094 AliEMCALClusterizerNxN *clusterizer = new AliEMCALClusterizerNxN(fEMCALGeo);
1095 clusterizer->SetNRowDiff(fRecParam->GetNRowDiff());
1096 clusterizer->SetNColDiff(fRecParam->GetNColDiff());
1097 fClusterizer = clusterizer;
1101 AliFatal(Form("Clusterizer < %d > not available", fRecParam->GetClusterizerFlag()));
1105 // Set the clustering parameters
1106 fClusterizer->SetECAClusteringThreshold( fRecParam->GetClusteringThreshold() );
1107 fClusterizer->SetECALogWeight ( fRecParam->GetW0() );
1108 fClusterizer->SetMinECut ( fRecParam->GetMinECut() );
1109 fClusterizer->SetUnfolding ( fRecParam->GetUnfold() );
1110 fClusterizer->SetECALocalMaxCut ( fRecParam->GetLocMaxCut() );
1111 fClusterizer->SetTimeCut ( fRecParam->GetTimeCut() );
1112 fClusterizer->SetTimeMin ( fRecParam->GetTimeMin() );
1113 fClusterizer->SetTimeMax ( fRecParam->GetTimeMax() );
1114 fClusterizer->SetInputCalibrated ( kTRUE );
1115 fClusterizer->SetJustClusters ( kTRUE );
1117 // In case of unfolding after clusterization is requested, set the corresponding parameters
1118 if (fRecParam->GetUnfold())
1120 for (Int_t i = 0; i < 8; ++i)
1122 fClusterizer->SetSSPars(i, fRecParam->GetSSPars(i));
1124 for (Int_t i = 0; i < 3; ++i)
1126 fClusterizer->SetPar5 (i, fRecParam->GetPar5(i));
1127 fClusterizer->SetPar6 (i, fRecParam->GetPar6(i));
1129 fClusterizer->InitClusterUnfolding();
1132 fClusterizer->SetDigitsArr(fDigitsArr);
1133 fClusterizer->SetOutput(0);
1134 fClusterArr = const_cast<TObjArray *>(fClusterizer->GetRecPoints());
1138 //_____________________________________________________
1139 void AliEMCALTenderSupply::FillDigitsArray()
1141 // Fill digits from cells to a TClonesArray.
1143 AliESDEvent *event = fTender->GetEvent();
1147 fDigitsArr->Clear("C");
1148 AliESDCaloCells *cells = event->GetEMCALCells();
1149 Int_t ncells = cells->GetNumberOfCells();
1150 for (Int_t icell = 0, idigit = 0; icell < ncells; ++icell)
1152 Double_t cellAmplitude=0, cellTime=0;
1153 Short_t cellNumber=0;
1155 if (cells->GetCell(icell, cellNumber, cellAmplitude, cellTime) != kTRUE)
1158 // Do not add if already too low (some cells set to 0 if bad channels)
1159 if (cellAmplitude < fRecParam->GetMinECut() )
1162 // If requested, do not include exotic cells
1163 if (fEMCALRecoUtils->IsExoticCell(cellNumber,cells,event->GetBunchCrossNumber()))
1166 AliEMCALDigit *digit = static_cast<AliEMCALDigit*>(fDigitsArr->New(idigit));
1167 digit->SetId(cellNumber);
1168 digit->SetTime(cellTime);
1169 digit->SetTimeR(cellTime);
1170 digit->SetIndexInList(idigit);
1171 digit->SetType(AliEMCALDigit::kHG);
1172 digit->SetAmplitude(cellAmplitude);
1177 //_____________________________________________________
1178 void AliEMCALTenderSupply::Clusterize()
1182 fClusterizer->Digits2Clusters("");
1185 //_____________________________________________________
1186 void AliEMCALTenderSupply::UpdateClusters()
1188 // Update ESD cluster list.
1190 AliESDEvent *event = fTender->GetEvent();
1194 TClonesArray *clus = dynamic_cast<TClonesArray*>(event->FindListObject("caloClusters"));
1196 clus = dynamic_cast<TClonesArray*>(event->FindListObject("CaloClusters"));
1199 AliError(" Null pointer to calo clusters array, returning");
1203 Int_t nents = clus->GetEntriesFast();
1204 for (Int_t i=0; i < nents; ++i)
1206 AliESDCaloCluster *c = static_cast<AliESDCaloCluster*>(clus->At(i));
1210 delete clus->RemoveAt(i);
1215 RecPoints2Clusters(clus);
1219 //_____________________________________________________
1220 void AliEMCALTenderSupply::RecPoints2Clusters(TClonesArray *clus)
1222 // Convert AliEMCALRecoPoints to AliESDCaloClusters.
1223 // Cluster energy, global position, cells and their amplitude fractions are restored.
1225 AliESDEvent *event = fTender->GetEvent();
1229 Int_t ncls = fClusterArr->GetEntriesFast();
1230 for(Int_t i=0, nout=clus->GetEntriesFast(); i < ncls; ++i)
1232 AliEMCALRecPoint *recpoint = static_cast<AliEMCALRecPoint*>(fClusterArr->At(i));
1234 Int_t ncellsTrue = 0;
1235 const Int_t ncells = recpoint->GetMultiplicity();
1236 UShort_t absIds[ncells];
1237 Double32_t ratios[ncells];
1238 Int_t *dlist = recpoint->GetDigitsList();
1239 Float_t *elist = recpoint->GetEnergiesList();
1240 for (Int_t c = 0; c < ncells; ++c)
1242 AliEMCALDigit *digit = static_cast<AliEMCALDigit*>(fDigitsArr->At(dlist[c]));
1243 absIds[ncellsTrue] = digit->GetId();
1244 ratios[ncellsTrue] = elist[c]/digit->GetAmplitude();
1245 if (ratios[ncellsTrue] < 0.001)
1252 AliWarning("Skipping cluster with no cells");
1256 // calculate new cluster position
1258 recpoint->GetGlobalPosition(gpos);
1262 AliESDCaloCluster *c = static_cast<AliESDCaloCluster*>(clus->New(nout++));
1264 c->SetType(AliVCluster::kEMCALClusterv1);
1265 c->SetE(recpoint->GetEnergy());
1267 c->SetNCells(ncellsTrue);
1268 c->SetDispersion(recpoint->GetDispersion());
1269 c->SetEmcCpvDistance(-1); //not yet implemented
1270 c->SetChi2(-1); //not yet implemented
1271 c->SetTOF(recpoint->GetTime()) ; //time-of-flight
1272 c->SetNExMax(recpoint->GetNExMax()); //number of local maxima
1273 Float_t elipAxis[2];
1274 recpoint->GetElipsAxis(elipAxis);
1275 c->SetM02(elipAxis[0]*elipAxis[0]) ;
1276 c->SetM20(elipAxis[1]*elipAxis[1]) ;
1277 AliESDCaloCluster *cesd = static_cast<AliESDCaloCluster*>(c);
1278 cesd->SetCellsAbsId(absIds);
1279 cesd->SetCellsAmplitudeFraction(ratios);
1283 //_____________________________________________________
1284 void AliEMCALTenderSupply::GetPass()
1286 // Get passx from filename.
1288 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
1289 fInputTree = mgr->GetTree();
1293 AliError("Pointer to tree = 0, returning");
1297 fInputFile = fInputTree->GetCurrentFile();
1299 AliError("Null pointer input file, returning");
1303 TString fname(fInputFile->GetName());
1304 if (fname.Contains("pass1")) fFilepass = TString("pass1");
1305 else if (fname.Contains("pass2")) fFilepass = TString("pass2");
1306 else if (fname.Contains("pass3")) fFilepass = TString("pass3");
1309 AliError(Form("Pass number string not found: %s", fname.Data()));