1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
16 //_________________________________________________________________________
17 // Class utility for Calorimeter specific selection methods ///
21 //-- Author: Gustavo Conesa (LPSC-Grenoble)
22 //////////////////////////////////////////////////////////////////////////////
25 // --- ROOT system ---
26 #include <TGeoManager.h>
32 #include <TParticle.h>
34 // --- ANALYSIS system ---
35 #include "AliCalorimeterUtils.h"
36 #include "AliESDEvent.h"
37 #include "AliMCEvent.h"
39 #include "AliAODPWG4Particle.h"
40 #include "AliVCluster.h"
41 #include "AliVCaloCells.h"
42 #include "AliAODCaloCluster.h"
43 #include "AliOADBContainer.h"
44 #include "AliAnalysisManager.h"
45 #include "AliAODMCParticle.h"
48 #include "AliEMCALGeometry.h"
49 #include "AliPHOSGeoUtils.h"
51 ClassImp(AliCalorimeterUtils)
54 //____________________________________________
55 AliCalorimeterUtils::AliCalorimeterUtils() :
59 fEMCALGeo(0x0), fPHOSGeo(0x0),
60 fEMCALGeoMatrixSet(kFALSE), fPHOSGeoMatrixSet(kFALSE),
61 fLoadEMCALMatrices(kFALSE), fLoadPHOSMatrices(kFALSE),
62 fRemoveBadChannels(kFALSE), fPHOSBadChannelMap(0x0),
63 fNCellsFromPHOSBorder(0),
64 fNMaskCellColumns(0), fMaskCellColumns(0x0),
65 fRecalibration(kFALSE), fRunDependentCorrection(kFALSE),
66 fPHOSRecalibrationFactors(), fEMCALRecoUtils(new AliEMCALRecoUtils),
67 fRecalculatePosition(kFALSE), fCorrectELinearity(kFALSE),
68 fRecalculateMatching(kFALSE),
70 fCutEta(20), fCutPhi(20),
71 fLocMaxCutE(0), fLocMaxCutEDiff(0),
72 fPlotCluster(0), fOADBSet(kFALSE),
73 fOADBForEMCAL(kFALSE), fOADBForPHOS(kFALSE),
74 fOADBFilePathEMCAL(""), fOADBFilePathPHOS(""),
75 fImportGeometryFromFile(0), fImportGeometryFilePath(""),
76 fNSuperModulesUsed(0),
77 fMCECellClusFracCorrOn(0), fMCECellClusFracCorrParam()
81 //Initialize parameters
83 for(Int_t i = 0; i < 12; i++) fEMCALMatrix[i] = 0 ;
84 for(Int_t i = 0; i < 5 ; i++) fPHOSMatrix [i] = 0 ;
88 //_________________________________________
89 AliCalorimeterUtils::~AliCalorimeterUtils()
93 //if(fPHOSGeo) delete fPHOSGeo ;
94 if(fEMCALGeo) delete fEMCALGeo ;
96 if(fPHOSBadChannelMap) {
97 fPHOSBadChannelMap->Clear();
98 delete fPHOSBadChannelMap;
101 if(fPHOSRecalibrationFactors) {
102 fPHOSRecalibrationFactors->Clear();
103 delete fPHOSRecalibrationFactors;
106 if(fEMCALRecoUtils) delete fEMCALRecoUtils ;
107 if(fNMaskCellColumns) delete [] fMaskCellColumns;
111 //____________________________________________________
112 void AliCalorimeterUtils::AccessOADB(AliVEvent* event)
114 // Set the AODB calibration, bad channels etc. parameters at least once
115 // alignment matrices from OADB done in SetGeometryMatrices
118 if(fOADBSet) return ;
120 Int_t runnumber = event->GetRunNumber() ;
121 TString pass = GetPass();
126 printf("AliCalorimeterUtils::SetOADBParameters() - Get AODB parameters from EMCAL in %s for run %d, and <%s> \n",fOADBFilePathEMCAL.Data(),runnumber,pass.Data());
128 Int_t nSM = fEMCALGeo->GetNumberOfSuperModules();
131 if(fRemoveBadChannels)
133 AliOADBContainer *contBC=new AliOADBContainer("");
134 contBC->InitFromFile(Form("%s/EMCALBadChannels.root",fOADBFilePathEMCAL.Data()),"AliEMCALBadChannels");
136 TObjArray *arrayBC=(TObjArray*)contBC->GetObject(runnumber);
140 SwitchOnDistToBadChannelRecalculation();
141 printf("AliCalorimeterUtils::SetOADBParameters() - Remove EMCAL bad cells \n");
143 for (Int_t i=0; i<nSM; ++i)
145 TH2I *hbm = GetEMCALChannelStatusMap(i);
150 hbm=(TH2I*)arrayBC->FindObject(Form("EMCALBadChannelMap_Mod%d",i));
154 AliError(Form("Can not get EMCALBadChannelMap_Mod%d",i));
158 hbm->SetDirectory(0);
159 SetEMCALChannelStatusMap(i,hbm);
162 } else printf("AliCalorimeterUtils::SetOADBParameters() - Do NOT remove EMCAL bad channels\n"); // run array
165 // Energy Recalibration
168 AliOADBContainer *contRF=new AliOADBContainer("");
170 contRF->InitFromFile(Form("%s/EMCALRecalib.root",fOADBFilePathEMCAL.Data()),"AliEMCALRecalib");
172 TObjArray *recal=(TObjArray*)contRF->GetObject(runnumber);
176 TObjArray *recalpass=(TObjArray*)recal->FindObject(pass);
180 TObjArray *recalib=(TObjArray*)recalpass->FindObject("Recalib");
184 printf("AliCalorimeterUtils::SetOADBParameters() - Recalibrate EMCAL \n");
185 for (Int_t i=0; i<nSM; ++i)
187 TH2F *h = GetEMCALChannelRecalibrationFactors(i);
192 h = (TH2F*)recalib->FindObject(Form("EMCALRecalFactors_SM%d",i));
196 AliError(Form("Could not load EMCALRecalFactors_SM%d",i));
202 SetEMCALChannelRecalibrationFactors(i,h);
204 }else printf("AliCalorimeterUtils::SetOADBParameters() - Do NOT recalibrate EMCAL, no params object array\n"); // array ok
205 }else printf("AliCalorimeterUtils::SetOADBParameters() - Do NOT recalibrate EMCAL, no params for pass\n"); // array pass ok
206 }else printf("AliCalorimeterUtils::SetOADBParameters() - Do NOT recalibrate EMCAL, no params for run\n"); // run number array ok
208 // once set, apply run dependent corrections if requested
209 //fEMCALRecoUtils->SetRunDependentCorrections(runnumber);
211 } // Recalibration on
213 // Energy Recalibration, apply on top of previous calibration factors
214 if(fRunDependentCorrection)
216 AliOADBContainer *contRFTD=new AliOADBContainer("");
218 contRFTD->InitFromFile(Form("%s/EMCALTemperatureCorrCalib.root",fOADBFilePathEMCAL.Data()),"AliEMCALRunDepTempCalibCorrections");
220 TH1S *htd=(TH1S*)contRFTD->GetObject(runnumber);
222 //If it did not exist for this run, get closes one
225 AliWarning(Form("No TemperatureCorrCalib Objects for run: %d",runnumber));
226 // let's get the closest runnumber instead then..
229 Int_t maxEntry = contRFTD->GetNumberOfEntries();
231 while ( (ic < maxEntry) && (contRFTD->UpperLimit(ic) < runnumber) ) {
236 Int_t closest = lower;
237 if ( (ic<maxEntry) &&
238 (contRFTD->LowerLimit(ic)-runnumber) < (runnumber - contRFTD->UpperLimit(lower)) ) {
242 AliWarning(Form("TemperatureCorrCalib Objects found closest id %d from run: %d", closest, contRFTD->LowerLimit(closest)));
243 htd = (TH1S*) contRFTD->GetObjectByIndex(closest);
248 printf("AliCalorimeterUtils::SetOADBParameters() - Recalibrate (Temperature) EMCAL \n");
250 for (Int_t ism=0; ism<nSM; ++ism)
252 for (Int_t icol=0; icol<48; ++icol)
254 for (Int_t irow=0; irow<24; ++irow)
256 Float_t factor = GetEMCALChannelRecalibrationFactor(ism,icol,irow);
258 Int_t absID = fEMCALGeo->GetAbsCellIdFromCellIndexes(ism, irow, icol); // original calibration factor
259 factor *= htd->GetBinContent(absID) / 10000. ; // correction dependent on T
260 //printf("\t ism %d, icol %d, irow %d,absID %d, corrA %2.3f, corrB %2.3f, corrAB %2.3f\n",ism, icol, irow, absID,
261 // GetEMCALChannelRecalibrationFactor(ism,icol,irow) , htd->GetBinContent(absID) / 10000., factor);
262 SetEMCALChannelRecalibrationFactor(ism,icol,irow,factor);
266 }else printf("AliCalorimeterUtils::SetOADBParameters() - Do NOT recalibrate EMCAL with T variations, no params TH1 \n");
267 } // Run by Run T calibration
269 // Time Recalibration
270 if(fEMCALRecoUtils->IsTimeRecalibrationOn())
272 AliOADBContainer *contTRF=new AliOADBContainer("");
274 contTRF->InitFromFile(Form("%s/EMCALTimeCalib.root",fOADBFilePathEMCAL.Data()),"AliEMCALTimeCalib");
276 TObjArray *trecal=(TObjArray*)contTRF->GetObject(runnumber);
280 TString passM = pass;
281 if(pass=="spc_calo") passM = "pass1";
282 TObjArray *trecalpass=(TObjArray*)trecal->FindObject(passM);
286 printf("AliCalorimeterUtils::SetOADBParameters() - Time Recalibrate EMCAL \n");
287 for (Int_t ibc = 0; ibc < 4; ++ibc)
289 TH1F *h = GetEMCALChannelTimeRecalibrationFactors(ibc);
294 h = (TH1F*)trecalpass->FindObject(Form("hAllTimeAvBC%d",ibc));
298 AliError(Form("Could not load hAllTimeAvBC%d",ibc));
304 SetEMCALChannelTimeRecalibrationFactors(ibc,h);
305 } // bunch crossing loop
306 }else printf("AliCalorimeterUtils::SetOADBParameters() - Do NOT recalibrate time EMCAL, no params for pass\n"); // array pass ok
307 }else printf("AliCalorimeterUtils::SetOADBParameters() - Do NOT recalibrate time EMCAL, no params for run\n"); // run number array ok
309 } // Recalibration on
316 printf("AliCalorimeterUtils::SetOADBParameters() - Get AODB parameters from PHOS in %s for run %d, and <%s> \n",fOADBFilePathPHOS.Data(),runnumber,pass.Data());
319 if(fRemoveBadChannels)
321 AliOADBContainer badmapContainer(Form("phosBadMap"));
322 TString fileName="$ALICE_ROOT/OADB/PHOS/PHOSBadMaps.root";
323 badmapContainer.InitFromFile(Form("%s/PHOSBadMaps.root",fOADBFilePathPHOS.Data()),"phosBadMap");
325 //Use a fixed run number from year 2010, this year not available yet.
326 TObjArray *maps = (TObjArray*)badmapContainer.GetObject(139000,"phosBadMap");
329 printf("AliCalorimeterUtils::SetOADBParameters() - Can not read PHOS bad map for run %d.\n",runnumber) ;
333 printf("AliCalorimeterUtils::SetOADBParameters() - Setting PHOS bad map with name %s \n",maps->GetName()) ;
334 for(Int_t mod=1; mod<5;mod++)
336 TH2I *hbmPH = GetPHOSChannelStatusMap(mod);
341 hbmPH = (TH2I*)maps->At(mod);
343 if(hbmPH) hbmPH->SetDirectory(0);
345 SetPHOSChannelStatusMap(mod-1,hbmPH);
349 } // Remove bad channels
352 // Parameters already set once, so do not it again
357 //_____________________________________________________________
358 void AliCalorimeterUtils::AccessGeometry(AliVEvent* inputEvent)
360 //Set the calorimeters transformation matrices and init geometry
362 // First init the geometry, a priory not done before
363 Int_t runnumber = inputEvent->GetRunNumber() ;
364 InitPHOSGeometry (runnumber);
365 InitEMCALGeometry(runnumber);
367 //Get the EMCAL transformation geometry matrices from ESD
368 if(!fEMCALGeoMatrixSet && fEMCALGeo)
370 if(fLoadEMCALMatrices)
372 printf("AliCalorimeterUtils::AccessGeometry() - Load user defined EMCAL geometry matrices\n");
375 AliOADBContainer emcGeoMat("AliEMCALgeo");
376 emcGeoMat.InitFromFile(Form("%s/EMCALlocal2master.root",fOADBFilePathEMCAL.Data()),"AliEMCALgeo");
377 TObjArray *matEMCAL=(TObjArray*)emcGeoMat.GetObject(runnumber,"EmcalMatrices");
379 for(Int_t mod=0; mod < (fEMCALGeo->GetEMCGeometry())->GetNumberOfSuperModules(); mod++)
381 if (!fEMCALMatrix[mod]) // Get it from OADB
384 printf("AliCalorimeterUtils::AccessGeometry() - EMCAL matrices SM %d, %p\n",
385 mod,((TGeoHMatrix*) matEMCAL->At(mod)));
386 //((TGeoHMatrix*) matEMCAL->At(mod))->Print();
388 fEMCALMatrix[mod] = (TGeoHMatrix*) matEMCAL->At(mod) ;
391 if(fEMCALMatrix[mod])
394 fEMCALMatrix[mod]->Print();
396 fEMCALGeo->SetMisalMatrix(fEMCALMatrix[mod],mod) ;
400 fEMCALGeoMatrixSet = kTRUE;//At least one, so good
403 else if (!gGeoManager)
406 printf(" AliCalorimeterUtils::AccessGeometry() - Load EMCAL misalignment matrices. \n");
407 if(!strcmp(inputEvent->GetName(),"AliESDEvent"))
409 for(Int_t mod=0; mod < (fEMCALGeo->GetEMCGeometry())->GetNumberOfSuperModules(); mod++)
411 //printf("Load ESD matrix %d, %p\n",mod,((AliESDEvent*)inputEvent)->GetEMCALMatrix(mod));
412 if(((AliESDEvent*)inputEvent)->GetEMCALMatrix(mod))
414 fEMCALGeo->SetMisalMatrix(((AliESDEvent*)inputEvent)->GetEMCALMatrix(mod),mod) ;
416 }// loop over super modules
418 fEMCALGeoMatrixSet = kTRUE;//At least one, so good
424 printf("AliCalorimeterUtils::SetGeometryTransformationMatrices() - Setting of EMCAL transformation matrixes for AODs not implemented yet. \n Import geometry.root file\n");
426 }//Get matrix from data
429 fEMCALGeoMatrixSet = kTRUE;
431 }//EMCAL geo && no geoManager
433 //Get the PHOS transformation geometry matrices from ESD
434 if(!fPHOSGeoMatrixSet && fPHOSGeo)
436 if(fLoadPHOSMatrices)
438 printf("AliCalorimeterUtils::SetGeometryTransformationMatrices() - Load user defined PHOS geometry matrices\n");
441 AliOADBContainer geomContainer("phosGeo");
442 geomContainer.InitFromFile(Form("%s/PHOSGeometry.root",fOADBFilePathPHOS.Data()),"PHOSRotationMatrixes");
443 TObjArray *matPHOS = (TObjArray*)geomContainer.GetObject(139000,"PHOSRotationMatrixes");
445 for(Int_t mod = 0 ; mod < 5 ; mod++)
447 if (!fPHOSMatrix[mod]) // Get it from OADB
450 printf("AliCalorimeterUtils::SetGeometryTransformationMatrices() - PHOS matrices module %d, %p\n",
451 mod,((TGeoHMatrix*) matPHOS->At(mod)));
452 //((TGeoHMatrix*) matPHOS->At(mod))->Print();
454 fPHOSMatrix[mod] = (TGeoHMatrix*) matPHOS->At(mod) ;
457 // Set it, if it exists
461 fPHOSMatrix[mod]->Print();
463 fPHOSGeo->SetMisalMatrix(fPHOSMatrix[mod],mod) ;
467 fPHOSGeoMatrixSet = kTRUE;//At least one, so good
470 else if (!gGeoManager)
473 printf(" AliCalorimeterUtils::SetGeometryTransformationMatrices() - Load PHOS misalignment matrices. \n");
474 if(!strcmp(inputEvent->GetName(),"AliESDEvent"))
476 for(Int_t mod = 0; mod < 5; mod++)
478 if( ((AliESDEvent*)inputEvent)->GetPHOSMatrix(mod))
480 //printf("PHOS: mod %d, matrix %p\n",mod, ((AliESDEvent*)inputEvent)->GetPHOSMatrix(mod));
481 fPHOSGeo->SetMisalMatrix( ((AliESDEvent*)inputEvent)->GetPHOSMatrix(mod),mod) ;
483 }// loop over modules
484 fPHOSGeoMatrixSet = kTRUE; //At least one so good
489 printf("AliCalorimeterUtils::SetGeometryTransformationMatrices() - Setting of EMCAL transformation matrixes for AODs not implemented yet. \n Import geometry.root file\n");
491 }// get matrix from data
494 fPHOSGeoMatrixSet = kTRUE;
496 }//PHOS geo and geoManager was not set
500 //________________________________________________________________________________________
501 Bool_t AliCalorimeterUtils::AreNeighbours(TString calo, Int_t absId1, Int_t absId2 ) const
503 // Tells if (true) or not (false) two cells are neighbours
504 // A neighbour is defined as being two cells which share a side or corner
506 Bool_t areNeighbours = kFALSE ;
508 Int_t iRCU1 = -1, irow1 = -1, icol1 = -1;
509 Int_t iRCU2 = -1, irow2 = -1, icol2 = -1;
511 Int_t rowdiff = 0, coldiff = 0;
513 Int_t nSupMod1 = GetModuleNumberCellIndexes(absId1, calo, icol1, irow1, iRCU1);
514 Int_t nSupMod2 = GetModuleNumberCellIndexes(absId2, calo, icol2, irow2, iRCU2);
516 if(calo=="EMCAL" && nSupMod1!=nSupMod2)
518 // In case of a shared cluster, index of SM in C side, columns start at 48 and ends at 48*2-1
519 // C Side impair SM, nSupMod%2=1; A side pair SM nSupMod%2=0
520 if(nSupMod1%2) icol1+=AliEMCALGeoParams::fgkEMCALCols;
521 else icol2+=AliEMCALGeoParams::fgkEMCALCols;
524 rowdiff = TMath::Abs( irow1 - irow2 ) ;
525 coldiff = TMath::Abs( icol1 - icol2 ) ;
527 //if (( coldiff <= 1 ) && ( rowdiff <= 1 ) && (coldiff + rowdiff > 0))
528 if ((coldiff + rowdiff == 1 ))
529 areNeighbours = kTRUE ;
531 return areNeighbours;
534 //_____________________________________________________________________________________
535 Bool_t AliCalorimeterUtils::IsClusterSharedByTwoSuperModules(const AliEMCALGeometry * geom,
536 AliVCluster* cluster)
538 //Method that checks if any of the cells in the cluster belongs to a different SM
548 for(Int_t iDigit=0; iDigit < cluster->GetNCells(); iDigit++)
550 //Get from the absid the supermodule, tower and eta/phi numbers
551 geom->GetCellIndex(cluster->GetCellAbsId(iDigit),iSupMod,iTower,iIphi,iIeta);
552 geom->GetCellPhiEtaIndexInSModule(iSupMod,iTower,iIphi,iIeta, iphi,ieta);
554 //Check if there are cells of different SM
555 if (iDigit == 0 ) iSM0 = iSupMod;
556 else if(iSupMod!= iSM0) return kTRUE;
563 //_____________________________________________________________________________________
564 Bool_t AliCalorimeterUtils::CheckCellFiducialRegion(AliVCluster* cluster,
565 AliVCaloCells* cells) const
568 // Given the list of AbsId of the cluster, get the maximum cell and
569 // check if there are fNCellsFromBorder from the calorimeter border
571 //If the distance to the border is 0 or negative just exit accept all clusters
572 if(cells->GetType()==AliVCaloCells::kEMCALCell && fEMCALRecoUtils->GetNumberOfCellsFromEMCALBorder() <= 0 ) return kTRUE;
573 if(cells->GetType()==AliVCaloCells::kPHOSCell && fNCellsFromPHOSBorder <= 0 ) return kTRUE;
578 for(Int_t i = 0; i < cluster->GetNCells() ; i++)
580 Int_t absId = cluster->GetCellAbsId(i) ;
581 Float_t amp = cells->GetCellAmplitude(absId);
590 printf("AliCalorimeterUtils::CheckCellFiducialRegion() - Cluster Max AbsId %d, Cell Energy %2.2f, Cluster Energy %2.2f\n",
591 absIdMax, ampMax, cluster->E());
593 if(absIdMax==-1) return kFALSE;
595 //Check if the cell is close to the borders:
596 Bool_t okrow = kFALSE;
597 Bool_t okcol = kFALSE;
599 if(cells->GetType()==AliVCaloCells::kEMCALCell)
601 Int_t iTower = -1, iIphi = -1, iIeta = -1, iphi = -1, ieta = -1, iSM = -1;
602 fEMCALGeo->GetCellIndex(absIdMax,iSM,iTower,iIphi,iIeta);
603 fEMCALGeo->GetCellPhiEtaIndexInSModule(iSM,iTower,iIphi, iIeta,iphi,ieta);
604 if(iSM < 0 || iphi < 0 || ieta < 0 ) {
605 Fatal("CheckCellFidutialRegion","Negative value for super module: %d, or cell ieta: %d, or cell iphi: %d, check EMCAL geometry name\n",iSM,ieta,iphi);
609 Int_t nborder = fEMCALRecoUtils->GetNumberOfCellsFromEMCALBorder();
612 if(iphi >= nborder && iphi < 24-nborder) okrow =kTRUE;
616 if(fEMCALGeoName.Contains("12SM")) // 1/3 SM
618 if(iphi >= nborder && iphi < 8-nborder) okrow =kTRUE;
622 if(iphi >= nborder && iphi <12-nborder) okrow =kTRUE;
627 if(!fEMCALRecoUtils->IsEMCALNoBorderAtEta0())
629 if(ieta > nborder && ieta < 48-nborder) okcol =kTRUE;
635 if(ieta >= nborder) okcol = kTRUE;
639 if(ieta < 48-nborder) okcol = kTRUE;
645 printf("AliCalorimeterUtils::CheckCellFiducialRegion() - EMCAL Cluster in %d cells fiducial volume: ieta %d, iphi %d, SM %d ?",
646 nborder, ieta, iphi, iSM);
647 if (okcol && okrow ) printf(" YES \n");
648 else printf(" NO: column ok? %d, row ok? %d \n",okcol,okrow);
651 else if ( cells->GetType() == AliVCaloCells::kPHOSCell )
654 Int_t irow = -1, icol = -1;
655 fPHOSGeo->AbsToRelNumbering(absIdMax,relId);
659 if(irow >= fNCellsFromPHOSBorder && irow < 64-fNCellsFromPHOSBorder) okrow =kTRUE;
660 if(icol >= fNCellsFromPHOSBorder && icol < 56-fNCellsFromPHOSBorder) okcol =kTRUE;
663 printf("AliCalorimeterUtils::CheckCellFiducialRegion() - PHOS Cluster in %d cells fiducial volume: icol %d, irow %d, Module %d?",
664 fNCellsFromPHOSBorder, icol, irow, relId[0]-1);
665 if (okcol && okrow ) printf(" YES \n");
666 else printf(" NO: column ok? %d, row ok? %d \n",okcol,okrow);
670 if (okcol && okrow) return kTRUE;
675 //__________________________________________________________________________________________________________
676 Bool_t AliCalorimeterUtils::ClusterContainsBadChannel(TString calorimeter, UShort_t* cellList, Int_t nCells)
678 // Check that in the cluster cells, there is no bad channel of those stored
679 // in fEMCALBadChannelMap or fPHOSBadChannelMap
681 if (!fRemoveBadChannels) return kFALSE;
682 //printf("fEMCALBadChannelMap %p, fPHOSBadChannelMap %p \n",fEMCALBadChannelMap,fPHOSBadChannelMap);
683 if(calorimeter == "EMCAL" && !fEMCALRecoUtils->GetEMCALChannelStatusMap(0)) return kFALSE;
684 if(calorimeter == "PHOS" && !fPHOSBadChannelMap) return kFALSE;
689 for(Int_t iCell = 0; iCell<nCells; iCell++){
691 //Get the column and row
692 if(calorimeter == "EMCAL"){
693 return fEMCALRecoUtils->ClusterContainsBadChannel((AliEMCALGeometry*)fEMCALGeo,cellList,nCells);
695 else if(calorimeter=="PHOS"){
697 fPHOSGeo->AbsToRelNumbering(cellList[iCell],relId);
701 if(fPHOSBadChannelMap->GetEntries() <= imod)continue;
702 //printf("PHOS bad channels imod %d, icol %d, irow %d\n",imod, irow, icol);
703 if(GetPHOSChannelStatus(imod, irow, icol)) return kTRUE;
707 }// cell cluster loop
713 //_______________________________________________________________
714 void AliCalorimeterUtils::CorrectClusterEnergy(AliVCluster *clus)
716 // Correct cluster energy non linearity
718 clus->SetE(fEMCALRecoUtils->CorrectClusterEnergyLinearity(clus));
722 //________________________________________________________________________________________
723 Int_t AliCalorimeterUtils::GetMaxEnergyCell(AliVCaloCells* cells, const AliVCluster* clu,
724 Float_t & clusterFraction) const
727 //For a given CaloCluster gets the absId of the cell
728 //with maximum energy deposit.
730 if( !clu || !cells ){
731 AliInfo("Cluster or cells pointer is null!");
738 Float_t fraction = 1.;
739 Float_t recalFactor = 1.;
740 Int_t cellAbsId =-1 , absId =-1 ;
741 Int_t iSupMod =-1 , ieta =-1 , iphi = -1, iRCU = -1;
743 TString calo = "EMCAL";
744 if(clu->IsPHOS()) calo = "PHOS";
746 for (Int_t iDig=0; iDig< clu->GetNCells(); iDig++) {
748 cellAbsId = clu->GetCellAbsId(iDig);
750 fraction = clu->GetCellAmplitudeFraction(iDig);
751 if(fraction < 1e-4) fraction = 1.; // in case unfolding is off
753 iSupMod = GetModuleNumberCellIndexes(cellAbsId, calo, ieta, iphi, iRCU);
755 if(IsRecalibrationOn()) {
756 if(calo=="EMCAL") recalFactor = GetEMCALChannelRecalibrationFactor(iSupMod,ieta,iphi);
757 else recalFactor = GetPHOSChannelRecalibrationFactor (iSupMod,iphi,ieta);
760 eCell = cells->GetCellAmplitude(cellAbsId)*fraction*recalFactor;
772 clusterFraction = (eTot-eMax)/eTot; //Do not use cluster energy in case it was corrected for non linearity.
780 //___________________________________________________________________________________
781 AliVTrack * AliCalorimeterUtils::GetMatchedTrack(AliVCluster* cluster,
782 AliVEvent* event, Int_t index) const
784 // Get the matched track given its index, usually just the first match
785 // Since it is different for ESDs and AODs here it is a wrap method to do it
787 AliVTrack *track = 0;
789 // EMCAL case only when matching is recalculated
790 if(cluster->IsEMCAL() && IsRecalculationOfClusterTrackMatchingOn())
792 Int_t trackIndex = fEMCALRecoUtils->GetMatchedTrackIndex(cluster->GetID());
793 //printf("track index %d, cluster ID %d \n ",trackIndex,cluster->GetID());
797 printf("AliCalorimeterUtils::GetMatchedTrack() - Wrong track index %d, from recalculation\n", trackIndex);
801 track = dynamic_cast<AliVTrack*> (event->GetTrack(trackIndex));
808 // Normal case, get info from ESD or AOD
810 if(!strcmp("AliESDCaloCluster",Form("%s",cluster->ClassName())))
812 Int_t iESDtrack = cluster->GetTrackMatchedIndex();
816 printf("AliCalorimeterUtils::GetMatchedTrack() - Wrong track index %d\n", index);
820 track = dynamic_cast<AliVTrack*> (event->GetTrack(iESDtrack));
825 if(cluster->GetNTracksMatched() > 0 )
826 track = dynamic_cast<AliVTrack*>(cluster->GetTrackMatched(index));
832 //______________________________________________________________________________________________
833 Float_t AliCalorimeterUtils::GetMCECellClusFracCorrection(Float_t eCell, Float_t eCluster) const
835 // Correction factor for cell energy in cluster to temptatively match Data and MC
836 if( eCluster <= 0 || eCluster < eCell )
838 printf("AliCalorimeterUtils::GetMCECellClusFracCorrection() - Bad values eCell=%f, eCluster %f\n",eCell,eCluster);
842 Float_t frac = eCell / eCluster;
844 Float_t correction = fMCECellClusFracCorrParam[0] +
845 TMath::Exp( frac*fMCECellClusFracCorrParam[2]+fMCECellClusFracCorrParam[1] ) +
846 fMCECellClusFracCorrParam[3]/TMath::Sqrt(frac);
848 // printf("AliCalorimeterUtils::GetMCECellClusFracCorrection(eCell=%f, eCluster %f, frac %f) = %f\n",eCell, eCluster, frac, correction);
849 // printf("\t %2.2f + TMath::Exp( %2.3f*%2.2f + %2.2f ) + %2.2f/TMath::Sqrt(%2.3f)) = %f\n",
850 // fMCECellClusFracCorrParam[0],frac,fMCECellClusFracCorrParam[2],fMCECellClusFracCorrParam[1],fMCECellClusFracCorrParam[3], frac, correction);
855 //_____________________________________________________________________________________________________
856 Int_t AliCalorimeterUtils::GetModuleNumber(AliAODPWG4Particle * particle, AliVEvent * inputEvent) const
858 //Get the EMCAL/PHOS module number that corresponds to this particle
861 if(particle->GetDetector()=="EMCAL")
863 fEMCALGeo->GetAbsCellIdFromEtaPhi(particle->Eta(),particle->Phi(), absId);
866 printf("AliCalorimeterUtils::GetModuleNumber(PWG4AOD) - EMCAL: cluster eta %f, phi %f, absid %d, SuperModule %d\n",
867 particle->Eta(), particle->Phi()*TMath::RadToDeg(),absId, fEMCALGeo->GetSuperModuleNumber(absId));
869 return fEMCALGeo->GetSuperModuleNumber(absId) ;
871 else if(particle->GetDetector()=="PHOS")
873 // In case we use the MC reader, the input are TParticles,
874 // in this case use the corresponing method in PHOS Geometry to get the particle.
875 if(strcmp(inputEvent->ClassName(), "AliMCEvent") == 0 )
878 Double_t z = 0., x=0.;
879 TParticle* primary = 0x0;
880 AliStack * stack = ((AliMCEvent*)inputEvent)->Stack();
883 primary = stack->Particle(particle->GetCaloLabel(0));
887 Fatal("GetModuleNumber(PWG4AOD)", "Stack not available, stop!");
892 fPHOSGeo->ImpactOnEmc(primary,mod,z,x) ;
896 Fatal("GetModuleNumber(PWG4AOD)", "Primary not available, stop!");
900 // Input are ESDs or AODs, get the PHOS module number like this.
904 //AliVCluster *cluster = inputEvent->GetCaloCluster(particle->GetCaloLabel(0));
905 //return GetModuleNumber(cluster);
914 //_____________________________________________________________________
915 Int_t AliCalorimeterUtils::GetModuleNumber(AliVCluster * cluster) const
917 //Get the EMCAL/PHOS module number that corresponds to this cluster
921 if(fDebug > 1) printf("AliCalorimeterUtils::GetModuleNumber() - NUL Cluster, please check!!!");
926 if ( cluster->GetNCells() <= 0 ) return -1;
928 Int_t absId = cluster->GetCellAbsId(0);
930 if ( absId < 0 ) return -1;
932 if( cluster->IsEMCAL() )
934 if(fDebug > 2) printf("AliCalorimeterUtils::GetModuleNumber() - EMCAL absid %d, SuperModule %d\n",absId, fEMCALGeo->GetSuperModuleNumber(absId));
936 return fEMCALGeo->GetSuperModuleNumber(absId) ;
938 else if ( cluster->IsPHOS() )
941 fPHOSGeo->AbsToRelNumbering(absId,relId);
943 if(fDebug > 2) printf("AliCalorimeterUtils::GetModuleNumber() - PHOS absid %d Module %d\n",absId, relId[0]-1);
951 //___________________________________________________________________________________________________
952 Int_t AliCalorimeterUtils::GetModuleNumberCellIndexes(Int_t absId, TString calo,
953 Int_t & icol, Int_t & irow, Int_t & iRCU) const
955 //Get the EMCAL/PHOS module, columns, row and RCU number that corresponds to this absId
959 if ( absId < 0) return -1 ;
961 if ( calo == "EMCAL" )
963 Int_t iTower = -1, iIphi = -1, iIeta = -1;
964 fEMCALGeo->GetCellIndex(absId,imod,iTower,iIphi,iIeta);
965 fEMCALGeo->GetCellPhiEtaIndexInSModule(imod,iTower,iIphi, iIeta,irow,icol);
967 if(imod < 0 || irow < 0 || icol < 0 )
969 Fatal("GetModuleNumberCellIndexes()","Negative value for super module: %d, or cell icol: %d, or cell irow: %d, check EMCAL geometry name\n",imod,icol,irow);
975 if (0<=irow&&irow<8) iRCU=0; // first cable row
976 else if (8<=irow&&irow<16 && 0<=icol&&icol<24) iRCU=0; // first half;
979 else if (8<=irow&&irow<16 && 24<=icol&&icol<48) iRCU=1; // second half;
981 else if (16<=irow&&irow<24) iRCU=1; // third cable row
983 if (imod%2==1) iRCU = 1 - iRCU; // swap for odd=C side, to allow us to cable both sides the same
987 // Last 2 SM have one single SRU, just assign RCU 0
993 Fatal("GetModuleNumberCellIndexes()","Wrong EMCAL RCU number = %d\n", iRCU);
1002 fPHOSGeo->AbsToRelNumbering(absId,relId);
1006 iRCU= (Int_t)(relId[2]-1)/16 ;
1007 //Int_t iBranch= (Int_t)(relid[3]-1)/28 ; //0 to 1
1010 Fatal("GetModuleNumberCellIndexes()","Wrong PHOS RCU number = %d\n", iRCU);
1018 //___________________________________________________________________________________________
1019 Int_t AliCalorimeterUtils::GetNumberOfLocalMaxima(AliVCluster* cluster, AliVCaloCells* cells)
1021 // Find local maxima in cluster
1023 const Int_t nc = cluster->GetNCells();
1024 Int_t absIdList[nc];
1025 Float_t maxEList[nc];
1027 Int_t nMax = GetNumberOfLocalMaxima(cluster, cells, absIdList, maxEList);
1033 //___________________________________________________________________________________________
1034 Int_t AliCalorimeterUtils::GetNumberOfLocalMaxima(AliVCluster* cluster, AliVCaloCells* cells,
1035 Int_t *absIdList, Float_t *maxEList)
1037 // Find local maxima in cluster
1043 const Int_t nCells = cluster->GetNCells();
1045 Float_t eCluster = RecalibrateClusterEnergy(cluster, cells);// recalculate cluster energy, avoid non lin correction.
1047 Float_t simuTotWeight = 0;
1048 if(fMCECellClusFracCorrOn)
1050 simuTotWeight = RecalibrateClusterEnergyWeightCell(cluster, cells,eCluster);// same but apply a weight
1051 simuTotWeight/= eCluster;
1054 TString calorimeter = "EMCAL";
1055 if(!cluster->IsEMCAL()) calorimeter = "PHOS";
1057 //printf("cluster : ncells %d \n",nCells);
1061 for(iDigit = 0; iDigit < nCells ; iDigit++)
1063 absIdList[iDigit] = cluster->GetCellsAbsId()[iDigit] ;
1064 Float_t en = cells->GetCellAmplitude(absIdList[iDigit]);
1065 RecalibrateCellAmplitude(en,calorimeter,absIdList[iDigit]);
1067 if(fMCECellClusFracCorrOn)
1068 en*=GetMCECellClusFracCorrection(en,eCluster)/simuTotWeight;
1073 idmax = absIdList[iDigit] ;
1075 //Int_t icol = -1, irow = -1, iRCU = -1;
1076 //Int_t sm = GetModuleNumberCellIndexes(absIdList[iDigit], calorimeter, icol, irow, iRCU) ;
1077 //printf("\t cell %d, id %d, sm %d, col %d, row %d, e %f\n", iDigit, absIdList[iDigit], sm, icol, irow, en );
1080 for(iDigit = 0 ; iDigit < nCells; iDigit++)
1082 if(absIdList[iDigit]>=0)
1084 absId1 = cluster->GetCellsAbsId()[iDigit];
1086 Float_t en1 = cells->GetCellAmplitude(absId1);
1087 RecalibrateCellAmplitude(en1,calorimeter,absId1);
1089 if(fMCECellClusFracCorrOn)
1090 en1*=GetMCECellClusFracCorrection(en1,eCluster)/simuTotWeight;
1092 //printf("%d : absIDi %d, E %f\n",iDigit, absId1,en1);
1094 for(iDigitN = 0; iDigitN < nCells; iDigitN++)
1096 absId2 = cluster->GetCellsAbsId()[iDigitN] ;
1098 if(absId2==-1 || absId2==absId1) continue;
1100 //printf("\t %d : absIDj %d\n",iDigitN, absId2);
1102 Float_t en2 = cells->GetCellAmplitude(absId2);
1103 RecalibrateCellAmplitude(en2,calorimeter,absId2);
1105 if(fMCECellClusFracCorrOn)
1106 en2*=GetMCECellClusFracCorrection(en2,eCluster)/simuTotWeight;
1108 //printf("\t %d : absIDj %d, E %f\n",iDigitN, absId2,en2);
1110 if ( AreNeighbours(calorimeter, absId1, absId2) )
1112 // printf("\t \t Neighbours \n");
1115 absIdList[iDigitN] = -1 ;
1116 //printf("\t \t indexN %d not local max\n",iDigitN);
1117 // but may be digit too is not local max ?
1118 if(en1 < en2 + fLocMaxCutEDiff) {
1119 //printf("\t \t index %d not local max cause locMaxCutEDiff\n",iDigit);
1120 absIdList[iDigit] = -1 ;
1125 absIdList[iDigit] = -1 ;
1126 //printf("\t \t index %d not local max\n",iDigitN);
1127 // but may be digitN too is not local max ?
1128 if(en1 > en2 - fLocMaxCutEDiff)
1130 absIdList[iDigitN] = -1 ;
1131 //printf("\t \t indexN %d not local max cause locMaxCutEDiff\n",iDigit);
1134 } // if Are neighbours
1135 //else printf("\t \t NOT Neighbours \n");
1141 for(iDigit = 0; iDigit < nCells; iDigit++)
1143 if(absIdList[iDigit]>=0 )
1145 absIdList[iDigitN] = absIdList[iDigit] ;
1147 Float_t en = cells->GetCellAmplitude(absIdList[iDigit]);
1148 RecalibrateCellAmplitude(en,calorimeter,absIdList[iDigit]);
1150 if(fMCECellClusFracCorrOn)
1151 en*=GetMCECellClusFracCorrection(en,eCluster)/simuTotWeight;
1153 if(en < fLocMaxCutE) continue; // Maxima only with seed energy at least
1155 maxEList[iDigitN] = en ;
1157 //printf("Local max %d, id %d, en %f\n", iDigit,absIdList[iDigitN],en);
1165 printf("AliCalorimeterUtils::GetNumberOfLocalMaxima() - No local maxima found, assign highest energy cell as maxima, id %d, en cell %2.2f, en cluster %2.2f\n",
1166 idmax,emax,cluster->E());
1168 maxEList[0] = emax ;
1169 absIdList[0] = idmax ;
1174 printf("AliCalorimeterUtils::GetNumberOfLocalMaxima() - In cluster E %2.2f (wth non lin. %2.2f), M02 %2.2f, M20 %2.2f, N maxima %d \n",
1175 cluster->E(),eCluster, cluster->GetM02(),cluster->GetM20(), iDigitN);
1177 if(fDebug > 1) for(Int_t imax = 0; imax < iDigitN; imax++)
1179 printf(" \t i %d, absId %d, Ecell %f\n",imax,absIdList[imax],maxEList[imax]);
1187 //____________________________________
1188 TString AliCalorimeterUtils::GetPass()
1190 // Get passx from filename.
1192 if (!AliAnalysisManager::GetAnalysisManager()->GetTree())
1194 AliError("AliCalorimeterUtils::GetPass() - Pointer to tree = 0, returning null\n");
1198 if (!AliAnalysisManager::GetAnalysisManager()->GetTree()->GetCurrentFile())
1200 AliError("AliCalorimeterUtils::GetPass() - Null pointer input file, returning null\n");
1204 TString pass(AliAnalysisManager::GetAnalysisManager()->GetTree()->GetCurrentFile()->GetName());
1205 if (pass.Contains("ass1")) return TString("pass1");
1206 else if (pass.Contains("ass2")) return TString("pass2");
1207 else if (pass.Contains("ass3")) return TString("pass3");
1208 else if (pass.Contains("ass4")) return TString("pass4");
1209 else if (pass.Contains("ass5")) return TString("pass5");
1210 else if (pass.Contains("LHC11c") && pass.Contains("spc_calo") ) return TString("spc_calo");
1211 else if (pass.Contains("calo") || pass.Contains("high_lumi"))
1213 printf("AliCalorimeterUtils::GetPass() - Path contains <calo> or <high-lumi>, set as <pass1>\n");
1214 return TString("pass1");
1217 // No condition fullfilled, give a default value
1218 printf("AliCalorimeterUtils::GetPass() - Pass number string not found \n");
1223 //________________________________________
1224 void AliCalorimeterUtils::InitParameters()
1226 //Initialize the parameters of the analysis.
1231 fEMCALGeoMatrixSet = kFALSE;
1232 fPHOSGeoMatrixSet = kFALSE;
1234 fRemoveBadChannels = kFALSE;
1236 fNCellsFromPHOSBorder = 0;
1239 fLocMaxCutEDiff = 0.0 ;
1241 // fMaskCellColumns = new Int_t[fNMaskCellColumns];
1242 // fMaskCellColumns[0] = 6 ; fMaskCellColumns[1] = 7 ; fMaskCellColumns[2] = 8 ;
1243 // fMaskCellColumns[3] = 35; fMaskCellColumns[4] = 36; fMaskCellColumns[5] = 37;
1244 // fMaskCellColumns[6] = 12+AliEMCALGeoParams::fgkEMCALCols; fMaskCellColumns[7] = 13+AliEMCALGeoParams::fgkEMCALCols;
1245 // fMaskCellColumns[8] = 40+AliEMCALGeoParams::fgkEMCALCols; fMaskCellColumns[9] = 41+AliEMCALGeoParams::fgkEMCALCols;
1246 // fMaskCellColumns[10]= 42+AliEMCALGeoParams::fgkEMCALCols;
1249 fOADBForEMCAL = kTRUE ;
1250 fOADBForPHOS = kFALSE;
1252 fOADBFilePathEMCAL = "$ALICE_ROOT/OADB/EMCAL" ;
1253 fOADBFilePathPHOS = "$ALICE_ROOT/OADB/PHOS" ;
1255 fImportGeometryFromFile = kTRUE;
1256 fImportGeometryFilePath = "";
1258 fNSuperModulesUsed = 22;
1260 fMCECellClusFracCorrParam[0] = 0.78;
1261 fMCECellClusFracCorrParam[1] =-1.8;
1262 fMCECellClusFracCorrParam[2] =-6.3;
1263 fMCECellClusFracCorrParam[3] = 0.014;
1268 //_____________________________________________________
1269 void AliCalorimeterUtils::InitPHOSBadChannelStatusMap()
1271 //Init PHOS bad channels map
1272 if(fDebug > 0 )printf("AliCalorimeterUtils::InitPHOSBadChannelStatusMap()\n");
1273 //In order to avoid rewriting the same histograms
1274 Bool_t oldStatus = TH1::AddDirectoryStatus();
1275 TH1::AddDirectory(kFALSE);
1277 fPHOSBadChannelMap = new TObjArray(5);
1278 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));
1280 fPHOSBadChannelMap->SetOwner(kTRUE);
1281 fPHOSBadChannelMap->Compress();
1283 //In order to avoid rewriting the same histograms
1284 TH1::AddDirectory(oldStatus);
1287 //______________________________________________________
1288 void AliCalorimeterUtils::InitPHOSRecalibrationFactors()
1290 //Init EMCAL recalibration factors
1291 if(fDebug > 0 )printf("AliCalorimeterUtils::InitPHOSRecalibrationFactors()\n");
1292 //In order to avoid rewriting the same histograms
1293 Bool_t oldStatus = TH1::AddDirectoryStatus();
1294 TH1::AddDirectory(kFALSE);
1296 fPHOSRecalibrationFactors = new TObjArray(5);
1297 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));
1298 //Init the histograms with 1
1299 for (Int_t m = 0; m < 5; m++) {
1300 for (Int_t i = 0; i < 56; i++) {
1301 for (Int_t j = 0; j < 64; j++) {
1302 SetPHOSChannelRecalibrationFactor(m,j,i,1.);
1306 fPHOSRecalibrationFactors->SetOwner(kTRUE);
1307 fPHOSRecalibrationFactors->Compress();
1309 //In order to avoid rewriting the same histograms
1310 TH1::AddDirectory(oldStatus);
1314 //__________________________________________________________
1315 void AliCalorimeterUtils::InitEMCALGeometry(Int_t runnumber)
1317 //Initialize EMCAL geometry if it did not exist previously
1321 if(fEMCALGeoName=="")
1323 if (runnumber < 140000 &&
1324 runnumber >= 100000) fEMCALGeoName = "EMCAL_FIRSTYEARV1";
1325 else if(runnumber >= 140000 &&
1326 runnumber < 171000) fEMCALGeoName = "EMCAL_COMPLETEV1";
1327 else fEMCALGeoName = "EMCAL_COMPLETE12SMV1";
1328 printf("AliCalorimeterUtils::InitEMCALGeometry() - Set EMCAL geometry name to <%s> for run %d\n",fEMCALGeoName.Data(),runnumber);
1331 fEMCALGeo = AliEMCALGeometry::GetInstance(fEMCALGeoName);
1333 // Init geometry, I do not like much to do it like this ...
1334 if(fImportGeometryFromFile && !gGeoManager)
1336 if(fImportGeometryFilePath=="") // If not specified, set location depending on run number
1338 // "$ALICE_ROOT/EVE/alice-data/default_geo.root"
1339 if (runnumber < 140000 &&
1340 runnumber >= 100000) fImportGeometryFilePath = "$ALICE_ROOT/OADB/EMCAL/geometry_2010.root";
1341 if (runnumber >= 140000 &&
1342 runnumber < 171000) fImportGeometryFilePath = "$ALICE_ROOT/OADB/EMCAL/geometry_2011.root";
1343 else fImportGeometryFilePath = "$ALICE_ROOT/OADB/EMCAL/geometry_2012.root"; // 2012-2013
1346 printf("AliCalorimeterUtils::InitEMCALGeometry() - Import %s\n",fImportGeometryFilePath.Data());
1347 TGeoManager::Import(fImportGeometryFilePath) ; // default need file "geometry.root" in local dir!!!!
1353 printf("AliCalorimeterUtils::InitEMCALGeometry(run=%d)",runnumber);
1354 if (!gGeoManager) printf(" - Careful!, gGeoManager not loaded, load misalign matrices");
1360 //_________________________________________________________
1361 void AliCalorimeterUtils::InitPHOSGeometry(Int_t runnumber)
1363 //Initialize PHOS geometry if it did not exist previously
1367 if(fPHOSGeoName=="") fPHOSGeoName = "PHOSgeo";
1369 fPHOSGeo = new AliPHOSGeoUtils(fPHOSGeoName);
1373 printf("AliCalorimeterUtils::InitPHOSGeometry(run=%d)",runnumber);
1374 if (!gGeoManager) printf(" - Careful!, gGeoManager not loaded, load misalign matrices");
1380 //_______________________________________________________________________________________________
1381 Bool_t AliCalorimeterUtils::IsMCParticleInCalorimeterAcceptance(TString calo, TParticle* particle)
1383 // Check that a MC ESD is in the calorimeter acceptance
1385 if(!particle || (calo!="EMCAL" && calo!="PHOS")) return kFALSE ;
1387 if( (!IsPHOSGeoMatrixSet () && calo == "PHOS" ) ||
1388 (!IsEMCALGeoMatrixSet() && calo == "EMCAL") )
1390 AliFatal(Form("Careful Geo Matrix for %s is not set, use AliFidutialCut instead \n",calo.Data()));
1397 Double_t x = 0, z = 0 ;
1398 return GetPHOSGeometry()->ImpactOnEmc( particle, mod, z, x);
1400 else if(calo == "EMCAL")
1403 Bool_t ok = GetEMCALGeometry()->GetAbsCellIdFromEtaPhi(particle->Eta(),particle->Phi(),absID);
1406 Int_t icol = -1, irow = -1, iRCU = -1;
1407 Int_t nModule = GetModuleNumberCellIndexes(absID,calo, icol, irow, iRCU);
1408 Int_t status = GetEMCALChannelStatus(nModule,icol,irow);
1409 if(status > 0) ok = kFALSE;
1417 //______________________________________________________________________________________________________
1418 Bool_t AliCalorimeterUtils::IsMCParticleInCalorimeterAcceptance(TString calo, AliAODMCParticle* particle)
1420 // Check that a MC AOD is in the calorimeter acceptance
1422 if(!particle || (calo!="EMCAL" && calo!="PHOS")) return kFALSE ;
1424 if( (!IsPHOSGeoMatrixSet () && calo == "PHOS" ) ||
1425 (!IsEMCALGeoMatrixSet() && calo == "EMCAL") )
1427 AliFatal(Form("Careful Geo Matrix for %s is not set, use AliFidutialCut instead \n",calo.Data()));
1431 Float_t phi = particle->Phi();
1432 if(phi < 0) phi+=TMath::TwoPi();
1437 Double_t x = 0, z = 0 ;
1438 Double_t vtx[]={ particle->Xv(), particle->Yv(), particle->Zv() } ;
1439 return GetPHOSGeometry()->ImpactOnEmc(vtx, particle->Theta(), phi, mod, z, x) ;
1441 else if(calo == "EMCAL")
1444 Bool_t ok = GetEMCALGeometry()->GetAbsCellIdFromEtaPhi(particle->Eta(),phi,absID);
1447 Int_t icol = -1, irow = -1, iRCU = -1;
1448 Int_t nModule = GetModuleNumberCellIndexes(absID,calo, icol, irow, iRCU);
1449 Int_t status = GetEMCALChannelStatus(nModule,icol,irow);
1450 if(status > 0) ok = kFALSE;
1458 //_____________________________________________________________________________________________________________________
1459 Bool_t AliCalorimeterUtils::IsMCParticleInCalorimeterAcceptance(TString calo, TLorentzVector particle, Int_t & absID)
1461 // Check that a TLorentzVector is in the calorimeter acceptance, give the cell number where it hit
1463 if(calo!="EMCAL" && calo!="PHOS") return kFALSE ;
1465 if( (!IsPHOSGeoMatrixSet () && calo == "PHOS" ) ||
1466 (!IsEMCALGeoMatrixSet() && calo == "EMCAL") )
1468 AliFatal(Form("Careful Geo Matrix for %s is not set, use AliFidutialCut instead \n",calo.Data()));
1472 Float_t phi = particle.Phi();
1473 if(phi < 0) phi+=TMath::TwoPi();
1478 Double_t x = 0, z = 0 ;
1479 Double_t vtx[]={0,0,0} ;
1480 return GetPHOSGeometry()->ImpactOnEmc(vtx, particle.Theta(), phi, mod, z, x) ;
1482 else if(calo == "EMCAL")
1484 Bool_t ok = GetEMCALGeometry()->GetAbsCellIdFromEtaPhi(particle.Eta(),phi,absID);
1487 Int_t icol = -1, irow = -1, iRCU = -1;
1488 Int_t nModule = GetModuleNumberCellIndexes(absID,calo, icol, irow, iRCU);
1489 Int_t status = GetEMCALChannelStatus(nModule,icol,irow);
1490 if(status > 0) ok = kFALSE;
1498 //_______________________________________________________________________
1499 Bool_t AliCalorimeterUtils::MaskFrameCluster(Int_t iSM, Int_t ieta) const
1501 //Check if cell is in one of the regions where we have significant amount
1502 //of material in front. Only EMCAL
1505 if(iSM%2) icol+=48; // Impair SM, shift index [0-47] to [48-96]
1507 if (fNMaskCellColumns && fMaskCellColumns)
1509 for (Int_t imask = 0; imask < fNMaskCellColumns; imask++)
1511 if(icol==fMaskCellColumns[imask]) return kTRUE;
1519 //_________________________________________________________
1520 void AliCalorimeterUtils::Print(const Option_t * opt) const
1523 //Print some relevant parameters set for the analysis
1527 printf("***** Print: %s %s ******\n", GetName(), GetTitle() ) ;
1528 printf("Remove Clusters with bad channels? %d\n",fRemoveBadChannels);
1529 printf("Remove Clusters with max cell at less than %d cells from EMCAL border and %d cells from PHOS border\n",
1530 fEMCALRecoUtils->GetNumberOfCellsFromEMCALBorder(), fNCellsFromPHOSBorder);
1531 if(fEMCALRecoUtils->IsEMCALNoBorderAtEta0()) printf("Do not remove EMCAL clusters at Eta = 0\n");
1532 printf("Recalibrate Clusters? %d, run by run %d\n",fRecalibration,fRunDependentCorrection);
1533 printf("Recalculate Clusters Position? %d\n",fRecalculatePosition);
1534 printf("Recalculate Clusters Energy? %d\n",fCorrectELinearity);
1535 printf("Matching criteria: dR < %2.2f[cm], dZ < %2.2f[cm]\n",fCutR,fCutZ);
1537 printf("Loc. Max. E > %2.2f\n", fLocMaxCutE);
1538 printf("Loc. Max. E Diff > %2.2f\n", fLocMaxCutEDiff);
1543 //_____________________________________________________________________________________________
1544 void AliCalorimeterUtils::RecalibrateCellAmplitude(Float_t & amp, TString calo, Int_t id) const
1546 //Recaculate cell energy if recalibration factor
1548 Int_t icol = -1; Int_t irow = -1; Int_t iRCU = -1;
1549 Int_t nModule = GetModuleNumberCellIndexes(id,calo, icol, irow, iRCU);
1551 if (IsRecalibrationOn())
1555 amp *= GetPHOSChannelRecalibrationFactor(nModule,icol,irow);
1559 amp *= GetEMCALChannelRecalibrationFactor(nModule,icol,irow);
1564 //____________________________________________________________________________________________________
1565 void AliCalorimeterUtils::RecalibrateCellTime(Double_t & time, TString calo, Int_t id, Int_t bc) const
1567 // Recalculate time if time recalibration available for EMCAL
1568 // not ready for PHOS
1570 if(calo == "EMCAL" && GetEMCALRecoUtils()->IsTimeRecalibrationOn())
1572 GetEMCALRecoUtils()->RecalibrateCellTime(id,bc,time);
1577 //__________________________________________________________________________
1578 Float_t AliCalorimeterUtils::RecalibrateClusterEnergy(AliVCluster * cluster,
1579 AliVCaloCells * cells)
1581 // Recalibrate the cluster energy, considering the recalibration map and the energy of the cells that compose the cluster.
1583 //Initialize some used variables
1584 Float_t frac = 0., energy = 0.;
1588 //Get the cluster number of cells and list of absId, check what kind of cluster do we have.
1590 UShort_t * index = cluster->GetCellsAbsId() ;
1591 Double_t * fraction = cluster->GetCellsAmplitudeFraction() ;
1593 Int_t ncells = cluster->GetNCells();
1595 TString calo = "EMCAL";
1596 if(cluster->IsPHOS())
1599 //Loop on the cells, get the cell amplitude and recalibration factor, multiply and and to the new energy
1600 for(Int_t icell = 0; icell < ncells; icell++){
1602 Int_t absId = index[icell];
1604 frac = fraction[icell];
1605 if(frac < 1e-3) frac = 1; //in case of EMCAL, this is set as 0, not used.
1607 Float_t amp = cells->GetCellAmplitude(absId);
1608 RecalibrateCellAmplitude(amp,calo, absId);
1611 printf("AliCalorimeterUtils::RecalibrateClusterEnergy() - recalibrate cell: %s, cell fraction %f, cell energy %f\n",
1612 calo.Data(),frac,cells->GetCellAmplitude(absId));
1618 printf("AliCalorimeterUtils::RecalibrateClusterEnergy() - Energy before %f, after %f\n",cluster->E(),energy);
1623 Fatal("RecalibrateClusterEnergy()","Cells pointer does not exist!");
1629 //__________________________________________________________________________
1630 Float_t AliCalorimeterUtils::RecalibrateClusterEnergyWeightCell(AliVCluster * cluster,
1631 AliVCaloCells * cells, Float_t energyOrg)
1633 // Recalibrate the cluster energy, considering the recalibration map and the energy of the cells that compose the cluster.
1634 // Also consider reweighting of cells energy
1636 //Initialize some used variables
1637 Float_t frac = 0., energy = 0.;
1641 //Get the cluster number of cells and list of absId, check what kind of cluster do we have.
1643 UShort_t * index = cluster->GetCellsAbsId() ;
1644 Double_t * fraction = cluster->GetCellsAmplitudeFraction() ;
1646 Int_t ncells = cluster->GetNCells();
1648 TString calo = "EMCAL";
1649 if(cluster->IsPHOS())
1652 //Loop on the cells, get the cell amplitude and recalibration factor, multiply and and to the new energy
1653 for(Int_t icell = 0; icell < ncells; icell++){
1655 Int_t absId = index[icell];
1657 frac = fraction[icell];
1658 if(frac < 1e-3) frac = 1; //in case of EMCAL, this is set as 0, not used.
1660 Float_t amp = cells->GetCellAmplitude(absId);
1661 RecalibrateCellAmplitude(amp,calo, absId);
1663 amp*=GetMCECellClusFracCorrection(amp,energyOrg);
1666 printf("AliCalorimeterUtils::RecalibrateClusterEnergy() - recalibrate cell: %s, cell fraction %f, cell energy %f\n",
1667 calo.Data(),frac,cells->GetCellAmplitude(absId));
1673 printf("AliCalorimeterUtils::RecalibrateClusterEnergy() - Energy before %f, after %f\n",cluster->E(),energy);
1678 Fatal("RecalibrateClusterEnergy()","Cells pointer does not exist!");
1685 //__________________________________________________________________________________________
1686 void AliCalorimeterUtils::RecalculateClusterPosition(AliVCaloCells* cells, AliVCluster* clu)
1689 //Recalculate EMCAL cluster position
1691 fEMCALRecoUtils->RecalculateClusterPosition((AliEMCALGeometry*)fEMCALGeo, cells,clu);
1695 //________________________________________________________________________________
1696 void AliCalorimeterUtils::RecalculateClusterTrackMatching(AliVEvent * event,
1697 TObjArray* clusterArray)
1699 //Recalculate track matching
1701 if (fRecalculateMatching)
1703 fEMCALRecoUtils->FindMatches(event,clusterArray,fEMCALGeo) ;
1704 //AliESDEvent* esdevent = dynamic_cast<AliESDEvent*> (event);
1706 // fEMCALRecoUtils->SetClusterMatchedToTrack(esdevent) ;
1707 // fEMCALRecoUtils->SetTracksMatchedToCluster(esdevent) ;
1712 //___________________________________________________________________________
1713 void AliCalorimeterUtils::SplitEnergy(Int_t absId1, Int_t absId2,
1714 AliVCluster* cluster,
1715 AliVCaloCells* cells,
1716 //Float_t & e1, Float_t & e2,
1717 AliAODCaloCluster* cluster1,
1718 AliAODCaloCluster* cluster2,
1719 Int_t nMax, Int_t eventNumber)
1722 // Split energy of cluster between the 2 local maxima, sum energy on 3x3, and if the 2
1723 // maxima are too close and have common cells, split the energy between the 2
1725 TH2F* hClusterMap = 0 ;
1726 TH2F* hClusterLocMax = 0 ;
1727 TH2F* hCluster1 = 0 ;
1728 TH2F* hCluster2 = 0 ;
1732 hClusterMap = new TH2F("hClusterMap","Cluster Map",48,0,48,24,0,24);
1733 hClusterLocMax = new TH2F("hClusterLocMax","Cluster 2 highest local maxima",48,0,48,24,0,24);
1734 hCluster1 = new TH2F("hCluster1","Cluster 1",48,0,48,24,0,24);
1735 hCluster2 = new TH2F("hCluster2","Cluster 2",48,0,48,24,0,24);
1736 hClusterMap ->SetXTitle("column");
1737 hClusterMap ->SetYTitle("row");
1738 hClusterLocMax ->SetXTitle("column");
1739 hClusterLocMax ->SetYTitle("row");
1740 hCluster1 ->SetXTitle("column");
1741 hCluster1 ->SetYTitle("row");
1742 hCluster2 ->SetXTitle("column");
1743 hCluster2 ->SetYTitle("row");
1746 TString calorimeter = "EMCAL";
1747 if(cluster->IsPHOS())
1750 printf("AliCalorimeterUtils::SplitEnerg() Not supported for PHOS yet \n");
1754 const Int_t ncells = cluster->GetNCells();
1755 Int_t absIdList[ncells];
1757 Float_t e1 = 0, e2 = 0 ;
1758 Int_t icol = -1, irow = -1, iRCU = -1, sm = -1;
1759 Float_t eCluster = 0;
1760 Float_t minCol = 100, minRow = 100, maxCol = -1, maxRow = -1;
1761 for(Int_t iDigit = 0; iDigit < ncells; iDigit++ )
1763 absIdList[iDigit] = cluster->GetCellsAbsId()[iDigit];
1765 Float_t ec = cells->GetCellAmplitude(absIdList[iDigit]);
1766 RecalibrateCellAmplitude(ec,calorimeter, absIdList[iDigit]);
1771 //printf("iDigit %d, absId %d, Ecell %f\n",iDigit,absIdList[iDigit], cells->GetCellAmplitude(absIdList[iDigit]));
1772 sm = GetModuleNumberCellIndexes(absIdList[iDigit], calorimeter, icol, irow, iRCU) ;
1773 if(sm > -1 && sm < 12) // just to avoid compilation warning
1775 if(icol > maxCol) maxCol = icol;
1776 if(icol < minCol) minCol = icol;
1777 if(irow > maxRow) maxRow = irow;
1778 if(irow < minRow) minRow = irow;
1779 hClusterMap->Fill(icol,irow,ec);
1785 // Init counters and variables
1787 UShort_t absIdList1[9] ;
1788 Double_t fracList1 [9] ;
1789 absIdList1[0] = absId1 ;
1790 fracList1 [0] = 1. ;
1792 Float_t ecell1 = cells->GetCellAmplitude(absId1);
1793 RecalibrateCellAmplitude(ecell1, calorimeter, absId1);
1797 UShort_t absIdList2[9] ;
1798 Double_t fracList2 [9] ;
1799 absIdList2[0] = absId2 ;
1800 fracList2 [0] = 1. ;
1802 Float_t ecell2 = cells->GetCellAmplitude(absId2);
1803 RecalibrateCellAmplitude(ecell2, calorimeter, absId2);
1808 Int_t icol1 = -1, irow1 = -1, icol2 = -1, irow2 = -1;
1809 sm = GetModuleNumberCellIndexes(absId1, calorimeter, icol1, irow1, iRCU) ;
1810 hClusterLocMax->Fill(icol1,irow1,ecell1);
1811 sm = GetModuleNumberCellIndexes(absId2, calorimeter, icol2, irow2, iRCU) ;
1812 hClusterLocMax->Fill(icol2,irow2,ecell2);
1815 // Very rough way to share the cluster energy
1816 Float_t eRemain = (eCluster-ecell1-ecell2)/2;
1817 Float_t shareFraction1 = ecell1/eCluster+eRemain/eCluster;
1818 Float_t shareFraction2 = ecell2/eCluster+eRemain/eCluster;
1820 for(Int_t iDigit = 0; iDigit < ncells; iDigit++)
1822 Int_t absId = absIdList[iDigit];
1824 if(absId==absId1 || absId==absId2 || absId < 0) continue;
1826 Float_t ecell = cells->GetCellAmplitude(absId);
1827 RecalibrateCellAmplitude(ecell, calorimeter, absId);
1829 if(AreNeighbours(calorimeter, absId1,absId ))
1831 absIdList1[ncells1]= absId;
1833 if(AreNeighbours(calorimeter, absId2,absId ))
1835 fracList1[ncells1] = shareFraction1;
1836 e1 += ecell*shareFraction1;
1840 fracList1[ncells1] = 1.;
1846 } // neigbour to cell1
1848 if(AreNeighbours(calorimeter, absId2,absId ))
1850 absIdList2[ncells2]= absId;
1852 if(AreNeighbours(calorimeter, absId1,absId ))
1854 fracList2[ncells2] = shareFraction2;
1855 e2 += ecell*shareFraction2;
1859 fracList2[ncells2] = 1.;
1865 } // neigbour to cell2
1869 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",
1870 nMax, eCluster,ecell1,ecell2,e1,e2,eCluster-e1-e2,ncells,ncells1,ncells2,shareFraction1,shareFraction2,shareFraction1+shareFraction2);
1875 cluster1->SetNCells(ncells1);
1876 cluster2->SetNCells(ncells2);
1878 cluster1->SetCellsAbsId(absIdList1);
1879 cluster2->SetCellsAbsId(absIdList2);
1881 cluster1->SetCellsAmplitudeFraction(fracList1);
1882 cluster2->SetCellsAmplitudeFraction(fracList2);
1885 CorrectClusterEnergy(cluster1) ;
1886 CorrectClusterEnergy(cluster2) ;
1888 if(calorimeter=="EMCAL")
1890 GetEMCALRecoUtils()->RecalculateClusterPosition(GetEMCALGeometry(), cells, cluster1);
1891 GetEMCALRecoUtils()->RecalculateClusterPosition(GetEMCALGeometry(), cells, cluster2);
1896 //printf("Cells of cluster1: ");
1897 for(Int_t iDigit = 0; iDigit < ncells1; iDigit++ )
1899 //printf(" %d ",absIdList1[iDigit]);
1901 sm = GetModuleNumberCellIndexes(absIdList1[iDigit], calorimeter, icol, irow, iRCU) ;
1903 Float_t ecell = cells->GetCellAmplitude(absIdList1[iDigit]);
1904 RecalibrateCellAmplitude(ecell, calorimeter, absIdList1[iDigit]);
1906 if( AreNeighbours(calorimeter, absId2,absIdList1[iDigit]) && absId1!=absIdList1[iDigit])
1907 hCluster1->Fill(icol,irow,ecell*shareFraction1);
1909 hCluster1->Fill(icol,irow,ecell);
1913 //printf("Cells of cluster2: ");
1915 for(Int_t iDigit = 0; iDigit < ncells2; iDigit++ )
1917 //printf(" %d ",absIdList2[iDigit]);
1919 sm = GetModuleNumberCellIndexes(absIdList2[iDigit], calorimeter, icol, irow, iRCU) ;
1921 Float_t ecell = cells->GetCellAmplitude(absIdList2[iDigit]);
1922 RecalibrateCellAmplitude(ecell, calorimeter, absIdList2[iDigit]);
1924 if( AreNeighbours(calorimeter, absId1,absIdList2[iDigit]) && absId2!=absIdList2[iDigit])
1925 hCluster2->Fill(icol,irow,ecell*shareFraction2);
1927 hCluster2->Fill(icol,irow,ecell);
1932 gStyle->SetPadRightMargin(0.1);
1933 gStyle->SetPadLeftMargin(0.1);
1934 gStyle->SetOptStat(0);
1935 gStyle->SetOptFit(000000);
1937 if(maxCol-minCol > maxRow-minRow)
1939 maxRow+= maxCol-minCol;
1943 maxCol+= maxRow-minRow;
1946 TCanvas * c= new TCanvas("canvas", "canvas", 4000, 4000) ;
1952 hClusterMap ->SetAxisRange(minCol, maxCol,"X");
1953 hClusterMap ->SetAxisRange(minRow, maxRow,"Y");
1954 hClusterMap ->Draw("colz TEXT");
1959 hClusterLocMax ->SetAxisRange(minCol, maxCol,"X");
1960 hClusterLocMax ->SetAxisRange(minRow, maxRow,"Y");
1961 hClusterLocMax ->Draw("colz TEXT");
1966 hCluster1 ->SetAxisRange(minCol, maxCol,"X");
1967 hCluster1 ->SetAxisRange(minRow, maxRow,"Y");
1968 hCluster1 ->Draw("colz TEXT");
1973 hCluster2 ->SetAxisRange(minCol, maxCol,"X");
1974 hCluster2 ->SetAxisRange(minRow, maxRow,"Y");
1975 hCluster2 ->Draw("colz TEXT");
1977 if(eCluster > 6 )c->Print(Form("clusterFigures/Event%d_E%1.0f_nMax%d_NCell1_%d_NCell2_%d.eps",
1978 eventNumber,cluster->E(),nMax,ncells1,ncells2));
1982 delete hClusterLocMax;