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>
33 // --- ANALYSIS system ---
34 #include "AliCalorimeterUtils.h"
35 #include "AliESDEvent.h"
36 #include "AliMCEvent.h"
38 #include "AliAODPWG4Particle.h"
39 #include "AliVCluster.h"
40 #include "AliVCaloCells.h"
41 #include "AliMixedEvent.h"
42 #include "AliAODCaloCluster.h"
43 #include "AliOADBContainer.h"
44 #include "AliAnalysisManager.h"
47 #include "AliEMCALGeometry.h"
48 #include "AliPHOSGeoUtils.h"
50 ClassImp(AliCalorimeterUtils)
53 //____________________________________________
54 AliCalorimeterUtils::AliCalorimeterUtils() :
58 fEMCALGeo(0x0), fPHOSGeo(0x0),
59 fEMCALGeoMatrixSet(kFALSE), fPHOSGeoMatrixSet(kFALSE),
60 fLoadEMCALMatrices(kFALSE), fLoadPHOSMatrices(kFALSE),
61 fRemoveBadChannels(kFALSE), fPHOSBadChannelMap(0x0),
62 fNCellsFromPHOSBorder(0),
63 fNMaskCellColumns(0), fMaskCellColumns(0x0),
64 fRecalibration(kFALSE), fRunDependentCorrection(kFALSE),
65 fPHOSRecalibrationFactors(), fEMCALRecoUtils(new AliEMCALRecoUtils),
66 fRecalculatePosition(kFALSE), fCorrectELinearity(kFALSE),
67 fRecalculateMatching(kFALSE),
69 fCutEta(20), fCutPhi(20),
70 fLocMaxCutE(0), fLocMaxCutEDiff(0),
71 fPlotCluster(0), fOADBSet(kFALSE),
72 fOADBForEMCAL(kFALSE), fOADBForPHOS(kFALSE),
73 fOADBFilePathEMCAL(""), fOADBFilePathPHOS(""),
74 fImportGeometryFromFile(0), fImportGeometryFilePath(""),
75 fNSuperModulesUsed(0),
76 fMCECellClusFracCorrOn(0), fMCECellClusFracCorrParam()
80 //Initialize parameters
82 for(Int_t i = 0; i < 12; i++) fEMCALMatrix[i] = 0 ;
83 for(Int_t i = 0; i < 5 ; i++) fPHOSMatrix [i] = 0 ;
87 //_________________________________________
88 AliCalorimeterUtils::~AliCalorimeterUtils()
92 //if(fPHOSGeo) delete fPHOSGeo ;
93 if(fEMCALGeo) delete fEMCALGeo ;
95 if(fPHOSBadChannelMap) {
96 fPHOSBadChannelMap->Clear();
97 delete fPHOSBadChannelMap;
100 if(fPHOSRecalibrationFactors) {
101 fPHOSRecalibrationFactors->Clear();
102 delete fPHOSRecalibrationFactors;
105 if(fEMCALRecoUtils) delete fEMCALRecoUtils ;
106 if(fNMaskCellColumns) delete [] fMaskCellColumns;
110 //____________________________________________________
111 void AliCalorimeterUtils::AccessOADB(AliVEvent* event)
113 // Set the AODB calibration, bad channels etc. parameters at least once
114 // alignment matrices from OADB done in SetGeometryMatrices
117 if(fOADBSet) return ;
119 Int_t runnumber = event->GetRunNumber() ;
120 TString pass = GetPass();
125 printf("AliCalorimeterUtils::SetOADBParameters() - Get AODB parameters from EMCAL in %s for run %d, and <%s> \n",fOADBFilePathEMCAL.Data(),runnumber,pass.Data());
127 Int_t nSM = fEMCALGeo->GetNumberOfSuperModules();
130 if(fRemoveBadChannels)
132 AliOADBContainer *contBC=new AliOADBContainer("");
133 contBC->InitFromFile(Form("%s/EMCALBadChannels.root",fOADBFilePathEMCAL.Data()),"AliEMCALBadChannels");
135 TObjArray *arrayBC=(TObjArray*)contBC->GetObject(runnumber);
139 SwitchOnDistToBadChannelRecalculation();
140 printf("AliCalorimeterUtils::SetOADBParameters() - Remove EMCAL bad cells \n");
142 for (Int_t i=0; i<nSM; ++i)
144 TH2I *hbm = GetEMCALChannelStatusMap(i);
149 hbm=(TH2I*)arrayBC->FindObject(Form("EMCALBadChannelMap_Mod%d",i));
153 AliError(Form("Can not get EMCALBadChannelMap_Mod%d",i));
157 hbm->SetDirectory(0);
158 SetEMCALChannelStatusMap(i,hbm);
161 } else printf("AliCalorimeterUtils::SetOADBParameters() - Do NOT remove EMCAL bad channels\n"); // run array
164 // Energy Recalibration
167 AliOADBContainer *contRF=new AliOADBContainer("");
169 contRF->InitFromFile(Form("%s/EMCALRecalib.root",fOADBFilePathEMCAL.Data()),"AliEMCALRecalib");
171 TObjArray *recal=(TObjArray*)contRF->GetObject(runnumber);
175 TObjArray *recalpass=(TObjArray*)recal->FindObject(pass);
179 TObjArray *recalib=(TObjArray*)recalpass->FindObject("Recalib");
183 printf("AliCalorimeterUtils::SetOADBParameters() - Recalibrate EMCAL \n");
184 for (Int_t i=0; i<nSM; ++i)
186 TH2F *h = GetEMCALChannelRecalibrationFactors(i);
191 h = (TH2F*)recalib->FindObject(Form("EMCALRecalFactors_SM%d",i));
195 AliError(Form("Could not load EMCALRecalFactors_SM%d",i));
201 SetEMCALChannelRecalibrationFactors(i,h);
203 }else printf("AliCalorimeterUtils::SetOADBParameters() - Do NOT recalibrate EMCAL, no params object array\n"); // array ok
204 }else printf("AliCalorimeterUtils::SetOADBParameters() - Do NOT recalibrate EMCAL, no params for pass\n"); // array pass ok
205 }else printf("AliCalorimeterUtils::SetOADBParameters() - Do NOT recalibrate EMCAL, no params for run\n"); // run number array ok
207 // once set, apply run dependent corrections if requested
208 //fEMCALRecoUtils->SetRunDependentCorrections(runnumber);
210 } // Recalibration on
212 // Energy Recalibration, apply on top of previous calibration factors
213 if(fRunDependentCorrection)
215 AliOADBContainer *contRFTD=new AliOADBContainer("");
217 contRFTD->InitFromFile(Form("%s/EMCALTemperatureCorrCalib.root",fOADBFilePathEMCAL.Data()),"AliEMCALRunDepTempCalibCorrections");
219 TH1S *htd=(TH1S*)contRFTD->GetObject(runnumber);
221 //If it did not exist for this run, get closes one
224 AliWarning(Form("No TemperatureCorrCalib Objects for run: %d",runnumber));
225 // let's get the closest runnumber instead then..
228 Int_t maxEntry = contRFTD->GetNumberOfEntries();
230 while ( (ic < maxEntry) && (contRFTD->UpperLimit(ic) < runnumber) ) {
235 Int_t closest = lower;
236 if ( (ic<maxEntry) &&
237 (contRFTD->LowerLimit(ic)-runnumber) < (runnumber - contRFTD->UpperLimit(lower)) ) {
241 AliWarning(Form("TemperatureCorrCalib Objects found closest id %d from run: %d", closest, contRFTD->LowerLimit(closest)));
242 htd = (TH1S*) contRFTD->GetObjectByIndex(closest);
247 printf("AliCalorimeterUtils::SetOADBParameters() - Recalibrate (Temperature) EMCAL \n");
249 for (Int_t ism=0; ism<nSM; ++ism)
251 for (Int_t icol=0; icol<48; ++icol)
253 for (Int_t irow=0; irow<24; ++irow)
255 Float_t factor = GetEMCALChannelRecalibrationFactor(ism,icol,irow);
257 Int_t absID = fEMCALGeo->GetAbsCellIdFromCellIndexes(ism, irow, icol); // original calibration factor
258 factor *= htd->GetBinContent(absID) / 10000. ; // correction dependent on T
259 //printf("\t ism %d, icol %d, irow %d,absID %d, corrA %2.3f, corrB %2.3f, corrAB %2.3f\n",ism, icol, irow, absID,
260 // GetEMCALChannelRecalibrationFactor(ism,icol,irow) , htd->GetBinContent(absID) / 10000., factor);
261 SetEMCALChannelRecalibrationFactor(ism,icol,irow,factor);
265 }else printf("AliCalorimeterUtils::SetOADBParameters() - Do NOT recalibrate EMCAL with T variations, no params TH1 \n");
266 } // Run by Run T calibration
268 // Time Recalibration
269 if(fEMCALRecoUtils->IsTimeRecalibrationOn())
271 AliOADBContainer *contTRF=new AliOADBContainer("");
273 contTRF->InitFromFile(Form("%s/EMCALTimeCalib.root",fOADBFilePathEMCAL.Data()),"AliEMCALTimeCalib");
275 TObjArray *trecal=(TObjArray*)contTRF->GetObject(runnumber);
279 TString passM = pass;
280 if(pass=="spc_calo") passM = "pass1";
281 TObjArray *trecalpass=(TObjArray*)trecal->FindObject(passM);
285 printf("AliCalorimeterUtils::SetOADBParameters() - Time Recalibrate EMCAL \n");
286 for (Int_t ibc = 0; ibc < 4; ++ibc)
288 TH1F *h = GetEMCALChannelTimeRecalibrationFactors(ibc);
293 h = (TH1F*)trecalpass->FindObject(Form("hAllTimeAvBC%d",ibc));
297 AliError(Form("Could not load hAllTimeAvBC%d",ibc));
303 SetEMCALChannelTimeRecalibrationFactors(ibc,h);
304 } // bunch crossing loop
305 }else printf("AliCalorimeterUtils::SetOADBParameters() - Do NOT recalibrate time EMCAL, no params for pass\n"); // array pass ok
306 }else printf("AliCalorimeterUtils::SetOADBParameters() - Do NOT recalibrate time EMCAL, no params for run\n"); // run number array ok
308 } // Recalibration on
315 printf("AliCalorimeterUtils::SetOADBParameters() - Get AODB parameters from PHOS in %s for run %d, and <%s> \n",fOADBFilePathPHOS.Data(),runnumber,pass.Data());
318 if(fRemoveBadChannels)
320 AliOADBContainer badmapContainer(Form("phosBadMap"));
321 TString fileName="$ALICE_ROOT/OADB/PHOS/PHOSBadMaps.root";
322 badmapContainer.InitFromFile(Form("%s/PHOSBadMaps.root",fOADBFilePathPHOS.Data()),"phosBadMap");
324 //Use a fixed run number from year 2010, this year not available yet.
325 TObjArray *maps = (TObjArray*)badmapContainer.GetObject(139000,"phosBadMap");
328 printf("AliCalorimeterUtils::SetOADBParameters() - Can not read PHOS bad map for run %d.\n",runnumber) ;
332 printf("AliCalorimeterUtils::SetOADBParameters() - Setting PHOS bad map with name %s \n",maps->GetName()) ;
333 for(Int_t mod=1; mod<5;mod++)
335 TH2I *hbmPH = GetPHOSChannelStatusMap(mod);
340 hbmPH = (TH2I*)maps->At(mod);
342 if(hbmPH) hbmPH->SetDirectory(0);
344 SetPHOSChannelStatusMap(mod-1,hbmPH);
348 } // Remove bad channels
351 // Parameters already set once, so do not it again
356 //_____________________________________________________________
357 void AliCalorimeterUtils::AccessGeometry(AliVEvent* inputEvent)
359 //Set the calorimeters transformation matrices and init geometry
361 // First init the geometry, a priory not done before
362 Int_t runnumber = inputEvent->GetRunNumber() ;
363 InitPHOSGeometry (runnumber);
364 InitEMCALGeometry(runnumber);
366 //Get the EMCAL transformation geometry matrices from ESD
367 if(!fEMCALGeoMatrixSet && fEMCALGeo)
369 if(fLoadEMCALMatrices)
371 printf("AliCalorimeterUtils::AccessGeometry() - Load user defined EMCAL geometry matrices\n");
374 AliOADBContainer emcGeoMat("AliEMCALgeo");
375 emcGeoMat.InitFromFile(Form("%s/EMCALlocal2master.root",fOADBFilePathEMCAL.Data()),"AliEMCALgeo");
376 TObjArray *matEMCAL=(TObjArray*)emcGeoMat.GetObject(runnumber,"EmcalMatrices");
378 for(Int_t mod=0; mod < (fEMCALGeo->GetEMCGeometry())->GetNumberOfSuperModules(); mod++)
380 if (!fEMCALMatrix[mod]) // Get it from OADB
383 printf("AliCalorimeterUtils::AccessGeometry() - EMCAL matrices SM %d, %p\n",
384 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)
405 printf(" AliCalorimeterUtils::AccessGeometry() - Load EMCAL misalignment matrices. \n");
406 if(!strcmp(inputEvent->GetName(),"AliESDEvent"))
408 for(Int_t mod=0; mod < (fEMCALGeo->GetEMCGeometry())->GetNumberOfSuperModules(); mod++)
410 //printf("Load ESD matrix %d, %p\n",mod,((AliESDEvent*)inputEvent)->GetEMCALMatrix(mod));
411 if(((AliESDEvent*)inputEvent)->GetEMCALMatrix(mod))
413 fEMCALGeo->SetMisalMatrix(((AliESDEvent*)inputEvent)->GetEMCALMatrix(mod),mod) ;
415 }// loop over super modules
417 fEMCALGeoMatrixSet = kTRUE;//At least one, so good
423 printf("AliCalorimeterUtils::SetGeometryTransformationMatrices() - Setting of EMCAL transformation matrixes for AODs not implemented yet. \n Import geometry.root file\n");
425 }//Get matrix from data
428 fEMCALGeoMatrixSet = kTRUE;
430 }//EMCAL geo && no geoManager
432 //Get the PHOS transformation geometry matrices from ESD
433 if(!fPHOSGeoMatrixSet && fPHOSGeo)
435 if(fLoadPHOSMatrices)
437 printf("AliCalorimeterUtils::SetGeometryTransformationMatrices() - Load user defined PHOS geometry matrices\n");
440 AliOADBContainer geomContainer("phosGeo");
441 geomContainer.InitFromFile(Form("%s/PHOSGeometry.root",fOADBFilePathPHOS.Data()),"PHOSRotationMatrixes");
442 TObjArray *matPHOS = (TObjArray*)geomContainer.GetObject(139000,"PHOSRotationMatrixes");
444 for(Int_t mod = 0 ; mod < 5 ; mod++)
446 if (!fPHOSMatrix[mod]) // Get it from OADB
449 printf("AliCalorimeterUtils::SetGeometryTransformationMatrices() - PHOS matrices module %d, %p\n",
450 mod,((TGeoHMatrix*) matPHOS->At(mod)));
451 //((TGeoHMatrix*) matPHOS->At(mod))->Print();
453 fPHOSMatrix[mod] = (TGeoHMatrix*) matPHOS->At(mod) ;
456 // Set it, if it exists
460 fPHOSMatrix[mod]->Print();
462 fPHOSGeo->SetMisalMatrix(fPHOSMatrix[mod],mod) ;
466 fPHOSGeoMatrixSet = kTRUE;//At least one, so good
469 else if (!gGeoManager)
472 printf(" AliCalorimeterUtils::SetGeometryTransformationMatrices() - Load PHOS misalignment matrices. \n");
473 if(!strcmp(inputEvent->GetName(),"AliESDEvent"))
475 for(Int_t mod = 0; mod < 5; mod++)
477 if( ((AliESDEvent*)inputEvent)->GetPHOSMatrix(mod))
479 //printf("PHOS: mod %d, matrix %p\n",mod, ((AliESDEvent*)inputEvent)->GetPHOSMatrix(mod));
480 fPHOSGeo->SetMisalMatrix( ((AliESDEvent*)inputEvent)->GetPHOSMatrix(mod),mod) ;
482 }// loop over modules
483 fPHOSGeoMatrixSet = kTRUE; //At least one so good
488 printf("AliCalorimeterUtils::SetGeometryTransformationMatrices() - Setting of EMCAL transformation matrixes for AODs not implemented yet. \n Import geometry.root file\n");
490 }// get matrix from data
493 fPHOSGeoMatrixSet = kTRUE;
495 }//PHOS geo and geoManager was not set
499 //________________________________________________________________________________________
500 Bool_t AliCalorimeterUtils::AreNeighbours(TString calo, Int_t absId1, Int_t absId2 ) const
502 // Tells if (true) or not (false) two cells are neighbours
503 // A neighbour is defined as being two cells which share a side or corner
505 Bool_t areNeighbours = kFALSE ;
507 Int_t iRCU1 = -1, irow1 = -1, icol1 = -1;
508 Int_t iRCU2 = -1, irow2 = -1, icol2 = -1;
510 Int_t rowdiff = 0, coldiff = 0;
512 Int_t nSupMod1 = GetModuleNumberCellIndexes(absId1, calo, icol1, irow1, iRCU1);
513 Int_t nSupMod2 = GetModuleNumberCellIndexes(absId2, calo, icol2, irow2, iRCU2);
515 if(calo=="EMCAL" && nSupMod1!=nSupMod2)
517 // In case of a shared cluster, index of SM in C side, columns start at 48 and ends at 48*2-1
518 // C Side impair SM, nSupMod%2=1; A side pair SM nSupMod%2=0
519 if(nSupMod1%2) icol1+=AliEMCALGeoParams::fgkEMCALCols;
520 else icol2+=AliEMCALGeoParams::fgkEMCALCols;
523 rowdiff = TMath::Abs( irow1 - irow2 ) ;
524 coldiff = TMath::Abs( icol1 - icol2 ) ;
526 //if (( coldiff <= 1 ) && ( rowdiff <= 1 ) && (coldiff + rowdiff > 0))
527 if ((coldiff + rowdiff == 1 ))
528 areNeighbours = kTRUE ;
530 return areNeighbours;
533 //_____________________________________________________________________________________
534 Bool_t AliCalorimeterUtils::IsClusterSharedByTwoSuperModules(const AliEMCALGeometry * geom,
535 AliVCluster* cluster)
537 //Method that checks if any of the cells in the cluster belongs to a different SM
547 for(Int_t iDigit=0; iDigit < cluster->GetNCells(); iDigit++)
549 //Get from the absid the supermodule, tower and eta/phi numbers
550 geom->GetCellIndex(cluster->GetCellAbsId(iDigit),iSupMod,iTower,iIphi,iIeta);
551 geom->GetCellPhiEtaIndexInSModule(iSupMod,iTower,iIphi,iIeta, iphi,ieta);
553 //Check if there are cells of different SM
554 if (iDigit == 0 ) iSM0 = iSupMod;
555 else if(iSupMod!= iSM0) return kTRUE;
563 //_____________________________________________________________________________________
564 Bool_t AliCalorimeterUtils::CheckCellFiducialRegion(AliVCluster* cluster,
565 AliVCaloCells* cells,
566 AliVEvent * event, Int_t iev) const
569 // Given the list of AbsId of the cluster, get the maximum cell and
570 // check if there are fNCellsFromBorder from the calorimeter border
572 //If the distance to the border is 0 or negative just exit accept all clusters
573 if(cells->GetType()==AliVCaloCells::kEMCALCell && fEMCALRecoUtils->GetNumberOfCellsFromEMCALBorder() <= 0 ) return kTRUE;
574 if(cells->GetType()==AliVCaloCells::kPHOSCell && fNCellsFromPHOSBorder <= 0 ) return kTRUE;
579 AliMixedEvent * mixEvent = dynamic_cast<AliMixedEvent*> (event);
580 Int_t nMixedEvents = 0 ;
581 Int_t * cellsCumul = NULL ;
582 Int_t numberOfCells = 0 ;
584 nMixedEvents = mixEvent->GetNumberOfEvents() ;
585 if (cells->GetType()==AliVCaloCells::kEMCALCell) {
586 cellsCumul = mixEvent->GetEMCALCellsCumul() ;
587 numberOfCells = mixEvent->GetNumberOfEMCALCells() ;
590 else if (cells->GetType()==AliVCaloCells::kPHOSCell) {
591 cellsCumul = mixEvent->GetPHOSCellsCumul() ;
592 numberOfCells = mixEvent->GetNumberOfPHOSCells() ;
597 Int_t startCell = cellsCumul[iev] ;
598 Int_t endCell = (iev+1 < nMixedEvents)?cellsCumul[iev+1]:numberOfCells;
599 //Find cells with maximum amplitude
600 for(Int_t i = 0; i < cluster->GetNCells() ; i++){
601 Int_t absId = cluster->GetCellAbsId(i) ;
602 for (Int_t j = startCell; j < endCell ; j++) {
605 Double_t amp, time, efrac;
606 cells->GetCell(j, cellNumber, amp, time,mclabel,efrac) ;
607 if (absId == cellNumber) {
614 }//loop on cluster cells
615 }// cells cumul available
617 printf("AliCalorimeterUtils::CheckCellFiducialRegion() - CellsCumul is NULL!!!\n");
620 } else {//Normal SE Events
621 for(Int_t i = 0; i < cluster->GetNCells() ; i++){
622 Int_t absId = cluster->GetCellAbsId(i) ;
623 Float_t amp = cells->GetCellAmplitude(absId);
632 printf("AliCalorimeterUtils::CheckCellFiducialRegion() - Cluster Max AbsId %d, Cell Energy %2.2f, Cluster Energy %2.2f\n",
633 absIdMax, ampMax, cluster->E());
635 if(absIdMax==-1) return kFALSE;
637 //Check if the cell is close to the borders:
638 Bool_t okrow = kFALSE;
639 Bool_t okcol = kFALSE;
641 if(cells->GetType()==AliVCaloCells::kEMCALCell){
643 Int_t iTower = -1, iIphi = -1, iIeta = -1, iphi = -1, ieta = -1, iSM = -1;
644 fEMCALGeo->GetCellIndex(absIdMax,iSM,iTower,iIphi,iIeta);
645 fEMCALGeo->GetCellPhiEtaIndexInSModule(iSM,iTower,iIphi, iIeta,iphi,ieta);
646 if(iSM < 0 || iphi < 0 || ieta < 0 ) {
647 Fatal("CheckCellFidutialRegion","Negative value for super module: %d, or cell ieta: %d, or cell iphi: %d, check EMCAL geometry name\n",iSM,ieta,iphi);
651 Int_t nborder = fEMCALRecoUtils->GetNumberOfCellsFromEMCALBorder();
654 if(iphi >= nborder && iphi < 24-nborder) okrow =kTRUE;
658 if(fEMCALGeoName.Contains("12SM")) // 1/3 SM
660 if(iphi >= nborder && iphi < 8-nborder) okrow =kTRUE;
664 if(iphi >= nborder && iphi <12-nborder) okrow =kTRUE;
669 if(!fEMCALRecoUtils->IsEMCALNoBorderAtEta0())
671 if(ieta > nborder && ieta < 48-nborder) okcol =kTRUE;
677 if(ieta >= nborder) okcol = kTRUE;
681 if(ieta < 48-nborder) okcol = kTRUE;
687 printf("AliCalorimeterUtils::CheckCellFiducialRegion() - EMCAL Cluster in %d cells fiducial volume: ieta %d, iphi %d, SM %d ?",
688 nborder, ieta, iphi, iSM);
689 if (okcol && okrow ) printf(" YES \n");
690 else printf(" NO: column ok? %d, row ok? %d \n",okcol,okrow);
693 else if(cells->GetType()==AliVCaloCells::kPHOSCell){
695 Int_t irow = -1, icol = -1;
696 fPHOSGeo->AbsToRelNumbering(absIdMax,relId);
700 if(irow >= fNCellsFromPHOSBorder && irow < 64-fNCellsFromPHOSBorder) okrow =kTRUE;
701 if(icol >= fNCellsFromPHOSBorder && icol < 56-fNCellsFromPHOSBorder) okcol =kTRUE;
704 printf("AliCalorimeterUtils::CheckCellFiducialRegion() - PHOS Cluster in %d cells fiducial volume: icol %d, irow %d, Module %d?",
705 fNCellsFromPHOSBorder, icol, irow, relId[0]-1);
706 if (okcol && okrow ) printf(" YES \n");
707 else printf(" NO: column ok? %d, row ok? %d \n",okcol,okrow);
711 if (okcol && okrow) return kTRUE;
716 //__________________________________________________________________________________________________________
717 Bool_t AliCalorimeterUtils::ClusterContainsBadChannel(TString calorimeter, UShort_t* cellList, Int_t nCells)
719 // Check that in the cluster cells, there is no bad channel of those stored
720 // in fEMCALBadChannelMap or fPHOSBadChannelMap
722 if (!fRemoveBadChannels) return kFALSE;
723 //printf("fEMCALBadChannelMap %p, fPHOSBadChannelMap %p \n",fEMCALBadChannelMap,fPHOSBadChannelMap);
724 if(calorimeter == "EMCAL" && !fEMCALRecoUtils->GetEMCALChannelStatusMap(0)) return kFALSE;
725 if(calorimeter == "PHOS" && !fPHOSBadChannelMap) return kFALSE;
730 for(Int_t iCell = 0; iCell<nCells; iCell++){
732 //Get the column and row
733 if(calorimeter == "EMCAL"){
734 return fEMCALRecoUtils->ClusterContainsBadChannel((AliEMCALGeometry*)fEMCALGeo,cellList,nCells);
736 else if(calorimeter=="PHOS"){
738 fPHOSGeo->AbsToRelNumbering(cellList[iCell],relId);
742 if(fPHOSBadChannelMap->GetEntries() <= imod)continue;
743 //printf("PHOS bad channels imod %d, icol %d, irow %d\n",imod, irow, icol);
744 if(GetPHOSChannelStatus(imod, irow, icol)) return kTRUE;
748 }// cell cluster loop
754 //_______________________________________________________________
755 void AliCalorimeterUtils::CorrectClusterEnergy(AliVCluster *clus)
757 // Correct cluster energy non linearity
759 clus->SetE(fEMCALRecoUtils->CorrectClusterEnergyLinearity(clus));
763 //________________________________________________________________________________________
764 Int_t AliCalorimeterUtils::GetMaxEnergyCell(AliVCaloCells* cells, const AliVCluster* clu,
765 Float_t & clusterFraction) const
768 //For a given CaloCluster gets the absId of the cell
769 //with maximum energy deposit.
771 if( !clu || !cells ){
772 AliInfo("Cluster or cells pointer is null!");
779 Float_t fraction = 1.;
780 Float_t recalFactor = 1.;
781 Int_t cellAbsId =-1 , absId =-1 ;
782 Int_t iSupMod =-1 , ieta =-1 , iphi = -1, iRCU = -1;
784 TString calo = "EMCAL";
785 if(clu->IsPHOS()) calo = "PHOS";
787 for (Int_t iDig=0; iDig< clu->GetNCells(); iDig++) {
789 cellAbsId = clu->GetCellAbsId(iDig);
791 fraction = clu->GetCellAmplitudeFraction(iDig);
792 if(fraction < 1e-4) fraction = 1.; // in case unfolding is off
794 iSupMod = GetModuleNumberCellIndexes(cellAbsId, calo, ieta, iphi, iRCU);
796 if(IsRecalibrationOn()) {
797 if(calo=="EMCAL") recalFactor = GetEMCALChannelRecalibrationFactor(iSupMod,ieta,iphi);
798 else recalFactor = GetPHOSChannelRecalibrationFactor (iSupMod,iphi,ieta);
801 eCell = cells->GetCellAmplitude(cellAbsId)*fraction*recalFactor;
813 clusterFraction = (eTot-eMax)/eTot; //Do not use cluster energy in case it was corrected for non linearity.
821 //___________________________________________________________________________________
822 AliVTrack * AliCalorimeterUtils::GetMatchedTrack(AliVCluster* cluster,
823 AliVEvent* event, Int_t index) const
825 // Get the matched track given its index, usually just the first match
826 // Since it is different for ESDs and AODs here it is a wrap method to do it
828 AliVTrack *track = 0;
830 // EMCAL case only when matching is recalculated
831 if(cluster->IsEMCAL() && IsRecalculationOfClusterTrackMatchingOn())
833 Int_t trackIndex = fEMCALRecoUtils->GetMatchedTrackIndex(cluster->GetID());
834 //printf("track index %d, cluster ID %d \n ",trackIndex,cluster->GetID());
838 printf("AliCalorimeterUtils::GetMatchedTrack() - Wrong track index %d, from recalculation\n", trackIndex);
842 track = dynamic_cast<AliVTrack*> (event->GetTrack(trackIndex));
849 // Normal case, get info from ESD or AOD
851 if(!strcmp("AliESDCaloCluster",Form("%s",cluster->ClassName())))
853 Int_t iESDtrack = cluster->GetTrackMatchedIndex();
857 printf("AliCalorimeterUtils::GetMatchedTrack() - Wrong track index %d\n", index);
861 track = dynamic_cast<AliVTrack*> (event->GetTrack(iESDtrack));
866 if(cluster->GetNTracksMatched() > 0 )
867 track = dynamic_cast<AliVTrack*>(cluster->GetTrackMatched(index));
873 //______________________________________________________________________________________________
874 Float_t AliCalorimeterUtils::GetMCECellClusFracCorrection(Float_t eCell, Float_t eCluster) const
876 // Correction factor for cell energy in cluster to temptatively match Data and MC
877 if( eCluster <= 0 || eCluster < eCell )
879 printf("AliCalorimeterUtils::GetMCECellClusFracCorrection() - Bad values eCell=%f, eCluster %f\n",eCell,eCluster);
883 Float_t frac = eCell / eCluster;
885 Float_t correction = fMCECellClusFracCorrParam[0] +
886 TMath::Exp( frac*fMCECellClusFracCorrParam[2]+fMCECellClusFracCorrParam[1] ) +
887 fMCECellClusFracCorrParam[3]/TMath::Sqrt(frac);
889 // printf("AliCalorimeterUtils::GetMCECellClusFracCorrection(eCell=%f, eCluster %f, frac %f) = %f\n",eCell, eCluster, frac, correction);
890 // printf("\t %2.2f + TMath::Exp( %2.3f*%2.2f + %2.2f ) + %2.2f/TMath::Sqrt(%2.3f)) = %f\n",
891 // 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"){
904 fEMCALGeo->GetAbsCellIdFromEtaPhi(particle->Eta(),particle->Phi(), absId);
906 printf("AliCalorimeterUtils::GetModuleNumber(PWG4AOD) - EMCAL: cluster eta %f, phi %f, absid %d, SuperModule %d\n",
907 particle->Eta(), particle->Phi()*TMath::RadToDeg(),absId, fEMCALGeo->GetSuperModuleNumber(absId));
908 return fEMCALGeo->GetSuperModuleNumber(absId) ;
910 else if(particle->GetDetector()=="PHOS")
912 // In case we use the MC reader, the input are TParticles,
913 // in this case use the corresponing method in PHOS Geometry to get the particle.
914 if(strcmp(inputEvent->ClassName(), "AliMCEvent") == 0 )
917 Double_t z = 0., x=0.;
918 TParticle* primary = 0x0;
919 AliStack * stack = ((AliMCEvent*)inputEvent)->Stack();
921 primary = stack->Particle(particle->GetCaloLabel(0));
924 Fatal("GetModuleNumber(PWG4AOD)", "Stack not available, stop!");
928 fPHOSGeo->ImpactOnEmc(primary,mod,z,x) ;
931 Fatal("GetModuleNumber(PWG4AOD)", "Primary not available, stop!");
935 // Input are ESDs or AODs, get the PHOS module number like this.
938 //AliVCluster *cluster = inputEvent->GetCaloCluster(particle->GetCaloLabel(0));
939 //return GetModuleNumber(cluster);
948 //_____________________________________________________________________
949 Int_t AliCalorimeterUtils::GetModuleNumber(AliVCluster * cluster) const
951 //Get the EMCAL/PHOS module number that corresponds to this cluster
953 Double_t v[]={0.,0.,0.}; //not necessary to pass the real vertex.
956 if(fDebug > 1) printf("AliCalorimeterUtils::GetModuleNumber() - NUL Cluster, please check!!!");
960 cluster->GetMomentum(lv,v);
961 Float_t phi = lv.Phi();
962 if(phi < 0) phi+=TMath::TwoPi();
964 if(cluster->IsEMCAL()){
965 fEMCALGeo->GetAbsCellIdFromEtaPhi(lv.Eta(),phi, absId);
967 printf("AliCalorimeterUtils::GetModuleNumber() - EMCAL: cluster eta %f, phi %f, absid %d, SuperModule %d\n",
968 lv.Eta(), phi*TMath::RadToDeg(),absId, fEMCALGeo->GetSuperModuleNumber(absId));
969 return fEMCALGeo->GetSuperModuleNumber(absId) ;
971 else if(cluster->IsPHOS())
974 if ( cluster->GetNCells() > 0)
976 absId = cluster->GetCellAbsId(0);
978 printf("AliCalorimeterUtils::GetModuleNumber() - PHOS: cluster eta %f, phi %f, e %f, absId %d\n",
979 lv.Eta(), phi*TMath::RadToDeg(), lv.E(), absId);
985 fPHOSGeo->AbsToRelNumbering(absId,relId);
987 printf("AliCalorimeterUtils::GetModuleNumber() - PHOS: Module %d\n",relId[0]-1);
996 //___________________________________________________________________________________________________
997 Int_t AliCalorimeterUtils::GetModuleNumberCellIndexes(Int_t absId, TString calo,
998 Int_t & icol, Int_t & irow, Int_t & iRCU) const
1000 //Get the EMCAL/PHOS module, columns, row and RCU number that corresponds to this absId
1006 Int_t iTower = -1, iIphi = -1, iIeta = -1;
1007 fEMCALGeo->GetCellIndex(absId,imod,iTower,iIphi,iIeta);
1008 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);
1061 //___________________________________________________________________________________________
1062 Int_t AliCalorimeterUtils::GetNumberOfLocalMaxima(AliVCluster* cluster, AliVCaloCells* cells)
1064 // Find local maxima in cluster
1066 const Int_t nc = cluster->GetNCells();
1067 Int_t absIdList[nc];
1068 Float_t maxEList[nc];
1070 Int_t nMax = GetNumberOfLocalMaxima(cluster, cells, absIdList, maxEList);
1076 //___________________________________________________________________________________________
1077 Int_t AliCalorimeterUtils::GetNumberOfLocalMaxima(AliVCluster* cluster, AliVCaloCells* cells,
1078 Int_t *absIdList, Float_t *maxEList)
1080 // Find local maxima in cluster
1086 const Int_t nCells = cluster->GetNCells();
1088 Float_t eCluster = RecalibrateClusterEnergy(cluster, cells);// recalculate cluster energy, avoid non lin correction.
1090 Float_t simuTotWeight = 0;
1091 if(fMCECellClusFracCorrOn)
1093 simuTotWeight = RecalibrateClusterEnergyWeightCell(cluster, cells,eCluster);// same but apply a weight
1094 simuTotWeight/= eCluster;
1097 TString calorimeter = "EMCAL";
1098 if(!cluster->IsEMCAL()) calorimeter = "PHOS";
1100 //printf("cluster : ncells %d \n",nCells);
1104 for(iDigit = 0; iDigit < nCells ; iDigit++)
1106 absIdList[iDigit] = cluster->GetCellsAbsId()[iDigit] ;
1107 Float_t en = cells->GetCellAmplitude(absIdList[iDigit]);
1108 RecalibrateCellAmplitude(en,calorimeter,absIdList[iDigit]);
1110 if(fMCECellClusFracCorrOn)
1111 en*=GetMCECellClusFracCorrection(en,eCluster)/simuTotWeight;
1116 idmax = absIdList[iDigit] ;
1118 //Int_t icol = -1, irow = -1, iRCU = -1;
1119 //Int_t sm = GetModuleNumberCellIndexes(absIdList[iDigit], calorimeter, icol, irow, iRCU) ;
1120 //printf("\t cell %d, id %d, sm %d, col %d, row %d, e %f\n", iDigit, absIdList[iDigit], sm, icol, irow, en );
1123 for(iDigit = 0 ; iDigit < nCells; iDigit++)
1125 if(absIdList[iDigit]>=0)
1127 absId1 = cluster->GetCellsAbsId()[iDigit];
1129 Float_t en1 = cells->GetCellAmplitude(absId1);
1130 RecalibrateCellAmplitude(en1,calorimeter,absId1);
1132 if(fMCECellClusFracCorrOn)
1133 en1*=GetMCECellClusFracCorrection(en1,eCluster)/simuTotWeight;
1135 //printf("%d : absIDi %d, E %f\n",iDigit, absId1,en1);
1137 for(iDigitN = 0; iDigitN < nCells; iDigitN++)
1139 absId2 = cluster->GetCellsAbsId()[iDigitN] ;
1141 if(absId2==-1 || absId2==absId1) continue;
1143 //printf("\t %d : absIDj %d\n",iDigitN, absId2);
1145 Float_t en2 = cells->GetCellAmplitude(absId2);
1146 RecalibrateCellAmplitude(en2,calorimeter,absId2);
1148 if(fMCECellClusFracCorrOn)
1149 en2*=GetMCECellClusFracCorrection(en2,eCluster)/simuTotWeight;
1151 //printf("\t %d : absIDj %d, E %f\n",iDigitN, absId2,en2);
1153 if ( AreNeighbours(calorimeter, absId1, absId2) )
1155 // printf("\t \t Neighbours \n");
1158 absIdList[iDigitN] = -1 ;
1159 //printf("\t \t indexN %d not local max\n",iDigitN);
1160 // but may be digit too is not local max ?
1161 if(en1 < en2 + fLocMaxCutEDiff) {
1162 //printf("\t \t index %d not local max cause locMaxCutEDiff\n",iDigit);
1163 absIdList[iDigit] = -1 ;
1168 absIdList[iDigit] = -1 ;
1169 //printf("\t \t index %d not local max\n",iDigitN);
1170 // but may be digitN too is not local max ?
1171 if(en1 > en2 - fLocMaxCutEDiff)
1173 absIdList[iDigitN] = -1 ;
1174 //printf("\t \t indexN %d not local max cause locMaxCutEDiff\n",iDigit);
1177 } // if Are neighbours
1178 //else printf("\t \t NOT Neighbours \n");
1184 for(iDigit = 0; iDigit < nCells; iDigit++)
1186 if(absIdList[iDigit]>=0 )
1188 absIdList[iDigitN] = absIdList[iDigit] ;
1190 Float_t en = cells->GetCellAmplitude(absIdList[iDigit]);
1191 RecalibrateCellAmplitude(en,calorimeter,absIdList[iDigit]);
1193 if(fMCECellClusFracCorrOn)
1194 en*=GetMCECellClusFracCorrection(en,eCluster)/simuTotWeight;
1196 if(en < fLocMaxCutE) continue; // Maxima only with seed energy at least
1198 maxEList[iDigitN] = en ;
1200 //printf("Local max %d, id %d, en %f\n", iDigit,absIdList[iDigitN],en);
1208 printf("AliCalorimeterUtils::GetNumberOfLocalMaxima() - No local maxima found, assign highest energy cell as maxima, id %d, en cell %2.2f, en cluster %2.2f\n",
1209 idmax,emax,cluster->E());
1211 maxEList[0] = emax ;
1212 absIdList[0] = idmax ;
1217 printf("AliCalorimeterUtils::GetNumberOfLocalMaxima() - In cluster E %2.2f (wth non lin. %2.2f), M02 %2.2f, M20 %2.2f, N maxima %d \n",
1218 cluster->E(),eCluster, cluster->GetM02(),cluster->GetM20(), iDigitN);
1220 if(fDebug > 1) for(Int_t imax = 0; imax < iDigitN; imax++)
1222 printf(" \t i %d, absId %d, Ecell %f\n",imax,absIdList[imax],maxEList[imax]);
1230 //____________________________________
1231 TString AliCalorimeterUtils::GetPass()
1233 // Get passx from filename.
1235 if (!AliAnalysisManager::GetAnalysisManager()->GetTree())
1237 AliError("AliCalorimeterUtils::GetPass() - Pointer to tree = 0, returning null\n");
1241 if (!AliAnalysisManager::GetAnalysisManager()->GetTree()->GetCurrentFile())
1243 AliError("AliCalorimeterUtils::GetPass() - Null pointer input file, returning null\n");
1247 TString pass(AliAnalysisManager::GetAnalysisManager()->GetTree()->GetCurrentFile()->GetName());
1248 if (pass.Contains("ass1")) return TString("pass1");
1249 else if (pass.Contains("ass2")) return TString("pass2");
1250 else if (pass.Contains("ass3")) return TString("pass3");
1251 else if (pass.Contains("ass4")) return TString("pass4");
1252 else if (pass.Contains("ass5")) return TString("pass5");
1253 else if (pass.Contains("LHC11c") && pass.Contains("spc_calo") ) return TString("spc_calo");
1254 else if (pass.Contains("calo") || pass.Contains("high_lumi"))
1256 printf("AliCalorimeterUtils::GetPass() - Path contains <calo> or <high-lumi>, set as <pass1>\n");
1257 return TString("pass1");
1260 // No condition fullfilled, give a default value
1261 printf("AliCalorimeterUtils::GetPass() - Pass number string not found \n");
1266 //________________________________________
1267 void AliCalorimeterUtils::InitParameters()
1269 //Initialize the parameters of the analysis.
1274 fEMCALGeoMatrixSet = kFALSE;
1275 fPHOSGeoMatrixSet = kFALSE;
1277 fRemoveBadChannels = kFALSE;
1279 fNCellsFromPHOSBorder = 0;
1282 fLocMaxCutEDiff = 0.0 ;
1284 // fMaskCellColumns = new Int_t[fNMaskCellColumns];
1285 // fMaskCellColumns[0] = 6 ; fMaskCellColumns[1] = 7 ; fMaskCellColumns[2] = 8 ;
1286 // fMaskCellColumns[3] = 35; fMaskCellColumns[4] = 36; fMaskCellColumns[5] = 37;
1287 // fMaskCellColumns[6] = 12+AliEMCALGeoParams::fgkEMCALCols; fMaskCellColumns[7] = 13+AliEMCALGeoParams::fgkEMCALCols;
1288 // fMaskCellColumns[8] = 40+AliEMCALGeoParams::fgkEMCALCols; fMaskCellColumns[9] = 41+AliEMCALGeoParams::fgkEMCALCols;
1289 // fMaskCellColumns[10]= 42+AliEMCALGeoParams::fgkEMCALCols;
1292 fOADBForEMCAL = kTRUE ;
1293 fOADBForPHOS = kFALSE;
1295 fOADBFilePathEMCAL = "$ALICE_ROOT/OADB/EMCAL" ;
1296 fOADBFilePathPHOS = "$ALICE_ROOT/OADB/PHOS" ;
1298 fImportGeometryFromFile = kTRUE;
1299 fImportGeometryFilePath = "";
1301 fNSuperModulesUsed = 22;
1303 fMCECellClusFracCorrParam[0] = 0.78;
1304 fMCECellClusFracCorrParam[1] =-1.8;
1305 fMCECellClusFracCorrParam[2] =-6.3;
1306 fMCECellClusFracCorrParam[3] = 0.014;
1311 //_____________________________________________________
1312 void AliCalorimeterUtils::InitPHOSBadChannelStatusMap()
1314 //Init PHOS bad channels map
1315 if(fDebug > 0 )printf("AliCalorimeterUtils::InitPHOSBadChannelStatusMap()\n");
1316 //In order to avoid rewriting the same histograms
1317 Bool_t oldStatus = TH1::AddDirectoryStatus();
1318 TH1::AddDirectory(kFALSE);
1320 fPHOSBadChannelMap = new TObjArray(5);
1321 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));
1323 fPHOSBadChannelMap->SetOwner(kTRUE);
1324 fPHOSBadChannelMap->Compress();
1326 //In order to avoid rewriting the same histograms
1327 TH1::AddDirectory(oldStatus);
1330 //______________________________________________________
1331 void AliCalorimeterUtils::InitPHOSRecalibrationFactors()
1333 //Init EMCAL recalibration factors
1334 if(fDebug > 0 )printf("AliCalorimeterUtils::InitPHOSRecalibrationFactors()\n");
1335 //In order to avoid rewriting the same histograms
1336 Bool_t oldStatus = TH1::AddDirectoryStatus();
1337 TH1::AddDirectory(kFALSE);
1339 fPHOSRecalibrationFactors = new TObjArray(5);
1340 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));
1341 //Init the histograms with 1
1342 for (Int_t m = 0; m < 5; m++) {
1343 for (Int_t i = 0; i < 56; i++) {
1344 for (Int_t j = 0; j < 64; j++) {
1345 SetPHOSChannelRecalibrationFactor(m,j,i,1.);
1349 fPHOSRecalibrationFactors->SetOwner(kTRUE);
1350 fPHOSRecalibrationFactors->Compress();
1352 //In order to avoid rewriting the same histograms
1353 TH1::AddDirectory(oldStatus);
1357 //__________________________________________________________
1358 void AliCalorimeterUtils::InitEMCALGeometry(Int_t runnumber)
1360 //Initialize EMCAL geometry if it did not exist previously
1364 if(fEMCALGeoName=="")
1366 if (runnumber < 140000 &&
1367 runnumber >= 100000) fEMCALGeoName = "EMCAL_FIRSTYEARV1";
1368 else if(runnumber >= 140000 &&
1369 runnumber < 171000) fEMCALGeoName = "EMCAL_COMPLETEV1";
1370 else fEMCALGeoName = "EMCAL_COMPLETE12SMV1";
1371 printf("AliCalorimeterUtils::InitEMCALGeometry() - Set EMCAL geometry name to <%s> for run %d\n",fEMCALGeoName.Data(),runnumber);
1374 fEMCALGeo = AliEMCALGeometry::GetInstance(fEMCALGeoName);
1376 // Init geometry, I do not like much to do it like this ...
1377 if(fImportGeometryFromFile && !gGeoManager)
1379 if(fImportGeometryFilePath=="") // If not specified, set location depending on run number
1381 // "$ALICE_ROOT/EVE/alice-data/default_geo.root"
1382 if (runnumber < 140000 &&
1383 runnumber >= 100000) fImportGeometryFilePath = "$ALICE_ROOT/OADB/EMCAL/geometry_2010.root";
1384 if (runnumber >= 140000 &&
1385 runnumber < 171000) fImportGeometryFilePath = "$ALICE_ROOT/OADB/EMCAL/geometry_2011.root";
1386 else fImportGeometryFilePath = "$ALICE_ROOT/OADB/EMCAL/geometry_2012.root"; // 2012-2013
1389 printf("AliCalorimeterUtils::InitEMCALGeometry() - Import %s\n",fImportGeometryFilePath.Data());
1390 TGeoManager::Import(fImportGeometryFilePath) ; // default need file "geometry.root" in local dir!!!!
1396 printf("AliCalorimeterUtils::InitEMCALGeometry(run=%d)",runnumber);
1397 if (!gGeoManager) printf(" - Careful!, gGeoManager not loaded, load misalign matrices");
1403 //_________________________________________________________
1404 void AliCalorimeterUtils::InitPHOSGeometry(Int_t runnumber)
1406 //Initialize PHOS geometry if it did not exist previously
1410 if(fPHOSGeoName=="") fPHOSGeoName = "PHOSgeo";
1412 fPHOSGeo = new AliPHOSGeoUtils(fPHOSGeoName);
1416 printf("AliCalorimeterUtils::InitPHOSGeometry(run=%d)",runnumber);
1417 if (!gGeoManager) printf(" - Careful!, gGeoManager not loaded, load misalign matrices");
1423 //_______________________________________________________________________
1424 Bool_t AliCalorimeterUtils::MaskFrameCluster(Int_t iSM, Int_t ieta) const
1426 //Check if cell is in one of the regions where we have significant amount
1427 //of material in front. Only EMCAL
1430 if(iSM%2) icol+=48; // Impair SM, shift index [0-47] to [48-96]
1432 if (fNMaskCellColumns && fMaskCellColumns)
1434 for (Int_t imask = 0; imask < fNMaskCellColumns; imask++)
1436 if(icol==fMaskCellColumns[imask]) return kTRUE;
1444 //_________________________________________________________
1445 void AliCalorimeterUtils::Print(const Option_t * opt) const
1448 //Print some relevant parameters set for the analysis
1452 printf("***** Print: %s %s ******\n", GetName(), GetTitle() ) ;
1453 printf("Remove Clusters with bad channels? %d\n",fRemoveBadChannels);
1454 printf("Remove Clusters with max cell at less than %d cells from EMCAL border and %d cells from PHOS border\n",
1455 fEMCALRecoUtils->GetNumberOfCellsFromEMCALBorder(), fNCellsFromPHOSBorder);
1456 if(fEMCALRecoUtils->IsEMCALNoBorderAtEta0()) printf("Do not remove EMCAL clusters at Eta = 0\n");
1457 printf("Recalibrate Clusters? %d, run by run %d\n",fRecalibration,fRunDependentCorrection);
1458 printf("Recalculate Clusters Position? %d\n",fRecalculatePosition);
1459 printf("Recalculate Clusters Energy? %d\n",fCorrectELinearity);
1460 printf("Matching criteria: dR < %2.2f[cm], dZ < %2.2f[cm]\n",fCutR,fCutZ);
1462 printf("Loc. Max. E > %2.2f\n", fLocMaxCutE);
1463 printf("Loc. Max. E Diff > %2.2f\n", fLocMaxCutEDiff);
1468 //_____________________________________________________________________________________________
1469 void AliCalorimeterUtils::RecalibrateCellAmplitude(Float_t & amp, TString calo, Int_t id) const
1471 //Recaculate cell energy if recalibration factor
1473 Int_t icol = -1; Int_t irow = -1; Int_t iRCU = -1;
1474 Int_t nModule = GetModuleNumberCellIndexes(id,calo, icol, irow, iRCU);
1476 if (IsRecalibrationOn())
1480 amp *= GetPHOSChannelRecalibrationFactor(nModule,icol,irow);
1484 amp *= GetEMCALChannelRecalibrationFactor(nModule,icol,irow);
1489 //____________________________________________________________________________________________________
1490 void AliCalorimeterUtils::RecalibrateCellTime(Double_t & time, TString calo, Int_t id, Int_t bc) const
1492 // Recalculate time if time recalibration available for EMCAL
1493 // not ready for PHOS
1495 if(calo == "EMCAL" && GetEMCALRecoUtils()->IsTimeRecalibrationOn())
1497 GetEMCALRecoUtils()->RecalibrateCellTime(id,bc,time);
1502 //__________________________________________________________________________
1503 Float_t AliCalorimeterUtils::RecalibrateClusterEnergy(AliVCluster * cluster,
1504 AliVCaloCells * cells)
1506 // Recalibrate the cluster energy, considering the recalibration map and the energy of the cells that compose the cluster.
1508 //Initialize some used variables
1509 Float_t frac = 0., energy = 0.;
1513 //Get the cluster number of cells and list of absId, check what kind of cluster do we have.
1515 UShort_t * index = cluster->GetCellsAbsId() ;
1516 Double_t * fraction = cluster->GetCellsAmplitudeFraction() ;
1518 Int_t ncells = cluster->GetNCells();
1520 TString calo = "EMCAL";
1521 if(cluster->IsPHOS())
1524 //Loop on the cells, get the cell amplitude and recalibration factor, multiply and and to the new energy
1525 for(Int_t icell = 0; icell < ncells; icell++){
1527 Int_t absId = index[icell];
1529 frac = fraction[icell];
1530 if(frac < 1e-3) frac = 1; //in case of EMCAL, this is set as 0, not used.
1532 Float_t amp = cells->GetCellAmplitude(absId);
1533 RecalibrateCellAmplitude(amp,calo, absId);
1536 printf("AliCalorimeterUtils::RecalibrateClusterEnergy() - recalibrate cell: %s, cell fraction %f, cell energy %f\n",
1537 calo.Data(),frac,cells->GetCellAmplitude(absId));
1543 printf("AliCalorimeterUtils::RecalibrateClusterEnergy() - Energy before %f, after %f\n",cluster->E(),energy);
1548 Fatal("RecalibrateClusterEnergy()","Cells pointer does not exist!");
1554 //__________________________________________________________________________
1555 Float_t AliCalorimeterUtils::RecalibrateClusterEnergyWeightCell(AliVCluster * cluster,
1556 AliVCaloCells * cells, Float_t energyOrg)
1558 // Recalibrate the cluster energy, considering the recalibration map and the energy of the cells that compose the cluster.
1559 // Also consider reweighting of cells energy
1561 //Initialize some used variables
1562 Float_t frac = 0., energy = 0.;
1566 //Get the cluster number of cells and list of absId, check what kind of cluster do we have.
1568 UShort_t * index = cluster->GetCellsAbsId() ;
1569 Double_t * fraction = cluster->GetCellsAmplitudeFraction() ;
1571 Int_t ncells = cluster->GetNCells();
1573 TString calo = "EMCAL";
1574 if(cluster->IsPHOS())
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 amp*=GetMCECellClusFracCorrection(amp,energyOrg);
1591 printf("AliCalorimeterUtils::RecalibrateClusterEnergy() - recalibrate cell: %s, cell fraction %f, cell energy %f\n",
1592 calo.Data(),frac,cells->GetCellAmplitude(absId));
1598 printf("AliCalorimeterUtils::RecalibrateClusterEnergy() - Energy before %f, after %f\n",cluster->E(),energy);
1603 Fatal("RecalibrateClusterEnergy()","Cells pointer does not exist!");
1610 //__________________________________________________________________________________________
1611 void AliCalorimeterUtils::RecalculateClusterPosition(AliVCaloCells* cells, AliVCluster* clu)
1614 //Recalculate EMCAL cluster position
1616 fEMCALRecoUtils->RecalculateClusterPosition((AliEMCALGeometry*)fEMCALGeo, cells,clu);
1620 //________________________________________________________________________________
1621 void AliCalorimeterUtils::RecalculateClusterTrackMatching(AliVEvent * event,
1622 TObjArray* clusterArray)
1624 //Recalculate track matching
1626 if (fRecalculateMatching)
1628 fEMCALRecoUtils->FindMatches(event,clusterArray,fEMCALGeo) ;
1629 //AliESDEvent* esdevent = dynamic_cast<AliESDEvent*> (event);
1631 // fEMCALRecoUtils->SetClusterMatchedToTrack(esdevent) ;
1632 // fEMCALRecoUtils->SetTracksMatchedToCluster(esdevent) ;
1637 //___________________________________________________________________________
1638 void AliCalorimeterUtils::SplitEnergy(Int_t absId1, Int_t absId2,
1639 AliVCluster* cluster,
1640 AliVCaloCells* cells,
1641 //Float_t & e1, Float_t & e2,
1642 AliAODCaloCluster* cluster1,
1643 AliAODCaloCluster* cluster2,
1644 Int_t nMax, Int_t eventNumber)
1647 // Split energy of cluster between the 2 local maxima, sum energy on 3x3, and if the 2
1648 // maxima are too close and have common cells, split the energy between the 2
1650 TH2F* hClusterMap = 0 ;
1651 TH2F* hClusterLocMax = 0 ;
1652 TH2F* hCluster1 = 0 ;
1653 TH2F* hCluster2 = 0 ;
1657 hClusterMap = new TH2F("hClusterMap","Cluster Map",48,0,48,24,0,24);
1658 hClusterLocMax = new TH2F("hClusterLocMax","Cluster 2 highest local maxima",48,0,48,24,0,24);
1659 hCluster1 = new TH2F("hCluster1","Cluster 1",48,0,48,24,0,24);
1660 hCluster2 = new TH2F("hCluster2","Cluster 2",48,0,48,24,0,24);
1661 hClusterMap ->SetXTitle("column");
1662 hClusterMap ->SetYTitle("row");
1663 hClusterLocMax ->SetXTitle("column");
1664 hClusterLocMax ->SetYTitle("row");
1665 hCluster1 ->SetXTitle("column");
1666 hCluster1 ->SetYTitle("row");
1667 hCluster2 ->SetXTitle("column");
1668 hCluster2 ->SetYTitle("row");
1671 TString calorimeter = "EMCAL";
1672 if(cluster->IsPHOS())
1675 printf("AliCalorimeterUtils::SplitEnerg() Not supported for PHOS yet \n");
1679 const Int_t ncells = cluster->GetNCells();
1680 Int_t absIdList[ncells];
1682 Float_t e1 = 0, e2 = 0 ;
1683 Int_t icol = -1, irow = -1, iRCU = -1, sm = -1;
1684 Float_t eCluster = 0;
1685 Float_t minCol = 100, minRow = 100, maxCol = -1, maxRow = -1;
1686 for(Int_t iDigit = 0; iDigit < ncells; iDigit++ )
1688 absIdList[iDigit] = cluster->GetCellsAbsId()[iDigit];
1690 Float_t ec = cells->GetCellAmplitude(absIdList[iDigit]);
1691 RecalibrateCellAmplitude(ec,calorimeter, absIdList[iDigit]);
1696 //printf("iDigit %d, absId %d, Ecell %f\n",iDigit,absIdList[iDigit], cells->GetCellAmplitude(absIdList[iDigit]));
1697 sm = GetModuleNumberCellIndexes(absIdList[iDigit], calorimeter, icol, irow, iRCU) ;
1698 if(sm > -1 && sm < 12) // just to avoid compilation warning
1700 if(icol > maxCol) maxCol = icol;
1701 if(icol < minCol) minCol = icol;
1702 if(irow > maxRow) maxRow = irow;
1703 if(irow < minRow) minRow = irow;
1704 hClusterMap->Fill(icol,irow,ec);
1710 // Init counters and variables
1712 UShort_t absIdList1[9] ;
1713 Double_t fracList1 [9] ;
1714 absIdList1[0] = absId1 ;
1715 fracList1 [0] = 1. ;
1717 Float_t ecell1 = cells->GetCellAmplitude(absId1);
1718 RecalibrateCellAmplitude(ecell1, calorimeter, absId1);
1722 UShort_t absIdList2[9] ;
1723 Double_t fracList2 [9] ;
1724 absIdList2[0] = absId2 ;
1725 fracList2 [0] = 1. ;
1727 Float_t ecell2 = cells->GetCellAmplitude(absId2);
1728 RecalibrateCellAmplitude(ecell2, calorimeter, absId2);
1733 Int_t icol1 = -1, irow1 = -1, icol2 = -1, irow2 = -1;
1734 sm = GetModuleNumberCellIndexes(absId1, calorimeter, icol1, irow1, iRCU) ;
1735 hClusterLocMax->Fill(icol1,irow1,ecell1);
1736 sm = GetModuleNumberCellIndexes(absId2, calorimeter, icol2, irow2, iRCU) ;
1737 hClusterLocMax->Fill(icol2,irow2,ecell2);
1740 // Very rough way to share the cluster energy
1741 Float_t eRemain = (eCluster-ecell1-ecell2)/2;
1742 Float_t shareFraction1 = ecell1/eCluster+eRemain/eCluster;
1743 Float_t shareFraction2 = ecell2/eCluster+eRemain/eCluster;
1745 for(Int_t iDigit = 0; iDigit < ncells; iDigit++)
1747 Int_t absId = absIdList[iDigit];
1749 if(absId==absId1 || absId==absId2 || absId < 0) continue;
1751 Float_t ecell = cells->GetCellAmplitude(absId);
1752 RecalibrateCellAmplitude(ecell, calorimeter, absId);
1754 if(AreNeighbours(calorimeter, absId1,absId ))
1756 absIdList1[ncells1]= absId;
1758 if(AreNeighbours(calorimeter, absId2,absId ))
1760 fracList1[ncells1] = shareFraction1;
1761 e1 += ecell*shareFraction1;
1765 fracList1[ncells1] = 1.;
1771 } // neigbour to cell1
1773 if(AreNeighbours(calorimeter, absId2,absId ))
1775 absIdList2[ncells2]= absId;
1777 if(AreNeighbours(calorimeter, absId1,absId ))
1779 fracList2[ncells2] = shareFraction2;
1780 e2 += ecell*shareFraction2;
1784 fracList2[ncells2] = 1.;
1790 } // neigbour to cell2
1794 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",
1795 nMax, eCluster,ecell1,ecell2,e1,e2,eCluster-e1-e2,ncells,ncells1,ncells2,shareFraction1,shareFraction2,shareFraction1+shareFraction2);
1800 cluster1->SetNCells(ncells1);
1801 cluster2->SetNCells(ncells2);
1803 cluster1->SetCellsAbsId(absIdList1);
1804 cluster2->SetCellsAbsId(absIdList2);
1806 cluster1->SetCellsAmplitudeFraction(fracList1);
1807 cluster2->SetCellsAmplitudeFraction(fracList2);
1810 CorrectClusterEnergy(cluster1) ;
1811 CorrectClusterEnergy(cluster2) ;
1813 if(calorimeter=="EMCAL")
1815 GetEMCALRecoUtils()->RecalculateClusterPosition(GetEMCALGeometry(), cells, cluster1);
1816 GetEMCALRecoUtils()->RecalculateClusterPosition(GetEMCALGeometry(), cells, cluster2);
1821 //printf("Cells of cluster1: ");
1822 for(Int_t iDigit = 0; iDigit < ncells1; iDigit++ )
1824 //printf(" %d ",absIdList1[iDigit]);
1826 sm = GetModuleNumberCellIndexes(absIdList1[iDigit], calorimeter, icol, irow, iRCU) ;
1828 Float_t ecell = cells->GetCellAmplitude(absIdList1[iDigit]);
1829 RecalibrateCellAmplitude(ecell, calorimeter, absIdList1[iDigit]);
1831 if( AreNeighbours(calorimeter, absId2,absIdList1[iDigit]) && absId1!=absIdList1[iDigit])
1832 hCluster1->Fill(icol,irow,ecell*shareFraction1);
1834 hCluster1->Fill(icol,irow,ecell);
1838 //printf("Cells of cluster2: ");
1840 for(Int_t iDigit = 0; iDigit < ncells2; iDigit++ )
1842 //printf(" %d ",absIdList2[iDigit]);
1844 sm = GetModuleNumberCellIndexes(absIdList2[iDigit], calorimeter, icol, irow, iRCU) ;
1846 Float_t ecell = cells->GetCellAmplitude(absIdList2[iDigit]);
1847 RecalibrateCellAmplitude(ecell, calorimeter, absIdList2[iDigit]);
1849 if( AreNeighbours(calorimeter, absId1,absIdList2[iDigit]) && absId2!=absIdList2[iDigit])
1850 hCluster2->Fill(icol,irow,ecell*shareFraction2);
1852 hCluster2->Fill(icol,irow,ecell);
1857 gStyle->SetPadRightMargin(0.1);
1858 gStyle->SetPadLeftMargin(0.1);
1859 gStyle->SetOptStat(0);
1860 gStyle->SetOptFit(000000);
1862 if(maxCol-minCol > maxRow-minRow)
1864 maxRow+= maxCol-minCol;
1868 maxCol+= maxRow-minRow;
1871 TCanvas * c= new TCanvas("canvas", "canvas", 4000, 4000) ;
1877 hClusterMap ->SetAxisRange(minCol, maxCol,"X");
1878 hClusterMap ->SetAxisRange(minRow, maxRow,"Y");
1879 hClusterMap ->Draw("colz TEXT");
1884 hClusterLocMax ->SetAxisRange(minCol, maxCol,"X");
1885 hClusterLocMax ->SetAxisRange(minRow, maxRow,"Y");
1886 hClusterLocMax ->Draw("colz TEXT");
1891 hCluster1 ->SetAxisRange(minCol, maxCol,"X");
1892 hCluster1 ->SetAxisRange(minRow, maxRow,"Y");
1893 hCluster1 ->Draw("colz TEXT");
1898 hCluster2 ->SetAxisRange(minCol, maxCol,"X");
1899 hCluster2 ->SetAxisRange(minRow, maxRow,"Y");
1900 hCluster2 ->Draw("colz TEXT");
1902 if(eCluster > 6 )c->Print(Form("clusterFigures/Event%d_E%1.0f_nMax%d_NCell1_%d_NCell2_%d.eps",
1903 eventNumber,cluster->E(),nMax,ncells1,ncells2));
1907 delete hClusterLocMax;