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 //_________________________________________________________________________
17 // Class utility for Calorimeter specific selection methods ///
21 //-- Author: Gustavo Conesa (LPSC-Grenoble)
22 //////////////////////////////////////////////////////////////////////////////
25 // --- ROOT system ---
26 #include <TGeoManager.h>
32 #include <TParticle.h>
34 // --- ANALYSIS system ---
35 #include "AliCalorimeterUtils.h"
36 #include "AliESDEvent.h"
37 #include "AliMCEvent.h"
39 #include "AliAODPWG4Particle.h"
40 #include "AliVCluster.h"
41 #include "AliVCaloCells.h"
42 #include "AliAODCaloCluster.h"
43 #include "AliOADBContainer.h"
44 #include "AliAnalysisManager.h"
45 #include "AliAODMCParticle.h"
49 #include "AliEMCALGeometry.h"
50 #include "AliPHOSGeoUtils.h"
52 ClassImp(AliCalorimeterUtils)
55 //____________________________________________
56 AliCalorimeterUtils::AliCalorimeterUtils() :
60 fEMCALGeo(0x0), fPHOSGeo(0x0),
61 fEMCALGeoMatrixSet(kFALSE), fPHOSGeoMatrixSet(kFALSE),
62 fLoadEMCALMatrices(kFALSE), fLoadPHOSMatrices(kFALSE),
63 fRemoveBadChannels(kFALSE), fPHOSBadChannelMap(0x0),
64 fNCellsFromPHOSBorder(0),
65 fNMaskCellColumns(0), fMaskCellColumns(0x0),
66 fRecalibration(kFALSE), fRunDependentCorrection(kFALSE),
67 fPHOSRecalibrationFactors(), fEMCALRecoUtils(new AliEMCALRecoUtils),
68 fRecalculatePosition(kFALSE), fCorrectELinearity(kFALSE),
69 fRecalculateMatching(kFALSE),
71 fCutEta(20), fCutPhi(20),
72 fLocMaxCutE(0), fLocMaxCutEDiff(0),
73 fPlotCluster(0), fOADBSet(kFALSE),
74 fOADBForEMCAL(kFALSE), fOADBForPHOS(kFALSE),
75 fOADBFilePathEMCAL(""), fOADBFilePathPHOS(""),
76 fImportGeometryFromFile(0), fImportGeometryFilePath(""),
77 fNSuperModulesUsed(0),
78 fMCECellClusFracCorrOn(0), fMCECellClusFracCorrParam()
82 //Initialize parameters
84 for(Int_t i = 0; i < 12; i++) fEMCALMatrix[i] = 0 ;
85 for(Int_t i = 0; i < 5 ; i++) fPHOSMatrix [i] = 0 ;
89 //_________________________________________
90 AliCalorimeterUtils::~AliCalorimeterUtils()
94 //if(fPHOSGeo) delete fPHOSGeo ;
95 if(fEMCALGeo) delete fEMCALGeo ;
97 if(fPHOSBadChannelMap) {
98 fPHOSBadChannelMap->Clear();
99 delete fPHOSBadChannelMap;
102 if(fPHOSRecalibrationFactors) {
103 fPHOSRecalibrationFactors->Clear();
104 delete fPHOSRecalibrationFactors;
107 if(fEMCALRecoUtils) delete fEMCALRecoUtils ;
108 if(fNMaskCellColumns) delete [] fMaskCellColumns;
112 //____________________________________________________
113 void AliCalorimeterUtils::AccessOADB(AliVEvent* event)
115 // Set the AODB calibration, bad channels etc. parameters at least once
116 // alignment matrices from OADB done in SetGeometryMatrices
119 if(fOADBSet) return ;
121 Int_t runnumber = event->GetRunNumber() ;
122 TString pass = GetPass();
127 AliInfo(Form("Get AODB parameters from EMCAL in %s for run %d, and <%s>",fOADBFilePathEMCAL.Data(),runnumber,pass.Data()));
129 Int_t nSM = fEMCALGeo->GetNumberOfSuperModules();
132 if(fRemoveBadChannels)
134 AliOADBContainer *contBC=new AliOADBContainer("");
135 contBC->InitFromFile(Form("%s/EMCALBadChannels.root",fOADBFilePathEMCAL.Data()),"AliEMCALBadChannels");
137 TObjArray *arrayBC=(TObjArray*)contBC->GetObject(runnumber);
141 SwitchOnDistToBadChannelRecalculation();
142 AliInfo("Remove EMCAL bad cells");
144 for (Int_t i=0; i<nSM; ++i)
146 TH2I *hbm = GetEMCALChannelStatusMap(i);
151 hbm=(TH2I*)arrayBC->FindObject(Form("EMCALBadChannelMap_Mod%d",i));
155 AliError(Form("Can not get EMCALBadChannelMap_Mod%d",i));
159 hbm->SetDirectory(0);
160 SetEMCALChannelStatusMap(i,hbm);
163 } else AliInfo("Do NOT remove EMCAL bad channels\n"); // run array
166 // Energy Recalibration
169 AliOADBContainer *contRF=new AliOADBContainer("");
171 contRF->InitFromFile(Form("%s/EMCALRecalib.root",fOADBFilePathEMCAL.Data()),"AliEMCALRecalib");
173 TObjArray *recal=(TObjArray*)contRF->GetObject(runnumber);
177 TObjArray *recalpass=(TObjArray*)recal->FindObject(pass);
181 TObjArray *recalib=(TObjArray*)recalpass->FindObject("Recalib");
185 AliInfo("Recalibrate EMCAL");
186 for (Int_t i=0; i < nSM; ++i)
188 TH2F *h = GetEMCALChannelRecalibrationFactors(i);
193 h = (TH2F*)recalib->FindObject(Form("EMCALRecalFactors_SM%d",i));
197 AliError(Form("Could not load EMCALRecalFactors_SM%d",i));
203 SetEMCALChannelRecalibrationFactors(i,h);
205 } else AliInfo("Do NOT recalibrate EMCAL, no params object array"); // array ok
206 } else AliInfo("Do NOT recalibrate EMCAL, no params for pass"); // array pass ok
207 } else AliInfo("Do NOT recalibrate EMCAL, no params for run"); // run number array ok
209 // once set, apply run dependent corrections if requested
210 //fEMCALRecoUtils->SetRunDependentCorrections(runnumber);
212 } // Recalibration on
214 // Energy Recalibration, apply on top of previous calibration factors
215 if(fRunDependentCorrection)
217 AliOADBContainer *contRFTD=new AliOADBContainer("");
219 contRFTD->InitFromFile(Form("%s/EMCALTemperatureCorrCalib.root",fOADBFilePathEMCAL.Data()),"AliEMCALRunDepTempCalibCorrections");
221 TH1S *htd=(TH1S*)contRFTD->GetObject(runnumber);
223 //If it did not exist for this run, get closes one
226 AliWarning(Form("No TemperatureCorrCalib Objects for run: %d",runnumber));
227 // let's get the closest runnumber instead then..
230 Int_t maxEntry = contRFTD->GetNumberOfEntries();
232 while ( (ic < maxEntry) && (contRFTD->UpperLimit(ic) < runnumber) ) {
237 Int_t closest = lower;
238 if ( (ic<maxEntry) &&
239 (contRFTD->LowerLimit(ic)-runnumber) < (runnumber - contRFTD->UpperLimit(lower)) ) {
243 AliWarning(Form("TemperatureCorrCalib Objects found closest id %d from run: %d", closest, contRFTD->LowerLimit(closest)));
244 htd = (TH1S*) contRFTD->GetObjectByIndex(closest);
249 AliInfo("Recalibrate (Temperature) EMCAL");
251 for (Int_t ism=0; ism<nSM; ++ism)
253 for (Int_t icol=0; icol<48; ++icol)
255 for (Int_t irow=0; irow<24; ++irow)
257 Float_t factor = GetEMCALChannelRecalibrationFactor(ism,icol,irow);
259 Int_t absID = fEMCALGeo->GetAbsCellIdFromCellIndexes(ism, irow, icol); // original calibration factor
260 factor *= htd->GetBinContent(absID) / 10000. ; // correction dependent on T
261 //printf("\t ism %d, icol %d, irow %d,absID %d, corrA %2.3f, corrB %2.3f, corrAB %2.3f\n",ism, icol, irow, absID,
262 // GetEMCALChannelRecalibrationFactor(ism,icol,irow) , htd->GetBinContent(absID) / 10000., factor);
263 SetEMCALChannelRecalibrationFactor(ism,icol,irow,factor);
267 }else AliInfo("Do NOT recalibrate EMCAL with T variations, no params TH1");
268 } // Run by Run T calibration
270 // Time Recalibration
271 if(fEMCALRecoUtils->IsTimeRecalibrationOn())
273 AliOADBContainer *contTRF=new AliOADBContainer("");
275 contTRF->InitFromFile(Form("%s/EMCALTimeCalib.root",fOADBFilePathEMCAL.Data()),"AliEMCALTimeCalib");
277 TObjArray *trecal=(TObjArray*)contTRF->GetObject(runnumber);
281 TString passM = pass;
282 if(pass=="spc_calo") passM = "pass1";
283 TObjArray *trecalpass=(TObjArray*)trecal->FindObject(passM);
287 AliInfo("Time Recalibrate EMCAL");
288 for (Int_t ibc = 0; ibc < 4; ++ibc)
290 TH1F *h = GetEMCALChannelTimeRecalibrationFactors(ibc);
295 h = (TH1F*)trecalpass->FindObject(Form("hAllTimeAvBC%d",ibc));
299 AliError(Form("Could not load hAllTimeAvBC%d",ibc));
305 SetEMCALChannelTimeRecalibrationFactors(ibc,h);
306 } // bunch crossing loop
307 } else AliInfo("Do NOT recalibrate time EMCAL, no params for pass"); // array pass ok
308 } else AliInfo("Do NOT recalibrate time EMCAL, no params for run"); // run number array ok
310 } // Recalibration on
317 AliInfo(Form("Get AODB parameters from PHOS in %s for run %d, and <%s>",fOADBFilePathPHOS.Data(),runnumber,pass.Data()));
320 if(fRemoveBadChannels)
322 AliOADBContainer badmapContainer(Form("phosBadMap"));
323 TString fileName="$ALICE_ROOT/OADB/PHOS/PHOSBadMaps.root";
324 badmapContainer.InitFromFile(Form("%s/PHOSBadMaps.root",fOADBFilePathPHOS.Data()),"phosBadMap");
326 //Use a fixed run number from year 2010, this year not available yet.
327 TObjArray *maps = (TObjArray*)badmapContainer.GetObject(139000,"phosBadMap");
330 AliInfo(Form("Can not read PHOS bad map for run %d",runnumber)) ;
334 AliInfo(Form("Setting PHOS bad map with name %s",maps->GetName())) ;
335 for(Int_t mod=1; mod<5;mod++)
337 TH2I *hbmPH = GetPHOSChannelStatusMap(mod);
342 hbmPH = (TH2I*)maps->At(mod);
344 if(hbmPH) hbmPH->SetDirectory(0);
346 SetPHOSChannelStatusMap(mod-1,hbmPH);
350 } // Remove bad channels
353 // Parameters already set once, so do not it again
358 //_____________________________________________________________
359 void AliCalorimeterUtils::AccessGeometry(AliVEvent* inputEvent)
361 //Set the calorimeters transformation matrices and init geometry
363 // First init the geometry, a priory not done before
364 Int_t runnumber = inputEvent->GetRunNumber() ;
365 InitPHOSGeometry (runnumber);
366 InitEMCALGeometry(runnumber);
368 //Get the EMCAL transformation geometry matrices from ESD
369 if(!fEMCALGeoMatrixSet && fEMCALGeo)
371 if(fLoadEMCALMatrices)
373 AliInfo("Load user defined EMCAL geometry matrices");
376 AliOADBContainer emcGeoMat("AliEMCALgeo");
377 emcGeoMat.InitFromFile(Form("%s/EMCALlocal2master.root",fOADBFilePathEMCAL.Data()),"AliEMCALgeo");
378 TObjArray *matEMCAL=(TObjArray*)emcGeoMat.GetObject(runnumber,"EmcalMatrices");
380 for(Int_t mod=0; mod < (fEMCALGeo->GetEMCGeometry())->GetNumberOfSuperModules(); mod++)
382 if (!fEMCALMatrix[mod]) // Get it from OADB
384 AliDebug(1,Form("EMCAL matrices SM %d, %p", mod,((TGeoHMatrix*) matEMCAL->At(mod))));
385 //((TGeoHMatrix*) matEMCAL->At(mod))->Print();
387 fEMCALMatrix[mod] = (TGeoHMatrix*) matEMCAL->At(mod) ;
390 if(fEMCALMatrix[mod])
393 fEMCALMatrix[mod]->Print();
395 fEMCALGeo->SetMisalMatrix(fEMCALMatrix[mod],mod) ;
399 fEMCALGeoMatrixSet = kTRUE;//At least one, so good
402 else if (!gGeoManager)
404 AliDebug(1,"Load EMCAL misalignment matrices");
405 if(!strcmp(inputEvent->GetName(),"AliESDEvent"))
407 for(Int_t mod=0; mod < (fEMCALGeo->GetEMCGeometry())->GetNumberOfSuperModules(); mod++)
409 //printf("Load ESD matrix %d, %p\n",mod,((AliESDEvent*)inputEvent)->GetEMCALMatrix(mod));
410 if(((AliESDEvent*)inputEvent)->GetEMCALMatrix(mod))
412 fEMCALGeo->SetMisalMatrix(((AliESDEvent*)inputEvent)->GetEMCALMatrix(mod),mod) ;
414 }// loop over super modules
416 fEMCALGeoMatrixSet = kTRUE;//At least one, so good
421 AliDebug(1,"Setting of EMCAL transformation matrixes for AODs not implemented yet. \n Import geometry.root file");
423 }//Get matrix from data
426 fEMCALGeoMatrixSet = kTRUE;
428 }//EMCAL geo && no geoManager
430 //Get the PHOS transformation geometry matrices from ESD
431 if(!fPHOSGeoMatrixSet && fPHOSGeo)
433 if(fLoadPHOSMatrices)
435 AliInfo("Load user defined PHOS geometry matrices");
438 AliOADBContainer geomContainer("phosGeo");
439 geomContainer.InitFromFile(Form("%s/PHOSGeometry.root",fOADBFilePathPHOS.Data()),"PHOSRotationMatrixes");
440 TObjArray *matPHOS = (TObjArray*)geomContainer.GetObject(139000,"PHOSRotationMatrixes");
442 for(Int_t mod = 0 ; mod < 5 ; mod++)
444 if (!fPHOSMatrix[mod]) // Get it from OADB
446 AliDebug(1,Form("PHOS matrices module %d, %p",mod,((TGeoHMatrix*) matPHOS->At(mod))));
447 //((TGeoHMatrix*) matPHOS->At(mod))->Print();
449 fPHOSMatrix[mod] = (TGeoHMatrix*) matPHOS->At(mod) ;
452 // Set it, if it exists
456 fPHOSMatrix[mod]->Print();
458 fPHOSGeo->SetMisalMatrix(fPHOSMatrix[mod],mod) ;
462 fPHOSGeoMatrixSet = kTRUE;//At least one, so good
465 else if (!gGeoManager)
467 AliDebug(1,"Load PHOS misalignment matrices.");
468 if(!strcmp(inputEvent->GetName(),"AliESDEvent"))
470 for(Int_t mod = 0; mod < 5; mod++)
472 if( ((AliESDEvent*)inputEvent)->GetPHOSMatrix(mod))
474 //printf("PHOS: mod %d, matrix %p\n",mod, ((AliESDEvent*)inputEvent)->GetPHOSMatrix(mod));
475 fPHOSGeo->SetMisalMatrix( ((AliESDEvent*)inputEvent)->GetPHOSMatrix(mod),mod) ;
477 }// loop over modules
478 fPHOSGeoMatrixSet = kTRUE; //At least one so good
482 AliDebug(1,"Setting of EMCAL transformation matrixes for AODs not implemented yet. \n Import geometry.root file");
484 }// get matrix from data
487 fPHOSGeoMatrixSet = kTRUE;
489 }//PHOS geo and geoManager was not set
493 //________________________________________________________________________________________
494 Bool_t AliCalorimeterUtils::AreNeighbours(Int_t calo, Int_t absId1, Int_t absId2 ) const
496 // Tells if (true) or not (false) two cells are neighbours
497 // A neighbour is defined as being two cells which share a side or corner
499 Bool_t areNeighbours = kFALSE ;
501 Int_t iRCU1 = -1, irow1 = -1, icol1 = -1;
502 Int_t iRCU2 = -1, irow2 = -1, icol2 = -1;
504 Int_t rowdiff = 0, coldiff = 0;
506 Int_t nSupMod1 = GetModuleNumberCellIndexes(absId1, calo, icol1, irow1, iRCU1);
507 Int_t nSupMod2 = GetModuleNumberCellIndexes(absId2, calo, icol2, irow2, iRCU2);
509 if(calo==kEMCAL && nSupMod1!=nSupMod2)
511 // In case of a shared cluster, index of SM in C side, columns start at 48 and ends at 48*2-1
512 // C Side impair SM, nSupMod%2=1; A side pair SM nSupMod%2=0
513 if(nSupMod1%2) icol1+=AliEMCALGeoParams::fgkEMCALCols;
514 else icol2+=AliEMCALGeoParams::fgkEMCALCols;
517 rowdiff = TMath::Abs( irow1 - irow2 ) ;
518 coldiff = TMath::Abs( icol1 - icol2 ) ;
520 //if (( coldiff <= 1 ) && ( rowdiff <= 1 ) && (coldiff + rowdiff > 0))
521 if ((coldiff + rowdiff == 1 ))
522 areNeighbours = kTRUE ;
524 return areNeighbours;
527 //_____________________________________________________________________________________
528 Bool_t AliCalorimeterUtils::IsClusterSharedByTwoSuperModules(const AliEMCALGeometry * geom,
529 AliVCluster* cluster)
531 //Method that checks if any of the cells in the cluster belongs to a different SM
541 for(Int_t iDigit=0; iDigit < cluster->GetNCells(); iDigit++)
543 //Get from the absid the supermodule, tower and eta/phi numbers
544 geom->GetCellIndex(cluster->GetCellAbsId(iDigit),iSupMod,iTower,iIphi,iIeta);
545 geom->GetCellPhiEtaIndexInSModule(iSupMod,iTower,iIphi,iIeta, iphi,ieta);
547 //Check if there are cells of different SM
548 if (iDigit == 0 ) iSM0 = iSupMod;
549 else if(iSupMod!= iSM0) return kTRUE;
556 //_____________________________________________________________________________________
557 Bool_t AliCalorimeterUtils::CheckCellFiducialRegion(AliVCluster* cluster,
558 AliVCaloCells* cells) const
561 // Given the list of AbsId of the cluster, get the maximum cell and
562 // check if there are fNCellsFromBorder from the calorimeter border
564 //If the distance to the border is 0 or negative just exit accept all clusters
565 if(cells->GetType()==AliVCaloCells::kEMCALCell && fEMCALRecoUtils->GetNumberOfCellsFromEMCALBorder() <= 0 ) return kTRUE;
566 if(cells->GetType()==AliVCaloCells::kPHOSCell && fNCellsFromPHOSBorder <= 0 ) return kTRUE;
571 for(Int_t i = 0; i < cluster->GetNCells() ; i++)
573 Int_t absId = cluster->GetCellAbsId(i) ;
574 Float_t amp = cells->GetCellAmplitude(absId);
582 AliDebug(1,Form("Cluster Max AbsId %d, Cell Energy %2.2f, Cluster Energy %2.2f",
583 absIdMax, ampMax, cluster->E()));
585 if(absIdMax==-1) return kFALSE;
587 //Check if the cell is close to the borders:
588 Bool_t okrow = kFALSE;
589 Bool_t okcol = kFALSE;
591 if(cells->GetType()==AliVCaloCells::kEMCALCell)
593 Int_t iTower = -1, iIphi = -1, iIeta = -1, iphi = -1, ieta = -1, iSM = -1;
594 fEMCALGeo->GetCellIndex(absIdMax,iSM,iTower,iIphi,iIeta);
595 fEMCALGeo->GetCellPhiEtaIndexInSModule(iSM,iTower,iIphi, iIeta,iphi,ieta);
596 if(iSM < 0 || iphi < 0 || ieta < 0 )
598 AliFatal(Form("Negative value for super module: %d, or cell ieta: %d, or cell iphi: %d, check EMCAL geometry name",iSM,ieta,iphi));
602 Int_t nborder = fEMCALRecoUtils->GetNumberOfCellsFromEMCALBorder();
605 if(iphi >= nborder && iphi < 24-nborder) okrow =kTRUE;
609 if(fEMCALGeoName.Contains("12SM")) // 1/3 SM
611 if(iphi >= nborder && iphi < 8-nborder) okrow =kTRUE;
615 if(iphi >= nborder && iphi <12-nborder) okrow =kTRUE;
620 if(!fEMCALRecoUtils->IsEMCALNoBorderAtEta0())
622 if(ieta > nborder && ieta < 48-nborder) okcol =kTRUE;
628 if(ieta >= nborder) okcol = kTRUE;
632 if(ieta < 48-nborder) okcol = kTRUE;
636 AliDebug(1,Form("EMCAL Cluster in %d cells fiducial volume: ieta %d, iphi %d, SM %d ? ok row %d, ok column %d",
637 nborder, ieta, iphi, iSM,okrow,okcol));
640 else if ( cells->GetType() == AliVCaloCells::kPHOSCell )
643 Int_t irow = -1, icol = -1;
644 fPHOSGeo->AbsToRelNumbering(absIdMax,relId);
649 if(irow >= fNCellsFromPHOSBorder && irow < 64-fNCellsFromPHOSBorder) okrow =kTRUE;
650 if(icol >= fNCellsFromPHOSBorder && icol < 56-fNCellsFromPHOSBorder) okcol =kTRUE;
652 AliDebug(1,Form("PHOS Cluster in %d cells fiducial volume: ieta %d, iphi %d, SM %d ? ok row %d, ok column %d",
653 fNCellsFromPHOSBorder, icol, irow, relId[0]-1,okrow,okcol));
656 if (okcol && okrow) return kTRUE;
661 //__________________________________________________________________________________________________________
662 Bool_t AliCalorimeterUtils::ClusterContainsBadChannel(Int_t calorimeter, UShort_t* cellList, Int_t nCells)
664 // Check that in the cluster cells, there is no bad channel of those stored
665 // in fEMCALBadChannelMap or fPHOSBadChannelMap
667 if (!fRemoveBadChannels) return kFALSE;
668 //printf("fEMCALBadChannelMap %p, fPHOSBadChannelMap %p \n",fEMCALBadChannelMap,fPHOSBadChannelMap);
669 if(calorimeter == kEMCAL && !fEMCALRecoUtils->GetEMCALChannelStatusMap(0)) return kFALSE;
670 if(calorimeter == kPHOS && !fPHOSBadChannelMap) return kFALSE;
675 for(Int_t iCell = 0; iCell<nCells; iCell++){
677 //Get the column and row
678 if(calorimeter == kEMCAL){
679 return fEMCALRecoUtils->ClusterContainsBadChannel((AliEMCALGeometry*)fEMCALGeo,cellList,nCells);
681 else if(calorimeter==kPHOS){
683 fPHOSGeo->AbsToRelNumbering(cellList[iCell],relId);
687 if(fPHOSBadChannelMap->GetEntries() <= imod)continue;
688 //printf("PHOS bad channels imod %d, icol %d, irow %d\n",imod, irow, icol);
689 if(GetPHOSChannelStatus(imod, irow, icol)) return kTRUE;
693 }// cell cluster loop
699 //_______________________________________________________________
700 void AliCalorimeterUtils::CorrectClusterEnergy(AliVCluster *clus)
702 // Correct cluster energy non linearity
704 clus->SetE(fEMCALRecoUtils->CorrectClusterEnergyLinearity(clus));
708 //________________________________________________________________________________________
709 Int_t AliCalorimeterUtils::GetMaxEnergyCell(AliVCaloCells* cells, const AliVCluster* clu,
710 Float_t & clusterFraction) const
713 //For a given CaloCluster gets the absId of the cell
714 //with maximum energy deposit.
716 if( !clu || !cells ){
717 AliInfo("Cluster or cells pointer is null!");
724 Float_t fraction = 1.;
725 Float_t recalFactor = 1.;
726 Int_t cellAbsId =-1 , absId =-1 ;
727 Int_t iSupMod =-1 , ieta =-1 , iphi = -1, iRCU = -1;
730 if(clu->IsPHOS()) calo = kPHOS ;
732 for (Int_t iDig=0; iDig< clu->GetNCells(); iDig++) {
734 cellAbsId = clu->GetCellAbsId(iDig);
736 fraction = clu->GetCellAmplitudeFraction(iDig);
737 if(fraction < 1e-4) fraction = 1.; // in case unfolding is off
739 iSupMod = GetModuleNumberCellIndexes(cellAbsId, calo, ieta, iphi, iRCU);
741 if(IsRecalibrationOn()) {
742 if(calo==kEMCAL) recalFactor = GetEMCALChannelRecalibrationFactor(iSupMod,ieta,iphi);
743 else recalFactor = GetPHOSChannelRecalibrationFactor (iSupMod,iphi,ieta);
746 eCell = cells->GetCellAmplitude(cellAbsId)*fraction*recalFactor;
758 clusterFraction = (eTot-eMax)/eTot; //Do not use cluster energy in case it was corrected for non linearity.
766 //___________________________________________________________________________________
767 AliVTrack * AliCalorimeterUtils::GetMatchedTrack(AliVCluster* cluster,
768 AliVEvent* event, Int_t index) const
770 // Get the matched track given its index, usually just the first match
771 // Since it is different for ESDs and AODs here it is a wrap method to do it
773 AliVTrack *track = 0;
775 // EMCAL case only when matching is recalculated
776 if(cluster->IsEMCAL() && IsRecalculationOfClusterTrackMatchingOn())
778 Int_t trackIndex = fEMCALRecoUtils->GetMatchedTrackIndex(cluster->GetID());
779 //printf("track index %d, cluster ID %d \n ",trackIndex,cluster->GetID());
783 AliInfo(Form("Wrong track index %d, from recalculation", trackIndex));
787 track = dynamic_cast<AliVTrack*> (event->GetTrack(trackIndex));
794 // Normal case, get info from ESD or AOD
796 if(!strcmp("AliESDCaloCluster",Form("%s",cluster->ClassName())))
798 Int_t iESDtrack = cluster->GetTrackMatchedIndex();
802 AliWarning(Form("Wrong track index %d", index));
806 track = dynamic_cast<AliVTrack*> (event->GetTrack(iESDtrack));
811 if(cluster->GetNTracksMatched() > 0 )
812 track = dynamic_cast<AliVTrack*>(cluster->GetTrackMatched(index));
818 //______________________________________________________________________________________________
819 Float_t AliCalorimeterUtils::GetMCECellClusFracCorrection(Float_t eCell, Float_t eCluster) const
821 // Correction factor for cell energy in cluster to temptatively match Data and MC
822 if( eCluster <= 0 || eCluster < eCell )
824 AliWarning(Form("Bad values eCell=%f, eCluster %f",eCell,eCluster));
828 Float_t frac = eCell / eCluster;
830 Float_t correction = fMCECellClusFracCorrParam[0] +
831 TMath::Exp( frac*fMCECellClusFracCorrParam[2]+fMCECellClusFracCorrParam[1] ) +
832 fMCECellClusFracCorrParam[3]/TMath::Sqrt(frac);
834 // printf("AliCalorimeterUtils::GetMCECellClusFracCorrection(eCell=%f, eCluster %f, frac %f) = %f\n",eCell, eCluster, frac, correction);
835 // printf("\t %2.2f + TMath::Exp( %2.3f*%2.2f + %2.2f ) + %2.2f/TMath::Sqrt(%2.3f)) = %f\n",
836 // fMCECellClusFracCorrParam[0],frac,fMCECellClusFracCorrParam[2],fMCECellClusFracCorrParam[1],fMCECellClusFracCorrParam[3], frac, correction);
841 //_____________________________________________________________________________________________________
842 Int_t AliCalorimeterUtils::GetModuleNumber(AliAODPWG4Particle * particle, AliVEvent * inputEvent) const
844 //Get the EMCAL/PHOS module number that corresponds to this particle
847 if(particle->GetDetectorTag()==kEMCAL)
849 fEMCALGeo->GetAbsCellIdFromEtaPhi(particle->Eta(),particle->Phi(), absId);
851 AliDebug(2,Form("EMCAL: cluster eta %f, phi %f, absid %d, SuperModule %d",
852 particle->Eta(), particle->Phi()*TMath::RadToDeg(),absId, fEMCALGeo->GetSuperModuleNumber(absId)));
854 return fEMCALGeo->GetSuperModuleNumber(absId) ;
856 else if(particle->GetDetectorTag()==kPHOS)
858 // In case we use the MC reader, the input are TParticles,
859 // in this case use the corresponing method in PHOS Geometry to get the particle.
860 if(strcmp(inputEvent->ClassName(), "AliMCEvent") == 0 )
863 Double_t z = 0., x=0.;
864 TParticle* primary = 0x0;
865 AliStack * stack = ((AliMCEvent*)inputEvent)->Stack();
868 primary = stack->Particle(particle->GetCaloLabel(0));
872 AliFatal("Stack not available, stop!");
877 fPHOSGeo->ImpactOnEmc(primary,mod,z,x) ;
881 AliFatal("Primary not available, stop!");
885 // Input are ESDs or AODs, get the PHOS module number like this.
889 //AliVCluster *cluster = inputEvent->GetCaloCluster(particle->GetCaloLabel(0));
890 //return GetModuleNumber(cluster);
899 //_____________________________________________________________________
900 Int_t AliCalorimeterUtils::GetModuleNumber(AliVCluster * cluster) const
902 //Get the EMCAL/PHOS module number that corresponds to this cluster
906 AliDebug(1,"AliCalorimeterUtils::GetModuleNumber() - NUL Cluster, please check!!!");
911 if ( cluster->GetNCells() <= 0 ) return -1;
913 Int_t absId = cluster->GetCellAbsId(0);
915 if ( absId < 0 ) return -1;
917 if( cluster->IsEMCAL() )
919 AliDebug(2,Form("EMCAL absid %d, SuperModule %d",absId, fEMCALGeo->GetSuperModuleNumber(absId)));
921 return fEMCALGeo->GetSuperModuleNumber(absId) ;
923 else if ( cluster->IsPHOS() )
926 fPHOSGeo->AbsToRelNumbering(absId,relId);
928 AliDebug(2,Form("PHOS absid %d Module %d",absId, relId[0]-1));
936 //___________________________________________________________________________________________________
937 Int_t AliCalorimeterUtils::GetModuleNumberCellIndexes(Int_t absId, Int_t calo,
938 Int_t & icol, Int_t & irow, Int_t & iRCU) const
940 //Get the EMCAL/PHOS module, columns, row and RCU number that corresponds to this absId
944 if ( absId < 0) return -1 ;
946 if ( calo == kEMCAL )
948 Int_t iTower = -1, iIphi = -1, iIeta = -1;
949 fEMCALGeo->GetCellIndex(absId,imod,iTower,iIphi,iIeta);
950 fEMCALGeo->GetCellPhiEtaIndexInSModule(imod,iTower,iIphi, iIeta,irow,icol);
952 if(imod < 0 || irow < 0 || icol < 0 )
954 AliFatal(Form("Negative value for super module: %d, or cell icol: %d, or cell irow: %d, check EMCAL geometry name",imod,icol,irow));
960 if (0<=irow&&irow<8) iRCU=0; // first cable row
961 else if (8<=irow&&irow<16 && 0<=icol&&icol<24) iRCU=0; // first half;
964 else if (8<=irow&&irow<16 && 24<=icol&&icol<48) iRCU=1; // second half;
966 else if (16<=irow&&irow<24) iRCU=1; // third cable row
968 if (imod%2==1) iRCU = 1 - iRCU; // swap for odd=C side, to allow us to cable both sides the same
972 // Last 2 SM have one single SRU, just assign RCU 0
978 AliFatal(Form("Wrong EMCAL RCU number = %d", iRCU));
987 fPHOSGeo->AbsToRelNumbering(absId,relId);
991 iRCU= (Int_t)(relId[2]-1)/16 ;
992 //Int_t iBranch= (Int_t)(relid[3]-1)/28 ; //0 to 1
995 AliFatal(Form("Wrong PHOS RCU number = %d", iRCU));
1003 //___________________________________________________________________________________________
1004 Int_t AliCalorimeterUtils::GetNumberOfLocalMaxima(AliVCluster* cluster, AliVCaloCells* cells)
1006 // Find local maxima in cluster
1008 const Int_t nc = cluster->GetNCells();
1009 Int_t absIdList[nc];
1010 Float_t maxEList[nc];
1012 Int_t nMax = GetNumberOfLocalMaxima(cluster, cells, absIdList, maxEList);
1018 //___________________________________________________________________________________________
1019 Int_t AliCalorimeterUtils::GetNumberOfLocalMaxima(AliVCluster* cluster, AliVCaloCells* cells,
1020 Int_t *absIdList, Float_t *maxEList)
1022 // Find local maxima in cluster
1028 const Int_t nCells = cluster->GetNCells();
1030 Float_t eCluster = RecalibrateClusterEnergy(cluster, cells);// recalculate cluster energy, avoid non lin correction.
1032 Float_t simuTotWeight = 0;
1033 if(fMCECellClusFracCorrOn)
1035 simuTotWeight = RecalibrateClusterEnergyWeightCell(cluster, cells,eCluster);// same but apply a weight
1036 simuTotWeight/= eCluster;
1039 Int_t calorimeter = kEMCAL;
1040 if(!cluster->IsEMCAL()) calorimeter = kPHOS;
1042 //printf("cluster : ncells %d \n",nCells);
1046 for(iDigit = 0; iDigit < nCells ; iDigit++)
1048 absIdList[iDigit] = cluster->GetCellsAbsId()[iDigit] ;
1049 Float_t en = cells->GetCellAmplitude(absIdList[iDigit]);
1050 RecalibrateCellAmplitude(en,calorimeter,absIdList[iDigit]);
1052 if(fMCECellClusFracCorrOn)
1053 en*=GetMCECellClusFracCorrection(en,eCluster)/simuTotWeight;
1058 idmax = absIdList[iDigit] ;
1060 //Int_t icol = -1, irow = -1, iRCU = -1;
1061 //Int_t sm = GetModuleNumberCellIndexes(absIdList[iDigit], calorimeter, icol, irow, iRCU) ;
1062 //printf("\t cell %d, id %d, sm %d, col %d, row %d, e %f\n", iDigit, absIdList[iDigit], sm, icol, irow, en );
1065 for(iDigit = 0 ; iDigit < nCells; iDigit++)
1067 if(absIdList[iDigit]>=0)
1069 absId1 = cluster->GetCellsAbsId()[iDigit];
1071 Float_t en1 = cells->GetCellAmplitude(absId1);
1072 RecalibrateCellAmplitude(en1,calorimeter,absId1);
1074 if(fMCECellClusFracCorrOn)
1075 en1*=GetMCECellClusFracCorrection(en1,eCluster)/simuTotWeight;
1077 //printf("%d : absIDi %d, E %f\n",iDigit, absId1,en1);
1079 for(iDigitN = 0; iDigitN < nCells; iDigitN++)
1081 absId2 = cluster->GetCellsAbsId()[iDigitN] ;
1083 if(absId2==-1 || absId2==absId1) continue;
1085 //printf("\t %d : absIDj %d\n",iDigitN, absId2);
1087 Float_t en2 = cells->GetCellAmplitude(absId2);
1088 RecalibrateCellAmplitude(en2,calorimeter,absId2);
1090 if(fMCECellClusFracCorrOn)
1091 en2*=GetMCECellClusFracCorrection(en2,eCluster)/simuTotWeight;
1093 //printf("\t %d : absIDj %d, E %f\n",iDigitN, absId2,en2);
1095 if ( AreNeighbours(calorimeter, absId1, absId2) )
1097 // printf("\t \t Neighbours \n");
1100 absIdList[iDigitN] = -1 ;
1101 //printf("\t \t indexN %d not local max\n",iDigitN);
1102 // but may be digit too is not local max ?
1103 if(en1 < en2 + fLocMaxCutEDiff) {
1104 //printf("\t \t index %d not local max cause locMaxCutEDiff\n",iDigit);
1105 absIdList[iDigit] = -1 ;
1110 absIdList[iDigit] = -1 ;
1111 //printf("\t \t index %d not local max\n",iDigitN);
1112 // but may be digitN too is not local max ?
1113 if(en1 > en2 - fLocMaxCutEDiff)
1115 absIdList[iDigitN] = -1 ;
1116 //printf("\t \t indexN %d not local max cause locMaxCutEDiff\n",iDigit);
1119 } // if Are neighbours
1120 //else printf("\t \t NOT Neighbours \n");
1126 for(iDigit = 0; iDigit < nCells; iDigit++)
1128 if(absIdList[iDigit]>=0 )
1130 absIdList[iDigitN] = absIdList[iDigit] ;
1132 Float_t en = cells->GetCellAmplitude(absIdList[iDigit]);
1133 RecalibrateCellAmplitude(en,calorimeter,absIdList[iDigit]);
1135 if(fMCECellClusFracCorrOn)
1136 en*=GetMCECellClusFracCorrection(en,eCluster)/simuTotWeight;
1138 if(en < fLocMaxCutE) continue; // Maxima only with seed energy at least
1140 maxEList[iDigitN] = en ;
1142 //printf("Local max %d, id %d, en %f\n", iDigit,absIdList[iDigitN],en);
1149 AliDebug(1,Form("No local maxima found, assign highest energy cell as maxima, id %d, en cell %2.2f, en cluster %2.2f",
1150 idmax,emax,cluster->E()));
1152 maxEList[0] = emax ;
1153 absIdList[0] = idmax ;
1157 AliDebug(1,Form("In cluster E %2.2f (wth non lin. %2.2f), M02 %2.2f, M20 %2.2f, N maxima %d",
1158 cluster->E(),eCluster, cluster->GetM02(),cluster->GetM20(), iDigitN));
1160 // if(fDebug > 1) for(Int_t imax = 0; imax < iDigitN; imax++)
1162 // printf(" \t i %d, absId %d, Ecell %f\n",imax,absIdList[imax],maxEList[imax]);
1169 //____________________________________
1170 TString AliCalorimeterUtils::GetPass()
1172 // Get passx from filename.
1174 if (!AliAnalysisManager::GetAnalysisManager()->GetTree())
1176 AliError("AliCalorimeterUtils::GetPass() - Pointer to tree = 0, returning null");
1180 if (!AliAnalysisManager::GetAnalysisManager()->GetTree()->GetCurrentFile())
1182 AliError("AliCalorimeterUtils::GetPass() - Null pointer input file, returning null");
1186 TString pass(AliAnalysisManager::GetAnalysisManager()->GetTree()->GetCurrentFile()->GetName());
1187 if (pass.Contains("ass1")) return TString("pass1");
1188 else if (pass.Contains("ass2")) return TString("pass2");
1189 else if (pass.Contains("ass3")) return TString("pass3");
1190 else if (pass.Contains("ass4")) return TString("pass4");
1191 else if (pass.Contains("ass5")) return TString("pass5");
1192 else if (pass.Contains("LHC11c") && pass.Contains("spc_calo") ) return TString("spc_calo");
1193 else if (pass.Contains("calo") || pass.Contains("high_lumi"))
1195 AliInfo("Path contains <calo> or <high-lumi>, set as <pass1>");
1196 return TString("pass1");
1199 // No condition fullfilled, give a default value
1200 AliInfo("Pass number string not found");
1205 //________________________________________
1206 void AliCalorimeterUtils::InitParameters()
1208 //Initialize the parameters of the analysis.
1213 fEMCALGeoMatrixSet = kFALSE;
1214 fPHOSGeoMatrixSet = kFALSE;
1216 fRemoveBadChannels = kFALSE;
1218 fNCellsFromPHOSBorder = 0;
1221 fLocMaxCutEDiff = 0.0 ;
1223 // fMaskCellColumns = new Int_t[fNMaskCellColumns];
1224 // fMaskCellColumns[0] = 6 ; fMaskCellColumns[1] = 7 ; fMaskCellColumns[2] = 8 ;
1225 // fMaskCellColumns[3] = 35; fMaskCellColumns[4] = 36; fMaskCellColumns[5] = 37;
1226 // fMaskCellColumns[6] = 12+AliEMCALGeoParams::fgkEMCALCols; fMaskCellColumns[7] = 13+AliEMCALGeoParams::fgkEMCALCols;
1227 // fMaskCellColumns[8] = 40+AliEMCALGeoParams::fgkEMCALCols; fMaskCellColumns[9] = 41+AliEMCALGeoParams::fgkEMCALCols;
1228 // fMaskCellColumns[10]= 42+AliEMCALGeoParams::fgkEMCALCols;
1231 fOADBForEMCAL = kTRUE ;
1232 fOADBForPHOS = kFALSE;
1234 fOADBFilePathEMCAL = "$ALICE_ROOT/OADB/EMCAL" ;
1235 fOADBFilePathPHOS = "$ALICE_ROOT/OADB/PHOS" ;
1237 fImportGeometryFromFile = kTRUE;
1238 fImportGeometryFilePath = "";
1240 fNSuperModulesUsed = 22;
1242 fMCECellClusFracCorrParam[0] = 0.78;
1243 fMCECellClusFracCorrParam[1] =-1.8;
1244 fMCECellClusFracCorrParam[2] =-6.3;
1245 fMCECellClusFracCorrParam[3] = 0.014;
1250 //_____________________________________________________
1251 void AliCalorimeterUtils::InitPHOSBadChannelStatusMap()
1253 //Init PHOS bad channels map
1254 AliDebug(1,"Init bad channel map");
1256 //In order to avoid rewriting the same histograms
1257 Bool_t oldStatus = TH1::AddDirectoryStatus();
1258 TH1::AddDirectory(kFALSE);
1260 fPHOSBadChannelMap = new TObjArray(5);
1261 for (int i = 0; i < 5; i++)fPHOSBadChannelMap->Add(new TH2I(Form("PHOS_BadMap_mod%d",i),Form("PHOS_BadMap_mod%d",i), 64, 0, 64, 56, 0, 56));
1263 fPHOSBadChannelMap->SetOwner(kTRUE);
1264 fPHOSBadChannelMap->Compress();
1266 //In order to avoid rewriting the same histograms
1267 TH1::AddDirectory(oldStatus);
1270 //______________________________________________________
1271 void AliCalorimeterUtils::InitPHOSRecalibrationFactors()
1273 //Init EMCAL recalibration factors
1274 AliDebug(1,"Init recalibration map");
1276 //In order to avoid rewriting the same histograms
1277 Bool_t oldStatus = TH1::AddDirectoryStatus();
1278 TH1::AddDirectory(kFALSE);
1280 fPHOSRecalibrationFactors = new TObjArray(5);
1281 for (int i = 0; i < 5; i++)fPHOSRecalibrationFactors->Add(new TH2F(Form("PHOSRecalFactors_Mod%d",i),Form("PHOSRecalFactors_Mod%d",i), 64, 0, 64, 56, 0, 56));
1282 //Init the histograms with 1
1283 for (Int_t m = 0; m < 5; m++) {
1284 for (Int_t i = 0; i < 56; i++) {
1285 for (Int_t j = 0; j < 64; j++) {
1286 SetPHOSChannelRecalibrationFactor(m,j,i,1.);
1290 fPHOSRecalibrationFactors->SetOwner(kTRUE);
1291 fPHOSRecalibrationFactors->Compress();
1293 //In order to avoid rewriting the same histograms
1294 TH1::AddDirectory(oldStatus);
1298 //__________________________________________________________
1299 void AliCalorimeterUtils::InitEMCALGeometry(Int_t runnumber)
1301 //Initialize EMCAL geometry if it did not exist previously
1303 if (fEMCALGeo) return;
1305 AliDebug(1,Form(" for run=%d",runnumber));
1307 if(fEMCALGeoName=="")
1309 if (runnumber < 140000 &&
1310 runnumber >= 100000) fEMCALGeoName = "EMCAL_FIRSTYEARV1";
1311 else if(runnumber >= 140000 &&
1312 runnumber < 171000) fEMCALGeoName = "EMCAL_COMPLETEV1";
1313 else fEMCALGeoName = "EMCAL_COMPLETE12SMV1";
1314 AliInfo(Form("Set EMCAL geometry name to <%s> for run %d",fEMCALGeoName.Data(),runnumber));
1317 fEMCALGeo = AliEMCALGeometry::GetInstance(fEMCALGeoName);
1319 // Init geometry, I do not like much to do it like this ...
1320 if(fImportGeometryFromFile && !gGeoManager)
1322 if(fImportGeometryFilePath=="") // If not specified, set location depending on run number
1324 // "$ALICE_ROOT/EVE/alice-data/default_geo.root"
1325 if (runnumber < 140000 &&
1326 runnumber >= 100000) fImportGeometryFilePath = "$ALICE_ROOT/OADB/EMCAL/geometry_2010.root";
1327 if (runnumber >= 140000 &&
1328 runnumber < 171000) fImportGeometryFilePath = "$ALICE_ROOT/OADB/EMCAL/geometry_2011.root";
1329 else fImportGeometryFilePath = "$ALICE_ROOT/OADB/EMCAL/geometry_2012.root"; // 2012-2013
1333 AliInfo(Form("Import %s",fImportGeometryFilePath.Data()));
1334 TGeoManager::Import(fImportGeometryFilePath) ; // default need file "geometry.root" in local dir!!!!
1336 else if (!gGeoManager) AliInfo("Careful!, gGeoManager not loaded, load misalign matrices");
1341 //_________________________________________________________
1342 void AliCalorimeterUtils::InitPHOSGeometry(Int_t runnumber)
1344 //Initialize PHOS geometry if it did not exist previously
1346 if (fPHOSGeo) return;
1348 AliDebug(1,Form(" for run=%d",runnumber));
1350 if(fPHOSGeoName=="") fPHOSGeoName = "PHOSgeo";
1352 fPHOSGeo = new AliPHOSGeoUtils(fPHOSGeoName);
1354 //if (!gGeoManager) AliInfo("Careful!, gGeoManager not loaded, load misalign matrices");
1358 //_______________________________________________________________________________________________
1359 Bool_t AliCalorimeterUtils::IsMCParticleInCalorimeterAcceptance(Int_t calo, TParticle* particle)
1361 // Check that a MC ESD is in the calorimeter acceptance
1363 if(!particle || (calo!=kEMCAL && calo!=kPHOS)) return kFALSE ;
1365 if( (!IsPHOSGeoMatrixSet () && calo == kPHOS ) ||
1366 (!IsEMCALGeoMatrixSet() && calo == kEMCAL) )
1368 AliFatal(Form("Careful Geo Matrix for calo <%d> is not set, use AliFidutialCut instead",calo));
1375 Double_t x = 0, z = 0 ;
1376 return GetPHOSGeometry()->ImpactOnEmc( particle, mod, z, x);
1378 else if(calo == kEMCAL)
1381 Bool_t ok = GetEMCALGeometry()->GetAbsCellIdFromEtaPhi(particle->Eta(),particle->Phi(),absID);
1384 Int_t icol = -1, irow = -1, iRCU = -1;
1385 Int_t nModule = GetModuleNumberCellIndexes(absID,calo, icol, irow, iRCU);
1386 Int_t status = GetEMCALChannelStatus(nModule,icol,irow);
1387 if(status > 0) ok = kFALSE;
1395 //______________________________________________________________________________________________________
1396 Bool_t AliCalorimeterUtils::IsMCParticleInCalorimeterAcceptance(Int_t calo, AliAODMCParticle* particle)
1398 // Check that a MC AOD is in the calorimeter acceptance
1400 if(!particle || (calo!=kEMCAL && calo!=kPHOS)) return kFALSE ;
1402 if( (!IsPHOSGeoMatrixSet () && calo == kPHOS ) ||
1403 (!IsEMCALGeoMatrixSet() && calo == kEMCAL) )
1405 AliFatal(Form("Careful Geo Matrix for calo <%d> is not set, use AliFidutialCut instead",calo));
1409 Float_t phi = particle->Phi();
1410 if(phi < 0) phi+=TMath::TwoPi();
1415 Double_t x = 0, z = 0 ;
1416 Double_t vtx[]={ particle->Xv(), particle->Yv(), particle->Zv() } ;
1417 return GetPHOSGeometry()->ImpactOnEmc(vtx, particle->Theta(), phi, mod, z, x) ;
1419 else if(calo == kEMCAL)
1422 Bool_t ok = GetEMCALGeometry()->GetAbsCellIdFromEtaPhi(particle->Eta(),phi,absID);
1425 Int_t icol = -1, irow = -1, iRCU = -1;
1426 Int_t nModule = GetModuleNumberCellIndexes(absID,calo, icol, irow, iRCU);
1427 Int_t status = GetEMCALChannelStatus(nModule,icol,irow);
1428 if(status > 0) ok = kFALSE;
1436 //_____________________________________________________________________________________________________
1437 Bool_t AliCalorimeterUtils::IsMCParticleInCalorimeterAcceptance(Int_t calo, Float_t eta, Float_t theta,
1438 Float_t phiOrg, Int_t & absID)
1440 // Check that a TLorentzVector is in the calorimeter acceptance, give the cell number where it hit
1442 if(calo!=kEMCAL && calo!=kPHOS) return kFALSE ;
1444 if( (!IsPHOSGeoMatrixSet () && calo == kPHOS ) ||
1445 (!IsEMCALGeoMatrixSet() && calo == kEMCAL) )
1447 AliFatal(Form("Careful Geo Matrix for calo <%d> is not set, use AliFidutialCut instead",calo));
1451 Float_t phi = phiOrg;
1452 if(phi < 0) phi+=TMath::TwoPi();
1457 Double_t x = 0, z = 0 ;
1458 Double_t vtx[]={0,0,0} ;
1459 return GetPHOSGeometry()->ImpactOnEmc(vtx, theta, phi, mod, z, x) ;
1461 else if(calo == kEMCAL)
1463 Bool_t ok = GetEMCALGeometry()->GetAbsCellIdFromEtaPhi(eta,phi,absID);
1466 Int_t icol = -1, irow = -1, iRCU = -1;
1467 Int_t nModule = GetModuleNumberCellIndexes(absID,calo, icol, irow, iRCU);
1468 Int_t status = GetEMCALChannelStatus(nModule,icol,irow);
1469 if(status > 0) ok = kFALSE;
1477 //_______________________________________________________________________
1478 Bool_t AliCalorimeterUtils::MaskFrameCluster(Int_t iSM, Int_t ieta) const
1480 //Check if cell is in one of the regions where we have significant amount
1481 //of material in front. Only EMCAL
1484 if(iSM%2) icol+=48; // Impair SM, shift index [0-47] to [48-96]
1486 if (fNMaskCellColumns && fMaskCellColumns)
1488 for (Int_t imask = 0; imask < fNMaskCellColumns; imask++)
1490 if(icol==fMaskCellColumns[imask]) return kTRUE;
1498 //_________________________________________________________
1499 void AliCalorimeterUtils::Print(const Option_t * opt) const
1502 //Print some relevant parameters set for the analysis
1506 printf("***** Print: %s %s ******\n", GetName(), GetTitle() ) ;
1507 printf("Remove Clusters with bad channels? %d\n",fRemoveBadChannels);
1508 printf("Remove Clusters with max cell at less than %d cells from EMCAL border and %d cells from PHOS border\n",
1509 fEMCALRecoUtils->GetNumberOfCellsFromEMCALBorder(), fNCellsFromPHOSBorder);
1510 if(fEMCALRecoUtils->IsEMCALNoBorderAtEta0()) printf("Do not remove EMCAL clusters at Eta = 0\n");
1511 printf("Recalibrate Clusters? %d, run by run %d\n",fRecalibration,fRunDependentCorrection);
1512 printf("Recalculate Clusters Position? %d\n",fRecalculatePosition);
1513 printf("Recalculate Clusters Energy? %d\n",fCorrectELinearity);
1514 printf("Matching criteria: dR < %2.2f[cm], dZ < %2.2f[cm]\n",fCutR,fCutZ);
1516 printf("Loc. Max. E > %2.2f\n", fLocMaxCutE);
1517 printf("Loc. Max. E Diff > %2.2f\n", fLocMaxCutEDiff);
1522 //_____________________________________________________________________________________________
1523 void AliCalorimeterUtils::RecalibrateCellAmplitude(Float_t & amp, Int_t calo, Int_t id) const
1525 //Recaculate cell energy if recalibration factor
1527 Int_t icol = -1; Int_t irow = -1; Int_t iRCU = -1;
1528 Int_t nModule = GetModuleNumberCellIndexes(id,calo, icol, irow, iRCU);
1530 if (IsRecalibrationOn())
1534 amp *= GetPHOSChannelRecalibrationFactor(nModule,icol,irow);
1538 amp *= GetEMCALChannelRecalibrationFactor(nModule,icol,irow);
1543 //____________________________________________________________________________________________________
1544 void AliCalorimeterUtils::RecalibrateCellTime(Double_t & time, Int_t calo, Int_t id, Int_t bc) const
1546 // Recalculate time if time recalibration available for EMCAL
1547 // not ready for PHOS
1549 if(calo == kEMCAL && GetEMCALRecoUtils()->IsTimeRecalibrationOn())
1551 GetEMCALRecoUtils()->RecalibrateCellTime(id,bc,time);
1556 //__________________________________________________________________________
1557 Float_t AliCalorimeterUtils::RecalibrateClusterEnergy(AliVCluster * cluster,
1558 AliVCaloCells * cells)
1560 // Recalibrate the cluster energy, considering the recalibration map and the energy of the cells that compose the cluster.
1562 //Initialize some used variables
1563 Float_t frac = 0., energy = 0.;
1567 //Get the cluster number of cells and list of absId, check what kind of cluster do we have.
1569 UShort_t * index = cluster->GetCellsAbsId() ;
1570 Double_t * fraction = cluster->GetCellsAmplitudeFraction() ;
1572 Int_t ncells = cluster->GetNCells();
1574 Int_t calo = kEMCAL;
1575 if(cluster->IsPHOS()) calo = kPHOS ;
1577 //Loop on the cells, get the cell amplitude and recalibration factor, multiply and and to the new energy
1578 for(Int_t icell = 0; icell < ncells; icell++){
1580 Int_t absId = index[icell];
1582 frac = fraction[icell];
1583 if(frac < 1e-3) frac = 1; //in case of EMCAL, this is set as 0, not used.
1585 Float_t amp = cells->GetCellAmplitude(absId);
1586 RecalibrateCellAmplitude(amp,calo, absId);
1588 AliDebug(2,Form("Recalibrate cell: calo <%d>, cell fraction %f, cell energy %f",
1589 calo,frac,cells->GetCellAmplitude(absId)));
1594 AliDebug(1,Form("Energy before %f, after %f",cluster->E(),energy));
1599 AliFatal("Cells pointer does not exist!");
1605 //_______________________________________________________________________________________________________
1606 Float_t AliCalorimeterUtils::RecalibrateClusterEnergyWeightCell(AliVCluster * cluster,
1607 AliVCaloCells * cells, Float_t energyOrg)
1609 // Recalibrate the cluster energy, considering the recalibration map and the energy of the cells that compose the cluster.
1610 // Also consider reweighting of cells energy
1612 //Initialize some used variables
1613 Float_t frac = 0., energy = 0.;
1617 //Get the cluster number of cells and list of absId, check what kind of cluster do we have.
1619 UShort_t * index = cluster->GetCellsAbsId() ;
1620 Double_t * fraction = cluster->GetCellsAmplitudeFraction() ;
1622 Int_t ncells = cluster->GetNCells();
1624 Int_t calo = kEMCAL;
1625 if(cluster->IsPHOS()) calo = kPHOS ;
1627 //Loop on the cells, get the cell amplitude and recalibration factor, multiply and and to the new energy
1628 for(Int_t icell = 0; icell < ncells; icell++)
1630 Int_t absId = index[icell];
1632 frac = fraction[icell];
1633 if(frac < 1e-3) frac = 1; //in case of EMCAL, this is set as 0, not used.
1635 Float_t amp = cells->GetCellAmplitude(absId);
1636 RecalibrateCellAmplitude(amp,calo, absId);
1638 amp*=GetMCECellClusFracCorrection(amp,energyOrg);
1640 AliDebug(2,Form("Recalibrate cell: calo <%d>, cell fraction %f, cell energy %f",
1641 calo,frac,cells->GetCellAmplitude(absId)));
1646 AliDebug(1,Form("Energy before %f, after %f",cluster->E(),energy));
1651 AliFatal("Cells pointer does not exist!");
1658 //__________________________________________________________________________________________
1659 void AliCalorimeterUtils::RecalculateClusterPosition(AliVCaloCells* cells, AliVCluster* clu)
1662 //Recalculate EMCAL cluster position
1664 fEMCALRecoUtils->RecalculateClusterPosition((AliEMCALGeometry*)fEMCALGeo, cells,clu);
1668 //________________________________________________________________________________
1669 void AliCalorimeterUtils::RecalculateClusterTrackMatching(AliVEvent * event,
1670 TObjArray* clusterArray)
1672 //Recalculate track matching
1674 if (fRecalculateMatching)
1676 fEMCALRecoUtils->FindMatches(event,clusterArray,fEMCALGeo) ;
1677 //AliESDEvent* esdevent = dynamic_cast<AliESDEvent*> (event);
1679 // fEMCALRecoUtils->SetClusterMatchedToTrack(esdevent) ;
1680 // fEMCALRecoUtils->SetTracksMatchedToCluster(esdevent) ;
1685 //___________________________________________________________________________
1686 void AliCalorimeterUtils::SplitEnergy(Int_t absId1, Int_t absId2,
1687 AliVCluster* cluster,
1688 AliVCaloCells* cells,
1689 //Float_t & e1, Float_t & e2,
1690 AliAODCaloCluster* cluster1,
1691 AliAODCaloCluster* cluster2,
1692 Int_t nMax, Int_t eventNumber)
1695 // Split energy of cluster between the 2 local maxima, sum energy on 3x3, and if the 2
1696 // maxima are too close and have common cells, split the energy between the 2
1698 TH2F* hClusterMap = 0 ;
1699 TH2F* hClusterLocMax = 0 ;
1700 TH2F* hCluster1 = 0 ;
1701 TH2F* hCluster2 = 0 ;
1705 hClusterMap = new TH2F("hClusterMap","Cluster Map",48,0,48,24,0,24);
1706 hClusterLocMax = new TH2F("hClusterLocMax","Cluster 2 highest local maxima",48,0,48,24,0,24);
1707 hCluster1 = new TH2F("hCluster1","Cluster 1",48,0,48,24,0,24);
1708 hCluster2 = new TH2F("hCluster2","Cluster 2",48,0,48,24,0,24);
1709 hClusterMap ->SetXTitle("column");
1710 hClusterMap ->SetYTitle("row");
1711 hClusterLocMax ->SetXTitle("column");
1712 hClusterLocMax ->SetYTitle("row");
1713 hCluster1 ->SetXTitle("column");
1714 hCluster1 ->SetYTitle("row");
1715 hCluster2 ->SetXTitle("column");
1716 hCluster2 ->SetYTitle("row");
1719 Int_t calorimeter = kEMCAL;
1720 if(cluster->IsPHOS())
1723 AliWarning("Not supported for PHOS yet");
1727 const Int_t ncells = cluster->GetNCells();
1728 Int_t absIdList[ncells];
1730 Float_t e1 = 0, e2 = 0 ;
1731 Int_t icol = -1, irow = -1, iRCU = -1, sm = -1;
1732 Float_t eCluster = 0;
1733 Float_t minCol = 100, minRow = 100, maxCol = -1, maxRow = -1;
1734 for(Int_t iDigit = 0; iDigit < ncells; iDigit++ )
1736 absIdList[iDigit] = cluster->GetCellsAbsId()[iDigit];
1738 Float_t ec = cells->GetCellAmplitude(absIdList[iDigit]);
1739 RecalibrateCellAmplitude(ec,calorimeter, absIdList[iDigit]);
1744 //printf("iDigit %d, absId %d, Ecell %f\n",iDigit,absIdList[iDigit], cells->GetCellAmplitude(absIdList[iDigit]));
1745 sm = GetModuleNumberCellIndexes(absIdList[iDigit], calorimeter, icol, irow, iRCU) ;
1746 if(sm > -1 && sm < 12) // just to avoid compilation warning
1748 if(icol > maxCol) maxCol = icol;
1749 if(icol < minCol) minCol = icol;
1750 if(irow > maxRow) maxRow = irow;
1751 if(irow < minRow) minRow = irow;
1752 hClusterMap->Fill(icol,irow,ec);
1758 // Init counters and variables
1760 UShort_t absIdList1[9] ;
1761 Double_t fracList1 [9] ;
1762 absIdList1[0] = absId1 ;
1763 fracList1 [0] = 1. ;
1765 Float_t ecell1 = cells->GetCellAmplitude(absId1);
1766 RecalibrateCellAmplitude(ecell1, calorimeter, absId1);
1770 UShort_t absIdList2[9] ;
1771 Double_t fracList2 [9] ;
1772 absIdList2[0] = absId2 ;
1773 fracList2 [0] = 1. ;
1775 Float_t ecell2 = cells->GetCellAmplitude(absId2);
1776 RecalibrateCellAmplitude(ecell2, calorimeter, absId2);
1781 Int_t icol1 = -1, irow1 = -1, icol2 = -1, irow2 = -1;
1782 sm = GetModuleNumberCellIndexes(absId1, calorimeter, icol1, irow1, iRCU) ;
1783 hClusterLocMax->Fill(icol1,irow1,ecell1);
1784 sm = GetModuleNumberCellIndexes(absId2, calorimeter, icol2, irow2, iRCU) ;
1785 hClusterLocMax->Fill(icol2,irow2,ecell2);
1788 // Very rough way to share the cluster energy
1789 Float_t eRemain = (eCluster-ecell1-ecell2)/2;
1790 Float_t shareFraction1 = ecell1/eCluster+eRemain/eCluster;
1791 Float_t shareFraction2 = ecell2/eCluster+eRemain/eCluster;
1793 for(Int_t iDigit = 0; iDigit < ncells; iDigit++)
1795 Int_t absId = absIdList[iDigit];
1797 if(absId==absId1 || absId==absId2 || absId < 0) continue;
1799 Float_t ecell = cells->GetCellAmplitude(absId);
1800 RecalibrateCellAmplitude(ecell, calorimeter, absId);
1802 if(AreNeighbours(calorimeter, absId1,absId ))
1804 absIdList1[ncells1]= absId;
1806 if(AreNeighbours(calorimeter, absId2,absId ))
1808 fracList1[ncells1] = shareFraction1;
1809 e1 += ecell*shareFraction1;
1813 fracList1[ncells1] = 1.;
1819 } // neigbour to cell1
1821 if(AreNeighbours(calorimeter, absId2,absId ))
1823 absIdList2[ncells2]= absId;
1825 if(AreNeighbours(calorimeter, absId1,absId ))
1827 fracList2[ncells2] = shareFraction2;
1828 e2 += ecell*shareFraction2;
1832 fracList2[ncells2] = 1.;
1838 } // neigbour to cell2
1842 AliDebug(1,Form("N Local Max %d, Cluster energy = %f, Ecell1 = %f, Ecell2 = %f, Enew1 = %f, Enew2 = %f, Remain %f, \n ncells %d, ncells1 %d, ncells2 %d, f1 %f, f2 %f, sum f12 = %f",
1843 nMax, eCluster,ecell1,ecell2,e1,e2,eCluster-e1-e2,ncells,ncells1,ncells2,shareFraction1,shareFraction2,shareFraction1+shareFraction2));
1848 cluster1->SetNCells(ncells1);
1849 cluster2->SetNCells(ncells2);
1851 cluster1->SetCellsAbsId(absIdList1);
1852 cluster2->SetCellsAbsId(absIdList2);
1854 cluster1->SetCellsAmplitudeFraction(fracList1);
1855 cluster2->SetCellsAmplitudeFraction(fracList2);
1858 CorrectClusterEnergy(cluster1) ;
1859 CorrectClusterEnergy(cluster2) ;
1861 if(calorimeter==kEMCAL)
1863 GetEMCALRecoUtils()->RecalculateClusterPosition(GetEMCALGeometry(), cells, cluster1);
1864 GetEMCALRecoUtils()->RecalculateClusterPosition(GetEMCALGeometry(), cells, cluster2);
1869 //printf("Cells of cluster1: ");
1870 for(Int_t iDigit = 0; iDigit < ncells1; iDigit++ )
1872 //printf(" %d ",absIdList1[iDigit]);
1874 sm = GetModuleNumberCellIndexes(absIdList1[iDigit], calorimeter, icol, irow, iRCU) ;
1876 Float_t ecell = cells->GetCellAmplitude(absIdList1[iDigit]);
1877 RecalibrateCellAmplitude(ecell, calorimeter, absIdList1[iDigit]);
1879 if( AreNeighbours(calorimeter, absId2,absIdList1[iDigit]) && absId1!=absIdList1[iDigit])
1880 hCluster1->Fill(icol,irow,ecell*shareFraction1);
1882 hCluster1->Fill(icol,irow,ecell);
1886 //printf("Cells of cluster2: ");
1888 for(Int_t iDigit = 0; iDigit < ncells2; iDigit++ )
1890 //printf(" %d ",absIdList2[iDigit]);
1892 sm = GetModuleNumberCellIndexes(absIdList2[iDigit], calorimeter, icol, irow, iRCU) ;
1894 Float_t ecell = cells->GetCellAmplitude(absIdList2[iDigit]);
1895 RecalibrateCellAmplitude(ecell, calorimeter, absIdList2[iDigit]);
1897 if( AreNeighbours(calorimeter, absId1,absIdList2[iDigit]) && absId2!=absIdList2[iDigit])
1898 hCluster2->Fill(icol,irow,ecell*shareFraction2);
1900 hCluster2->Fill(icol,irow,ecell);
1905 gStyle->SetPadRightMargin(0.1);
1906 gStyle->SetPadLeftMargin(0.1);
1907 gStyle->SetOptStat(0);
1908 gStyle->SetOptFit(000000);
1910 if(maxCol-minCol > maxRow-minRow)
1912 maxRow+= maxCol-minCol;
1916 maxCol+= maxRow-minRow;
1919 TCanvas * c= new TCanvas("canvas", "canvas", 4000, 4000) ;
1925 hClusterMap ->SetAxisRange(minCol, maxCol,"X");
1926 hClusterMap ->SetAxisRange(minRow, maxRow,"Y");
1927 hClusterMap ->Draw("colz TEXT");
1932 hClusterLocMax ->SetAxisRange(minCol, maxCol,"X");
1933 hClusterLocMax ->SetAxisRange(minRow, maxRow,"Y");
1934 hClusterLocMax ->Draw("colz TEXT");
1939 hCluster1 ->SetAxisRange(minCol, maxCol,"X");
1940 hCluster1 ->SetAxisRange(minRow, maxRow,"Y");
1941 hCluster1 ->Draw("colz TEXT");
1946 hCluster2 ->SetAxisRange(minCol, maxCol,"X");
1947 hCluster2 ->SetAxisRange(minRow, maxRow,"Y");
1948 hCluster2 ->Draw("colz TEXT");
1950 if(eCluster > 6 )c->Print(Form("clusterFigures/Event%d_E%1.0f_nMax%d_NCell1_%d_NCell2_%d.eps",
1951 eventNumber,cluster->E(),nMax,ncells1,ncells2));
1955 delete hClusterLocMax;