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 ;
110 //_____________________________________________________
111 AliEMCALTenderSupply::AliEMCALTenderSupply(const char *name, const AliTender *tender) :
112 AliTenderSupply(name,tender)
114 ,fEMCALGeoName("EMCAL_COMPLETEV1")
119 ,fNonLinearThreshold(-1)
120 ,fReCalibCluster(kFALSE)
122 ,fCalibrateEnergy(kFALSE)
123 ,fCalibrateTime(kFALSE)
124 ,fDoNonLinearity(kFALSE)
125 ,fBadCellRemove(kFALSE)
126 ,fRejectExoticCells(kFALSE)
127 ,fRejectExoticClusters(kFALSE)
128 ,fClusterBadChannelCheck(kFALSE)
129 ,fRecalClusPos(kFALSE)
131 ,fNCellsFromEMCALBorder(-1)
132 ,fRecalDistToBadChannels(kFALSE)
133 ,fRecalShowerShape(kFALSE)
139 ,fCutEtaPhiSum(kTRUE)
140 ,fCutEtaPhiSeparate(kFALSE)
145 ,fReClusterize(kFALSE)
147 ,fGeomMatrixSet(kFALSE)
148 ,fLoadGeomMatrices(kFALSE)
150 ,fDoTrackMatch(kFALSE)
151 ,fDoUpdateOnly(kFALSE)
155 ,fMisalignSurvey(kdefault)
156 ,fExoticCellFraction(-1)
157 ,fExoticCellDiffTime(-1)
158 ,fExoticCellMinAmplitude(-1)
162 for(Int_t i = 0; i < 10; i++) fEMCALMatrix[i] = 0 ;
163 fEMCALRecoUtils = new AliEMCALRecoUtils;
164 fDigitsArr = new TClonesArray("AliEMCALDigit",1000);
167 //_____________________________________________________
168 AliEMCALTenderSupply::~AliEMCALTenderSupply()
172 delete fEMCALRecoUtils;
176 fDigitsArr->Clear("C");
184 //_____________________________________________________
185 void AliEMCALTenderSupply::Init()
187 // Initialise EMCAL tender.
190 AliInfo("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 fEMCALGeo = AliEMCALGeometry::GetInstance(fEMCALGeoName) ;
239 // Initialising non-linearity parameters
240 if( fNonLinearThreshold != -1 )
241 fEMCALRecoUtils->SetNonLinearityThreshold(fNonLinearThreshold);
242 if( fNonLinearFunc != -1 )
243 fEMCALRecoUtils->SetNonLinearityFunction(fNonLinearFunc);
245 // missalignment function
246 fEMCALRecoUtils->SetPositionAlgorithm(AliEMCALRecoUtils::kPosTowerGlobal);
249 // do not do the eta0 fiducial cut
250 if( fNCellsFromEMCALBorder != -1 )
251 fEMCALRecoUtils->SetNumberOfCellsFromEMCALBorder(fNCellsFromEMCALBorder);
252 fEMCALRecoUtils->SwitchOnNoFiducialBorderInEMCALEta0();
254 // exotic cell rejection
255 if( fExoticCellFraction != -1 )
256 fEMCALRecoUtils->SetExoticCellFractionCut( fExoticCellFraction );
257 if( fExoticCellDiffTime != -1 )
258 fEMCALRecoUtils->SetExoticCellDiffTimeCut( fExoticCellDiffTime );
259 if( fExoticCellMinAmplitude != -1 )
260 fEMCALRecoUtils->SetExoticCellMinAmplitudeCut( fExoticCellMinAmplitude );
262 // Setting track matching parameters ... mass, step size and residual cut
264 fEMCALRecoUtils->SetMass(fMass);
266 fEMCALRecoUtils->SetStep(fStep);
268 // spatial cut based on separate eta/phi or common processing
270 fEMCALRecoUtils->SwitchOnCutEtaPhiSum();
272 fEMCALRecoUtils->SetCutR(fRcut);
273 } else if (fCutEtaPhiSeparate) {
274 fEMCALRecoUtils->SwitchOnCutEtaPhiSeparate();
276 fEMCALRecoUtils->SetCutEta(fEtacut);
278 fEMCALRecoUtils->SetCutPhi(fPhicut);
282 //_____________________________________________________
283 void AliEMCALTenderSupply::ProcessEvent()
287 AliESDEvent *event = fTender->GetEvent();
289 AliError("ESD event ptr = 0, returning");
293 // Initialising parameters once per run number
294 if (fTender->RunChanged()){
296 // initiate default reco params if not supplied by user
303 // define what recalib parameters are needed for various switches
304 // this is based on implementation in AliEMCALRecoUtils
305 Bool_t needBadChannels = fBadCellRemove | fClusterBadChannelCheck | fRecalDistToBadChannels | fReClusterize;
306 Bool_t needRecalib = fCalibrateEnergy | fReClusterize;
307 Bool_t needTimecalib = fCalibrateTime | fReClusterize;
308 Bool_t needMisalign = fRecalClusPos | fReClusterize;
309 Bool_t needClusterizer = fReClusterize;
312 if( needBadChannels )
314 Int_t fInitBC = InitBadChannels();
317 AliError("InitBadChannels returned false, returning");
322 AliInfo("InitBadChannels OK");
326 AliInfo(Form("No external hot channel set: %d - %s", event->GetRunNumber(), fFilepass.Data()));
330 // init recalibration factors
333 Int_t fInitRecalib = InitRecalib();
336 AliError("InitRecalib returned false, returning");
341 AliInfo("InitRecalib OK");
345 AliInfo(Form("No recalibration available: %d - %s", event->GetRunNumber(), fFilepass.Data()));
346 fReCalibCluster = kFALSE;
350 // init time calibration
353 Int_t initTC = InitTimeCalibration();
356 AliError("InitTimeCalibration returned false, returning");
361 AliInfo("InitTimeCalib OK");
365 AliInfo(Form("No external time calibration set: %d - %s", event->GetRunNumber(), fFilepass.Data()));
369 // init misalignment matrix
372 if (!InitMisalignMatrix()) {
374 AliError("InitMisalignmentMatrix returned false, returning");
378 AliInfo("InitMisalignMatrix OK");
382 if( needClusterizer )
384 if (!InitClusterization())
386 AliError("InitClusterization returned false, returning");
390 AliInfo("InitClusterization OK");
394 fEMCALRecoUtils->Print("");
397 // disable implied switches -------------------------------------------------
398 // AliEMCALRecoUtils or clusterizer functions alredy include some
399 // recalibration so based on those implied callibration te switches
400 // here are disabled to avoid duplication
402 // clusterizer does cluster energy recalibration, position recomputation
406 fReCalibCluster = kFALSE;
407 fRecalClusPos = kFALSE;
408 fRecalShowerShape = kFALSE;
411 // CONFIGURE THE RECO UTILS -------------------------------------------------
412 // configure the reco utils
413 // this option does energy recalibration
414 if( fCalibrateEnergy )
415 fEMCALRecoUtils->SwitchOnRecalibration();
417 fEMCALRecoUtils->SwitchOffRecalibration();
419 // allows time calibration
421 fEMCALRecoUtils->SwitchOnTimeRecalibration();
423 fEMCALRecoUtils->SwitchOffTimeRecalibration();
425 // allows to zero bad cells
427 fEMCALRecoUtils->SwitchOnBadChannelsRemoval();
429 fEMCALRecoUtils->SwitchOffBadChannelsRemoval();
431 // distance to bad channel recalibration
432 if( fRecalDistToBadChannels )
433 fEMCALRecoUtils->SwitchOnDistToBadChannelRecalculation();
435 fEMCALRecoUtils->SwitchOffDistToBadChannelRecalculation();
437 // exclude exotic cells
438 if( fRejectExoticCells )
439 fEMCALRecoUtils->SwitchOnRejectExoticCell();
441 fEMCALRecoUtils->SwitchOffRejectExoticCell();
443 // exclude clusters with exotic cells
444 if( fRejectExoticClusters )
445 fEMCALRecoUtils->SwitchOnRejectExoticCluster();
447 fEMCALRecoUtils->SwitchOffRejectExoticCluster();
449 // TODO: not implemented switches
450 // SwitchOnClusterEnergySmearing
451 // SwitchOnRunDepCorrection
453 // START PROCESSING ---------------------------------------------------------
454 // Test if cells present
455 AliESDCaloCells *cells= event->GetEMCALCells();
456 if (cells->GetNumberOfCells()<=0)
459 AliWarning(Form("Number of EMCAL cells = %d, returning", cells->GetNumberOfCells()));
464 AliInfo(Form("Re-calibrate cluster %d\n",fReCalibCluster));
466 // mark the cells not recalibrated in case of selected
467 // time, energy recalibration or bad channel removal
468 if( fCalibrateEnergy || fCalibrateTime || fBadCellRemove )
469 fEMCALRecoUtils->ResetCellsCalibrated();
471 // CELL RECALIBRATION -------------------------------------------------------
472 // cell objects will be updated
473 // the cell calibrations are also processed locally any time those are needed
474 // in case that the cell objects are not to be updated here for later use
478 // includes exotic cell check in the UpdateCells function - is not provided
482 // switch off recalibrations so those are not done multiple times
483 // this is just for safety, the recalibrated flag of cell object
484 // should not allow for farther processing anyways
485 fEMCALRecoUtils->SwitchOffRecalibration();
486 fEMCALRecoUtils->SwitchOffTimeRecalibration();
492 // RECLUSTERIZATION ---------------------------------------------------------
500 // Store good clusters
501 TClonesArray *clusArr = dynamic_cast<TClonesArray*>(event->FindListObject("caloClusters"));
503 clusArr = dynamic_cast<TClonesArray*>(event->FindListObject("CaloClusters"));
505 AliWarning(Form("No cluster array, number of cells in event = %d, returning", cells->GetNumberOfCells()));
509 // PROCESS SINGLE CLUSTER RECALIBRATION -------------------------------------
510 // now go through clusters one by one and process separate correction
511 // as those were defined or not
512 Int_t nclusters = clusArr->GetEntriesFast();
513 for (Int_t icluster=0; icluster < nclusters; ++icluster)
515 AliVCluster *clust = static_cast<AliVCluster*>(clusArr->At(icluster));
518 if (!clust->IsEMCAL())
521 // REMOVE CLUSTERS WITH BAD CELLS -----------------------------
522 if( fClusterBadChannelCheck )
524 // careful, the the ClusterContainsBadChannel is dependent on
525 // SwitchOnBadChannelsRemoval, switching it ON automatically
526 // and returning to original value after processing
527 Bool_t badRemoval = fEMCALRecoUtils->IsBadChannelsRemovalSwitchedOn();
528 fEMCALRecoUtils->SwitchOnBadChannelsRemoval();
530 Bool_t badResult = fEMCALRecoUtils->ClusterContainsBadChannel(fEMCALGeo, clust->GetCellsAbsId(), clust->GetNCells());
532 // switch the bad channels removal back
534 fEMCALRecoUtils->SwitchOffBadChannelsRemoval();
538 delete clusArr->RemoveAt(icluster);
539 continue; //TODO is it really needed to remove it? Or should we flag it?
543 // REMOVE EXOTIC CLUSTERS -------------------------------------
544 // does process local cell recalibration energy and time without replacing
545 // the global cell values, in case of no cell recalib done yet
546 if( fRejectExoticClusters )
548 // careful, the IsExoticCluster is dependent on
549 // SwitchOnRejectExoticCell, switching it ON automatically
550 // and returning to original value after processing
551 Bool_t exRemoval = fEMCALRecoUtils->IsRejectExoticCell();
552 fEMCALRecoUtils->SwitchOnRejectExoticCell();
554 // get bunch crossing
555 Int_t bunchCrossNo = fTender->GetEvent()->GetBunchCrossNumber();
557 Bool_t exResult = fEMCALRecoUtils->IsExoticCluster(clust, cells, bunchCrossNo );
559 // switch the exotic channels removal back
561 fEMCALRecoUtils->SwitchOffRejectExoticCell();
565 delete clusArr->RemoveAt(icluster);
566 continue; //TODO is it really needed to remove it? Or should we flag it?
570 // FIDUCIAL CUT -----------------------------------------------
573 // depends on SetNumberOfCellsFromEMCALBorder
574 // SwitchOnNoFiducialBorderInEMCALEta0
575 if (!fEMCALRecoUtils->CheckCellFiducialRegion(fEMCALGeo, clust, cells)){
576 delete clusArr->RemoveAt(icluster);
577 continue; //TODO it would be nice to store the distance
581 // CLUSTER ENERGY ---------------------------------------------
582 // does process local cell recalibration energy and time without replacing
583 // the global cell values, in case of no cell recalib done yet
584 if( fReCalibCluster )
585 fEMCALRecoUtils->RecalibrateClusterEnergy(fEMCALGeo, clust, cells);
587 // CLUSTER POSITION -------------------------------------------
588 // does process local cell energy recalibration, if enabled and cells
589 // not calibratied yet
591 fEMCALRecoUtils->RecalculateClusterPosition(fEMCALGeo, cells, clust);
593 // SHOWER SHAPE -----------------------------------------------
594 if( fRecalShowerShape )
595 fEMCALRecoUtils->RecalculateClusterShowerShapeParameters(fEMCALGeo, cells, clust);
597 // NONLINEARITY -----------------------------------------------
598 if( fDoNonLinearity )
600 Float_t correctedEnergy = fEMCALRecoUtils->CorrectClusterEnergyLinearity(clust);
601 clust->SetE(correctedEnergy);
604 // DISTANCE TO BAD CHANNELS -----------------------------------
605 if( fRecalDistToBadChannels )
606 fEMCALRecoUtils->RecalculateClusterDistanceToBadChannel(fEMCALGeo, cells, clust);
614 // TRACK MATCHING -----------------------------------------------------------
615 if (!TGeoGlobalMagField::Instance()->GetField())
617 event->InitMagneticField();
620 fEMCALRecoUtils->FindMatches(event,0x0,fEMCALGeo);
621 fEMCALRecoUtils->SetClusterMatchedToTrack(event);
622 fEMCALRecoUtils->SetTracksMatchedToCluster(event);
625 //_____________________________________________________
626 Bool_t AliEMCALTenderSupply::InitMisalignMatrix()
628 // Initialising misalignment matrices
630 AliESDEvent *event = fTender->GetEvent();
636 AliInfo("Misalignment matrix already set");
641 AliInfo("Initialising misalignment matrix");
643 if (fLoadGeomMatrices) {
644 for(Int_t mod=0; mod < fEMCALGeo->GetNumberOfSuperModules(); ++mod)
646 if (fEMCALMatrix[mod]){
648 fEMCALMatrix[mod]->Print();
649 fEMCALGeo->SetMisalMatrix(fEMCALMatrix[mod],mod);
652 fGeomMatrixSet = kTRUE;
656 Int_t runGM = event->GetRunNumber();
659 if(fMisalignSurvey == kdefault)
660 { //take default alignment corresponding to run no
661 AliOADBContainer emcalgeoCont(Form("emcal"));
662 emcalgeoCont.InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALlocal2master.root",Form("AliEMCALgeo"));
663 mobj=(TObjArray*)emcalgeoCont.GetObject(runGM,"EmcalMatrices");
666 if(fMisalignSurvey == kSurveybyS)
667 { //take alignment at sector level
668 if (runGM <= 140000) { //2010 data
669 AliOADBContainer emcalgeoCont(Form("emcal2010"));
670 emcalgeoCont.InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALlocal2master.root",Form("AliEMCALgeo"));
671 mobj=(TObjArray*)emcalgeoCont.GetObject(100,"survey10");
673 } else if (runGM>140000)
674 { // 2011 LHC11a pass1 data
675 AliOADBContainer emcalgeoCont(Form("emcal2011"));
676 emcalgeoCont.InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALlocal2master.root",Form("AliEMCALgeo"));
677 mobj=(TObjArray*)emcalgeoCont.GetObject(100,"survey11byS");
681 if(fMisalignSurvey == kSurveybyM)
682 { //take alignment at module level
683 if (runGM <= 140000) { //2010 data
684 AliOADBContainer emcalgeoCont(Form("emcal2010"));
685 emcalgeoCont.InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALlocal2master.root",Form("AliEMCALgeo"));
686 mobj=(TObjArray*)emcalgeoCont.GetObject(100,"survey10");
688 } else if (runGM>140000)
689 { // 2011 LHC11a pass1 data
690 AliOADBContainer emcalgeoCont(Form("emcal2011"));
691 emcalgeoCont.InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALlocal2master.root",Form("AliEMCALgeo"));
692 mobj=(TObjArray*)emcalgeoCont.GetObject(100,"survey11byM");
698 AliFatal("Geometry matrix array not found");
702 for(Int_t mod=0; mod < (fEMCALGeo->GetEMCGeometry())->GetNumberOfSuperModules(); mod++)
704 fEMCALMatrix[mod] = (TGeoHMatrix*) mobj->At(mod);
705 fEMCALGeo->SetMisalMatrix(fEMCALMatrix[mod],mod);
706 fEMCALMatrix[mod]->Print();
712 //_____________________________________________________
713 Int_t AliEMCALTenderSupply::InitBadChannels()
715 // Initialising bad channel maps
716 AliESDEvent *event = fTender->GetEvent();
721 AliInfo("Initialising Bad channel map");
723 // init default maps first
724 if( !fEMCALRecoUtils->GetEMCALBadChannelStatusMapArray() )
725 fEMCALRecoUtils->InitEMCALBadChannelStatusMap() ;
727 Int_t runBC = event->GetRunNumber();
729 AliOADBContainer *contBC = new AliOADBContainer("");
731 { //if fBasePath specified in the ->SetBasePath()
732 if (fDebugLevel>0) AliInfo(Form("Loading Bad Channels OADB from given path %s",fBasePath.Data()));
734 TFile *fbad=new TFile(Form("%s/EMCALBadChannels.root",fBasePath.Data()),"read");
735 if (!fbad || fbad->IsZombie())
737 AliFatal(Form("EMCALBadChannels.root was not found in the path provided: %s",fBasePath.Data()));
741 if (fbad) delete fbad;
743 contBC->InitFromFile(Form("%s/EMCALBadChannels.root",fBasePath.Data()),"AliEMCALBadChannels");
746 { // Else choose the one in the $ALICE_ROOT directory
747 if (fDebugLevel>0) AliInfo("Loading Bad Channels OADB from $ALICE_ROOT/OADB/EMCAL");
749 TFile *fbad=new TFile("$ALICE_ROOT/OADB/EMCAL/EMCALBadChannels.root","read");
750 if (!fbad || fbad->IsZombie())
752 AliFatal("$ALICE_ROOT/OADB/EMCAL/EMCALBadChannels.root was not found");
756 if (fbad) delete fbad;
758 contBC->InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALBadChannels.root","AliEMCALBadChannels");
761 TObjArray *arrayBC=(TObjArray*)contBC->GetObject(runBC);
764 AliError(Form("No external hot channel set for run number: %d", runBC));
768 TObjArray *arrayBCpass=(TObjArray*)arrayBC->FindObject(fFilepass); // Here, it looks for a specific pass
771 AliError(Form("No external hot channel set for: %d -%s", runBC,fFilepass.Data()));
775 if (fDebugLevel>0) arrayBCpass->Print();
777 Int_t sms = fEMCALGeo->GetEMCGeometry()->GetNumberOfSuperModules();
778 for (Int_t i=0; i<sms; ++i)
780 TH2I *h = fEMCALRecoUtils->GetEMCALChannelStatusMap(i);
783 h=(TH2I*)arrayBCpass->FindObject(Form("EMCALBadChannelMap_Mod%d",i));
787 AliError(Form("Can not get EMCALBadChannelMap_Mod%d",i));
791 fEMCALRecoUtils->SetEMCALChannelStatusMap(i,h);
796 //_____________________________________________________
797 Int_t AliEMCALTenderSupply::InitRecalib()
799 // Initialising recalibration factors.
801 AliESDEvent *event = fTender->GetEvent();
806 AliInfo("Initialising recalibration factors");
808 // init default maps first
809 if( !fEMCALRecoUtils->GetEMCALRecalibrationFactorsArray() )
810 fEMCALRecoUtils->InitEMCALRecalibrationFactors() ;
812 Int_t runRC = event->GetRunNumber();
814 AliOADBContainer *contRF=new AliOADBContainer("");
816 { //if fBasePath specified in the ->SetBasePath()
817 if (fDebugLevel>0) AliInfo(Form("Loading Recalib OADB from given path %s",fBasePath.Data()));
819 TFile *fRecalib= new TFile(Form("%s/EMCALRecalib.root",fBasePath.Data()),"read");
820 if (!fRecalib || fRecalib->IsZombie())
822 AliFatal(Form("EMCALRecalib.root not found in %s",fBasePath.Data()));
826 if (fRecalib) delete fRecalib;
828 contRF->InitFromFile(Form("%s/EMCALRecalib.root",fBasePath.Data()),"AliEMCALRecalib");
831 { // Else choose the one in the $ALICE_ROOT directory
832 if (fDebugLevel>0) AliInfo("Loading Recalib OADB from $ALICE_ROOT/OADB/EMCAL");
834 TFile *fRecalib= new TFile("$ALICE_ROOT/OADB/EMCAL/EMCALRecalib.root","read");
835 if (!fRecalib || fRecalib->IsZombie())
837 AliFatal("$ALICE_ROOT/OADB/EMCAL/EMCALRecalib.root was not found");
841 if (fRecalib) delete fRecalib;
843 contRF->InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALRecalib.root","AliEMCALRecalib");
846 TObjArray *recal=(TObjArray*)contRF->GetObject(runRC); //GetObject(int runnumber)
849 AliError(Form("No Objects for run: %d",runRC));
853 TObjArray *recalpass=(TObjArray*)recal->FindObject(fFilepass);
856 AliError(Form("No Objects for run: %d - %s",runRC,fFilepass.Data()));
860 TObjArray *recalib=(TObjArray*)recalpass->FindObject("Recalib");
863 AliError(Form("No Recalib histos found for %d - %s",runRC,fFilepass.Data()));
867 if (fDebugLevel>0) recalib->Print();
869 Int_t sms = fEMCALGeo->GetEMCGeometry()->GetNumberOfSuperModules();
870 for (Int_t i=0; i<sms; ++i)
872 TH2F *h = fEMCALRecoUtils->GetEMCALChannelRecalibrationFactors(i);
875 h = (TH2F*)recalib->FindObject(Form("EMCALRecalFactors_SM%d",i));
878 AliError(Form("Could not load EMCALRecalFactors_SM%d",i));
882 fEMCALRecoUtils->SetEMCALChannelRecalibrationFactors(i,h);
887 //_____________________________________________________
888 Int_t AliEMCALTenderSupply::InitTimeCalibration()
890 // Initialising bad channel maps
891 AliESDEvent *event = fTender->GetEvent();
896 AliInfo("Initialising time calibration map");
898 // init default maps first
899 if( !fEMCALRecoUtils->GetEMCALTimeRecalibrationFactorsArray() )
900 fEMCALRecoUtils->InitEMCALTimeRecalibrationFactors() ;
902 Int_t runBC = event->GetRunNumber();
904 AliOADBContainer *contBC = new AliOADBContainer("");
906 { //if fBasePath specified in the ->SetBasePath()
907 if (fDebugLevel>0) AliInfo(Form("Loading time calibration OADB from given path %s",fBasePath.Data()));
909 TFile *fbad=new TFile(Form("%s/EMCALTimeCalib.root",fBasePath.Data()),"read");
910 if (!fbad || fbad->IsZombie())
912 AliFatal(Form("EMCALTimeCalib.root was not found in the path provided: %s",fBasePath.Data()));
916 if (fbad) delete fbad;
918 contBC->InitFromFile(Form("%s/EMCALTimeCalib.root",fBasePath.Data()),"AliEMCALTimeCalib");
921 { // Else choose the one in the $ALICE_ROOT directory
922 if (fDebugLevel>0) AliInfo("Loading time calibration OADB from $ALICE_ROOT/OADB/EMCAL");
924 TFile *fbad=new TFile("$ALICE_ROOT/OADB/EMCAL/EMCALTimeCalib.root","read");
925 if (!fbad || fbad->IsZombie())
927 AliFatal("$ALICE_ROOT/OADB/EMCAL/EMCALTimeCalib.root was not found");
931 if (fbad) delete fbad;
933 contBC->InitFromFile("$ALICE_ROOT/OADB/EMCAL/EMCALTimeCalib.root","AliEMCALTimeCalib");
936 TObjArray *arrayBC=(TObjArray*)contBC->GetObject(runBC);
939 AliError(Form("No external time calibration set for run number: %d", runBC));
943 TObjArray *arrayBCpass=(TObjArray*)arrayBC->FindObject(fFilepass); // Here, it looks for a specific pass
946 AliError(Form("No external time calibration set for: %d -%s", runBC,fFilepass.Data()));
950 if (fDebugLevel>0) arrayBCpass->Print();
952 for( Int_t i = 0; i < 4; i++ )
954 TH1F *h = fEMCALRecoUtils->GetEMCALChannelTimeRecalibrationFactors( i );
958 h = (TH1F*)arrayBCpass->FindObject(Form("hAllTimeAvBC%d",i));
962 AliError(Form("Can not get hAllTimeAvBC%d",i));
966 fEMCALRecoUtils->SetEMCALChannelTimeRecalibrationFactors(i,h);
971 //_____________________________________________________
972 void AliEMCALTenderSupply::UpdateCells()
974 //Remove bad cells from the cell list
975 //Recalibrate energy and time cells
976 //This is required for later reclusterization
978 AliESDCaloCells *cells = fTender->GetEvent()->GetEMCALCells();
979 Int_t bunchCrossNo = fTender->GetEvent()->GetBunchCrossNumber();
981 fEMCALRecoUtils->RecalibrateCells(cells, bunchCrossNo);
983 // remove exotic cells - loop through cells and zero the exotic ones
984 // just like with bad cell rejection in reco utils (inside RecalibrateCells)
985 if( fRejectExoticCells )
988 Bool_t isExot = kFALSE;
990 // loop through cells
991 Int_t nEMcell = cells->GetNumberOfCells() ;
992 for (Int_t iCell = 0; iCell < nEMcell; iCell++)
994 absId = cells->GetCellNumber(iCell);
996 isExot = fEMCALRecoUtils->IsExoticCell( absId, cells, bunchCrossNo );
999 cells->SetCell( iCell, absId, 0.0, 0.0 );
1001 } // reject exotic cells
1006 //_____________________________________________________
1007 void AliEMCALTenderSupply::InitRecParam()
1009 // Initalize the reconstructor parameters
1010 // Depending on the data type, different type of clusterizer
1013 AliInfo("Initialize the recParam");
1015 fRecParam = new AliEMCALRecParam;
1016 const AliESDRun *run = fTender->GetEvent()->GetESDRun();
1017 TString bt(run->GetBeamType());
1020 fRecParam->SetClusterizerFlag(AliEMCALRecParam::kClusterizerv2);
1021 fRecParam->SetClusteringThreshold(0.100);
1022 fRecParam->SetMinECut(0.050);
1026 fRecParam->SetClusterizerFlag(AliEMCALRecParam::kClusterizerv1);
1027 fRecParam->SetClusteringThreshold(0.100);
1028 fRecParam->SetMinECut(0.050);
1032 //_____________________________________________________
1033 Bool_t AliEMCALTenderSupply::InitClusterization()
1035 // Initialing clusterization/unfolding algorithm and set all the needed parameters.
1037 AliESDEvent *event = fTender->GetEvent();
1042 AliInfo(Form("Initialising reclustering parameters: Clusterizer type: %d",fRecParam->GetClusterizerFlag()));
1044 //---setup clusterizer
1045 delete fClusterizer;
1046 if (fRecParam->GetClusterizerFlag() == AliEMCALRecParam::kClusterizerv1)
1047 fClusterizer = new AliEMCALClusterizerv1 (fEMCALGeo);
1048 else if (fRecParam->GetClusterizerFlag() == AliEMCALRecParam::kClusterizerv2)
1049 fClusterizer = new AliEMCALClusterizerv2(fEMCALGeo);
1050 else if (fRecParam->GetClusterizerFlag() == AliEMCALRecParam::kClusterizerNxN)
1052 AliEMCALClusterizerNxN *clusterizer = new AliEMCALClusterizerNxN(fEMCALGeo);
1053 clusterizer->SetNRowDiff(fRecParam->GetNRowDiff());
1054 clusterizer->SetNColDiff(fRecParam->GetNColDiff());
1055 fClusterizer = clusterizer;
1059 AliFatal(Form("Clusterizer < %d > not available", fRecParam->GetClusterizerFlag()));
1063 // Set the clustering parameters
1064 fClusterizer->SetECAClusteringThreshold( fRecParam->GetClusteringThreshold() );
1065 fClusterizer->SetECALogWeight ( fRecParam->GetW0() );
1066 fClusterizer->SetMinECut ( fRecParam->GetMinECut() );
1067 fClusterizer->SetUnfolding ( fRecParam->GetUnfold() );
1068 fClusterizer->SetECALocalMaxCut ( fRecParam->GetLocMaxCut() );
1069 fClusterizer->SetTimeCut ( fRecParam->GetTimeCut() );
1070 fClusterizer->SetTimeMin ( fRecParam->GetTimeMin() );
1071 fClusterizer->SetTimeMax ( fRecParam->GetTimeMax() );
1072 fClusterizer->SetInputCalibrated ( kTRUE );
1073 fClusterizer->SetJustClusters ( kTRUE );
1075 // In case of unfolding after clusterization is requested, set the corresponding parameters
1076 if (fRecParam->GetUnfold())
1078 for (Int_t i = 0; i < 8; ++i)
1080 fClusterizer->SetSSPars(i, fRecParam->GetSSPars(i));
1082 for (Int_t i = 0; i < 3; ++i)
1084 fClusterizer->SetPar5 (i, fRecParam->GetPar5(i));
1085 fClusterizer->SetPar6 (i, fRecParam->GetPar6(i));
1087 fClusterizer->InitClusterUnfolding();
1090 fClusterizer->SetDigitsArr(fDigitsArr);
1091 fClusterizer->SetOutput(0);
1092 fClusterArr = const_cast<TObjArray *>(fClusterizer->GetRecPoints());
1096 //_____________________________________________________
1097 void AliEMCALTenderSupply::FillDigitsArray()
1099 // Fill digits from cells to a TClonesArray.
1101 AliESDEvent *event = fTender->GetEvent();
1105 fDigitsArr->Clear("C");
1106 AliESDCaloCells *cells = event->GetEMCALCells();
1107 Int_t ncells = cells->GetNumberOfCells();
1108 for (Int_t icell = 0, idigit = 0; icell < ncells; ++icell)
1110 Double_t cellAmplitude=0, cellTime=0;
1111 Short_t cellNumber=0;
1113 if (cells->GetCell(icell, cellNumber, cellAmplitude, cellTime) != kTRUE)
1116 // Do not add if already too low (some cells set to 0 if bad channels)
1117 if (cellAmplitude < fRecParam->GetMinECut() )
1120 // If requested, do not include exotic cells
1121 if (fEMCALRecoUtils->IsExoticCell(cellNumber,cells,event->GetBunchCrossNumber()))
1124 AliEMCALDigit *digit = static_cast<AliEMCALDigit*>(fDigitsArr->New(idigit));
1125 digit->SetId(cellNumber);
1126 digit->SetTime(cellTime);
1127 digit->SetTimeR(cellTime);
1128 digit->SetIndexInList(idigit);
1129 digit->SetType(AliEMCALDigit::kHG);
1130 digit->SetAmplitude(cellAmplitude);
1135 //_____________________________________________________
1136 void AliEMCALTenderSupply::Clusterize()
1140 fClusterizer->Digits2Clusters("");
1143 //_____________________________________________________
1144 void AliEMCALTenderSupply::UpdateClusters()
1146 // Update ESD cluster list.
1148 AliESDEvent *event = fTender->GetEvent();
1152 TClonesArray *clus = dynamic_cast<TClonesArray*>(event->FindListObject("caloClusters"));
1154 clus = dynamic_cast<TClonesArray*>(event->FindListObject("CaloClusters"));
1157 AliError(" Null pointer to calo clusters array, returning");
1161 Int_t nents = clus->GetEntriesFast();
1162 for (Int_t i=0; i < nents; ++i)
1164 AliESDCaloCluster *c = static_cast<AliESDCaloCluster*>(clus->At(i));
1168 delete clus->RemoveAt(i);
1173 RecPoints2Clusters(clus);
1177 //_____________________________________________________
1178 void AliEMCALTenderSupply::RecPoints2Clusters(TClonesArray *clus)
1180 // Convert AliEMCALRecoPoints to AliESDCaloClusters.
1181 // Cluster energy, global position, cells and their amplitude fractions are restored.
1183 AliESDEvent *event = fTender->GetEvent();
1187 Int_t ncls = fClusterArr->GetEntriesFast();
1188 for(Int_t i=0, nout=clus->GetEntriesFast(); i < ncls; ++i)
1190 AliEMCALRecPoint *recpoint = static_cast<AliEMCALRecPoint*>(fClusterArr->At(i));
1192 Int_t ncellsTrue = 0;
1193 const Int_t ncells = recpoint->GetMultiplicity();
1194 UShort_t absIds[ncells];
1195 Double32_t ratios[ncells];
1196 Int_t *dlist = recpoint->GetDigitsList();
1197 Float_t *elist = recpoint->GetEnergiesList();
1198 for (Int_t c = 0; c < ncells; ++c)
1200 AliEMCALDigit *digit = static_cast<AliEMCALDigit*>(fDigitsArr->At(dlist[c]));
1201 absIds[ncellsTrue] = digit->GetId();
1202 ratios[ncellsTrue] = elist[c]/digit->GetAmplitude();
1203 if (ratios[ncellsTrue] < 0.001)
1210 AliWarning("Skipping cluster with no cells");
1214 // calculate new cluster position
1216 recpoint->GetGlobalPosition(gpos);
1220 AliESDCaloCluster *c = static_cast<AliESDCaloCluster*>(clus->New(nout++));
1222 c->SetType(AliVCluster::kEMCALClusterv1);
1223 c->SetE(recpoint->GetEnergy());
1225 c->SetNCells(ncellsTrue);
1226 c->SetDispersion(recpoint->GetDispersion());
1227 c->SetEmcCpvDistance(-1); //not yet implemented
1228 c->SetChi2(-1); //not yet implemented
1229 c->SetTOF(recpoint->GetTime()) ; //time-of-flight
1230 c->SetNExMax(recpoint->GetNExMax()); //number of local maxima
1231 Float_t elipAxis[2];
1232 recpoint->GetElipsAxis(elipAxis);
1233 c->SetM02(elipAxis[0]*elipAxis[0]) ;
1234 c->SetM20(elipAxis[1]*elipAxis[1]) ;
1235 AliESDCaloCluster *cesd = static_cast<AliESDCaloCluster*>(c);
1236 cesd->SetCellsAbsId(absIds);
1237 cesd->SetCellsAmplitudeFraction(ratios);
1241 //_____________________________________________________
1242 void AliEMCALTenderSupply::GetPass()
1244 // Get passx from filename.
1246 AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
1247 fInputTree = mgr->GetTree();
1251 AliError("Pointer to tree = 0, returning");
1255 fInputFile = fInputTree->GetCurrentFile();
1257 AliError("Null pointer input file, returning");
1261 TString fname(fInputFile->GetName());
1262 if (fname.Contains("pass1")) fFilepass = TString("pass1");
1263 else if (fname.Contains("pass2")) fFilepass = TString("pass2");
1264 else if (fname.Contains("pass3")) fFilepass = TString("pass3");
1267 AliError(Form("Pass number string not found: %s", fname.Data()));