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(""),
79 //Initialize parameters
81 for(Int_t i = 0; i < 12; i++) fEMCALMatrix[i] = 0 ;
82 for(Int_t i = 0; i < 5 ; i++) fPHOSMatrix [i] = 0 ;
86 //_________________________________________
87 AliCalorimeterUtils::~AliCalorimeterUtils()
91 //if(fPHOSGeo) delete fPHOSGeo ;
92 if(fEMCALGeo) delete fEMCALGeo ;
94 if(fPHOSBadChannelMap) {
95 fPHOSBadChannelMap->Clear();
96 delete fPHOSBadChannelMap;
99 if(fPHOSRecalibrationFactors) {
100 fPHOSRecalibrationFactors->Clear();
101 delete fPHOSRecalibrationFactors;
104 if(fEMCALRecoUtils) delete fEMCALRecoUtils ;
105 if(fNMaskCellColumns) delete [] fMaskCellColumns;
109 //____________________________________________________
110 void AliCalorimeterUtils::AccessOADB(AliVEvent* event)
112 // Set the AODB calibration, bad channels etc. parameters at least once
113 // alignment matrices from OADB done in SetGeometryMatrices
116 if(fOADBSet) return ;
118 Int_t runnumber = event->GetRunNumber() ;
119 TString pass = GetPass();
124 printf("AliCalorimeterUtils::SetOADBParameters() - Get AODB parameters from EMCAL in %s for run %d, and <%s> \n",fOADBFilePathEMCAL.Data(),runnumber,pass.Data());
126 Int_t nSM = fEMCALGeo->GetNumberOfSuperModules();
129 if(fRemoveBadChannels)
131 AliOADBContainer *contBC=new AliOADBContainer("");
132 contBC->InitFromFile(Form("%s/EMCALBadChannels.root",fOADBFilePathEMCAL.Data()),"AliEMCALBadChannels");
134 TObjArray *arrayBC=(TObjArray*)contBC->GetObject(runnumber);
138 SwitchOnDistToBadChannelRecalculation();
139 printf("AliCalorimeterUtils::SetOADBParameters() - Remove EMCAL bad cells \n");
141 for (Int_t i=0; i<nSM; ++i)
143 TH2I *hbm = GetEMCALChannelStatusMap(i);
148 hbm=(TH2I*)arrayBC->FindObject(Form("EMCALBadChannelMap_Mod%d",i));
152 AliError(Form("Can not get EMCALBadChannelMap_Mod%d",i));
156 hbm->SetDirectory(0);
157 SetEMCALChannelStatusMap(i,hbm);
160 } else printf("AliCalorimeterUtils::SetOADBParameters() - Do NOT remove EMCAL bad channels\n"); // run array
163 // Energy Recalibration
166 AliOADBContainer *contRF=new AliOADBContainer("");
168 contRF->InitFromFile(Form("%s/EMCALRecalib.root",fOADBFilePathEMCAL.Data()),"AliEMCALRecalib");
170 TObjArray *recal=(TObjArray*)contRF->GetObject(runnumber);
174 TObjArray *recalpass=(TObjArray*)recal->FindObject(pass);
178 TObjArray *recalib=(TObjArray*)recalpass->FindObject("Recalib");
182 printf("AliCalorimeterUtils::SetOADBParameters() - Recalibrate EMCAL \n");
183 for (Int_t i=0; i<nSM; ++i)
185 TH2F *h = GetEMCALChannelRecalibrationFactors(i);
190 h = (TH2F*)recalib->FindObject(Form("EMCALRecalFactors_SM%d",i));
194 AliError(Form("Could not load EMCALRecalFactors_SM%d",i));
200 SetEMCALChannelRecalibrationFactors(i,h);
202 }else printf("AliCalorimeterUtils::SetOADBParameters() - Do NOT recalibrate EMCAL, no params object array\n"); // array ok
203 }else printf("AliCalorimeterUtils::SetOADBParameters() - Do NOT recalibrate EMCAL, no params for pass\n"); // array pass ok
204 }else printf("AliCalorimeterUtils::SetOADBParameters() - Do NOT recalibrate EMCAL, no params for run\n"); // run number array ok
206 // once set, apply run dependent corrections if requested
207 //fEMCALRecoUtils->SetRunDependentCorrections(runnumber);
209 } // Recalibration on
211 // Energy Recalibration, apply on top of previous calibration factors
212 if(fRunDependentCorrection)
214 AliOADBContainer *contRFTD=new AliOADBContainer("");
216 contRFTD->InitFromFile(Form("%s/EMCALTemperatureCorrCalib.root",fOADBFilePathEMCAL.Data()),"AliEMCALRunDepTempCalibCorrections");
218 TH1S *htd=(TH1S*)contRFTD->GetObject(runnumber);
220 //If it did not exist for this run, get closes one
223 AliWarning(Form("No TemperatureCorrCalib Objects for run: %d",runnumber));
224 // let's get the closest runnumber instead then..
227 Int_t maxEntry = contRFTD->GetNumberOfEntries();
229 while ( (ic < maxEntry) && (contRFTD->UpperLimit(ic) < runnumber) ) {
234 Int_t closest = lower;
235 if ( (ic<maxEntry) &&
236 (contRFTD->LowerLimit(ic)-runnumber) < (runnumber - contRFTD->UpperLimit(lower)) ) {
240 AliWarning(Form("TemperatureCorrCalib Objects found closest id %d from run: %d", closest, contRFTD->LowerLimit(closest)));
241 htd = (TH1S*) contRFTD->GetObjectByIndex(closest);
246 printf("AliCalorimeterUtils::SetOADBParameters() - Recalibrate (Temperature) EMCAL \n");
248 for (Int_t ism=0; ism<nSM; ++ism)
250 for (Int_t icol=0; icol<48; ++icol)
252 for (Int_t irow=0; irow<24; ++irow)
254 Float_t factor = GetEMCALChannelRecalibrationFactor(ism,icol,irow);
256 Int_t absID = fEMCALGeo->GetAbsCellIdFromCellIndexes(ism, irow, icol); // original calibration factor
257 factor *= htd->GetBinContent(absID) / 10000. ; // correction dependent on T
258 //printf("\t ism %d, icol %d, irow %d,absID %d, corrA %2.3f, corrB %2.3f, corrAB %2.3f\n",ism, icol, irow, absID,
259 // GetEMCALChannelRecalibrationFactor(ism,icol,irow) , htd->GetBinContent(absID) / 10000., factor);
260 SetEMCALChannelRecalibrationFactor(ism,icol,irow,factor);
264 }else printf("AliCalorimeterUtils::SetOADBParameters() - Do NOT recalibrate EMCAL with T variations, no params TH1 \n");
265 } // Run by Run T calibration
267 // Time Recalibration
268 if(fEMCALRecoUtils->IsTimeRecalibrationOn())
270 AliOADBContainer *contTRF=new AliOADBContainer("");
272 contTRF->InitFromFile(Form("%s/EMCALTimeCalib.root",fOADBFilePathEMCAL.Data()),"AliEMCALTimeCalib");
274 TObjArray *trecal=(TObjArray*)contTRF->GetObject(runnumber);
278 TString passM = pass;
279 if(pass=="spc_calo") passM = "pass1";
280 TObjArray *trecalpass=(TObjArray*)trecal->FindObject(passM);
284 printf("AliCalorimeterUtils::SetOADBParameters() - Time Recalibrate EMCAL \n");
285 for (Int_t ibc = 0; ibc < 4; ++ibc)
287 TH1F *h = GetEMCALChannelTimeRecalibrationFactors(ibc);
292 h = (TH1F*)trecalpass->FindObject(Form("hAllTimeAvBC%d",ibc));
296 AliError(Form("Could not load hAllTimeAvBC%d",ibc));
302 SetEMCALChannelTimeRecalibrationFactors(ibc,h);
303 } // bunch crossing loop
304 }else printf("AliCalorimeterUtils::SetOADBParameters() - Do NOT recalibrate time EMCAL, no params for pass\n"); // array pass ok
305 }else printf("AliCalorimeterUtils::SetOADBParameters() - Do NOT recalibrate time EMCAL, no params for run\n"); // run number array ok
307 } // Recalibration on
314 printf("AliCalorimeterUtils::SetOADBParameters() - Get AODB parameters from PHOS in %s for run %d, and <%s> \n",fOADBFilePathPHOS.Data(),runnumber,pass.Data());
317 if(fRemoveBadChannels)
319 AliOADBContainer badmapContainer(Form("phosBadMap"));
320 TString fileName="$ALICE_ROOT/OADB/PHOS/PHOSBadMaps.root";
321 badmapContainer.InitFromFile(Form("%s/PHOSBadMaps.root",fOADBFilePathPHOS.Data()),"phosBadMap");
323 //Use a fixed run number from year 2010, this year not available yet.
324 TObjArray *maps = (TObjArray*)badmapContainer.GetObject(139000,"phosBadMap");
327 printf("AliCalorimeterUtils::SetOADBParameters() - Can not read PHOS bad map for run %d.\n",runnumber) ;
331 printf("AliCalorimeterUtils::SetOADBParameters() - Setting PHOS bad map with name %s \n",maps->GetName()) ;
332 for(Int_t mod=1; mod<5;mod++)
334 TH2I *hbmPH = GetPHOSChannelStatusMap(mod);
339 hbmPH = (TH2I*)maps->At(mod);
341 if(hbmPH) hbmPH->SetDirectory(0);
343 SetPHOSChannelStatusMap(mod-1,hbmPH);
347 } // Remove bad channels
350 // Parameters already set once, so do not it again
355 //_____________________________________________________________
356 void AliCalorimeterUtils::AccessGeometry(AliVEvent* inputEvent)
358 //Set the calorimeters transformation matrices and init geometry
360 // First init the geometry, a priory not done before
361 Int_t runnumber = inputEvent->GetRunNumber() ;
362 InitPHOSGeometry (runnumber);
363 InitEMCALGeometry(runnumber);
365 //Get the EMCAL transformation geometry matrices from ESD
366 if(!fEMCALGeoMatrixSet && fEMCALGeo)
368 if(fLoadEMCALMatrices)
370 printf("AliCalorimeterUtils::AccessGeometry() - Load user defined EMCAL geometry matrices\n");
373 AliOADBContainer emcGeoMat("AliEMCALgeo");
374 emcGeoMat.InitFromFile(Form("%s/EMCALlocal2master.root",fOADBFilePathEMCAL.Data()),"AliEMCALgeo");
375 TObjArray *matEMCAL=(TObjArray*)emcGeoMat.GetObject(runnumber,"EmcalMatrices");
377 for(Int_t mod=0; mod < (fEMCALGeo->GetEMCGeometry())->GetNumberOfSuperModules(); mod++)
379 if (!fEMCALMatrix[mod]) // Get it from OADB
382 printf("AliCalorimeterUtils::AccessGeometry() - EMCAL matrices SM %d, %p\n",
383 mod,((TGeoHMatrix*) matEMCAL->At(mod)));
384 //((TGeoHMatrix*) matEMCAL->At(mod))->Print();
386 fEMCALMatrix[mod] = (TGeoHMatrix*) matEMCAL->At(mod) ;
389 if(fEMCALMatrix[mod])
392 fEMCALMatrix[mod]->Print();
394 fEMCALGeo->SetMisalMatrix(fEMCALMatrix[mod],mod) ;
398 fEMCALGeoMatrixSet = kTRUE;//At least one, so good
401 else if (!gGeoManager)
404 printf(" AliCalorimeterUtils::AccessGeometry() - Load EMCAL misalignment matrices. \n");
405 if(!strcmp(inputEvent->GetName(),"AliESDEvent"))
407 for(Int_t mod=0; mod < (fEMCALGeo->GetEMCGeometry())->GetNumberOfSuperModules(); mod++)
409 //printf("Load ESD matrix %d, %p\n",mod,((AliESDEvent*)inputEvent)->GetEMCALMatrix(mod));
410 if(((AliESDEvent*)inputEvent)->GetEMCALMatrix(mod))
412 fEMCALGeo->SetMisalMatrix(((AliESDEvent*)inputEvent)->GetEMCALMatrix(mod),mod) ;
414 }// loop over super modules
416 fEMCALGeoMatrixSet = kTRUE;//At least one, so good
422 printf("AliCalorimeterUtils::SetGeometryTransformationMatrices() - Setting of EMCAL transformation matrixes for AODs not implemented yet. \n Import geometry.root file\n");
424 }//Get matrix from data
427 fEMCALGeoMatrixSet = kTRUE;
429 }//EMCAL geo && no geoManager
431 //Get the PHOS transformation geometry matrices from ESD
432 if(!fPHOSGeoMatrixSet && fPHOSGeo)
434 if(fLoadPHOSMatrices)
436 printf("AliCalorimeterUtils::SetGeometryTransformationMatrices() - Load user defined PHOS geometry matrices\n");
439 AliOADBContainer geomContainer("phosGeo");
440 geomContainer.InitFromFile(Form("%s/PHOSGeometry.root",fOADBFilePathPHOS.Data()),"PHOSRotationMatrixes");
441 TObjArray *matPHOS = (TObjArray*)geomContainer.GetObject(139000,"PHOSRotationMatrixes");
443 for(Int_t mod = 0 ; mod < 5 ; mod++)
445 if (!fPHOSMatrix[mod]) // Get it from OADB
448 printf("AliCalorimeterUtils::SetGeometryTransformationMatrices() - PHOS matrices module %d, %p\n",
449 mod,((TGeoHMatrix*) matPHOS->At(mod)));
450 //((TGeoHMatrix*) matPHOS->At(mod))->Print();
452 fPHOSMatrix[mod] = (TGeoHMatrix*) matPHOS->At(mod) ;
455 // Set it, if it exists
459 fPHOSMatrix[mod]->Print();
461 fPHOSGeo->SetMisalMatrix(fPHOSMatrix[mod],mod) ;
465 fPHOSGeoMatrixSet = kTRUE;//At least one, so good
468 else if (!gGeoManager)
471 printf(" AliCalorimeterUtils::SetGeometryTransformationMatrices() - Load PHOS misalignment matrices. \n");
472 if(!strcmp(inputEvent->GetName(),"AliESDEvent"))
474 for(Int_t mod = 0; mod < 5; mod++)
476 if( ((AliESDEvent*)inputEvent)->GetPHOSMatrix(mod))
478 //printf("PHOS: mod %d, matrix %p\n",mod, ((AliESDEvent*)inputEvent)->GetPHOSMatrix(mod));
479 fPHOSGeo->SetMisalMatrix( ((AliESDEvent*)inputEvent)->GetPHOSMatrix(mod),mod) ;
481 }// loop over modules
482 fPHOSGeoMatrixSet = kTRUE; //At least one so good
487 printf("AliCalorimeterUtils::SetGeometryTransformationMatrices() - Setting of EMCAL transformation matrixes for AODs not implemented yet. \n Import geometry.root file\n");
489 }// get matrix from data
492 fPHOSGeoMatrixSet = kTRUE;
494 }//PHOS geo and geoManager was not set
498 //________________________________________________________________________________________
499 Bool_t AliCalorimeterUtils::AreNeighbours(TString calo, Int_t absId1, Int_t absId2 ) const
501 // Tells if (true) or not (false) two cells are neighbours
502 // A neighbour is defined as being two cells which share a side or corner
504 Bool_t areNeighbours = kFALSE ;
506 Int_t iRCU1 = -1, irow1 = -1, icol1 = -1;
507 Int_t iRCU2 = -1, irow2 = -1, icol2 = -1;
509 Int_t rowdiff = 0, coldiff = 0;
511 Int_t nSupMod1 = GetModuleNumberCellIndexes(absId1, calo, icol1, irow1, iRCU1);
512 Int_t nSupMod2 = GetModuleNumberCellIndexes(absId2, calo, icol2, irow2, iRCU2);
514 if(calo=="EMCAL" && nSupMod1!=nSupMod2)
516 // In case of a shared cluster, index of SM in C side, columns start at 48 and ends at 48*2-1
517 // C Side impair SM, nSupMod%2=1; A side pair SM nSupMod%2=0
518 if(nSupMod1%2) icol1+=AliEMCALGeoParams::fgkEMCALCols;
519 else icol2+=AliEMCALGeoParams::fgkEMCALCols;
522 rowdiff = TMath::Abs( irow1 - irow2 ) ;
523 coldiff = TMath::Abs( icol1 - icol2 ) ;
525 //if (( coldiff <= 1 ) && ( rowdiff <= 1 ) && (coldiff + rowdiff > 0))
526 if ((coldiff + rowdiff == 1 ))
527 areNeighbours = kTRUE ;
529 return areNeighbours;
534 //_____________________________________________________________________________________
535 Bool_t AliCalorimeterUtils::CheckCellFiducialRegion(AliVCluster* cluster,
536 AliVCaloCells* cells,
537 AliVEvent * event, Int_t iev) const
540 // Given the list of AbsId of the cluster, get the maximum cell and
541 // check if there are fNCellsFromBorder from the calorimeter border
543 //If the distance to the border is 0 or negative just exit accept all clusters
544 if(cells->GetType()==AliVCaloCells::kEMCALCell && fEMCALRecoUtils->GetNumberOfCellsFromEMCALBorder() <= 0 ) return kTRUE;
545 if(cells->GetType()==AliVCaloCells::kPHOSCell && fNCellsFromPHOSBorder <= 0 ) return kTRUE;
550 AliMixedEvent * mixEvent = dynamic_cast<AliMixedEvent*> (event);
551 Int_t nMixedEvents = 0 ;
552 Int_t * cellsCumul = NULL ;
553 Int_t numberOfCells = 0 ;
555 nMixedEvents = mixEvent->GetNumberOfEvents() ;
556 if (cells->GetType()==AliVCaloCells::kEMCALCell) {
557 cellsCumul = mixEvent->GetEMCALCellsCumul() ;
558 numberOfCells = mixEvent->GetNumberOfEMCALCells() ;
561 else if (cells->GetType()==AliVCaloCells::kPHOSCell) {
562 cellsCumul = mixEvent->GetPHOSCellsCumul() ;
563 numberOfCells = mixEvent->GetNumberOfPHOSCells() ;
568 Int_t startCell = cellsCumul[iev] ;
569 Int_t endCell = (iev+1 < nMixedEvents)?cellsCumul[iev+1]:numberOfCells;
570 //Find cells with maximum amplitude
571 for(Int_t i = 0; i < cluster->GetNCells() ; i++){
572 Int_t absId = cluster->GetCellAbsId(i) ;
573 for (Int_t j = startCell; j < endCell ; j++) {
576 Double_t amp, time, efrac;
577 cells->GetCell(j, cellNumber, amp, time,mclabel,efrac) ;
578 if (absId == cellNumber) {
585 }//loop on cluster cells
586 }// cells cumul available
588 printf("AliCalorimeterUtils::CheckCellFiducialRegion() - CellsCumul is NULL!!!\n");
591 } else {//Normal SE Events
592 for(Int_t i = 0; i < cluster->GetNCells() ; i++){
593 Int_t absId = cluster->GetCellAbsId(i) ;
594 Float_t amp = cells->GetCellAmplitude(absId);
603 printf("AliCalorimeterUtils::CheckCellFiducialRegion() - Cluster Max AbsId %d, Cell Energy %2.2f, Cluster Energy %2.2f\n",
604 absIdMax, ampMax, cluster->E());
606 if(absIdMax==-1) return kFALSE;
608 //Check if the cell is close to the borders:
609 Bool_t okrow = kFALSE;
610 Bool_t okcol = kFALSE;
612 if(cells->GetType()==AliVCaloCells::kEMCALCell){
614 Int_t iTower = -1, iIphi = -1, iIeta = -1, iphi = -1, ieta = -1, iSM = -1;
615 fEMCALGeo->GetCellIndex(absIdMax,iSM,iTower,iIphi,iIeta);
616 fEMCALGeo->GetCellPhiEtaIndexInSModule(iSM,iTower,iIphi, iIeta,iphi,ieta);
617 if(iSM < 0 || iphi < 0 || ieta < 0 ) {
618 Fatal("CheckCellFidutialRegion","Negative value for super module: %d, or cell ieta: %d, or cell iphi: %d, check EMCAL geometry name\n",iSM,ieta,iphi);
622 Int_t nborder = fEMCALRecoUtils->GetNumberOfCellsFromEMCALBorder();
625 if(iphi >= nborder && iphi < 24-nborder) okrow =kTRUE;
629 if(fEMCALGeoName.Contains("12SM")) // 1/3 SM
631 if(iphi >= nborder && iphi < 8-nborder) okrow =kTRUE;
635 if(iphi >= nborder && iphi <12-nborder) okrow =kTRUE;
640 if(!fEMCALRecoUtils->IsEMCALNoBorderAtEta0())
642 if(ieta > nborder && ieta < 48-nborder) okcol =kTRUE;
648 if(ieta >= nborder) okcol = kTRUE;
652 if(ieta < 48-nborder) okcol = kTRUE;
658 printf("AliCalorimeterUtils::CheckCellFiducialRegion() - EMCAL Cluster in %d cells fiducial volume: ieta %d, iphi %d, SM %d ?",
659 nborder, ieta, iphi, iSM);
660 if (okcol && okrow ) printf(" YES \n");
661 else printf(" NO: column ok? %d, row ok? %d \n",okcol,okrow);
664 else if(cells->GetType()==AliVCaloCells::kPHOSCell){
666 Int_t irow = -1, icol = -1;
667 fPHOSGeo->AbsToRelNumbering(absIdMax,relId);
671 if(irow >= fNCellsFromPHOSBorder && irow < 64-fNCellsFromPHOSBorder) okrow =kTRUE;
672 if(icol >= fNCellsFromPHOSBorder && icol < 56-fNCellsFromPHOSBorder) okcol =kTRUE;
675 printf("AliCalorimeterUtils::CheckCellFiducialRegion() - PHOS Cluster in %d cells fiducial volume: icol %d, irow %d, Module %d?",
676 fNCellsFromPHOSBorder, icol, irow, relId[0]-1);
677 if (okcol && okrow ) printf(" YES \n");
678 else printf(" NO: column ok? %d, row ok? %d \n",okcol,okrow);
682 if (okcol && okrow) return kTRUE;
687 //__________________________________________________________________________________________________________
688 Bool_t AliCalorimeterUtils::ClusterContainsBadChannel(TString calorimeter, UShort_t* cellList, Int_t nCells)
690 // Check that in the cluster cells, there is no bad channel of those stored
691 // in fEMCALBadChannelMap or fPHOSBadChannelMap
693 if (!fRemoveBadChannels) return kFALSE;
694 //printf("fEMCALBadChannelMap %p, fPHOSBadChannelMap %p \n",fEMCALBadChannelMap,fPHOSBadChannelMap);
695 if(calorimeter == "EMCAL" && !fEMCALRecoUtils->GetEMCALChannelStatusMap(0)) return kFALSE;
696 if(calorimeter == "PHOS" && !fPHOSBadChannelMap) return kFALSE;
701 for(Int_t iCell = 0; iCell<nCells; iCell++){
703 //Get the column and row
704 if(calorimeter == "EMCAL"){
705 return fEMCALRecoUtils->ClusterContainsBadChannel((AliEMCALGeometry*)fEMCALGeo,cellList,nCells);
707 else if(calorimeter=="PHOS"){
709 fPHOSGeo->AbsToRelNumbering(cellList[iCell],relId);
713 if(fPHOSBadChannelMap->GetEntries() <= imod)continue;
714 //printf("PHOS bad channels imod %d, icol %d, irow %d\n",imod, irow, icol);
715 if(GetPHOSChannelStatus(imod, irow, icol)) return kTRUE;
719 }// cell cluster loop
725 //_______________________________________________________________
726 void AliCalorimeterUtils::CorrectClusterEnergy(AliVCluster *clus)
728 // Correct cluster energy non linearity
730 clus->SetE(fEMCALRecoUtils->CorrectClusterEnergyLinearity(clus));
734 //________________________________________________________________________________________
735 Int_t AliCalorimeterUtils::GetMaxEnergyCell(AliVCaloCells* cells, const AliVCluster* clu,
736 Float_t & clusterFraction) const
739 //For a given CaloCluster gets the absId of the cell
740 //with maximum energy deposit.
742 if( !clu || !cells ){
743 AliInfo("Cluster or cells pointer is null!");
750 Float_t fraction = 1.;
751 Float_t recalFactor = 1.;
752 Int_t cellAbsId =-1 , absId =-1 ;
753 Int_t iSupMod =-1 , ieta =-1 , iphi = -1, iRCU = -1;
755 TString calo = "EMCAL";
756 if(clu->IsPHOS()) calo = "PHOS";
758 for (Int_t iDig=0; iDig< clu->GetNCells(); iDig++) {
760 cellAbsId = clu->GetCellAbsId(iDig);
762 fraction = clu->GetCellAmplitudeFraction(iDig);
763 if(fraction < 1e-4) fraction = 1.; // in case unfolding is off
765 iSupMod = GetModuleNumberCellIndexes(cellAbsId, calo, ieta, iphi, iRCU);
767 if(IsRecalibrationOn()) {
768 if(calo=="EMCAL") recalFactor = GetEMCALChannelRecalibrationFactor(iSupMod,ieta,iphi);
769 else recalFactor = GetPHOSChannelRecalibrationFactor (iSupMod,iphi,ieta);
772 eCell = cells->GetCellAmplitude(cellAbsId)*fraction*recalFactor;
784 clusterFraction = (eTot-eMax)/eTot; //Do not use cluster energy in case it was corrected for non linearity.
792 //___________________________________________________________________________________
793 AliVTrack * AliCalorimeterUtils::GetMatchedTrack(AliVCluster* cluster,
794 AliVEvent* event, Int_t index) const
796 // Get the matched track given its index, usually just the first match
797 // Since it is different for ESDs and AODs here it is a wrap method to do it
799 AliVTrack *track = 0;
801 // EMCAL case only when matching is recalculated
802 if(cluster->IsEMCAL() && IsRecalculationOfClusterTrackMatchingOn())
804 Int_t trackIndex = fEMCALRecoUtils->GetMatchedTrackIndex(cluster->GetID());
805 //printf("track index %d, cluster ID %d \n ",trackIndex,cluster->GetID());
809 printf("AliCalorimeterUtils::GetMatchedTrack() - Wrong track index %d, from recalculation\n", trackIndex);
813 track = dynamic_cast<AliVTrack*> (event->GetTrack(trackIndex));
820 // Normal case, get info from ESD or AOD
822 if(!strcmp("AliESDCaloCluster",Form("%s",cluster->ClassName())))
824 Int_t iESDtrack = cluster->GetTrackMatchedIndex();
828 printf("AliCalorimeterUtils::GetMatchedTrack() - Wrong track index %d\n", index);
832 track = dynamic_cast<AliVTrack*> (event->GetTrack(iESDtrack));
837 if(cluster->GetNTracksMatched() > 0 )
838 track = dynamic_cast<AliVTrack*>(cluster->GetTrackMatched(index));
845 //_____________________________________________________________________________________________________
846 Int_t AliCalorimeterUtils::GetModuleNumber(AliAODPWG4Particle * particle, AliVEvent * inputEvent) const
848 //Get the EMCAL/PHOS module number that corresponds to this particle
851 if(particle->GetDetector()=="EMCAL"){
852 fEMCALGeo->GetAbsCellIdFromEtaPhi(particle->Eta(),particle->Phi(), absId);
854 printf("AliCalorimeterUtils::GetModuleNumber(PWG4AOD) - EMCAL: cluster eta %f, phi %f, absid %d, SuperModule %d\n",
855 particle->Eta(), particle->Phi()*TMath::RadToDeg(),absId, fEMCALGeo->GetSuperModuleNumber(absId));
856 return fEMCALGeo->GetSuperModuleNumber(absId) ;
858 else if(particle->GetDetector()=="PHOS")
860 // In case we use the MC reader, the input are TParticles,
861 // in this case use the corresponing method in PHOS Geometry to get the particle.
862 if(strcmp(inputEvent->ClassName(), "AliMCEvent") == 0 )
865 Double_t z = 0., x=0.;
866 TParticle* primary = 0x0;
867 AliStack * stack = ((AliMCEvent*)inputEvent)->Stack();
869 primary = stack->Particle(particle->GetCaloLabel(0));
872 Fatal("GetModuleNumber(PWG4AOD)", "Stack not available, stop!");
876 fPHOSGeo->ImpactOnEmc(primary,mod,z,x) ;
879 Fatal("GetModuleNumber(PWG4AOD)", "Primary not available, stop!");
883 // Input are ESDs or AODs, get the PHOS module number like this.
886 //AliVCluster *cluster = inputEvent->GetCaloCluster(particle->GetCaloLabel(0));
887 //return GetModuleNumber(cluster);
896 //_____________________________________________________________________
897 Int_t AliCalorimeterUtils::GetModuleNumber(AliVCluster * cluster) const
899 //Get the EMCAL/PHOS module number that corresponds to this cluster
901 Double_t v[]={0.,0.,0.}; //not necessary to pass the real vertex.
904 if(fDebug > 1) printf("AliCalorimeterUtils::GetModuleNumber() - NUL Cluster, please check!!!");
908 cluster->GetMomentum(lv,v);
909 Float_t phi = lv.Phi();
910 if(phi < 0) phi+=TMath::TwoPi();
912 if(cluster->IsEMCAL()){
913 fEMCALGeo->GetAbsCellIdFromEtaPhi(lv.Eta(),phi, absId);
915 printf("AliCalorimeterUtils::GetModuleNumber() - EMCAL: cluster eta %f, phi %f, absid %d, SuperModule %d\n",
916 lv.Eta(), phi*TMath::RadToDeg(),absId, fEMCALGeo->GetSuperModuleNumber(absId));
917 return fEMCALGeo->GetSuperModuleNumber(absId) ;
919 else if(cluster->IsPHOS())
922 if ( cluster->GetNCells() > 0)
924 absId = cluster->GetCellAbsId(0);
926 printf("AliCalorimeterUtils::GetModuleNumber() - PHOS: cluster eta %f, phi %f, e %f, absId %d\n",
927 lv.Eta(), phi*TMath::RadToDeg(), lv.E(), absId);
933 fPHOSGeo->AbsToRelNumbering(absId,relId);
935 printf("AliCalorimeterUtils::GetModuleNumber() - PHOS: Module %d\n",relId[0]-1);
944 //___________________________________________________________________________________________________
945 Int_t AliCalorimeterUtils::GetModuleNumberCellIndexes(Int_t absId, TString calo,
946 Int_t & icol, Int_t & irow, Int_t & iRCU) const
948 //Get the EMCAL/PHOS module, columns, row and RCU number that corresponds to this absId
954 Int_t iTower = -1, iIphi = -1, iIeta = -1;
955 fEMCALGeo->GetCellIndex(absId,imod,iTower,iIphi,iIeta);
956 fEMCALGeo->GetCellPhiEtaIndexInSModule(imod,iTower,iIphi, iIeta,irow,icol);
957 if(imod < 0 || irow < 0 || icol < 0 )
959 Fatal("GetModuleNumberCellIndexes()","Negative value for super module: %d, or cell icol: %d, or cell irow: %d, check EMCAL geometry name\n",imod,icol,irow);
965 if (0<=irow&&irow<8) iRCU=0; // first cable row
966 else if (8<=irow&&irow<16 && 0<=icol&&icol<24) iRCU=0; // first half;
969 else if (8<=irow&&irow<16 && 24<=icol&&icol<48) iRCU=1; // second half;
971 else if (16<=irow&&irow<24) iRCU=1; // third cable row
973 if (imod%2==1) iRCU = 1 - iRCU; // swap for odd=C side, to allow us to cable both sides the same
977 // Last 2 SM have one single SRU, just assign RCU 0
983 Fatal("GetModuleNumberCellIndexes()","Wrong EMCAL RCU number = %d\n", iRCU);
992 fPHOSGeo->AbsToRelNumbering(absId,relId);
996 iRCU= (Int_t)(relId[2]-1)/16 ;
997 //Int_t iBranch= (Int_t)(relid[3]-1)/28 ; //0 to 1
1000 Fatal("GetModuleNumberCellIndexes()","Wrong PHOS RCU number = %d\n", iRCU);
1009 //___________________________________________________________________________________________
1010 Int_t AliCalorimeterUtils::GetNumberOfLocalMaxima(AliVCluster* cluster, AliVCaloCells* cells)
1012 // Find local maxima in cluster
1014 const Int_t nc = cluster->GetNCells();
1015 Int_t absIdList[nc];
1016 Float_t maxEList[nc];
1018 Int_t nMax = GetNumberOfLocalMaxima(cluster, cells, absIdList, maxEList);
1024 //___________________________________________________________________________________________
1025 Int_t AliCalorimeterUtils::GetNumberOfLocalMaxima(AliVCluster* cluster, AliVCaloCells* cells,
1026 Int_t *absIdList, Float_t *maxEList)
1028 // Find local maxima in cluster
1034 const Int_t nCells = cluster->GetNCells();
1036 TString calorimeter = "EMCAL";
1037 if(!cluster->IsEMCAL()) calorimeter = "PHOS";
1039 //printf("cluster : ncells %d \n",nCells);
1043 for(iDigit = 0; iDigit < nCells ; iDigit++)
1045 absIdList[iDigit] = cluster->GetCellsAbsId()[iDigit] ;
1046 Float_t en = cells->GetCellAmplitude(absIdList[iDigit]);
1047 RecalibrateCellAmplitude(en,calorimeter,absIdList[iDigit]);
1051 idmax = absIdList[iDigit] ;
1053 //Int_t icol = -1, irow = -1, iRCU = -1;
1054 //Int_t sm = GetModuleNumberCellIndexes(absIdList[iDigit], calorimeter, icol, irow, iRCU) ;
1055 //printf("\t cell %d, id %d, sm %d, col %d, row %d, e %f\n", iDigit, absIdList[iDigit], sm, icol, irow, en );
1058 for(iDigit = 0 ; iDigit < nCells; iDigit++)
1060 if(absIdList[iDigit]>=0)
1062 absId1 = cluster->GetCellsAbsId()[iDigit];
1064 Float_t en1 = cells->GetCellAmplitude(absId1);
1065 RecalibrateCellAmplitude(en1,calorimeter,absId1);
1067 //printf("%d : absIDi %d, E %f\n",iDigit, absId1,en1);
1069 for(iDigitN = 0; iDigitN < nCells; iDigitN++)
1071 absId2 = cluster->GetCellsAbsId()[iDigitN] ;
1073 if(absId2==-1 || absId2==absId1) continue;
1075 //printf("\t %d : absIDj %d\n",iDigitN, absId2);
1077 Float_t en2 = cells->GetCellAmplitude(absId2);
1078 RecalibrateCellAmplitude(en2,calorimeter,absId2);
1080 //printf("\t %d : absIDj %d, E %f\n",iDigitN, absId2,en2);
1082 if ( AreNeighbours(calorimeter, absId1, absId2) )
1084 // printf("\t \t Neighbours \n");
1087 absIdList[iDigitN] = -1 ;
1088 //printf("\t \t indexN %d not local max\n",iDigitN);
1089 // but may be digit too is not local max ?
1090 if(en1 < en2 + fLocMaxCutEDiff) {
1091 //printf("\t \t index %d not local max cause locMaxCutEDiff\n",iDigit);
1092 absIdList[iDigit] = -1 ;
1097 absIdList[iDigit] = -1 ;
1098 //printf("\t \t index %d not local max\n",iDigitN);
1099 // but may be digitN too is not local max ?
1100 if(en1 > en2 - fLocMaxCutEDiff)
1102 absIdList[iDigitN] = -1 ;
1103 //printf("\t \t indexN %d not local max cause locMaxCutEDiff\n",iDigit);
1106 } // if Are neighbours
1107 //else printf("\t \t NOT Neighbours \n");
1113 for(iDigit = 0; iDigit < nCells; iDigit++)
1115 if(absIdList[iDigit]>=0 )
1117 absIdList[iDigitN] = absIdList[iDigit] ;
1118 Float_t en = cells->GetCellAmplitude(absIdList[iDigit]);
1119 RecalibrateCellAmplitude(en,calorimeter,absIdList[iDigit]);
1120 if(en < fLocMaxCutE) continue; // Maxima only with seed energy at least
1121 maxEList[iDigitN] = en ;
1122 //printf("Local max %d, id %d, en %f\n", iDigit,absIdList[iDigitN],en);
1130 printf("AliCalorimeterUtils::GetNumberOfLocalMaxima() - No local maxima found, assign highest energy cell as maxima, id %d, en cell %2.2f, en cluster %2.2f\n",
1131 idmax,emax,cluster->E());
1133 maxEList[0] = emax ;
1134 absIdList[0] = idmax ;
1139 printf("AliCalorimeterUtils::GetNumberOfLocalMaxima() - In cluster E %2.2f, M02 %2.2f, M20 %2.2f, N maxima %d \n",
1140 cluster->E(),cluster->GetM02(),cluster->GetM20(), iDigitN);
1142 if(fDebug > 1) for(Int_t imax = 0; imax < iDigitN; imax++)
1144 printf(" \t i %d, absId %d, Ecell %f\n",imax,absIdList[imax],maxEList[imax]);
1152 //____________________________________
1153 TString AliCalorimeterUtils::GetPass()
1155 // Get passx from filename.
1157 if (!AliAnalysisManager::GetAnalysisManager()->GetTree())
1159 AliError("AliCalorimeterUtils::GetPass() - Pointer to tree = 0, returning null\n");
1163 if (!AliAnalysisManager::GetAnalysisManager()->GetTree()->GetCurrentFile())
1165 AliError("AliCalorimeterUtils::GetPass() - Null pointer input file, returning null\n");
1169 TString pass(AliAnalysisManager::GetAnalysisManager()->GetTree()->GetCurrentFile()->GetName());
1170 if (pass.Contains("ass1")) return TString("pass1");
1171 else if (pass.Contains("ass2")) return TString("pass2");
1172 else if (pass.Contains("ass3")) return TString("pass3");
1173 else if (pass.Contains("ass4")) return TString("pass4");
1174 else if (pass.Contains("ass5")) return TString("pass5");
1175 else if (pass.Contains("LHC11c") && pass.Contains("spc_calo") ) return TString("spc_calo");
1176 else if (pass.Contains("calo") || pass.Contains("high_lumi"))
1178 printf("AliCalorimeterUtils::GetPass() - Path contains <calo> or <high-lumi>, set as <pass1>\n");
1179 return TString("pass1");
1182 // No condition fullfilled, give a default value
1183 printf("AliCalorimeterUtils::GetPass() - Pass number string not found \n");
1188 //________________________________________
1189 void AliCalorimeterUtils::InitParameters()
1191 //Initialize the parameters of the analysis.
1196 fEMCALGeoMatrixSet = kFALSE;
1197 fPHOSGeoMatrixSet = kFALSE;
1199 fRemoveBadChannels = kFALSE;
1201 fNCellsFromPHOSBorder = 0;
1204 fLocMaxCutEDiff = 0.0 ;
1206 // fMaskCellColumns = new Int_t[fNMaskCellColumns];
1207 // fMaskCellColumns[0] = 6 ; fMaskCellColumns[1] = 7 ; fMaskCellColumns[2] = 8 ;
1208 // fMaskCellColumns[3] = 35; fMaskCellColumns[4] = 36; fMaskCellColumns[5] = 37;
1209 // fMaskCellColumns[6] = 12+AliEMCALGeoParams::fgkEMCALCols; fMaskCellColumns[7] = 13+AliEMCALGeoParams::fgkEMCALCols;
1210 // fMaskCellColumns[8] = 40+AliEMCALGeoParams::fgkEMCALCols; fMaskCellColumns[9] = 41+AliEMCALGeoParams::fgkEMCALCols;
1211 // fMaskCellColumns[10]= 42+AliEMCALGeoParams::fgkEMCALCols;
1214 fOADBForEMCAL = kTRUE ;
1215 fOADBForPHOS = kFALSE;
1217 fOADBFilePathEMCAL = "$ALICE_ROOT/OADB/EMCAL" ;
1218 fOADBFilePathPHOS = "$ALICE_ROOT/OADB/PHOS" ;
1220 fImportGeometryFromFile = kTRUE;
1221 fImportGeometryFilePath = "";
1223 fNSuperModulesUsed = 22;
1228 //_____________________________________________________
1229 void AliCalorimeterUtils::InitPHOSBadChannelStatusMap()
1231 //Init PHOS bad channels map
1232 if(fDebug > 0 )printf("AliCalorimeterUtils::InitPHOSBadChannelStatusMap()\n");
1233 //In order to avoid rewriting the same histograms
1234 Bool_t oldStatus = TH1::AddDirectoryStatus();
1235 TH1::AddDirectory(kFALSE);
1237 fPHOSBadChannelMap = new TObjArray(5);
1238 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));
1240 fPHOSBadChannelMap->SetOwner(kTRUE);
1241 fPHOSBadChannelMap->Compress();
1243 //In order to avoid rewriting the same histograms
1244 TH1::AddDirectory(oldStatus);
1247 //______________________________________________________
1248 void AliCalorimeterUtils::InitPHOSRecalibrationFactors()
1250 //Init EMCAL recalibration factors
1251 if(fDebug > 0 )printf("AliCalorimeterUtils::InitPHOSRecalibrationFactors()\n");
1252 //In order to avoid rewriting the same histograms
1253 Bool_t oldStatus = TH1::AddDirectoryStatus();
1254 TH1::AddDirectory(kFALSE);
1256 fPHOSRecalibrationFactors = new TObjArray(5);
1257 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));
1258 //Init the histograms with 1
1259 for (Int_t m = 0; m < 5; m++) {
1260 for (Int_t i = 0; i < 56; i++) {
1261 for (Int_t j = 0; j < 64; j++) {
1262 SetPHOSChannelRecalibrationFactor(m,j,i,1.);
1266 fPHOSRecalibrationFactors->SetOwner(kTRUE);
1267 fPHOSRecalibrationFactors->Compress();
1269 //In order to avoid rewriting the same histograms
1270 TH1::AddDirectory(oldStatus);
1274 //__________________________________________________________
1275 void AliCalorimeterUtils::InitEMCALGeometry(Int_t runnumber)
1277 //Initialize EMCAL geometry if it did not exist previously
1281 if(fEMCALGeoName=="")
1283 if (runnumber < 140000 &&
1284 runnumber >= 100000) fEMCALGeoName = "EMCAL_FIRSTYEARV1";
1285 else if(runnumber >= 140000 &&
1286 runnumber < 171000) fEMCALGeoName = "EMCAL_COMPLETEV1";
1287 else fEMCALGeoName = "EMCAL_COMPLETE12SMV1";
1288 printf("AliCalorimeterUtils::InitEMCALGeometry() - Set EMCAL geometry name to <%s> for run %d\n",fEMCALGeoName.Data(),runnumber);
1291 fEMCALGeo = AliEMCALGeometry::GetInstance(fEMCALGeoName);
1293 // Init geometry, I do not like much to do it like this ...
1294 if(fImportGeometryFromFile && !gGeoManager)
1296 if(fImportGeometryFilePath=="") // If not specified, set location depending on run number
1298 // "$ALICE_ROOT/EVE/alice-data/default_geo.root"
1299 if (runnumber < 140000 &&
1300 runnumber >= 100000) fImportGeometryFilePath = "$ALICE_ROOT/OADB/EMCAL/geometry_2010.root";
1301 if (runnumber >= 140000 &&
1302 runnumber < 171000) fImportGeometryFilePath = "$ALICE_ROOT/OADB/EMCAL/geometry_2011.root";
1303 else fImportGeometryFilePath = "$ALICE_ROOT/OADB/EMCAL/geometry_2012.root"; // 2012-2013
1306 printf("AliCalorimeterUtils::InitEMCALGeometry() - Import %s\n",fImportGeometryFilePath.Data());
1307 TGeoManager::Import(fImportGeometryFilePath) ; // default need file "geometry.root" in local dir!!!!
1313 printf("AliCalorimeterUtils::InitEMCALGeometry(run=%d)",runnumber);
1314 if (!gGeoManager) printf(" - Careful!, gGeoManager not loaded, load misalign matrices");
1320 //_________________________________________________________
1321 void AliCalorimeterUtils::InitPHOSGeometry(Int_t runnumber)
1323 //Initialize PHOS geometry if it did not exist previously
1327 if(fPHOSGeoName=="") fPHOSGeoName = "PHOSgeo";
1329 fPHOSGeo = new AliPHOSGeoUtils(fPHOSGeoName);
1333 printf("AliCalorimeterUtils::InitPHOSGeometry(run=%d)",runnumber);
1334 if (!gGeoManager) printf(" - Careful!, gGeoManager not loaded, load misalign matrices");
1340 //_______________________________________________________________________
1341 Bool_t AliCalorimeterUtils::MaskFrameCluster(Int_t iSM, Int_t ieta) const
1343 //Check if cell is in one of the regions where we have significant amount
1344 //of material in front. Only EMCAL
1347 if(iSM%2) icol+=48; // Impair SM, shift index [0-47] to [48-96]
1349 if (fNMaskCellColumns && fMaskCellColumns)
1351 for (Int_t imask = 0; imask < fNMaskCellColumns; imask++)
1353 if(icol==fMaskCellColumns[imask]) return kTRUE;
1361 //_________________________________________________________
1362 void AliCalorimeterUtils::Print(const Option_t * opt) const
1365 //Print some relevant parameters set for the analysis
1369 printf("***** Print: %s %s ******\n", GetName(), GetTitle() ) ;
1370 printf("Remove Clusters with bad channels? %d\n",fRemoveBadChannels);
1371 printf("Remove Clusters with max cell at less than %d cells from EMCAL border and %d cells from PHOS border\n",
1372 fEMCALRecoUtils->GetNumberOfCellsFromEMCALBorder(), fNCellsFromPHOSBorder);
1373 if(fEMCALRecoUtils->IsEMCALNoBorderAtEta0()) printf("Do not remove EMCAL clusters at Eta = 0\n");
1374 printf("Recalibrate Clusters? %d, run by run %d\n",fRecalibration,fRunDependentCorrection);
1375 printf("Recalculate Clusters Position? %d\n",fRecalculatePosition);
1376 printf("Recalculate Clusters Energy? %d\n",fCorrectELinearity);
1377 printf("Matching criteria: dR < %2.2f[cm], dZ < %2.2f[cm]\n",fCutR,fCutZ);
1379 printf("Loc. Max. E > %2.2f\n", fLocMaxCutE);
1380 printf("Loc. Max. E Diff > %2.2f\n", fLocMaxCutEDiff);
1385 //_____________________________________________________________________________________________
1386 void AliCalorimeterUtils::RecalibrateCellAmplitude(Float_t & amp, TString calo, Int_t id) const
1388 //Recaculate cell energy if recalibration factor
1390 Int_t icol = -1; Int_t irow = -1; Int_t iRCU = -1;
1391 Int_t nModule = GetModuleNumberCellIndexes(id,calo, icol, irow, iRCU);
1393 if (IsRecalibrationOn())
1397 amp *= GetPHOSChannelRecalibrationFactor(nModule,icol,irow);
1401 amp *= GetEMCALChannelRecalibrationFactor(nModule,icol,irow);
1406 //____________________________________________________________________________________________________
1407 void AliCalorimeterUtils::RecalibrateCellTime(Double_t & time, TString calo, Int_t id, Int_t bc) const
1409 // Recalculate time if time recalibration available for EMCAL
1410 // not ready for PHOS
1412 if(calo == "EMCAL" && GetEMCALRecoUtils()->IsTimeRecalibrationOn())
1414 GetEMCALRecoUtils()->RecalibrateCellTime(id,bc,time);
1419 //__________________________________________________________________________
1420 Float_t AliCalorimeterUtils::RecalibrateClusterEnergy(AliVCluster * cluster,
1421 AliVCaloCells * cells)
1423 // Recalibrate the cluster energy, considering the recalibration map and the energy of the cells that compose the cluster.
1425 //Initialize some used variables
1426 Float_t frac = 0., energy = 0.;
1430 //Get the cluster number of cells and list of absId, check what kind of cluster do we have.
1432 UShort_t * index = cluster->GetCellsAbsId() ;
1433 Double_t * fraction = cluster->GetCellsAmplitudeFraction() ;
1435 Int_t ncells = cluster->GetNCells();
1437 TString calo = "EMCAL";
1438 if(cluster->IsPHOS())
1441 //Loop on the cells, get the cell amplitude and recalibration factor, multiply and and to the new energy
1442 for(Int_t icell = 0; icell < ncells; icell++){
1444 Int_t absId = index[icell];
1446 frac = fraction[icell];
1447 if(frac < 1e-3) frac = 1; //in case of EMCAL, this is set as 0, not used.
1449 Float_t amp = cells->GetCellAmplitude(absId);
1450 RecalibrateCellAmplitude(amp,calo, absId);
1453 printf("AliCalorimeterUtils::RecalibrateClusterEnergy() - recalibrate cell: %s, cell fraction %f, cell energy %f\n",
1454 calo.Data(),frac,cells->GetCellAmplitude(absId));
1460 printf("AliCalorimeterUtils::RecalibrateClusterEnergy() - Energy before %f, after %f\n",cluster->E(),energy);
1465 Fatal("RecalibrateClusterEnergy()","Cells pointer does not exist!");
1471 //__________________________________________________________________________________________
1472 void AliCalorimeterUtils::RecalculateClusterPosition(AliVCaloCells* cells, AliVCluster* clu)
1475 //Recalculate EMCAL cluster position
1477 fEMCALRecoUtils->RecalculateClusterPosition((AliEMCALGeometry*)fEMCALGeo, cells,clu);
1481 //________________________________________________________________________________
1482 void AliCalorimeterUtils::RecalculateClusterTrackMatching(AliVEvent * event,
1483 TObjArray* clusterArray)
1485 //Recalculate track matching
1487 if (fRecalculateMatching)
1489 fEMCALRecoUtils->FindMatches(event,clusterArray,fEMCALGeo) ;
1490 //AliESDEvent* esdevent = dynamic_cast<AliESDEvent*> (event);
1492 // fEMCALRecoUtils->SetClusterMatchedToTrack(esdevent) ;
1493 // fEMCALRecoUtils->SetTracksMatchedToCluster(esdevent) ;
1498 //___________________________________________________________________________
1499 void AliCalorimeterUtils::SplitEnergy(Int_t absId1, Int_t absId2,
1500 AliVCluster* cluster,
1501 AliVCaloCells* cells,
1502 //Float_t & e1, Float_t & e2,
1503 AliAODCaloCluster* cluster1,
1504 AliAODCaloCluster* cluster2,
1505 Int_t nMax, Int_t eventNumber)
1508 // Split energy of cluster between the 2 local maxima, sum energy on 3x3, and if the 2
1509 // maxima are too close and have common cells, split the energy between the 2
1511 TH2F* hClusterMap = 0 ;
1512 TH2F* hClusterLocMax = 0 ;
1513 TH2F* hCluster1 = 0 ;
1514 TH2F* hCluster2 = 0 ;
1518 hClusterMap = new TH2F("hClusterMap","Cluster Map",48,0,48,24,0,24);
1519 hClusterLocMax = new TH2F("hClusterLocMax","Cluster 2 highest local maxima",48,0,48,24,0,24);
1520 hCluster1 = new TH2F("hCluster1","Cluster 1",48,0,48,24,0,24);
1521 hCluster2 = new TH2F("hCluster2","Cluster 2",48,0,48,24,0,24);
1522 hClusterMap ->SetXTitle("column");
1523 hClusterMap ->SetYTitle("row");
1524 hClusterLocMax ->SetXTitle("column");
1525 hClusterLocMax ->SetYTitle("row");
1526 hCluster1 ->SetXTitle("column");
1527 hCluster1 ->SetYTitle("row");
1528 hCluster2 ->SetXTitle("column");
1529 hCluster2 ->SetYTitle("row");
1532 TString calorimeter = "EMCAL";
1533 if(cluster->IsPHOS())
1536 printf("AliCalorimeterUtils::SplitEnerg() Not supported for PHOS yet \n");
1540 const Int_t ncells = cluster->GetNCells();
1541 Int_t absIdList[ncells];
1543 Float_t e1 = 0, e2 = 0 ;
1544 Int_t icol = -1, irow = -1, iRCU = -1, sm = -1;
1545 Float_t eCluster = 0;
1546 Float_t minCol = 100, minRow = 100, maxCol = -1, maxRow = -1;
1547 for(Int_t iDigit = 0; iDigit < ncells; iDigit++ )
1549 absIdList[iDigit] = cluster->GetCellsAbsId()[iDigit];
1551 Float_t ec = cells->GetCellAmplitude(absIdList[iDigit]);
1552 RecalibrateCellAmplitude(ec,calorimeter, absIdList[iDigit]);
1557 //printf("iDigit %d, absId %d, Ecell %f\n",iDigit,absIdList[iDigit], cells->GetCellAmplitude(absIdList[iDigit]));
1558 sm = GetModuleNumberCellIndexes(absIdList[iDigit], calorimeter, icol, irow, iRCU) ;
1559 if(sm > -1 && sm < 12) // just to avoid compilation warning
1561 if(icol > maxCol) maxCol = icol;
1562 if(icol < minCol) minCol = icol;
1563 if(irow > maxRow) maxRow = irow;
1564 if(irow < minRow) minRow = irow;
1565 hClusterMap->Fill(icol,irow,ec);
1571 // Init counters and variables
1573 UShort_t absIdList1[9] ;
1574 Double_t fracList1 [9] ;
1575 absIdList1[0] = absId1 ;
1576 fracList1 [0] = 1. ;
1578 Float_t ecell1 = cells->GetCellAmplitude(absId1);
1579 RecalibrateCellAmplitude(ecell1, calorimeter, absId1);
1583 UShort_t absIdList2[9] ;
1584 Double_t fracList2 [9] ;
1585 absIdList2[0] = absId2 ;
1586 fracList2 [0] = 1. ;
1588 Float_t ecell2 = cells->GetCellAmplitude(absId2);
1589 RecalibrateCellAmplitude(ecell2, calorimeter, absId2);
1594 Int_t icol1 = -1, irow1 = -1, icol2 = -1, irow2 = -1;
1595 sm = GetModuleNumberCellIndexes(absId1, calorimeter, icol1, irow1, iRCU) ;
1596 hClusterLocMax->Fill(icol1,irow1,ecell1);
1597 sm = GetModuleNumberCellIndexes(absId2, calorimeter, icol2, irow2, iRCU) ;
1598 hClusterLocMax->Fill(icol2,irow2,ecell2);
1601 // Very rough way to share the cluster energy
1602 Float_t eRemain = (eCluster-ecell1-ecell2)/2;
1603 Float_t shareFraction1 = ecell1/eCluster+eRemain/eCluster;
1604 Float_t shareFraction2 = ecell2/eCluster+eRemain/eCluster;
1606 for(Int_t iDigit = 0; iDigit < ncells; iDigit++)
1608 Int_t absId = absIdList[iDigit];
1610 if(absId==absId1 || absId==absId2 || absId < 0) continue;
1612 Float_t ecell = cells->GetCellAmplitude(absId);
1613 RecalibrateCellAmplitude(ecell, calorimeter, absId);
1615 if(AreNeighbours(calorimeter, absId1,absId ))
1617 absIdList1[ncells1]= absId;
1619 if(AreNeighbours(calorimeter, absId2,absId ))
1621 fracList1[ncells1] = shareFraction1;
1622 e1 += ecell*shareFraction1;
1626 fracList1[ncells1] = 1.;
1632 } // neigbour to cell1
1634 if(AreNeighbours(calorimeter, absId2,absId ))
1636 absIdList2[ncells2]= absId;
1638 if(AreNeighbours(calorimeter, absId1,absId ))
1640 fracList2[ncells2] = shareFraction2;
1641 e2 += ecell*shareFraction2;
1645 fracList2[ncells2] = 1.;
1651 } // neigbour to cell2
1655 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",
1656 nMax, eCluster,ecell1,ecell2,e1,e2,eCluster-e1-e2,ncells,ncells1,ncells2,shareFraction1,shareFraction2,shareFraction1+shareFraction2);
1661 cluster1->SetNCells(ncells1);
1662 cluster2->SetNCells(ncells2);
1664 cluster1->SetCellsAbsId(absIdList1);
1665 cluster2->SetCellsAbsId(absIdList2);
1667 cluster1->SetCellsAmplitudeFraction(fracList1);
1668 cluster2->SetCellsAmplitudeFraction(fracList2);
1671 CorrectClusterEnergy(cluster1) ;
1672 CorrectClusterEnergy(cluster2) ;
1674 if(calorimeter=="EMCAL")
1676 GetEMCALRecoUtils()->RecalculateClusterPosition(GetEMCALGeometry(), cells, cluster1);
1677 GetEMCALRecoUtils()->RecalculateClusterPosition(GetEMCALGeometry(), cells, cluster2);
1682 //printf("Cells of cluster1: ");
1683 for(Int_t iDigit = 0; iDigit < ncells1; iDigit++ )
1685 //printf(" %d ",absIdList1[iDigit]);
1687 sm = GetModuleNumberCellIndexes(absIdList1[iDigit], calorimeter, icol, irow, iRCU) ;
1689 Float_t ecell = cells->GetCellAmplitude(absIdList1[iDigit]);
1690 RecalibrateCellAmplitude(ecell, calorimeter, absIdList1[iDigit]);
1692 if( AreNeighbours(calorimeter, absId2,absIdList1[iDigit]) && absId1!=absIdList1[iDigit])
1693 hCluster1->Fill(icol,irow,ecell*shareFraction1);
1695 hCluster1->Fill(icol,irow,ecell);
1699 //printf("Cells of cluster2: ");
1701 for(Int_t iDigit = 0; iDigit < ncells2; iDigit++ )
1703 //printf(" %d ",absIdList2[iDigit]);
1705 sm = GetModuleNumberCellIndexes(absIdList2[iDigit], calorimeter, icol, irow, iRCU) ;
1707 Float_t ecell = cells->GetCellAmplitude(absIdList2[iDigit]);
1708 RecalibrateCellAmplitude(ecell, calorimeter, absIdList2[iDigit]);
1710 if( AreNeighbours(calorimeter, absId1,absIdList2[iDigit]) && absId2!=absIdList2[iDigit])
1711 hCluster2->Fill(icol,irow,ecell*shareFraction2);
1713 hCluster2->Fill(icol,irow,ecell);
1718 gStyle->SetPadRightMargin(0.1);
1719 gStyle->SetPadLeftMargin(0.1);
1720 gStyle->SetOptStat(0);
1721 gStyle->SetOptFit(000000);
1723 if(maxCol-minCol > maxRow-minRow)
1725 maxRow+= maxCol-minCol;
1729 maxCol+= maxRow-minRow;
1732 TCanvas * c= new TCanvas("canvas", "canvas", 4000, 4000) ;
1738 hClusterMap ->SetAxisRange(minCol, maxCol,"X");
1739 hClusterMap ->SetAxisRange(minRow, maxRow,"Y");
1740 hClusterMap ->Draw("colz TEXT");
1745 hClusterLocMax ->SetAxisRange(minCol, maxCol,"X");
1746 hClusterLocMax ->SetAxisRange(minRow, maxRow,"Y");
1747 hClusterLocMax ->Draw("colz TEXT");
1752 hCluster1 ->SetAxisRange(minCol, maxCol,"X");
1753 hCluster1 ->SetAxisRange(minRow, maxRow,"Y");
1754 hCluster1 ->Draw("colz TEXT");
1759 hCluster2 ->SetAxisRange(minCol, maxCol,"X");
1760 hCluster2 ->SetAxisRange(minRow, maxRow,"Y");
1761 hCluster2 ->Draw("colz TEXT");
1763 if(eCluster > 6 )c->Print(Form("clusterFigures/Event%d_E%1.0f_nMax%d_NCell1_%d_NCell2_%d.eps",
1764 eventNumber,cluster->E(),nMax,ncells1,ncells2));
1768 delete hClusterLocMax;