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 **************************************************************************/
16 /* $Id: AliEMCALRecoUtils.cxx 33808 2009-07-15 09:48:08Z gconesab $ */
18 ///////////////////////////////////////////////////////////////////////////////
20 // Class AliEMCALRecoUtils
21 // Some utilities to recalculate the cluster position or energy linearity
24 // Author: Gustavo Conesa (LPSC- Grenoble)
25 ///////////////////////////////////////////////////////////////////////////////
29 // standard C++ includes
30 //#include <Riostream.h>
33 #include <TGeoManager.h>
34 #include <TGeoMatrix.h>
38 #include "AliEMCALRecoUtils.h"
39 #include "AliEMCALGeometry.h"
40 #include "AliVCluster.h"
41 #include "AliVCaloCells.h"
42 #include "AliVEvent.h"
44 #include "AliEMCALPIDUtils.h"
46 #include "AliESDEvent.h"
47 #include "AliESDtrack.h"
48 #include "AliEMCALTrack.h"
49 #include "AliEMCALCalibTimeDepCorrection.h"
51 ClassImp(AliEMCALRecoUtils)
53 //______________________________________________
54 AliEMCALRecoUtils::AliEMCALRecoUtils():
55 fNonLinearityFunction (kNoCorrection), fParticleType(kPhoton),
56 fPosAlgo(kUnchanged),fW0(4.),
57 fRecalibration(kFALSE), fEMCALRecalibrationFactors(),
58 fRemoveBadChannels(kFALSE), fRecalDistToBadChannels(kFALSE), fEMCALBadChannelMap(),
59 fNCellsFromEMCALBorder(0), fNoEMCALBorderAtEta0(kTRUE),
60 fMatchedClusterIndex(0x0), fResidualZ(0x0), fResidualR(0x0), fCutR(20), fCutZ(20),
61 fCutMinNClusterTPC(0), fCutMinNClusterITS(0), fCutMaxChi2PerClusterTPC(0), fCutMaxChi2PerClusterITS(0),
62 fCutRequireTPCRefit(0), fCutRequireITSRefit(0), fCutAcceptKinkDaughters(0),
63 fCutMaxDCAToVertexXY(0), fCutMaxDCAToVertexZ(0),fCutDCAToVertex2D(0),fPIDUtils(),
64 fUseTimeCorrectionFactors(kFALSE), fTimeCorrectionFactorsSet(kFALSE)
68 // Initialize all constant values which have to be used
69 // during Reco algorithm execution
72 for(Int_t i = 0; i < 15 ; i++) {
73 fMisalTransShift[i] = 0.;
74 fMisalRotShift[i] = 0.;
76 for(Int_t i = 0; i < 6 ; i++) fNonLinearityParams[i] = 0.;
77 //For kPi0GammaGamma case, but default is no correction
78 fNonLinearityParams[0] = 0.1457/0.1349766/1.038;
79 fNonLinearityParams[1] = -0.02024/0.1349766/1.038;
80 fNonLinearityParams[2] = 1.046;
82 fMatchedClusterIndex = new TArrayI();
83 fResidualZ = new TArrayF();
84 fResidualR = new TArrayF();
86 fPIDUtils = new AliEMCALPIDUtils();
92 //______________________________________________________________________
93 AliEMCALRecoUtils::AliEMCALRecoUtils(const AliEMCALRecoUtils & reco)
94 : TNamed(reco), fNonLinearityFunction(reco.fNonLinearityFunction),
95 fParticleType(reco.fParticleType), fPosAlgo(reco.fPosAlgo), fW0(reco.fW0),
96 fRecalibration(reco.fRecalibration),fEMCALRecalibrationFactors(reco.fEMCALRecalibrationFactors),
97 fRemoveBadChannels(reco.fRemoveBadChannels),fRecalDistToBadChannels(reco.fRecalDistToBadChannels),
98 fEMCALBadChannelMap(reco.fEMCALBadChannelMap),
99 fNCellsFromEMCALBorder(reco.fNCellsFromEMCALBorder),fNoEMCALBorderAtEta0(reco.fNoEMCALBorderAtEta0),
100 fMatchedClusterIndex(reco.fMatchedClusterIndex?new TArrayI(*reco.fMatchedClusterIndex):0x0),
101 fResidualZ(reco.fResidualZ?new TArrayF(*reco.fResidualZ):0x0),
102 fResidualR(reco.fResidualR?new TArrayF(*reco.fResidualR):0x0),
103 fCutR(reco.fCutR),fCutZ(reco.fCutZ),
104 fCutMinNClusterTPC(reco.fCutMinNClusterTPC), fCutMinNClusterITS(reco.fCutMinNClusterITS),
105 fCutMaxChi2PerClusterTPC(reco.fCutMaxChi2PerClusterTPC), fCutMaxChi2PerClusterITS(reco.fCutMaxChi2PerClusterITS),
106 fCutRequireTPCRefit(reco.fCutRequireTPCRefit), fCutRequireITSRefit(reco.fCutRequireITSRefit),
107 fCutAcceptKinkDaughters(reco.fCutAcceptKinkDaughters),
108 fCutMaxDCAToVertexXY(reco.fCutMaxDCAToVertexXY), fCutMaxDCAToVertexZ(reco.fCutMaxDCAToVertexZ),fCutDCAToVertex2D(reco.fCutDCAToVertex2D),
109 fPIDUtils(reco.fPIDUtils),
110 fUseTimeCorrectionFactors(reco.fUseTimeCorrectionFactors), fTimeCorrectionFactorsSet(reco.fTimeCorrectionFactorsSet)
114 for(Int_t i = 0; i < 15 ; i++) {
115 fMisalRotShift[i] = reco.fMisalRotShift[i];
116 fMisalTransShift[i] = reco.fMisalTransShift[i];
118 for(Int_t i = 0; i < 6 ; i++) fNonLinearityParams[i] = reco.fNonLinearityParams[i];
123 //______________________________________________________________________
124 AliEMCALRecoUtils & AliEMCALRecoUtils::operator = (const AliEMCALRecoUtils & reco)
126 //Assignment operator
128 if(this == &reco)return *this;
129 ((TNamed *)this)->operator=(reco);
131 fNonLinearityFunction = reco.fNonLinearityFunction;
132 fParticleType = reco.fParticleType;
133 fPosAlgo = reco.fPosAlgo;
135 fRecalibration = reco.fRecalibration;
136 fEMCALRecalibrationFactors = reco.fEMCALRecalibrationFactors;
137 fRemoveBadChannels = reco.fRemoveBadChannels;
138 fRecalDistToBadChannels = reco.fRecalDistToBadChannels;
139 fEMCALBadChannelMap = reco.fEMCALBadChannelMap;
140 fNCellsFromEMCALBorder = reco.fNCellsFromEMCALBorder;
141 fNoEMCALBorderAtEta0 = reco.fNoEMCALBorderAtEta0;
144 for(Int_t i = 0; i < 15 ; i++) {fMisalTransShift[i] = reco.fMisalTransShift[i]; fMisalRotShift[i] = reco.fMisalRotShift[i];}
145 for(Int_t i = 0; i < 6 ; i++) fNonLinearityParams[i] = reco.fNonLinearityParams[i];
150 fCutMinNClusterTPC = reco.fCutMinNClusterTPC;
151 fCutMinNClusterITS = reco.fCutMinNClusterITS;
152 fCutMaxChi2PerClusterTPC = reco.fCutMaxChi2PerClusterTPC;
153 fCutMaxChi2PerClusterITS = reco.fCutMaxChi2PerClusterITS;
154 fCutRequireTPCRefit = reco.fCutRequireTPCRefit;
155 fCutRequireITSRefit = reco.fCutRequireITSRefit;
156 fCutAcceptKinkDaughters = reco.fCutAcceptKinkDaughters;
157 fCutMaxDCAToVertexXY = reco.fCutMaxDCAToVertexXY;
158 fCutMaxDCAToVertexZ = reco.fCutMaxDCAToVertexZ;
159 fCutDCAToVertex2D = reco.fCutDCAToVertex2D;
161 fPIDUtils = reco.fPIDUtils;
163 fUseTimeCorrectionFactors = reco.fUseTimeCorrectionFactors;
164 fTimeCorrectionFactorsSet = reco.fTimeCorrectionFactorsSet;
168 // assign or copy construct
170 *fResidualR = *reco.fResidualR;
172 else fResidualR = new TArrayF(*reco.fResidualR);
175 if(fResidualR)delete fResidualR;
180 // assign or copy construct
182 *fResidualZ = *reco.fResidualZ;
184 else fResidualZ = new TArrayF(*reco.fResidualZ);
187 if(fResidualZ)delete fResidualZ;
192 if(reco.fMatchedClusterIndex){
193 // assign or copy construct
194 if(fMatchedClusterIndex){
195 *fMatchedClusterIndex = *reco.fMatchedClusterIndex;
197 else fMatchedClusterIndex = new TArrayI(*reco.fMatchedClusterIndex);
200 if(fMatchedClusterIndex)delete fMatchedClusterIndex;
201 fMatchedClusterIndex = 0;
209 //__________________________________________________
210 AliEMCALRecoUtils::~AliEMCALRecoUtils()
214 if(fEMCALRecalibrationFactors) {
215 fEMCALRecalibrationFactors->Clear();
216 delete fEMCALRecalibrationFactors;
219 if(fEMCALBadChannelMap) {
220 fEMCALBadChannelMap->Clear();
221 delete fEMCALBadChannelMap;
224 if(fMatchedClusterIndex) {delete fMatchedClusterIndex; fMatchedClusterIndex=0;}
225 if(fResidualR) {delete fResidualR; fResidualR=0;}
226 if(fResidualZ) {delete fResidualZ; fResidualZ=0;}
230 //_______________________________________________________________
231 Bool_t AliEMCALRecoUtils::CheckCellFiducialRegion(AliEMCALGeometry* geom, AliVCluster* cluster, AliVCaloCells* cells)
233 // Given the list of AbsId of the cluster, get the maximum cell and
234 // check if there are fNCellsFromBorder from the calorimeter border
236 //If the distance to the border is 0 or negative just exit accept all clusters
237 if(cells->GetType()==AliVCaloCells::kEMCALCell && fNCellsFromEMCALBorder <= 0 ) return kTRUE;
239 Int_t absIdMax = -1, iSM =-1, ieta = -1, iphi = -1;
240 Bool_t shared = kFALSE;
241 GetMaxEnergyCell(geom, cells, cluster, absIdMax, iSM, ieta, iphi, shared);
243 AliDebug(2,Form("Cluster Max AbsId %d, Cell Energy %2.2f, Cluster Energy %2.2f, Ncells from border %d, EMCAL eta=0 %d\n",
244 absIdMax, cells->GetCellAmplitude(absIdMax), cluster->E(), fNCellsFromEMCALBorder, fNoEMCALBorderAtEta0));
246 if(absIdMax==-1) return kFALSE;
248 //Check if the cell is close to the borders:
249 Bool_t okrow = kFALSE;
250 Bool_t okcol = kFALSE;
252 if(iSM < 0 || iphi < 0 || ieta < 0 ) {
253 AliFatal(Form("Negative value for super module: %d, or cell ieta: %d, or cell iphi: %d, check EMCAL geometry name\n",
259 if(iphi >= fNCellsFromEMCALBorder && iphi < 24-fNCellsFromEMCALBorder) okrow =kTRUE;
262 if(iphi >= fNCellsFromEMCALBorder && iphi < 12-fNCellsFromEMCALBorder) okrow =kTRUE;
266 if(!fNoEMCALBorderAtEta0){
267 if(ieta > fNCellsFromEMCALBorder && ieta < 48-fNCellsFromEMCALBorder) okcol =kTRUE;
271 if(ieta >= fNCellsFromEMCALBorder) okcol = kTRUE;
274 if(ieta < 48-fNCellsFromEMCALBorder) okcol = kTRUE;
278 AliDebug(2,Form("EMCAL Cluster in %d cells fiducial volume: ieta %d, iphi %d, SM %d: column? %d, row? %d\nq",
279 fNCellsFromEMCALBorder, ieta, iphi, iSM, okcol, okrow));
281 if (okcol && okrow) {
282 //printf("Accept\n");
286 //printf("Reject\n");
287 AliDebug(2,Form("Reject cluster in border, max cell : ieta %d, iphi %d, SM %d\n",ieta, iphi, iSM));
294 //_________________________________________________________________________________________________________
295 Bool_t AliEMCALRecoUtils::ClusterContainsBadChannel(AliEMCALGeometry* geom, UShort_t* cellList, Int_t nCells){
296 // Check that in the cluster cells, there is no bad channel of those stored
297 // in fEMCALBadChannelMap or fPHOSBadChannelMap
299 if(!fRemoveBadChannels) return kFALSE;
300 if(!fEMCALBadChannelMap) return kFALSE;
305 for(Int_t iCell = 0; iCell<nCells; iCell++){
307 //Get the column and row
308 Int_t iTower = -1, iIphi = -1, iIeta = -1;
309 geom->GetCellIndex(cellList[iCell],imod,iTower,iIphi,iIeta);
310 if(fEMCALBadChannelMap->GetEntries() <= imod) continue;
311 geom->GetCellPhiEtaIndexInSModule(imod,iTower,iIphi, iIeta,irow,icol);
312 if(GetEMCALChannelStatus(imod, icol, irow)){
313 AliDebug(2,Form("Cluster with bad channel: SM %d, col %d, row %d\n",imod, icol, irow));
317 }// cell cluster loop
323 //__________________________________________________
324 Float_t AliEMCALRecoUtils::CorrectClusterEnergyLinearity(AliVCluster* cluster){
325 // Correct cluster energy from non linearity functions
326 Float_t energy = cluster->E();
328 switch (fNonLinearityFunction) {
332 //Non-Linearity correction (from MC with function ([0]*exp(-[1]/E))+(([2]/([3]*2.*TMath::Pi())*exp(-(E-[4])^2/(2.*[3]^2)))))
333 //Double_t fNonLinearityParams[0] = 1.001;
334 //Double_t fNonLinearityParams[1] = -0.01264;
335 //Double_t fNonLinearityParams[2] = -0.03632;
336 //Double_t fNonLinearityParams[3] = 0.1798;
337 //Double_t fNonLinearityParams[4] = -0.522;
338 energy /= (fNonLinearityParams[0]*exp(-fNonLinearityParams[1]/energy))+
339 ((fNonLinearityParams[2]/(fNonLinearityParams[3]*2.*TMath::Pi())*
340 exp(-(energy-fNonLinearityParams[4])*(energy-fNonLinearityParams[4])/(2.*fNonLinearityParams[3]*fNonLinearityParams[3]))));
346 //Non-Linearity correction (from Olga Data with function p0+p1*exp(-p2*E))
347 //Double_t fNonLinearityParams[0] = 1.04;
348 //Double_t fNonLinearityParams[1] = -0.1445;
349 //Double_t fNonLinearityParams[2] = 1.046;
350 energy /= (fNonLinearityParams[0]+fNonLinearityParams[1]*exp(-fNonLinearityParams[2]*energy)); //Olga function
354 case kPi0GammaConversion:
356 //Non-Linearity correction (Nicolas from Dimitri Data with function C*[1-a*exp(-b*E)])
357 //fNonLinearityParams[0] = 0.139393/0.1349766;
358 //fNonLinearityParams[1] = 0.0566186;
359 //fNonLinearityParams[2] = 0.982133;
360 energy /= fNonLinearityParams[0]*(1-fNonLinearityParams[1]*exp(-fNonLinearityParams[2]*energy));
367 //From beam test, Alexei's results, for different ZS thresholds
368 // th=30 MeV; th = 45 MeV; th = 75 MeV
369 //fNonLinearityParams[0] = 1.007; 1.003; 1.002
370 //fNonLinearityParams[1] = 0.894; 0.719; 0.797
371 //fNonLinearityParams[2] = 0.246; 0.334; 0.358
372 //Rescale the param[0] with 1.03
373 energy /= fNonLinearityParams[0]/(1+fNonLinearityParams[1]*exp(-energy/fNonLinearityParams[2]));
379 AliDebug(2,"No correction on the energy\n");
388 //__________________________________________________
389 Float_t AliEMCALRecoUtils::GetDepth(const Float_t energy, const Int_t iParticle, const Int_t iSM) const
391 //Calculate shower depth for a given cluster energy and particle type
401 depth = x0 * (TMath::Log(energy*1000/ ecr) + 0.5); //Multiply energy by 1000 to transform to MeV
405 depth = x0 * (TMath::Log(energy*1000/ ecr) - 0.5); //Multiply energy by 1000 to transform to MeV
412 gGeoManager->cd("ALIC_1/XEN1_1");
413 TGeoNode *geoXEn1 = gGeoManager->GetCurrentNode();
414 TGeoNodeMatrix *geoSM = dynamic_cast<TGeoNodeMatrix *>(geoXEn1->GetDaughter(iSM));
416 TGeoVolume *geoSMVol = geoSM->GetVolume();
417 TGeoShape *geoSMShape = geoSMVol->GetShape();
418 TGeoBBox *geoBox = dynamic_cast<TGeoBBox *>(geoSMShape);
419 if(geoBox) depth = 0.5 * geoBox->GetDX()*2 ;
420 else AliFatal("Null GEANT box");
421 }else AliFatal("NULL GEANT node matrix");
424 depth = x0 * (TMath::Log(energy*1000 / ecr) - 0.5); //Multiply energy by 1000 to transform to MeV
430 depth = x0 * (TMath::Log(energy*1000 / ecr) + 0.5); //Multiply energy by 1000 to transform to MeV
437 //__________________________________________________
438 void AliEMCALRecoUtils::GetMaxEnergyCell(AliEMCALGeometry *geom, AliVCaloCells* cells, AliVCluster* clu,
439 Int_t & absId, Int_t& iSupMod, Int_t& ieta, Int_t& iphi, Bool_t &shared)
441 //For a given CaloCluster gets the absId of the cell
442 //with maximum energy deposit.
445 Double_t eCell = -1.;
446 Float_t fraction = 1.;
447 Float_t recalFactor = 1.;
448 Int_t cellAbsId = -1 ;
454 //printf("---Max?\n");
455 for (Int_t iDig=0; iDig< clu->GetNCells(); iDig++) {
456 cellAbsId = clu->GetCellAbsId(iDig);
457 fraction = clu->GetCellAmplitudeFraction(iDig);
458 //printf("a Cell %d, id, %d, amp %f, fraction %f\n",iDig,cellAbsId,cells->GetCellAmplitude(cellAbsId),fraction);
459 if(fraction < 1e-4) fraction = 1.; // in case unfolding is off
460 geom->GetCellIndex(cellAbsId,iSupMod,iTower,iIphi,iIeta);
461 geom->GetCellPhiEtaIndexInSModule(iSupMod,iTower,iIphi, iIeta,iphi,ieta);
462 if(iDig==0) iSupMod0=iSupMod;
463 else if(iSupMod0!=iSupMod) {
465 //printf("AliEMCALRecoUtils::GetMaxEnergyCell() - SHARED CLUSTER\n");
467 if(IsRecalibrationOn()) {
468 recalFactor = GetEMCALChannelRecalibrationFactor(iSupMod,ieta,iphi);
470 eCell = cells->GetCellAmplitude(cellAbsId)*fraction*recalFactor;
471 //printf("b Cell %d, id, %d, amp %f, fraction %f\n",iDig,cellAbsId,eCell,fraction);
475 //printf("\t new max: cell %d, e %f, ecell %f\n",maxId, eMax,eCell);
479 //Get from the absid the supermodule, tower and eta/phi numbers
480 geom->GetCellIndex(absId,iSupMod,iTower,iIphi,iIeta);
481 //Gives SuperModule and Tower numbers
482 geom->GetCellPhiEtaIndexInSModule(iSupMod,iTower,
483 iIphi, iIeta,iphi,ieta);
484 //printf("Max id %d, iSM %d, col %d, row %d\n",absId,iSupMod,ieta,iphi);
485 //printf("Max end---\n");
489 //________________________________________________________________
490 void AliEMCALRecoUtils::InitEMCALRecalibrationFactors(){
491 //Init EMCAL recalibration factors
492 AliDebug(2,"AliCalorimeterUtils::InitEMCALRecalibrationFactors()");
493 //In order to avoid rewriting the same histograms
494 Bool_t oldStatus = TH1::AddDirectoryStatus();
495 TH1::AddDirectory(kFALSE);
497 fEMCALRecalibrationFactors = new TObjArray(10);
498 for (int i = 0; i < 12; i++) fEMCALRecalibrationFactors->Add(new TH2F(Form("EMCALRecalFactors_SM%d",i),Form("EMCALRecalFactors_SM%d",i), 48, 0, 48, 24, 0, 24));
499 //Init the histograms with 1
500 for (Int_t sm = 0; sm < 12; sm++) {
501 for (Int_t i = 0; i < 48; i++) {
502 for (Int_t j = 0; j < 24; j++) {
503 SetEMCALChannelRecalibrationFactor(sm,i,j,1.);
507 fEMCALRecalibrationFactors->SetOwner(kTRUE);
508 fEMCALRecalibrationFactors->Compress();
510 //In order to avoid rewriting the same histograms
511 TH1::AddDirectory(oldStatus);
515 //________________________________________________________________
516 void AliEMCALRecoUtils::InitEMCALBadChannelStatusMap(){
517 //Init EMCAL bad channels map
518 AliDebug(2,"AliEMCALRecoUtils::InitEMCALBadChannelStatusMap()");
519 //In order to avoid rewriting the same histograms
520 Bool_t oldStatus = TH1::AddDirectoryStatus();
521 TH1::AddDirectory(kFALSE);
523 fEMCALBadChannelMap = new TObjArray(10);
524 //TH2F * hTemp = new TH2I("EMCALBadChannelMap","EMCAL SuperModule bad channel map", 48, 0, 48, 24, 0, 24);
525 for (int i = 0; i < 10; i++) {
526 fEMCALBadChannelMap->Add(new TH2I(Form("EMCALBadChannelMap_Mod%d",i),Form("EMCALBadChannelMap_Mod%d",i), 48, 0, 48, 24, 0, 24));
531 fEMCALBadChannelMap->SetOwner(kTRUE);
532 fEMCALBadChannelMap->Compress();
534 //In order to avoid rewriting the same histograms
535 TH1::AddDirectory(oldStatus);
538 //________________________________________________________________
539 void AliEMCALRecoUtils::RecalibrateClusterEnergy(AliEMCALGeometry* geom, AliVCluster * cluster, AliVCaloCells * cells){
540 // Recalibrate the cluster energy, considering the recalibration map and the energy of the cells that compose the cluster.
542 //Get the cluster number of cells and list of absId, check what kind of cluster do we have.
543 UShort_t * index = cluster->GetCellsAbsId() ;
544 Double_t * fraction = cluster->GetCellsAmplitudeFraction() ;
545 Int_t ncells = cluster->GetNCells();
547 //Initialize some used variables
550 Int_t icol = -1, irow = -1, imod=1;
551 Float_t factor = 1, frac = 0;
553 //Loop on the cells, get the cell amplitude and recalibration factor, multiply and and to the new energy
554 for(Int_t icell = 0; icell < ncells; icell++){
555 absId = index[icell];
556 frac = fraction[icell];
557 if(frac < 1e-5) frac = 1; //in case of EMCAL, this is set as 0 since unfolding is off
558 Int_t iTower = -1, iIphi = -1, iIeta = -1;
559 geom->GetCellIndex(absId,imod,iTower,iIphi,iIeta);
560 if(fEMCALRecalibrationFactors->GetEntries() <= imod) continue;
561 geom->GetCellPhiEtaIndexInSModule(imod,iTower,iIphi, iIeta,irow,icol);
562 factor = GetEMCALChannelRecalibrationFactor(imod,icol,irow);
563 AliDebug(2,Form("AliEMCALRecoUtils::RecalibrateClusterEnergy - recalibrate cell: module %d, col %d, row %d, cell fraction %f,recalibration factor %f, cell energy %f\n",
564 imod,icol,irow,frac,factor,cells->GetCellAmplitude(absId)));
566 energy += cells->GetCellAmplitude(absId)*factor*frac;
570 AliDebug(2,Form("AliEMCALRecoUtils::RecalibrateClusterEnergy - Energy before %f, after %f\n",cluster->E(),energy));
572 cluster->SetE(energy);
577 //__________________________________________________
578 void AliEMCALRecoUtils::RecalculateClusterPosition(AliEMCALGeometry *geom, AliVCaloCells* cells, AliVCluster* clu)
580 //For a given CaloCluster recalculates the position for a given set of misalignment shifts and puts it again in the CaloCluster.
582 if (fPosAlgo==kPosTowerGlobal) RecalculateClusterPositionFromTowerGlobal( geom, cells, clu);
583 else if(fPosAlgo==kPosTowerIndex) RecalculateClusterPositionFromTowerIndex ( geom, cells, clu);
584 else AliDebug(2,"Algorithm to recalculate position not selected, do nothing.");
588 //__________________________________________________
589 void AliEMCALRecoUtils::RecalculateClusterPositionFromTowerGlobal(AliEMCALGeometry *geom, AliVCaloCells* cells, AliVCluster* clu)
591 // For a given CaloCluster recalculates the position for a given set of misalignment shifts and puts it again in the CaloCluster.
592 // The algorithm is a copy of what is done in AliEMCALRecPoint
595 Float_t fraction = 1.;
596 Float_t recalFactor = 1.;
599 Int_t iTower = -1, iIphi = -1, iIeta = -1;
600 Int_t iSupModMax = -1, iSM=-1, iphi = -1, ieta = -1;
601 Float_t weight = 0., totalWeight=0.;
602 Float_t newPos[3] = {0,0,0};
603 Double_t pLocal[3], pGlobal[3];
604 Bool_t shared = kFALSE;
606 Float_t clEnergy = clu->E(); //Energy already recalibrated previously
607 GetMaxEnergyCell(geom, cells, clu, absId, iSupModMax, ieta, iphi,shared);
608 Double_t depth = GetDepth(clEnergy,fParticleType,iSupModMax) ;
610 //printf("** Cluster energy %f, ncells %d, depth %f\n",clEnergy,clu->GetNCells(),depth);
612 for (Int_t iDig=0; iDig< clu->GetNCells(); iDig++) {
613 absId = clu->GetCellAbsId(iDig);
614 fraction = clu->GetCellAmplitudeFraction(iDig);
615 if(fraction < 1e-4) fraction = 1.; // in case unfolding is off
616 geom->GetCellIndex(absId,iSM,iTower,iIphi,iIeta);
617 geom->GetCellPhiEtaIndexInSModule(iSM,iTower,iIphi, iIeta,iphi,ieta);
619 if(IsRecalibrationOn()) {
620 recalFactor = GetEMCALChannelRecalibrationFactor(iSM,ieta,iphi);
622 eCell = cells->GetCellAmplitude(absId)*fraction*recalFactor;
624 weight = GetCellWeight(eCell,clEnergy);
625 //printf("cell energy %f, weight %f\n",eCell,weight);
626 totalWeight += weight;
627 geom->RelPosCellInSModule(absId,depth,pLocal[0],pLocal[1],pLocal[2]);
628 //printf("pLocal (%f,%f,%f), SM %d, absId %d\n",pLocal[0],pLocal[1],pLocal[2],iSupModMax,absId);
629 geom->GetGlobal(pLocal,pGlobal,iSupModMax);
630 //printf("pLocal (%f,%f,%f)\n",pGlobal[0],pGlobal[1],pGlobal[2]);
632 for(int i=0; i<3; i++ ) newPos[i] += (weight*pGlobal[i]);
637 for(int i=0; i<3; i++ ) newPos[i] /= totalWeight;
640 //Float_t pos[]={0,0,0};
641 //clu->GetPosition(pos);
642 //printf("OldPos : %2.3f,%2.3f,%2.3f\n",pos[0],pos[1],pos[2]);
643 //printf("NewPos : %2.3f,%2.3f,%2.3f\n",newPos[0],newPos[1],newPos[2]);
645 if(iSupModMax > 1) {//sector 1
646 newPos[0] +=fMisalTransShift[3];//-=3.093;
647 newPos[1] +=fMisalTransShift[4];//+=6.82;
648 newPos[2] +=fMisalTransShift[5];//+=1.635;
649 //printf(" + : %2.3f,%2.3f,%2.3f\n",fMisalTransShift[3],fMisalTransShift[4],fMisalTransShift[5]);
653 newPos[0] +=fMisalTransShift[0];//+=1.134;
654 newPos[1] +=fMisalTransShift[1];//+=8.2;
655 newPos[2] +=fMisalTransShift[2];//+=1.197;
656 //printf(" + : %2.3f,%2.3f,%2.3f\n",fMisalTransShift[0],fMisalTransShift[1],fMisalTransShift[2]);
659 //printf("NewPos : %2.3f,%2.3f,%2.3f\n",newPos[0],newPos[1],newPos[2]);
661 clu->SetPosition(newPos);
665 //__________________________________________________
666 void AliEMCALRecoUtils::RecalculateClusterPositionFromTowerIndex(AliEMCALGeometry *geom, AliVCaloCells* cells, AliVCluster* clu)
668 // For a given CaloCluster recalculates the position for a given set of misalignment shifts and puts it again in the CaloCluster.
669 // The algorithm works with the tower indeces, averages the indeces and from them it calculates the global position
672 Float_t fraction = 1.;
673 Float_t recalFactor = 1.;
677 Int_t iIphi = -1, iIeta = -1;
678 Int_t iSupMod = -1, iSupModMax = -1;
679 Int_t iphi = -1, ieta =-1;
680 Bool_t shared = kFALSE;
682 Float_t clEnergy = clu->E(); //Energy already recalibrated previously.
683 GetMaxEnergyCell(geom, cells, clu, absId, iSupModMax, ieta, iphi,shared);
684 Float_t depth = GetDepth(clEnergy,fParticleType,iSupMod) ;
686 Float_t weight = 0., weightedCol = 0., weightedRow = 0., totalWeight=0.;
687 Bool_t areInSameSM = kTRUE; //exclude clusters with cells in different SMs for now
688 Int_t startingSM = -1;
690 for (Int_t iDig=0; iDig< clu->GetNCells(); iDig++) {
691 absId = clu->GetCellAbsId(iDig);
692 fraction = clu->GetCellAmplitudeFraction(iDig);
693 if(fraction < 1e-4) fraction = 1.; // in case unfolding is off
694 geom->GetCellIndex(absId,iSupMod,iTower,iIphi,iIeta);
695 geom->GetCellPhiEtaIndexInSModule(iSupMod,iTower,iIphi, iIeta,iphi,ieta);
697 if (iDig==0) startingSM = iSupMod;
698 else if(iSupMod != startingSM) areInSameSM = kFALSE;
700 eCell = cells->GetCellAmplitude(absId);
702 if(IsRecalibrationOn()) {
703 recalFactor = GetEMCALChannelRecalibrationFactor(iSupMod,ieta,iphi);
705 eCell = cells->GetCellAmplitude(absId)*fraction*recalFactor;
707 weight = GetCellWeight(eCell,clEnergy);
708 if(weight < 0) weight = 0;
709 totalWeight += weight;
710 weightedCol += ieta*weight;
711 weightedRow += iphi*weight;
713 //printf("Max cell? cell %d, amplitude org %f, fraction %f, recalibration %f, amplitude new %f \n",cellAbsId, cells->GetCellAmplitude(cellAbsId), fraction, recalFactor, eCell) ;
717 Float_t xyzNew[]={0.,0.,0.};
718 if(areInSameSM == kTRUE) {
719 //printf("In Same SM\n");
720 weightedCol = weightedCol/totalWeight;
721 weightedRow = weightedRow/totalWeight;
722 geom->RecalculateTowerPosition(weightedRow, weightedCol, iSupModMax, depth, fMisalTransShift, fMisalRotShift, xyzNew);
725 //printf("In Different SM\n");
726 geom->RecalculateTowerPosition(iphi, ieta, iSupModMax, depth, fMisalTransShift, fMisalRotShift, xyzNew);
729 clu->SetPosition(xyzNew);
733 //____________________________________________________________________________
734 void AliEMCALRecoUtils::RecalculateClusterDistanceToBadChannel(AliEMCALGeometry * geom, AliVCaloCells* cells, AliVCluster * cluster){
736 //re-evaluate distance to bad channel with updated bad map
738 if(!fRecalDistToBadChannels) return;
740 //Get channels map of the supermodule where the cluster is.
741 Int_t absIdMax = -1, iSupMod =-1, icolM = -1, irowM = -1;
742 Bool_t shared = kFALSE;
743 GetMaxEnergyCell(geom, cells, cluster, absIdMax, iSupMod, icolM, irowM, shared);
744 TH2D* hMap = (TH2D*)fEMCALBadChannelMap->At(iSupMod);
747 Float_t minDist = 10000.;
750 //Loop on tower status map
751 for(Int_t irow = 0; irow < AliEMCALGeoParams::fgkEMCALRows; irow++){
752 for(Int_t icol = 0; icol < AliEMCALGeoParams::fgkEMCALCols; icol++){
753 //Check if tower is bad.
754 if(hMap->GetBinContent(icol,irow)==0) continue;
755 //printf("AliEMCALRecoUtils::RecalculateDistanceToBadChannels() - \n \t Bad channel in SM %d, col %d, row %d, \n \t Cluster max in col %d, row %d\n",
756 // iSupMod,icol, irow, icolM,irowM);
758 dRrow=TMath::Abs(irowM-irow);
759 dRcol=TMath::Abs(icolM-icol);
760 dist=TMath::Sqrt(dRrow*dRrow+dRcol*dRcol);
762 //printf("MIN DISTANCE TO BAD %2.2f\n",dist);
769 //In case the cluster is shared by 2 SuperModules, need to check the map of the second Super Module
774 //The only possible combinations are (0,1), (2,3) ... (8,9)
775 if(iSupMod%2) iSupMod2 = iSupMod-1;
776 else iSupMod2 = iSupMod+1;
777 hMap2 = (TH2D*)fEMCALBadChannelMap->At(iSupMod2);
779 //Loop on tower status map of second super module
780 for(Int_t irow = 0; irow < AliEMCALGeoParams::fgkEMCALRows; irow++){
781 for(Int_t icol = 0; icol < AliEMCALGeoParams::fgkEMCALCols; icol++){
782 //Check if tower is bad.
783 if(hMap2->GetBinContent(icol,irow)==0) continue;
784 //printf("AliEMCALRecoUtils::RecalculateDistanceToBadChannels(shared) - \n \t Bad channel in SM %d, col %d, row %d \n \t Cluster max in SM %d, col %d, row %d\n",
785 // iSupMod2,icol, irow,iSupMod,icolM,irowM);
787 dRrow=TMath::Abs(irow-irowM);
790 dRcol=TMath::Abs(icol-(AliEMCALGeoParams::fgkEMCALCols+icolM));
793 dRcol=TMath::Abs(AliEMCALGeoParams::fgkEMCALCols+icol-icolM);
796 dist=TMath::Sqrt(dRrow*dRrow+dRcol*dRcol);
797 if(dist < minDist) minDist = dist;
802 }// shared cluster in 2 SuperModules
804 AliDebug(2,Form("Max cluster cell (SM,col,row)=(%d %d %d) - Distance to Bad Channel %2.2f",iSupMod, icolM, irowM, minDist));
805 cluster->SetDistanceToBadChannel(minDist);
809 //____________________________________________________________________________
810 void AliEMCALRecoUtils::RecalculateClusterPID(AliVCluster * cluster){
812 //re-evaluate identification parameters with bayesian
814 if ( cluster->GetM02() != 0)
815 fPIDUtils->ComputePID(cluster->E(),cluster->GetM02());
817 Float_t pidlist[AliPID::kSPECIESN+1];
818 for(Int_t i = 0; i < AliPID::kSPECIESN+1; i++) pidlist[i] = fPIDUtils->GetPIDFinal(i);
820 cluster->SetPID(pidlist);
824 //____________________________________________________________________________
825 void AliEMCALRecoUtils::RecalculateClusterShowerShapeParameters(AliEMCALGeometry * geom, AliVCaloCells* cells, AliVCluster * cluster)
827 // Calculates new center of gravity in the local EMCAL-module coordinates
828 // and tranfers into global ALICE coordinates
829 // Calculates Dispersion and main axis
834 Float_t fraction = 1.;
835 Float_t recalFactor = 1.;
855 for(Int_t iDigit=0; iDigit < cluster->GetNCells(); iDigit++) {
857 //Get from the absid the supermodule, tower and eta/phi numbers
858 geom->GetCellIndex(cluster->GetCellAbsId(iDigit),iSupMod,iTower,iIphi,iIeta);
859 geom->GetCellPhiEtaIndexInSModule(iSupMod,iTower,iIphi,iIeta, iphi,ieta);
861 //Get the cell energy, if recalibration is on, apply factors
862 fraction = cluster->GetCellAmplitudeFraction(iDigit);
863 if(fraction < 1e-4) fraction = 1.; // in case unfolding is off
864 if(IsRecalibrationOn()) {
865 recalFactor = GetEMCALChannelRecalibrationFactor(iSupMod,ieta,iphi);
867 eCell = cells->GetCellAmplitude(cluster->GetCellAbsId(iDigit))*fraction*recalFactor;
869 if(cluster->E() > 0 && eCell > 0){
871 w = GetCellWeight(eCell,cluster->E());
879 dxx += w * etai * etai ;
881 dzz += w * phii * phii ;
883 dxz += w * etai * phii ;
887 AliError(Form("Wrong energy %f and/or amplitude %f\n", eCell, cluster->E()));
890 //Normalize to the weight
896 AliError(Form("Wrong weight %f\n", wtot));
898 //Calculate dispersion
899 for(Int_t iDigit=0; iDigit < cluster->GetNCells(); iDigit++) {
901 //Get from the absid the supermodule, tower and eta/phi numbers
902 geom->GetCellIndex(cluster->GetCellAbsId(iDigit),iSupMod,iTower,iIphi,iIeta);
903 geom->GetCellPhiEtaIndexInSModule(iSupMod,iTower,iIphi,iIeta, iphi,ieta);
905 //Get the cell energy, if recalibration is on, apply factors
906 fraction = cluster->GetCellAmplitudeFraction(iDigit);
907 if(fraction < 1e-4) fraction = 1.; // in case unfolding is off
908 if(IsRecalibrationOn()) {
909 recalFactor = GetEMCALChannelRecalibrationFactor(iSupMod,ieta,iphi);
911 eCell = cells->GetCellAmplitude(cluster->GetCellAbsId(iDigit))*fraction*recalFactor;
913 if(cluster->E() > 0 && eCell > 0){
915 w = GetCellWeight(eCell,cluster->E());
919 if(w > 0.0) d += w*((etai-xmean)*(etai-xmean)+(phii-zmean)*(phii-zmean));
922 AliError(Form("Wrong energy %f and/or amplitude %f\n", eCell, cluster->E()));
925 //Normalize to the weigth and set shower shape parameters
926 if (wtot > 0 && nstat > 1) {
931 dxx -= xmean * xmean ;
932 dzz -= zmean * zmean ;
933 dxz -= xmean * zmean ;
934 cluster->SetM02(0.5 * (dxx + dzz) + TMath::Sqrt( 0.25 * (dxx - dzz) * (dxx - dzz) + dxz * dxz ));
935 cluster->SetM20(0.5 * (dxx + dzz) - TMath::Sqrt( 0.25 * (dxx - dzz) * (dxx - dzz) + dxz * dxz ));
939 cluster->SetM20(0.) ;
940 cluster->SetM02(0.) ;
944 cluster->SetDispersion(TMath::Sqrt(d)) ;
946 cluster->SetDispersion(0) ;
950 //__________________________________________________
951 void AliEMCALRecoUtils::FindMatches(AliVEvent *event)
953 //This function should be called before the cluster loop
954 //Before call this function, please recalculate the cluster positions
955 //Given the input event, loop over all the tracks, select the closest cluster as matched with fCutR
956 //Store matched cluster indexes and residuals
957 //It only works with ESDs, not AODs
959 fMatchedClusterIndex->Reset();
963 fMatchedClusterIndex->Set(100);
964 fResidualZ->Set(100);
965 fResidualR->Set(100);
970 for(Int_t itr=0; itr<event->GetNumberOfTracks(); itr++)
972 AliESDtrack *track = ((AliESDEvent*)event)->GetTrack(itr);
973 if(!track || !IsAccepted(track)) continue;
975 Float_t dRMax = fCutR, dZMax = fCutZ;
977 AliEMCALTrack *emctrack = new AliEMCALTrack(*track);
978 for(Int_t icl=0; icl<event->GetNumberOfCaloClusters(); icl++)
980 AliVCluster *cluster = (AliVCluster*) event->GetCaloCluster(icl);
981 if(!cluster->IsEMCAL()) continue;
982 cluster->GetPosition(clsPos); //Has been recalculated
983 if(!emctrack->PropagateToGlobal(clsPos[0],clsPos[1],clsPos[2],0.,0.) ) continue;
984 emctrack->GetXYZ(trkPos);
985 Float_t tmpR = TMath::Sqrt( TMath::Power(clsPos[0]-trkPos[0],2)+TMath::Power(clsPos[1]-trkPos[1],2)+TMath::Power(clsPos[2]-trkPos[2],2) );
986 Float_t tmpZ = TMath::Abs(clsPos[2]-trkPos[2]);
999 fMatchedClusterIndex->AddAt(index,matched);
1000 fResidualZ->AddAt(dZMax,matched);
1001 fResidualR->AddAt(dRMax,matched);
1006 fMatchedClusterIndex->Set(matched);
1007 fResidualZ->Set(matched);
1008 fResidualR->Set(matched);
1010 //printf("Number of matched pairs: %d\n",matched);
1013 //__________________________________________________
1014 void AliEMCALRecoUtils::GetMatchedResiduals(Int_t index, Float_t &dR, Float_t &dZ)
1016 //Given a cluster index as in AliESDEvent::GetCaloCluster(index)
1017 //Get the residuals dR and dZ for this cluster
1018 //It only works with ESDs, not AODs
1020 if( FindMatchedPos(index) >= 999 )
1022 AliDebug(2,"No matched tracks found!\n");
1027 dR = fResidualR->At(FindMatchedPos(index));
1028 dZ = fResidualZ->At(FindMatchedPos(index));
1029 //printf("dR %f, dZ %f\n",dR, dZ);
1032 //__________________________________________________
1033 Bool_t AliEMCALRecoUtils::IsMatched(Int_t index)
1035 //Given a cluster index as in AliESDEvent::GetCaloCluster(index)
1036 //Returns if cluster has a match
1037 if(FindMatchedPos(index) < 999)
1042 //__________________________________________________
1043 UInt_t AliEMCALRecoUtils::FindMatchedPos(Int_t index) const
1045 //Given a cluster index as in AliESDEvent::GetCaloCluster(index)
1046 //Returns the position of the match in the fMatchedClusterIndex array
1047 Float_t tmpR = fCutR;
1050 for(Int_t i=0; i<fMatchedClusterIndex->GetSize(); i++)
1052 if(fMatchedClusterIndex->At(i)==index && fResidualR->At(i)<tmpR)
1055 tmpR=fResidualR->At(i);
1057 AliDebug(3,Form("Matched cluster pos: %d, index: %d, dR: %2.4f, dZ: %2.4f.\n",i,fMatchedClusterIndex->At(i),fResidualR->At(i),fResidualZ->At(i)));
1062 Bool_t AliEMCALRecoUtils::IsAccepted(AliESDtrack *esdTrack)
1064 // Given a esd track, return whether the track survive all the cuts
1066 // The different quality parameter are first
1067 // retrieved from the track. then it is found out what cuts the
1068 // track did not survive and finally the cuts are imposed.
1070 UInt_t status = esdTrack->GetStatus();
1072 Int_t nClustersITS = esdTrack->GetITSclusters(0);
1073 Int_t nClustersTPC = esdTrack->GetTPCclusters(0);
1075 Float_t chi2PerClusterITS = -1;
1076 Float_t chi2PerClusterTPC = -1;
1077 if (nClustersITS!=0)
1078 chi2PerClusterITS = esdTrack->GetITSchi2()/Float_t(nClustersITS);
1079 if (nClustersTPC!=0)
1080 chi2PerClusterTPC = esdTrack->GetTPCchi2()/Float_t(nClustersTPC);
1084 Float_t MaxDCAToVertexXYPtDep = 0.0182 + 0.0350/TMath::Power(esdTrack->Pt(),1.01); //This expression comes from AliESDtrackCuts::GetStandardITSTPCTrackCuts2010()
1085 //AliDebug(3,Form("Track pT = %f, DCAtoVertexXY = %f",esdTrack->Pt(),MaxDCAToVertexXYPtDep));
1086 SetMaxDCAToVertexXY(MaxDCAToVertexXYPtDep); //Set pT dependent DCA cut to vertex in x-y plane
1091 esdTrack->GetImpactParameters(b,bCov);
1092 if (bCov[0]<=0 || bCov[2]<=0) {
1093 AliDebug(1, "Estimated b resolution lower or equal zero!");
1094 bCov[0]=0; bCov[2]=0;
1097 Float_t dcaToVertexXY = b[0];
1098 Float_t dcaToVertexZ = b[1];
1099 Float_t dcaToVertex = -1;
1101 if (fCutDCAToVertex2D)
1102 dcaToVertex = TMath::Sqrt(dcaToVertexXY*dcaToVertexXY/fCutMaxDCAToVertexXY/fCutMaxDCAToVertexXY + dcaToVertexZ*dcaToVertexZ/fCutMaxDCAToVertexZ/fCutMaxDCAToVertexZ);
1104 dcaToVertex = TMath::Sqrt(dcaToVertexXY*dcaToVertexXY + dcaToVertexZ*dcaToVertexZ);
1108 Bool_t cuts[kNCuts];
1109 for (Int_t i=0; i<kNCuts; i++) cuts[i]=kFALSE;
1111 // track quality cuts
1112 if (fCutRequireTPCRefit && (status&AliESDtrack::kTPCrefit)==0)
1114 if (fCutRequireITSRefit && (status&AliESDtrack::kITSrefit)==0)
1116 if (nClustersTPC<fCutMinNClusterTPC)
1118 if (nClustersITS<fCutMinNClusterITS)
1120 if (chi2PerClusterTPC>fCutMaxChi2PerClusterTPC)
1122 if (chi2PerClusterITS>fCutMaxChi2PerClusterITS)
1124 if (!fCutAcceptKinkDaughters && esdTrack->GetKinkIndex(0)>0)
1126 if (fCutDCAToVertex2D && dcaToVertex > 1)
1128 if (!fCutDCAToVertex2D && TMath::Abs(dcaToVertexXY) > fCutMaxDCAToVertexXY)
1130 if (!fCutDCAToVertex2D && TMath::Abs(dcaToVertexZ) > fCutMaxDCAToVertexZ)
1133 //Require at least one SPD point + anything else in ITS
1134 if( (esdTrack->HasPointOnITSLayer(0) || esdTrack->HasPointOnITSLayer(1)) == kFALSE)
1138 for (Int_t i=0; i<kNCuts; i++)
1139 if (cuts[i]) {cut = kTRUE;}
1147 //__________________________________________________
1148 void AliEMCALRecoUtils::InitTrackCuts()
1150 //Intilize the track cut criteria
1151 //By default these cuts are set according to AliESDtrackCuts::GetStandardITSTPCTrackCuts2010()
1152 //Also you can customize the cuts using the setters
1155 SetMinNClustersTPC(70);
1156 SetMaxChi2PerClusterTPC(4);
1157 SetAcceptKinkDaughters(kFALSE);
1158 SetRequireTPCRefit(kTRUE);
1161 SetRequireITSRefit(kTRUE);
1162 SetMaxDCAToVertexZ(2);
1163 SetDCAToVertex2D(kFALSE);
1164 SetMaxChi2PerClusterITS(); //which by default sets the value to 1e10.
1165 SetMinNClustersITS();
1168 //__________________________________________________
1169 void AliEMCALRecoUtils::Print(const Option_t *) const
1173 printf("AliEMCALRecoUtils Settings: \n");
1174 printf("Misalignment shifts\n");
1175 for(Int_t i=0; i<5; i++) printf("\t sector %d, traslation (x,y,z)=(%f,%f,%f), rotation (x,y,z)=(%f,%f,%f)\n",i,
1176 fMisalTransShift[i*3],fMisalTransShift[i*3+1],fMisalTransShift[i*3+2],
1177 fMisalRotShift[i*3], fMisalRotShift[i*3+1], fMisalRotShift[i*3+2] );
1178 printf("Non linearity function %d, parameters:\n", fNonLinearityFunction);
1179 for(Int_t i=0; i<6; i++) printf("param[%d]=%f\n",i, fNonLinearityParams[i]);
1181 printf("Position Recalculation option %d, Particle Type %d, fW0 %2.2f, Recalibrate Data %d \n",fPosAlgo,fParticleType,fW0, fRecalibration);
1183 printf("Matching criteria: dR < %2.2f[cm], dZ < %2.2f[cm]\n",fCutR,fCutZ);
1185 printf("Track cuts: \n");
1186 printf("TPCRefit = %d, ITSRefit = %d\n",fCutRequireTPCRefit,fCutRequireITSRefit);
1187 printf("AcceptKinks = %d\n",fCutAcceptKinkDaughters);
1188 printf("MinNCulsterTPC = %d, MinNClusterITS = %d\n",fCutMinNClusterTPC,fCutMinNClusterITS);
1189 printf("MaxChi2TPC = %2.2f, MaxChi2ITS = %2.2f\n",fCutMaxChi2PerClusterTPC,fCutMaxChi2PerClusterITS);
1190 printf("DCSToVertex2D = %d, MaxDCAToVertexXY = %2.2f, MaxDCAToVertexZ = %2.2f\n",fCutDCAToVertex2D,fCutMaxDCAToVertexXY,fCutMaxDCAToVertexZ);
1195 //__________________________________________________
1196 void AliEMCALRecoUtils::SetTimeDependentCorrections(Int_t runnumber){
1197 //Get EMCAL time dependent corrections from file and put them in the recalibration histograms
1198 //Do it only once and only if it is requested
1200 if(!fUseTimeCorrectionFactors) return;
1201 if(fTimeCorrectionFactorsSet) return;
1203 printf("AliEMCALRecoUtils::GetTimeDependentCorrections() - Get Correction Factors for Run number %d\n",runnumber);
1205 AliEMCALCalibTimeDepCorrection *corr = new AliEMCALCalibTimeDepCorrection();
1206 corr->ReadRootInfo(Form("CorrectionFiles/Run%d_Correction.root",runnumber));
1208 SwitchOnRecalibration();
1209 for(Int_t ism = 0; ism < 4; ism++){
1210 for(Int_t icol = 0; icol < 48; icol++){
1211 for(Int_t irow = 0; irow < 24; irow++){
1212 Float_t orgRecalFactor = GetEMCALChannelRecalibrationFactors(ism)->GetBinContent(icol,irow);
1213 Float_t newRecalFactor = orgRecalFactor*corr->GetCorrection(ism, icol,irow,0);
1214 GetEMCALChannelRecalibrationFactors(ism)->SetBinContent(icol,irow,newRecalFactor);
1215 //printf("ism %d, icol %d, irow %d, corrections : org %f, time dep %f, final %f (org*time %f)\n",ism, icol, irow,
1216 // orgRecalFactor, corr->GetCorrection(ism, icol,irow,0),
1217 // (GetEMCALChannelRecalibrationFactors(ism))->GetBinContent(icol,irow),newRecalFactor);
1221 fTimeCorrectionFactorsSet = kTRUE;