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 "AliMixedEvent.h"
43 #include "AliAODCaloCluster.h"
44 #include "AliOADBContainer.h"
45 #include "AliAnalysisManager.h"
46 #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 printf("AliCalorimeterUtils::SetOADBParameters() - Get AODB parameters from EMCAL in %s for run %d, and <%s> \n",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 printf("AliCalorimeterUtils::SetOADBParameters() - Remove EMCAL bad cells \n");
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 printf("AliCalorimeterUtils::SetOADBParameters() - 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 printf("AliCalorimeterUtils::SetOADBParameters() - Recalibrate EMCAL \n");
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 printf("AliCalorimeterUtils::SetOADBParameters() - Do NOT recalibrate EMCAL, no params object array\n"); // array ok
206 }else printf("AliCalorimeterUtils::SetOADBParameters() - Do NOT recalibrate EMCAL, no params for pass\n"); // array pass ok
207 }else printf("AliCalorimeterUtils::SetOADBParameters() - Do NOT recalibrate EMCAL, no params for run\n"); // 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 printf("AliCalorimeterUtils::SetOADBParameters() - Recalibrate (Temperature) EMCAL \n");
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 printf("AliCalorimeterUtils::SetOADBParameters() - Do NOT recalibrate EMCAL with T variations, no params TH1 \n");
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 printf("AliCalorimeterUtils::SetOADBParameters() - Time Recalibrate EMCAL \n");
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 printf("AliCalorimeterUtils::SetOADBParameters() - Do NOT recalibrate time EMCAL, no params for pass\n"); // array pass ok
308 }else printf("AliCalorimeterUtils::SetOADBParameters() - Do NOT recalibrate time EMCAL, no params for run\n"); // run number array ok
310 } // Recalibration on
317 printf("AliCalorimeterUtils::SetOADBParameters() - Get AODB parameters from PHOS in %s for run %d, and <%s> \n",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 printf("AliCalorimeterUtils::SetOADBParameters() - Can not read PHOS bad map for run %d.\n",runnumber) ;
334 printf("AliCalorimeterUtils::SetOADBParameters() - Setting PHOS bad map with name %s \n",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 printf("AliCalorimeterUtils::AccessGeometry() - Load user defined EMCAL geometry matrices\n");
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
385 printf("AliCalorimeterUtils::AccessGeometry() - EMCAL matrices SM %d, %p\n",
386 mod,((TGeoHMatrix*) matEMCAL->At(mod)));
387 //((TGeoHMatrix*) matEMCAL->At(mod))->Print();
389 fEMCALMatrix[mod] = (TGeoHMatrix*) matEMCAL->At(mod) ;
392 if(fEMCALMatrix[mod])
395 fEMCALMatrix[mod]->Print();
397 fEMCALGeo->SetMisalMatrix(fEMCALMatrix[mod],mod) ;
401 fEMCALGeoMatrixSet = kTRUE;//At least one, so good
404 else if (!gGeoManager)
407 printf(" AliCalorimeterUtils::AccessGeometry() - Load EMCAL misalignment matrices. \n");
408 if(!strcmp(inputEvent->GetName(),"AliESDEvent"))
410 for(Int_t mod=0; mod < (fEMCALGeo->GetEMCGeometry())->GetNumberOfSuperModules(); mod++)
412 //printf("Load ESD matrix %d, %p\n",mod,((AliESDEvent*)inputEvent)->GetEMCALMatrix(mod));
413 if(((AliESDEvent*)inputEvent)->GetEMCALMatrix(mod))
415 fEMCALGeo->SetMisalMatrix(((AliESDEvent*)inputEvent)->GetEMCALMatrix(mod),mod) ;
417 }// loop over super modules
419 fEMCALGeoMatrixSet = kTRUE;//At least one, so good
425 printf("AliCalorimeterUtils::SetGeometryTransformationMatrices() - Setting of EMCAL transformation matrixes for AODs not implemented yet. \n Import geometry.root file\n");
427 }//Get matrix from data
430 fEMCALGeoMatrixSet = kTRUE;
432 }//EMCAL geo && no geoManager
434 //Get the PHOS transformation geometry matrices from ESD
435 if(!fPHOSGeoMatrixSet && fPHOSGeo)
437 if(fLoadPHOSMatrices)
439 printf("AliCalorimeterUtils::SetGeometryTransformationMatrices() - Load user defined PHOS geometry matrices\n");
442 AliOADBContainer geomContainer("phosGeo");
443 geomContainer.InitFromFile(Form("%s/PHOSGeometry.root",fOADBFilePathPHOS.Data()),"PHOSRotationMatrixes");
444 TObjArray *matPHOS = (TObjArray*)geomContainer.GetObject(139000,"PHOSRotationMatrixes");
446 for(Int_t mod = 0 ; mod < 5 ; mod++)
448 if (!fPHOSMatrix[mod]) // Get it from OADB
451 printf("AliCalorimeterUtils::SetGeometryTransformationMatrices() - PHOS matrices module %d, %p\n",
452 mod,((TGeoHMatrix*) matPHOS->At(mod)));
453 //((TGeoHMatrix*) matPHOS->At(mod))->Print();
455 fPHOSMatrix[mod] = (TGeoHMatrix*) matPHOS->At(mod) ;
458 // Set it, if it exists
462 fPHOSMatrix[mod]->Print();
464 fPHOSGeo->SetMisalMatrix(fPHOSMatrix[mod],mod) ;
468 fPHOSGeoMatrixSet = kTRUE;//At least one, so good
471 else if (!gGeoManager)
474 printf(" AliCalorimeterUtils::SetGeometryTransformationMatrices() - Load PHOS misalignment matrices. \n");
475 if(!strcmp(inputEvent->GetName(),"AliESDEvent"))
477 for(Int_t mod = 0; mod < 5; mod++)
479 if( ((AliESDEvent*)inputEvent)->GetPHOSMatrix(mod))
481 //printf("PHOS: mod %d, matrix %p\n",mod, ((AliESDEvent*)inputEvent)->GetPHOSMatrix(mod));
482 fPHOSGeo->SetMisalMatrix( ((AliESDEvent*)inputEvent)->GetPHOSMatrix(mod),mod) ;
484 }// loop over modules
485 fPHOSGeoMatrixSet = kTRUE; //At least one so good
490 printf("AliCalorimeterUtils::SetGeometryTransformationMatrices() - Setting of EMCAL transformation matrixes for AODs not implemented yet. \n Import geometry.root file\n");
492 }// get matrix from data
495 fPHOSGeoMatrixSet = kTRUE;
497 }//PHOS geo and geoManager was not set
501 //________________________________________________________________________________________
502 Bool_t AliCalorimeterUtils::AreNeighbours(TString calo, Int_t absId1, Int_t absId2 ) const
504 // Tells if (true) or not (false) two cells are neighbours
505 // A neighbour is defined as being two cells which share a side or corner
507 Bool_t areNeighbours = kFALSE ;
509 Int_t iRCU1 = -1, irow1 = -1, icol1 = -1;
510 Int_t iRCU2 = -1, irow2 = -1, icol2 = -1;
512 Int_t rowdiff = 0, coldiff = 0;
514 Int_t nSupMod1 = GetModuleNumberCellIndexes(absId1, calo, icol1, irow1, iRCU1);
515 Int_t nSupMod2 = GetModuleNumberCellIndexes(absId2, calo, icol2, irow2, iRCU2);
517 if(calo=="EMCAL" && nSupMod1!=nSupMod2)
519 // In case of a shared cluster, index of SM in C side, columns start at 48 and ends at 48*2-1
520 // C Side impair SM, nSupMod%2=1; A side pair SM nSupMod%2=0
521 if(nSupMod1%2) icol1+=AliEMCALGeoParams::fgkEMCALCols;
522 else icol2+=AliEMCALGeoParams::fgkEMCALCols;
525 rowdiff = TMath::Abs( irow1 - irow2 ) ;
526 coldiff = TMath::Abs( icol1 - icol2 ) ;
528 //if (( coldiff <= 1 ) && ( rowdiff <= 1 ) && (coldiff + rowdiff > 0))
529 if ((coldiff + rowdiff == 1 ))
530 areNeighbours = kTRUE ;
532 return areNeighbours;
535 //_____________________________________________________________________________________
536 Bool_t AliCalorimeterUtils::IsClusterSharedByTwoSuperModules(const AliEMCALGeometry * geom,
537 AliVCluster* cluster)
539 //Method that checks if any of the cells in the cluster belongs to a different SM
549 for(Int_t iDigit=0; iDigit < cluster->GetNCells(); iDigit++)
551 //Get from the absid the supermodule, tower and eta/phi numbers
552 geom->GetCellIndex(cluster->GetCellAbsId(iDigit),iSupMod,iTower,iIphi,iIeta);
553 geom->GetCellPhiEtaIndexInSModule(iSupMod,iTower,iIphi,iIeta, iphi,ieta);
555 //Check if there are cells of different SM
556 if (iDigit == 0 ) iSM0 = iSupMod;
557 else if(iSupMod!= iSM0) return kTRUE;
564 //_____________________________________________________________________________________
565 Bool_t AliCalorimeterUtils::CheckCellFiducialRegion(AliVCluster* cluster,
566 AliVCaloCells* cells,
567 AliVEvent * event, Int_t iev) const
570 // Given the list of AbsId of the cluster, get the maximum cell and
571 // check if there are fNCellsFromBorder from the calorimeter border
573 //If the distance to the border is 0 or negative just exit accept all clusters
574 if(cells->GetType()==AliVCaloCells::kEMCALCell && fEMCALRecoUtils->GetNumberOfCellsFromEMCALBorder() <= 0 ) return kTRUE;
575 if(cells->GetType()==AliVCaloCells::kPHOSCell && fNCellsFromPHOSBorder <= 0 ) return kTRUE;
580 AliMixedEvent * mixEvent = dynamic_cast<AliMixedEvent*> (event);
581 Int_t nMixedEvents = 0 ;
582 Int_t * cellsCumul = NULL ;
583 Int_t numberOfCells = 0 ;
585 nMixedEvents = mixEvent->GetNumberOfEvents() ;
586 if (cells->GetType()==AliVCaloCells::kEMCALCell) {
587 cellsCumul = mixEvent->GetEMCALCellsCumul() ;
588 numberOfCells = mixEvent->GetNumberOfEMCALCells() ;
591 else if (cells->GetType()==AliVCaloCells::kPHOSCell) {
592 cellsCumul = mixEvent->GetPHOSCellsCumul() ;
593 numberOfCells = mixEvent->GetNumberOfPHOSCells() ;
598 Int_t startCell = cellsCumul[iev] ;
599 Int_t endCell = (iev+1 < nMixedEvents)?cellsCumul[iev+1]:numberOfCells;
600 //Find cells with maximum amplitude
601 for(Int_t i = 0; i < cluster->GetNCells() ; i++){
602 Int_t absId = cluster->GetCellAbsId(i) ;
603 for (Int_t j = startCell; j < endCell ; j++) {
606 Double_t amp, time, efrac;
607 cells->GetCell(j, cellNumber, amp, time,mclabel,efrac) ;
608 if (absId == cellNumber) {
615 }//loop on cluster cells
616 }// cells cumul available
618 printf("AliCalorimeterUtils::CheckCellFiducialRegion() - CellsCumul is NULL!!!\n");
621 } else {//Normal SE Events
622 for(Int_t i = 0; i < cluster->GetNCells() ; i++){
623 Int_t absId = cluster->GetCellAbsId(i) ;
624 Float_t amp = cells->GetCellAmplitude(absId);
633 printf("AliCalorimeterUtils::CheckCellFiducialRegion() - Cluster Max AbsId %d, Cell Energy %2.2f, Cluster Energy %2.2f\n",
634 absIdMax, ampMax, cluster->E());
636 if(absIdMax==-1) return kFALSE;
638 //Check if the cell is close to the borders:
639 Bool_t okrow = kFALSE;
640 Bool_t okcol = kFALSE;
642 if(cells->GetType()==AliVCaloCells::kEMCALCell){
644 Int_t iTower = -1, iIphi = -1, iIeta = -1, iphi = -1, ieta = -1, iSM = -1;
645 fEMCALGeo->GetCellIndex(absIdMax,iSM,iTower,iIphi,iIeta);
646 fEMCALGeo->GetCellPhiEtaIndexInSModule(iSM,iTower,iIphi, iIeta,iphi,ieta);
647 if(iSM < 0 || iphi < 0 || ieta < 0 ) {
648 Fatal("CheckCellFidutialRegion","Negative value for super module: %d, or cell ieta: %d, or cell iphi: %d, check EMCAL geometry name\n",iSM,ieta,iphi);
652 Int_t nborder = fEMCALRecoUtils->GetNumberOfCellsFromEMCALBorder();
655 if(iphi >= nborder && iphi < 24-nborder) okrow =kTRUE;
659 if(fEMCALGeoName.Contains("12SM")) // 1/3 SM
661 if(iphi >= nborder && iphi < 8-nborder) okrow =kTRUE;
665 if(iphi >= nborder && iphi <12-nborder) okrow =kTRUE;
670 if(!fEMCALRecoUtils->IsEMCALNoBorderAtEta0())
672 if(ieta > nborder && ieta < 48-nborder) okcol =kTRUE;
678 if(ieta >= nborder) okcol = kTRUE;
682 if(ieta < 48-nborder) okcol = kTRUE;
688 printf("AliCalorimeterUtils::CheckCellFiducialRegion() - EMCAL Cluster in %d cells fiducial volume: ieta %d, iphi %d, SM %d ?",
689 nborder, ieta, iphi, iSM);
690 if (okcol && okrow ) printf(" YES \n");
691 else printf(" NO: column ok? %d, row ok? %d \n",okcol,okrow);
694 else if(cells->GetType()==AliVCaloCells::kPHOSCell){
696 Int_t irow = -1, icol = -1;
697 fPHOSGeo->AbsToRelNumbering(absIdMax,relId);
701 if(irow >= fNCellsFromPHOSBorder && irow < 64-fNCellsFromPHOSBorder) okrow =kTRUE;
702 if(icol >= fNCellsFromPHOSBorder && icol < 56-fNCellsFromPHOSBorder) okcol =kTRUE;
705 printf("AliCalorimeterUtils::CheckCellFiducialRegion() - PHOS Cluster in %d cells fiducial volume: icol %d, irow %d, Module %d?",
706 fNCellsFromPHOSBorder, icol, irow, relId[0]-1);
707 if (okcol && okrow ) printf(" YES \n");
708 else printf(" NO: column ok? %d, row ok? %d \n",okcol,okrow);
712 if (okcol && okrow) return kTRUE;
717 //__________________________________________________________________________________________________________
718 Bool_t AliCalorimeterUtils::ClusterContainsBadChannel(TString calorimeter, UShort_t* cellList, Int_t nCells)
720 // Check that in the cluster cells, there is no bad channel of those stored
721 // in fEMCALBadChannelMap or fPHOSBadChannelMap
723 if (!fRemoveBadChannels) return kFALSE;
724 //printf("fEMCALBadChannelMap %p, fPHOSBadChannelMap %p \n",fEMCALBadChannelMap,fPHOSBadChannelMap);
725 if(calorimeter == "EMCAL" && !fEMCALRecoUtils->GetEMCALChannelStatusMap(0)) return kFALSE;
726 if(calorimeter == "PHOS" && !fPHOSBadChannelMap) return kFALSE;
731 for(Int_t iCell = 0; iCell<nCells; iCell++){
733 //Get the column and row
734 if(calorimeter == "EMCAL"){
735 return fEMCALRecoUtils->ClusterContainsBadChannel((AliEMCALGeometry*)fEMCALGeo,cellList,nCells);
737 else if(calorimeter=="PHOS"){
739 fPHOSGeo->AbsToRelNumbering(cellList[iCell],relId);
743 if(fPHOSBadChannelMap->GetEntries() <= imod)continue;
744 //printf("PHOS bad channels imod %d, icol %d, irow %d\n",imod, irow, icol);
745 if(GetPHOSChannelStatus(imod, irow, icol)) return kTRUE;
749 }// cell cluster loop
755 //_______________________________________________________________
756 void AliCalorimeterUtils::CorrectClusterEnergy(AliVCluster *clus)
758 // Correct cluster energy non linearity
760 clus->SetE(fEMCALRecoUtils->CorrectClusterEnergyLinearity(clus));
764 //________________________________________________________________________________________
765 Int_t AliCalorimeterUtils::GetMaxEnergyCell(AliVCaloCells* cells, const AliVCluster* clu,
766 Float_t & clusterFraction) const
769 //For a given CaloCluster gets the absId of the cell
770 //with maximum energy deposit.
772 if( !clu || !cells ){
773 AliInfo("Cluster or cells pointer is null!");
780 Float_t fraction = 1.;
781 Float_t recalFactor = 1.;
782 Int_t cellAbsId =-1 , absId =-1 ;
783 Int_t iSupMod =-1 , ieta =-1 , iphi = -1, iRCU = -1;
785 TString calo = "EMCAL";
786 if(clu->IsPHOS()) calo = "PHOS";
788 for (Int_t iDig=0; iDig< clu->GetNCells(); iDig++) {
790 cellAbsId = clu->GetCellAbsId(iDig);
792 fraction = clu->GetCellAmplitudeFraction(iDig);
793 if(fraction < 1e-4) fraction = 1.; // in case unfolding is off
795 iSupMod = GetModuleNumberCellIndexes(cellAbsId, calo, ieta, iphi, iRCU);
797 if(IsRecalibrationOn()) {
798 if(calo=="EMCAL") recalFactor = GetEMCALChannelRecalibrationFactor(iSupMod,ieta,iphi);
799 else recalFactor = GetPHOSChannelRecalibrationFactor (iSupMod,iphi,ieta);
802 eCell = cells->GetCellAmplitude(cellAbsId)*fraction*recalFactor;
814 clusterFraction = (eTot-eMax)/eTot; //Do not use cluster energy in case it was corrected for non linearity.
822 //___________________________________________________________________________________
823 AliVTrack * AliCalorimeterUtils::GetMatchedTrack(AliVCluster* cluster,
824 AliVEvent* event, Int_t index) const
826 // Get the matched track given its index, usually just the first match
827 // Since it is different for ESDs and AODs here it is a wrap method to do it
829 AliVTrack *track = 0;
831 // EMCAL case only when matching is recalculated
832 if(cluster->IsEMCAL() && IsRecalculationOfClusterTrackMatchingOn())
834 Int_t trackIndex = fEMCALRecoUtils->GetMatchedTrackIndex(cluster->GetID());
835 //printf("track index %d, cluster ID %d \n ",trackIndex,cluster->GetID());
839 printf("AliCalorimeterUtils::GetMatchedTrack() - Wrong track index %d, from recalculation\n", trackIndex);
843 track = dynamic_cast<AliVTrack*> (event->GetTrack(trackIndex));
850 // Normal case, get info from ESD or AOD
852 if(!strcmp("AliESDCaloCluster",Form("%s",cluster->ClassName())))
854 Int_t iESDtrack = cluster->GetTrackMatchedIndex();
858 printf("AliCalorimeterUtils::GetMatchedTrack() - Wrong track index %d\n", index);
862 track = dynamic_cast<AliVTrack*> (event->GetTrack(iESDtrack));
867 if(cluster->GetNTracksMatched() > 0 )
868 track = dynamic_cast<AliVTrack*>(cluster->GetTrackMatched(index));
874 //______________________________________________________________________________________________
875 Float_t AliCalorimeterUtils::GetMCECellClusFracCorrection(Float_t eCell, Float_t eCluster) const
877 // Correction factor for cell energy in cluster to temptatively match Data and MC
878 if( eCluster <= 0 || eCluster < eCell )
880 printf("AliCalorimeterUtils::GetMCECellClusFracCorrection() - Bad values eCell=%f, eCluster %f\n",eCell,eCluster);
884 Float_t frac = eCell / eCluster;
886 Float_t correction = fMCECellClusFracCorrParam[0] +
887 TMath::Exp( frac*fMCECellClusFracCorrParam[2]+fMCECellClusFracCorrParam[1] ) +
888 fMCECellClusFracCorrParam[3]/TMath::Sqrt(frac);
890 // printf("AliCalorimeterUtils::GetMCECellClusFracCorrection(eCell=%f, eCluster %f, frac %f) = %f\n",eCell, eCluster, frac, correction);
891 // printf("\t %2.2f + TMath::Exp( %2.3f*%2.2f + %2.2f ) + %2.2f/TMath::Sqrt(%2.3f)) = %f\n",
892 // fMCECellClusFracCorrParam[0],frac,fMCECellClusFracCorrParam[2],fMCECellClusFracCorrParam[1],fMCECellClusFracCorrParam[3], frac, correction);
897 //_____________________________________________________________________________________________________
898 Int_t AliCalorimeterUtils::GetModuleNumber(AliAODPWG4Particle * particle, AliVEvent * inputEvent) const
900 //Get the EMCAL/PHOS module number that corresponds to this particle
903 if(particle->GetDetector()=="EMCAL")
905 fEMCALGeo->GetAbsCellIdFromEtaPhi(particle->Eta(),particle->Phi(), absId);
908 printf("AliCalorimeterUtils::GetModuleNumber(PWG4AOD) - EMCAL: cluster eta %f, phi %f, absid %d, SuperModule %d\n",
909 particle->Eta(), particle->Phi()*TMath::RadToDeg(),absId, fEMCALGeo->GetSuperModuleNumber(absId));
911 return fEMCALGeo->GetSuperModuleNumber(absId) ;
913 else if(particle->GetDetector()=="PHOS")
915 // In case we use the MC reader, the input are TParticles,
916 // in this case use the corresponing method in PHOS Geometry to get the particle.
917 if(strcmp(inputEvent->ClassName(), "AliMCEvent") == 0 )
920 Double_t z = 0., x=0.;
921 TParticle* primary = 0x0;
922 AliStack * stack = ((AliMCEvent*)inputEvent)->Stack();
925 primary = stack->Particle(particle->GetCaloLabel(0));
929 Fatal("GetModuleNumber(PWG4AOD)", "Stack not available, stop!");
934 fPHOSGeo->ImpactOnEmc(primary,mod,z,x) ;
938 Fatal("GetModuleNumber(PWG4AOD)", "Primary not available, stop!");
942 // Input are ESDs or AODs, get the PHOS module number like this.
946 //AliVCluster *cluster = inputEvent->GetCaloCluster(particle->GetCaloLabel(0));
947 //return GetModuleNumber(cluster);
956 //_____________________________________________________________________
957 Int_t AliCalorimeterUtils::GetModuleNumber(AliVCluster * cluster) const
959 //Get the EMCAL/PHOS module number that corresponds to this cluster
963 if(fDebug > 1) printf("AliCalorimeterUtils::GetModuleNumber() - NUL Cluster, please check!!!");
968 if ( cluster->GetNCells() <= 0 ) return -1;
970 Int_t absId = cluster->GetCellAbsId(0);
972 if ( absId < 0 ) return -1;
974 if( cluster->IsEMCAL() )
976 if(fDebug > 2) printf("AliCalorimeterUtils::GetModuleNumber() - EMCAL absid %d, SuperModule %d\n",absId, fEMCALGeo->GetSuperModuleNumber(absId));
978 return fEMCALGeo->GetSuperModuleNumber(absId) ;
980 else if ( cluster->IsPHOS() )
983 fPHOSGeo->AbsToRelNumbering(absId,relId);
985 if(fDebug > 2) printf("AliCalorimeterUtils::GetModuleNumber() - PHOS absid %d Module %d\n",absId, relId[0]-1);
993 //___________________________________________________________________________________________________
994 Int_t AliCalorimeterUtils::GetModuleNumberCellIndexes(Int_t absId, TString calo,
995 Int_t & icol, Int_t & irow, Int_t & iRCU) const
997 //Get the EMCAL/PHOS module, columns, row and RCU number that corresponds to this absId
1001 if ( absId < 0) return -1 ;
1003 if ( calo == "EMCAL" )
1005 Int_t iTower = -1, iIphi = -1, iIeta = -1;
1006 fEMCALGeo->GetCellIndex(absId,imod,iTower,iIphi,iIeta);
1007 fEMCALGeo->GetCellPhiEtaIndexInSModule(imod,iTower,iIphi, iIeta,irow,icol);
1009 if(imod < 0 || irow < 0 || icol < 0 )
1011 Fatal("GetModuleNumberCellIndexes()","Negative value for super module: %d, or cell icol: %d, or cell irow: %d, check EMCAL geometry name\n",imod,icol,irow);
1017 if (0<=irow&&irow<8) iRCU=0; // first cable row
1018 else if (8<=irow&&irow<16 && 0<=icol&&icol<24) iRCU=0; // first half;
1021 else if (8<=irow&&irow<16 && 24<=icol&&icol<48) iRCU=1; // second half;
1023 else if (16<=irow&&irow<24) iRCU=1; // third cable row
1025 if (imod%2==1) iRCU = 1 - iRCU; // swap for odd=C side, to allow us to cable both sides the same
1029 // Last 2 SM have one single SRU, just assign RCU 0
1035 Fatal("GetModuleNumberCellIndexes()","Wrong EMCAL RCU number = %d\n", iRCU);
1044 fPHOSGeo->AbsToRelNumbering(absId,relId);
1048 iRCU= (Int_t)(relId[2]-1)/16 ;
1049 //Int_t iBranch= (Int_t)(relid[3]-1)/28 ; //0 to 1
1052 Fatal("GetModuleNumberCellIndexes()","Wrong PHOS RCU number = %d\n", iRCU);
1060 //___________________________________________________________________________________________
1061 Int_t AliCalorimeterUtils::GetNumberOfLocalMaxima(AliVCluster* cluster, AliVCaloCells* cells)
1063 // Find local maxima in cluster
1065 const Int_t nc = cluster->GetNCells();
1066 Int_t absIdList[nc];
1067 Float_t maxEList[nc];
1069 Int_t nMax = GetNumberOfLocalMaxima(cluster, cells, absIdList, maxEList);
1075 //___________________________________________________________________________________________
1076 Int_t AliCalorimeterUtils::GetNumberOfLocalMaxima(AliVCluster* cluster, AliVCaloCells* cells,
1077 Int_t *absIdList, Float_t *maxEList)
1079 // Find local maxima in cluster
1085 const Int_t nCells = cluster->GetNCells();
1087 Float_t eCluster = RecalibrateClusterEnergy(cluster, cells);// recalculate cluster energy, avoid non lin correction.
1089 Float_t simuTotWeight = 0;
1090 if(fMCECellClusFracCorrOn)
1092 simuTotWeight = RecalibrateClusterEnergyWeightCell(cluster, cells,eCluster);// same but apply a weight
1093 simuTotWeight/= eCluster;
1096 TString calorimeter = "EMCAL";
1097 if(!cluster->IsEMCAL()) calorimeter = "PHOS";
1099 //printf("cluster : ncells %d \n",nCells);
1103 for(iDigit = 0; iDigit < nCells ; iDigit++)
1105 absIdList[iDigit] = cluster->GetCellsAbsId()[iDigit] ;
1106 Float_t en = cells->GetCellAmplitude(absIdList[iDigit]);
1107 RecalibrateCellAmplitude(en,calorimeter,absIdList[iDigit]);
1109 if(fMCECellClusFracCorrOn)
1110 en*=GetMCECellClusFracCorrection(en,eCluster)/simuTotWeight;
1115 idmax = absIdList[iDigit] ;
1117 //Int_t icol = -1, irow = -1, iRCU = -1;
1118 //Int_t sm = GetModuleNumberCellIndexes(absIdList[iDigit], calorimeter, icol, irow, iRCU) ;
1119 //printf("\t cell %d, id %d, sm %d, col %d, row %d, e %f\n", iDigit, absIdList[iDigit], sm, icol, irow, en );
1122 for(iDigit = 0 ; iDigit < nCells; iDigit++)
1124 if(absIdList[iDigit]>=0)
1126 absId1 = cluster->GetCellsAbsId()[iDigit];
1128 Float_t en1 = cells->GetCellAmplitude(absId1);
1129 RecalibrateCellAmplitude(en1,calorimeter,absId1);
1131 if(fMCECellClusFracCorrOn)
1132 en1*=GetMCECellClusFracCorrection(en1,eCluster)/simuTotWeight;
1134 //printf("%d : absIDi %d, E %f\n",iDigit, absId1,en1);
1136 for(iDigitN = 0; iDigitN < nCells; iDigitN++)
1138 absId2 = cluster->GetCellsAbsId()[iDigitN] ;
1140 if(absId2==-1 || absId2==absId1) continue;
1142 //printf("\t %d : absIDj %d\n",iDigitN, absId2);
1144 Float_t en2 = cells->GetCellAmplitude(absId2);
1145 RecalibrateCellAmplitude(en2,calorimeter,absId2);
1147 if(fMCECellClusFracCorrOn)
1148 en2*=GetMCECellClusFracCorrection(en2,eCluster)/simuTotWeight;
1150 //printf("\t %d : absIDj %d, E %f\n",iDigitN, absId2,en2);
1152 if ( AreNeighbours(calorimeter, absId1, absId2) )
1154 // printf("\t \t Neighbours \n");
1157 absIdList[iDigitN] = -1 ;
1158 //printf("\t \t indexN %d not local max\n",iDigitN);
1159 // but may be digit too is not local max ?
1160 if(en1 < en2 + fLocMaxCutEDiff) {
1161 //printf("\t \t index %d not local max cause locMaxCutEDiff\n",iDigit);
1162 absIdList[iDigit] = -1 ;
1167 absIdList[iDigit] = -1 ;
1168 //printf("\t \t index %d not local max\n",iDigitN);
1169 // but may be digitN too is not local max ?
1170 if(en1 > en2 - fLocMaxCutEDiff)
1172 absIdList[iDigitN] = -1 ;
1173 //printf("\t \t indexN %d not local max cause locMaxCutEDiff\n",iDigit);
1176 } // if Are neighbours
1177 //else printf("\t \t NOT Neighbours \n");
1183 for(iDigit = 0; iDigit < nCells; iDigit++)
1185 if(absIdList[iDigit]>=0 )
1187 absIdList[iDigitN] = absIdList[iDigit] ;
1189 Float_t en = cells->GetCellAmplitude(absIdList[iDigit]);
1190 RecalibrateCellAmplitude(en,calorimeter,absIdList[iDigit]);
1192 if(fMCECellClusFracCorrOn)
1193 en*=GetMCECellClusFracCorrection(en,eCluster)/simuTotWeight;
1195 if(en < fLocMaxCutE) continue; // Maxima only with seed energy at least
1197 maxEList[iDigitN] = en ;
1199 //printf("Local max %d, id %d, en %f\n", iDigit,absIdList[iDigitN],en);
1207 printf("AliCalorimeterUtils::GetNumberOfLocalMaxima() - No local maxima found, assign highest energy cell as maxima, id %d, en cell %2.2f, en cluster %2.2f\n",
1208 idmax,emax,cluster->E());
1210 maxEList[0] = emax ;
1211 absIdList[0] = idmax ;
1216 printf("AliCalorimeterUtils::GetNumberOfLocalMaxima() - In cluster E %2.2f (wth non lin. %2.2f), M02 %2.2f, M20 %2.2f, N maxima %d \n",
1217 cluster->E(),eCluster, cluster->GetM02(),cluster->GetM20(), iDigitN);
1219 if(fDebug > 1) for(Int_t imax = 0; imax < iDigitN; imax++)
1221 printf(" \t i %d, absId %d, Ecell %f\n",imax,absIdList[imax],maxEList[imax]);
1229 //____________________________________
1230 TString AliCalorimeterUtils::GetPass()
1232 // Get passx from filename.
1234 if (!AliAnalysisManager::GetAnalysisManager()->GetTree())
1236 AliError("AliCalorimeterUtils::GetPass() - Pointer to tree = 0, returning null\n");
1240 if (!AliAnalysisManager::GetAnalysisManager()->GetTree()->GetCurrentFile())
1242 AliError("AliCalorimeterUtils::GetPass() - Null pointer input file, returning null\n");
1246 TString pass(AliAnalysisManager::GetAnalysisManager()->GetTree()->GetCurrentFile()->GetName());
1247 if (pass.Contains("ass1")) return TString("pass1");
1248 else if (pass.Contains("ass2")) return TString("pass2");
1249 else if (pass.Contains("ass3")) return TString("pass3");
1250 else if (pass.Contains("ass4")) return TString("pass4");
1251 else if (pass.Contains("ass5")) return TString("pass5");
1252 else if (pass.Contains("LHC11c") && pass.Contains("spc_calo") ) return TString("spc_calo");
1253 else if (pass.Contains("calo") || pass.Contains("high_lumi"))
1255 printf("AliCalorimeterUtils::GetPass() - Path contains <calo> or <high-lumi>, set as <pass1>\n");
1256 return TString("pass1");
1259 // No condition fullfilled, give a default value
1260 printf("AliCalorimeterUtils::GetPass() - Pass number string not found \n");
1265 //________________________________________
1266 void AliCalorimeterUtils::InitParameters()
1268 //Initialize the parameters of the analysis.
1273 fEMCALGeoMatrixSet = kFALSE;
1274 fPHOSGeoMatrixSet = kFALSE;
1276 fRemoveBadChannels = kFALSE;
1278 fNCellsFromPHOSBorder = 0;
1281 fLocMaxCutEDiff = 0.0 ;
1283 // fMaskCellColumns = new Int_t[fNMaskCellColumns];
1284 // fMaskCellColumns[0] = 6 ; fMaskCellColumns[1] = 7 ; fMaskCellColumns[2] = 8 ;
1285 // fMaskCellColumns[3] = 35; fMaskCellColumns[4] = 36; fMaskCellColumns[5] = 37;
1286 // fMaskCellColumns[6] = 12+AliEMCALGeoParams::fgkEMCALCols; fMaskCellColumns[7] = 13+AliEMCALGeoParams::fgkEMCALCols;
1287 // fMaskCellColumns[8] = 40+AliEMCALGeoParams::fgkEMCALCols; fMaskCellColumns[9] = 41+AliEMCALGeoParams::fgkEMCALCols;
1288 // fMaskCellColumns[10]= 42+AliEMCALGeoParams::fgkEMCALCols;
1291 fOADBForEMCAL = kTRUE ;
1292 fOADBForPHOS = kFALSE;
1294 fOADBFilePathEMCAL = "$ALICE_ROOT/OADB/EMCAL" ;
1295 fOADBFilePathPHOS = "$ALICE_ROOT/OADB/PHOS" ;
1297 fImportGeometryFromFile = kTRUE;
1298 fImportGeometryFilePath = "";
1300 fNSuperModulesUsed = 22;
1302 fMCECellClusFracCorrParam[0] = 0.78;
1303 fMCECellClusFracCorrParam[1] =-1.8;
1304 fMCECellClusFracCorrParam[2] =-6.3;
1305 fMCECellClusFracCorrParam[3] = 0.014;
1310 //_____________________________________________________
1311 void AliCalorimeterUtils::InitPHOSBadChannelStatusMap()
1313 //Init PHOS bad channels map
1314 if(fDebug > 0 )printf("AliCalorimeterUtils::InitPHOSBadChannelStatusMap()\n");
1315 //In order to avoid rewriting the same histograms
1316 Bool_t oldStatus = TH1::AddDirectoryStatus();
1317 TH1::AddDirectory(kFALSE);
1319 fPHOSBadChannelMap = new TObjArray(5);
1320 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));
1322 fPHOSBadChannelMap->SetOwner(kTRUE);
1323 fPHOSBadChannelMap->Compress();
1325 //In order to avoid rewriting the same histograms
1326 TH1::AddDirectory(oldStatus);
1329 //______________________________________________________
1330 void AliCalorimeterUtils::InitPHOSRecalibrationFactors()
1332 //Init EMCAL recalibration factors
1333 if(fDebug > 0 )printf("AliCalorimeterUtils::InitPHOSRecalibrationFactors()\n");
1334 //In order to avoid rewriting the same histograms
1335 Bool_t oldStatus = TH1::AddDirectoryStatus();
1336 TH1::AddDirectory(kFALSE);
1338 fPHOSRecalibrationFactors = new TObjArray(5);
1339 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));
1340 //Init the histograms with 1
1341 for (Int_t m = 0; m < 5; m++) {
1342 for (Int_t i = 0; i < 56; i++) {
1343 for (Int_t j = 0; j < 64; j++) {
1344 SetPHOSChannelRecalibrationFactor(m,j,i,1.);
1348 fPHOSRecalibrationFactors->SetOwner(kTRUE);
1349 fPHOSRecalibrationFactors->Compress();
1351 //In order to avoid rewriting the same histograms
1352 TH1::AddDirectory(oldStatus);
1356 //__________________________________________________________
1357 void AliCalorimeterUtils::InitEMCALGeometry(Int_t runnumber)
1359 //Initialize EMCAL geometry if it did not exist previously
1363 if(fEMCALGeoName=="")
1365 if (runnumber < 140000 &&
1366 runnumber >= 100000) fEMCALGeoName = "EMCAL_FIRSTYEARV1";
1367 else if(runnumber >= 140000 &&
1368 runnumber < 171000) fEMCALGeoName = "EMCAL_COMPLETEV1";
1369 else fEMCALGeoName = "EMCAL_COMPLETE12SMV1";
1370 printf("AliCalorimeterUtils::InitEMCALGeometry() - Set EMCAL geometry name to <%s> for run %d\n",fEMCALGeoName.Data(),runnumber);
1373 fEMCALGeo = AliEMCALGeometry::GetInstance(fEMCALGeoName);
1375 // Init geometry, I do not like much to do it like this ...
1376 if(fImportGeometryFromFile && !gGeoManager)
1378 if(fImportGeometryFilePath=="") // If not specified, set location depending on run number
1380 // "$ALICE_ROOT/EVE/alice-data/default_geo.root"
1381 if (runnumber < 140000 &&
1382 runnumber >= 100000) fImportGeometryFilePath = "$ALICE_ROOT/OADB/EMCAL/geometry_2010.root";
1383 if (runnumber >= 140000 &&
1384 runnumber < 171000) fImportGeometryFilePath = "$ALICE_ROOT/OADB/EMCAL/geometry_2011.root";
1385 else fImportGeometryFilePath = "$ALICE_ROOT/OADB/EMCAL/geometry_2012.root"; // 2012-2013
1388 printf("AliCalorimeterUtils::InitEMCALGeometry() - Import %s\n",fImportGeometryFilePath.Data());
1389 TGeoManager::Import(fImportGeometryFilePath) ; // default need file "geometry.root" in local dir!!!!
1395 printf("AliCalorimeterUtils::InitEMCALGeometry(run=%d)",runnumber);
1396 if (!gGeoManager) printf(" - Careful!, gGeoManager not loaded, load misalign matrices");
1402 //_________________________________________________________
1403 void AliCalorimeterUtils::InitPHOSGeometry(Int_t runnumber)
1405 //Initialize PHOS geometry if it did not exist previously
1409 if(fPHOSGeoName=="") fPHOSGeoName = "PHOSgeo";
1411 fPHOSGeo = new AliPHOSGeoUtils(fPHOSGeoName);
1415 printf("AliCalorimeterUtils::InitPHOSGeometry(run=%d)",runnumber);
1416 if (!gGeoManager) printf(" - Careful!, gGeoManager not loaded, load misalign matrices");
1422 //_______________________________________________________________________________________________
1423 Bool_t AliCalorimeterUtils::IsMCParticleInCalorimeterAcceptance(TString calo, TParticle* particle)
1425 // Check that a MC ESD is in the calorimeter acceptance
1427 if( (!IsPHOSGeoMatrixSet() && calo == "PHOS" ) ||
1428 (!IsPHOSGeoMatrixSet() && calo == "EMCAL") )
1430 AliFatal(Form("Careful Geo Matrix for %s is not set, use AliFidutialCut instead \n",calo.Data()));
1437 Double_t x = 0, z = 0 ;
1439 return GetPHOSGeometry()->ImpactOnEmc( particle, mod, z, x);
1441 else if(calo == "EMCAL")
1445 GetEMCALGeometry()->GetAbsCellIdFromEtaPhi( particle->Eta(), particle->Phi(), absID);
1447 if( absID >= 0) return kTRUE ;
1448 else return kFALSE ;
1454 //______________________________________________________________________________________________________
1455 Bool_t AliCalorimeterUtils::IsMCParticleInCalorimeterAcceptance(TString calo, AliAODMCParticle* particle)
1457 // Check that a MC AOD is in the calorimeter acceptance
1459 if( (!IsPHOSGeoMatrixSet() && calo == "PHOS" ) ||
1460 (!IsPHOSGeoMatrixSet() && calo == "EMCAL") )
1462 AliFatal(Form("Careful Geo Matrix for %s is not set, use AliFidutialCut instead \n",calo.Data()));
1469 Double_t x = 0, z = 0 ;
1471 Double_t vtx[]={ particle->Xv(), particle->Yv(), particle->Zv() } ;
1473 return GetPHOSGeometry()->ImpactOnEmc(vtx, particle->Theta(), particle->Phi(), mod, z, x) ;
1475 else if(calo == "EMCAL")
1479 GetEMCALGeometry()->GetAbsCellIdFromEtaPhi(particle->Eta(),particle->Phi(),absID);
1481 if( absID >= 0) return kTRUE ;
1482 else return kFALSE ;
1488 //_______________________________________________________________________
1489 Bool_t AliCalorimeterUtils::MaskFrameCluster(Int_t iSM, Int_t ieta) const
1491 //Check if cell is in one of the regions where we have significant amount
1492 //of material in front. Only EMCAL
1495 if(iSM%2) icol+=48; // Impair SM, shift index [0-47] to [48-96]
1497 if (fNMaskCellColumns && fMaskCellColumns)
1499 for (Int_t imask = 0; imask < fNMaskCellColumns; imask++)
1501 if(icol==fMaskCellColumns[imask]) return kTRUE;
1509 //_________________________________________________________
1510 void AliCalorimeterUtils::Print(const Option_t * opt) const
1513 //Print some relevant parameters set for the analysis
1517 printf("***** Print: %s %s ******\n", GetName(), GetTitle() ) ;
1518 printf("Remove Clusters with bad channels? %d\n",fRemoveBadChannels);
1519 printf("Remove Clusters with max cell at less than %d cells from EMCAL border and %d cells from PHOS border\n",
1520 fEMCALRecoUtils->GetNumberOfCellsFromEMCALBorder(), fNCellsFromPHOSBorder);
1521 if(fEMCALRecoUtils->IsEMCALNoBorderAtEta0()) printf("Do not remove EMCAL clusters at Eta = 0\n");
1522 printf("Recalibrate Clusters? %d, run by run %d\n",fRecalibration,fRunDependentCorrection);
1523 printf("Recalculate Clusters Position? %d\n",fRecalculatePosition);
1524 printf("Recalculate Clusters Energy? %d\n",fCorrectELinearity);
1525 printf("Matching criteria: dR < %2.2f[cm], dZ < %2.2f[cm]\n",fCutR,fCutZ);
1527 printf("Loc. Max. E > %2.2f\n", fLocMaxCutE);
1528 printf("Loc. Max. E Diff > %2.2f\n", fLocMaxCutEDiff);
1533 //_____________________________________________________________________________________________
1534 void AliCalorimeterUtils::RecalibrateCellAmplitude(Float_t & amp, TString calo, Int_t id) const
1536 //Recaculate cell energy if recalibration factor
1538 Int_t icol = -1; Int_t irow = -1; Int_t iRCU = -1;
1539 Int_t nModule = GetModuleNumberCellIndexes(id,calo, icol, irow, iRCU);
1541 if (IsRecalibrationOn())
1545 amp *= GetPHOSChannelRecalibrationFactor(nModule,icol,irow);
1549 amp *= GetEMCALChannelRecalibrationFactor(nModule,icol,irow);
1554 //____________________________________________________________________________________________________
1555 void AliCalorimeterUtils::RecalibrateCellTime(Double_t & time, TString calo, Int_t id, Int_t bc) const
1557 // Recalculate time if time recalibration available for EMCAL
1558 // not ready for PHOS
1560 if(calo == "EMCAL" && GetEMCALRecoUtils()->IsTimeRecalibrationOn())
1562 GetEMCALRecoUtils()->RecalibrateCellTime(id,bc,time);
1567 //__________________________________________________________________________
1568 Float_t AliCalorimeterUtils::RecalibrateClusterEnergy(AliVCluster * cluster,
1569 AliVCaloCells * cells)
1571 // Recalibrate the cluster energy, considering the recalibration map and the energy of the cells that compose the cluster.
1573 //Initialize some used variables
1574 Float_t frac = 0., energy = 0.;
1578 //Get the cluster number of cells and list of absId, check what kind of cluster do we have.
1580 UShort_t * index = cluster->GetCellsAbsId() ;
1581 Double_t * fraction = cluster->GetCellsAmplitudeFraction() ;
1583 Int_t ncells = cluster->GetNCells();
1585 TString calo = "EMCAL";
1586 if(cluster->IsPHOS())
1589 //Loop on the cells, get the cell amplitude and recalibration factor, multiply and and to the new energy
1590 for(Int_t icell = 0; icell < ncells; icell++){
1592 Int_t absId = index[icell];
1594 frac = fraction[icell];
1595 if(frac < 1e-3) frac = 1; //in case of EMCAL, this is set as 0, not used.
1597 Float_t amp = cells->GetCellAmplitude(absId);
1598 RecalibrateCellAmplitude(amp,calo, absId);
1601 printf("AliCalorimeterUtils::RecalibrateClusterEnergy() - recalibrate cell: %s, cell fraction %f, cell energy %f\n",
1602 calo.Data(),frac,cells->GetCellAmplitude(absId));
1608 printf("AliCalorimeterUtils::RecalibrateClusterEnergy() - Energy before %f, after %f\n",cluster->E(),energy);
1613 Fatal("RecalibrateClusterEnergy()","Cells pointer does not exist!");
1619 //__________________________________________________________________________
1620 Float_t AliCalorimeterUtils::RecalibrateClusterEnergyWeightCell(AliVCluster * cluster,
1621 AliVCaloCells * cells, Float_t energyOrg)
1623 // Recalibrate the cluster energy, considering the recalibration map and the energy of the cells that compose the cluster.
1624 // Also consider reweighting of cells energy
1626 //Initialize some used variables
1627 Float_t frac = 0., energy = 0.;
1631 //Get the cluster number of cells and list of absId, check what kind of cluster do we have.
1633 UShort_t * index = cluster->GetCellsAbsId() ;
1634 Double_t * fraction = cluster->GetCellsAmplitudeFraction() ;
1636 Int_t ncells = cluster->GetNCells();
1638 TString calo = "EMCAL";
1639 if(cluster->IsPHOS())
1642 //Loop on the cells, get the cell amplitude and recalibration factor, multiply and and to the new energy
1643 for(Int_t icell = 0; icell < ncells; icell++){
1645 Int_t absId = index[icell];
1647 frac = fraction[icell];
1648 if(frac < 1e-3) frac = 1; //in case of EMCAL, this is set as 0, not used.
1650 Float_t amp = cells->GetCellAmplitude(absId);
1651 RecalibrateCellAmplitude(amp,calo, absId);
1653 amp*=GetMCECellClusFracCorrection(amp,energyOrg);
1656 printf("AliCalorimeterUtils::RecalibrateClusterEnergy() - recalibrate cell: %s, cell fraction %f, cell energy %f\n",
1657 calo.Data(),frac,cells->GetCellAmplitude(absId));
1663 printf("AliCalorimeterUtils::RecalibrateClusterEnergy() - Energy before %f, after %f\n",cluster->E(),energy);
1668 Fatal("RecalibrateClusterEnergy()","Cells pointer does not exist!");
1675 //__________________________________________________________________________________________
1676 void AliCalorimeterUtils::RecalculateClusterPosition(AliVCaloCells* cells, AliVCluster* clu)
1679 //Recalculate EMCAL cluster position
1681 fEMCALRecoUtils->RecalculateClusterPosition((AliEMCALGeometry*)fEMCALGeo, cells,clu);
1685 //________________________________________________________________________________
1686 void AliCalorimeterUtils::RecalculateClusterTrackMatching(AliVEvent * event,
1687 TObjArray* clusterArray)
1689 //Recalculate track matching
1691 if (fRecalculateMatching)
1693 fEMCALRecoUtils->FindMatches(event,clusterArray,fEMCALGeo) ;
1694 //AliESDEvent* esdevent = dynamic_cast<AliESDEvent*> (event);
1696 // fEMCALRecoUtils->SetClusterMatchedToTrack(esdevent) ;
1697 // fEMCALRecoUtils->SetTracksMatchedToCluster(esdevent) ;
1702 //___________________________________________________________________________
1703 void AliCalorimeterUtils::SplitEnergy(Int_t absId1, Int_t absId2,
1704 AliVCluster* cluster,
1705 AliVCaloCells* cells,
1706 //Float_t & e1, Float_t & e2,
1707 AliAODCaloCluster* cluster1,
1708 AliAODCaloCluster* cluster2,
1709 Int_t nMax, Int_t eventNumber)
1712 // Split energy of cluster between the 2 local maxima, sum energy on 3x3, and if the 2
1713 // maxima are too close and have common cells, split the energy between the 2
1715 TH2F* hClusterMap = 0 ;
1716 TH2F* hClusterLocMax = 0 ;
1717 TH2F* hCluster1 = 0 ;
1718 TH2F* hCluster2 = 0 ;
1722 hClusterMap = new TH2F("hClusterMap","Cluster Map",48,0,48,24,0,24);
1723 hClusterLocMax = new TH2F("hClusterLocMax","Cluster 2 highest local maxima",48,0,48,24,0,24);
1724 hCluster1 = new TH2F("hCluster1","Cluster 1",48,0,48,24,0,24);
1725 hCluster2 = new TH2F("hCluster2","Cluster 2",48,0,48,24,0,24);
1726 hClusterMap ->SetXTitle("column");
1727 hClusterMap ->SetYTitle("row");
1728 hClusterLocMax ->SetXTitle("column");
1729 hClusterLocMax ->SetYTitle("row");
1730 hCluster1 ->SetXTitle("column");
1731 hCluster1 ->SetYTitle("row");
1732 hCluster2 ->SetXTitle("column");
1733 hCluster2 ->SetYTitle("row");
1736 TString calorimeter = "EMCAL";
1737 if(cluster->IsPHOS())
1740 printf("AliCalorimeterUtils::SplitEnerg() Not supported for PHOS yet \n");
1744 const Int_t ncells = cluster->GetNCells();
1745 Int_t absIdList[ncells];
1747 Float_t e1 = 0, e2 = 0 ;
1748 Int_t icol = -1, irow = -1, iRCU = -1, sm = -1;
1749 Float_t eCluster = 0;
1750 Float_t minCol = 100, minRow = 100, maxCol = -1, maxRow = -1;
1751 for(Int_t iDigit = 0; iDigit < ncells; iDigit++ )
1753 absIdList[iDigit] = cluster->GetCellsAbsId()[iDigit];
1755 Float_t ec = cells->GetCellAmplitude(absIdList[iDigit]);
1756 RecalibrateCellAmplitude(ec,calorimeter, absIdList[iDigit]);
1761 //printf("iDigit %d, absId %d, Ecell %f\n",iDigit,absIdList[iDigit], cells->GetCellAmplitude(absIdList[iDigit]));
1762 sm = GetModuleNumberCellIndexes(absIdList[iDigit], calorimeter, icol, irow, iRCU) ;
1763 if(sm > -1 && sm < 12) // just to avoid compilation warning
1765 if(icol > maxCol) maxCol = icol;
1766 if(icol < minCol) minCol = icol;
1767 if(irow > maxRow) maxRow = irow;
1768 if(irow < minRow) minRow = irow;
1769 hClusterMap->Fill(icol,irow,ec);
1775 // Init counters and variables
1777 UShort_t absIdList1[9] ;
1778 Double_t fracList1 [9] ;
1779 absIdList1[0] = absId1 ;
1780 fracList1 [0] = 1. ;
1782 Float_t ecell1 = cells->GetCellAmplitude(absId1);
1783 RecalibrateCellAmplitude(ecell1, calorimeter, absId1);
1787 UShort_t absIdList2[9] ;
1788 Double_t fracList2 [9] ;
1789 absIdList2[0] = absId2 ;
1790 fracList2 [0] = 1. ;
1792 Float_t ecell2 = cells->GetCellAmplitude(absId2);
1793 RecalibrateCellAmplitude(ecell2, calorimeter, absId2);
1798 Int_t icol1 = -1, irow1 = -1, icol2 = -1, irow2 = -1;
1799 sm = GetModuleNumberCellIndexes(absId1, calorimeter, icol1, irow1, iRCU) ;
1800 hClusterLocMax->Fill(icol1,irow1,ecell1);
1801 sm = GetModuleNumberCellIndexes(absId2, calorimeter, icol2, irow2, iRCU) ;
1802 hClusterLocMax->Fill(icol2,irow2,ecell2);
1805 // Very rough way to share the cluster energy
1806 Float_t eRemain = (eCluster-ecell1-ecell2)/2;
1807 Float_t shareFraction1 = ecell1/eCluster+eRemain/eCluster;
1808 Float_t shareFraction2 = ecell2/eCluster+eRemain/eCluster;
1810 for(Int_t iDigit = 0; iDigit < ncells; iDigit++)
1812 Int_t absId = absIdList[iDigit];
1814 if(absId==absId1 || absId==absId2 || absId < 0) continue;
1816 Float_t ecell = cells->GetCellAmplitude(absId);
1817 RecalibrateCellAmplitude(ecell, calorimeter, absId);
1819 if(AreNeighbours(calorimeter, absId1,absId ))
1821 absIdList1[ncells1]= absId;
1823 if(AreNeighbours(calorimeter, absId2,absId ))
1825 fracList1[ncells1] = shareFraction1;
1826 e1 += ecell*shareFraction1;
1830 fracList1[ncells1] = 1.;
1836 } // neigbour to cell1
1838 if(AreNeighbours(calorimeter, absId2,absId ))
1840 absIdList2[ncells2]= absId;
1842 if(AreNeighbours(calorimeter, absId1,absId ))
1844 fracList2[ncells2] = shareFraction2;
1845 e2 += ecell*shareFraction2;
1849 fracList2[ncells2] = 1.;
1855 } // neigbour to cell2
1859 if(GetDebug() > 1) printf("AliCalorimeterUtils::SplitEnergy() - 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 \n",
1860 nMax, eCluster,ecell1,ecell2,e1,e2,eCluster-e1-e2,ncells,ncells1,ncells2,shareFraction1,shareFraction2,shareFraction1+shareFraction2);
1865 cluster1->SetNCells(ncells1);
1866 cluster2->SetNCells(ncells2);
1868 cluster1->SetCellsAbsId(absIdList1);
1869 cluster2->SetCellsAbsId(absIdList2);
1871 cluster1->SetCellsAmplitudeFraction(fracList1);
1872 cluster2->SetCellsAmplitudeFraction(fracList2);
1875 CorrectClusterEnergy(cluster1) ;
1876 CorrectClusterEnergy(cluster2) ;
1878 if(calorimeter=="EMCAL")
1880 GetEMCALRecoUtils()->RecalculateClusterPosition(GetEMCALGeometry(), cells, cluster1);
1881 GetEMCALRecoUtils()->RecalculateClusterPosition(GetEMCALGeometry(), cells, cluster2);
1886 //printf("Cells of cluster1: ");
1887 for(Int_t iDigit = 0; iDigit < ncells1; iDigit++ )
1889 //printf(" %d ",absIdList1[iDigit]);
1891 sm = GetModuleNumberCellIndexes(absIdList1[iDigit], calorimeter, icol, irow, iRCU) ;
1893 Float_t ecell = cells->GetCellAmplitude(absIdList1[iDigit]);
1894 RecalibrateCellAmplitude(ecell, calorimeter, absIdList1[iDigit]);
1896 if( AreNeighbours(calorimeter, absId2,absIdList1[iDigit]) && absId1!=absIdList1[iDigit])
1897 hCluster1->Fill(icol,irow,ecell*shareFraction1);
1899 hCluster1->Fill(icol,irow,ecell);
1903 //printf("Cells of cluster2: ");
1905 for(Int_t iDigit = 0; iDigit < ncells2; iDigit++ )
1907 //printf(" %d ",absIdList2[iDigit]);
1909 sm = GetModuleNumberCellIndexes(absIdList2[iDigit], calorimeter, icol, irow, iRCU) ;
1911 Float_t ecell = cells->GetCellAmplitude(absIdList2[iDigit]);
1912 RecalibrateCellAmplitude(ecell, calorimeter, absIdList2[iDigit]);
1914 if( AreNeighbours(calorimeter, absId1,absIdList2[iDigit]) && absId2!=absIdList2[iDigit])
1915 hCluster2->Fill(icol,irow,ecell*shareFraction2);
1917 hCluster2->Fill(icol,irow,ecell);
1922 gStyle->SetPadRightMargin(0.1);
1923 gStyle->SetPadLeftMargin(0.1);
1924 gStyle->SetOptStat(0);
1925 gStyle->SetOptFit(000000);
1927 if(maxCol-minCol > maxRow-minRow)
1929 maxRow+= maxCol-minCol;
1933 maxCol+= maxRow-minRow;
1936 TCanvas * c= new TCanvas("canvas", "canvas", 4000, 4000) ;
1942 hClusterMap ->SetAxisRange(minCol, maxCol,"X");
1943 hClusterMap ->SetAxisRange(minRow, maxRow,"Y");
1944 hClusterMap ->Draw("colz TEXT");
1949 hClusterLocMax ->SetAxisRange(minCol, maxCol,"X");
1950 hClusterLocMax ->SetAxisRange(minRow, maxRow,"Y");
1951 hClusterLocMax ->Draw("colz TEXT");
1956 hCluster1 ->SetAxisRange(minCol, maxCol,"X");
1957 hCluster1 ->SetAxisRange(minRow, maxRow,"Y");
1958 hCluster1 ->Draw("colz TEXT");
1963 hCluster2 ->SetAxisRange(minCol, maxCol,"X");
1964 hCluster2 ->SetAxisRange(minRow, maxRow,"Y");
1965 hCluster2 ->Draw("colz TEXT");
1967 if(eCluster > 6 )c->Print(Form("clusterFigures/Event%d_E%1.0f_nMax%d_NCell1_%d_NCell2_%d.eps",
1968 eventNumber,cluster->E(),nMax,ncells1,ncells2));
1972 delete hClusterLocMax;