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"
28 // --- ANALYSIS system ---
29 #include "AliCalorimeterUtils.h"
30 #include "AliESDEvent.h"
31 #include "AliMCEvent.h"
33 #include "AliAODPWG4Particle.h"
34 #include "AliVCluster.h"
35 #include "AliVCaloCells.h"
36 #include "AliMixedEvent.h"
39 #include "AliEMCALGeometry.h"
40 #include "AliPHOSGeoUtils.h"
42 ClassImp(AliCalorimeterUtils)
45 //____________________________________________
46 AliCalorimeterUtils::AliCalorimeterUtils() :
48 fEMCALGeoName("EMCAL_COMPLETE12SMV1"),
49 fPHOSGeoName ("PHOSgeo"),
50 fEMCALGeo(0x0), fPHOSGeo(0x0),
51 fEMCALGeoMatrixSet(kFALSE), fPHOSGeoMatrixSet(kFALSE),
52 fLoadEMCALMatrices(kFALSE), fLoadPHOSMatrices(kFALSE),
53 fRemoveBadChannels(kFALSE), fPHOSBadChannelMap(0x0),
54 fNCellsFromPHOSBorder(0),
55 fNMaskCellColumns(0), fMaskCellColumns(0x0),
56 fRecalibration(kFALSE), fPHOSRecalibrationFactors(),
57 fEMCALRecoUtils(new AliEMCALRecoUtils),
58 fRecalculatePosition(kFALSE), fCorrectELinearity(kFALSE),
59 fRecalculateMatching(kFALSE),
61 fCutEta(20), fCutPhi(20),
62 fLocMaxCutE(0), fLocMaxCutEDiff(0)
66 //Initialize parameters
68 for(Int_t i = 0; i < 12; i++) fEMCALMatrix[i] = 0 ;
69 for(Int_t i = 0; i < 5 ; i++) fPHOSMatrix [i] = 0 ;
73 //_________________________________________
74 AliCalorimeterUtils::~AliCalorimeterUtils()
78 //if(fPHOSGeo) delete fPHOSGeo ;
79 if(fEMCALGeo) delete fEMCALGeo ;
81 if(fPHOSBadChannelMap) {
82 fPHOSBadChannelMap->Clear();
83 delete fPHOSBadChannelMap;
86 if(fPHOSRecalibrationFactors) {
87 fPHOSRecalibrationFactors->Clear();
88 delete fPHOSRecalibrationFactors;
91 if(fEMCALRecoUtils) delete fEMCALRecoUtils ;
92 if(fNMaskCellColumns) delete [] fMaskCellColumns;
96 //______________________________________________________________________________________
97 Bool_t AliCalorimeterUtils::AreNeighbours(const TString calo,
98 const Int_t absId1, const Int_t absId2 ) const
100 // Tells if (true) or not (false) two cells are neighbours
101 // A neighbour is defined as being two cells which share a side or corner
103 Bool_t areNeighbours = kFALSE ;
105 Int_t iRCU1 = -1, irow1 = -1, icol1 = -1;
106 Int_t iRCU2 = -1, irow2 = -1, icol2 = -1;
108 Int_t rowdiff = 0, coldiff = 0;
110 Int_t nSupMod1 = GetModuleNumberCellIndexes(absId1, calo, icol1, irow1, iRCU1);
111 Int_t nSupMod2 = GetModuleNumberCellIndexes(absId2, calo, icol2, irow2, iRCU2);
113 if(calo=="EMCAL" && nSupMod1!=nSupMod2)
115 // In case of a shared cluster, index of SM in C side, columns start at 48 and ends at 48*2-1
116 // C Side impair SM, nSupMod%2=1; A side pair SM nSupMod%2=0
117 if(nSupMod1%2) icol1+=AliEMCALGeoParams::fgkEMCALCols;
118 else icol2+=AliEMCALGeoParams::fgkEMCALCols;
121 rowdiff = TMath::Abs( irow1 - irow2 ) ;
122 coldiff = TMath::Abs( icol1 - icol2 ) ;
124 if (( coldiff <= 1 ) && ( rowdiff <= 1 ) && (coldiff + rowdiff > 0))
125 areNeighbours = kTRUE ;
127 return areNeighbours;
132 //_____________________________________________________________________________________
133 Bool_t AliCalorimeterUtils::CheckCellFiducialRegion(AliVCluster* cluster,
134 AliVCaloCells* cells,
135 AliVEvent * event, Int_t iev) const
138 // Given the list of AbsId of the cluster, get the maximum cell and
139 // check if there are fNCellsFromBorder from the calorimeter border
141 //If the distance to the border is 0 or negative just exit accept all clusters
142 if(cells->GetType()==AliVCaloCells::kEMCALCell && fEMCALRecoUtils->GetNumberOfCellsFromEMCALBorder() <= 0 ) return kTRUE;
143 if(cells->GetType()==AliVCaloCells::kPHOSCell && fNCellsFromPHOSBorder <= 0 ) return kTRUE;
148 AliMixedEvent * mixEvent = dynamic_cast<AliMixedEvent*> (event);
149 Int_t nMixedEvents = 0 ;
150 Int_t * cellsCumul = NULL ;
151 Int_t numberOfCells = 0 ;
153 nMixedEvents = mixEvent->GetNumberOfEvents() ;
154 if (cells->GetType()==AliVCaloCells::kEMCALCell) {
155 cellsCumul = mixEvent->GetEMCALCellsCumul() ;
156 numberOfCells = mixEvent->GetNumberOfEMCALCells() ;
159 else if (cells->GetType()==AliVCaloCells::kPHOSCell) {
160 cellsCumul = mixEvent->GetPHOSCellsCumul() ;
161 numberOfCells = mixEvent->GetNumberOfPHOSCells() ;
166 Int_t startCell = cellsCumul[iev] ;
167 Int_t endCell = (iev+1 < nMixedEvents)?cellsCumul[iev+1]:numberOfCells;
168 //Find cells with maximum amplitude
169 for(Int_t i = 0; i < cluster->GetNCells() ; i++){
170 Int_t absId = cluster->GetCellAbsId(i) ;
171 for (Int_t j = startCell; j < endCell ; j++) {
175 cells->GetCell(j, cellNumber, amp, time) ;
176 if (absId == cellNumber) {
183 }//loop on cluster cells
184 }// cells cumul available
186 printf("AliCalorimeterUtils::CheckCellFiducialRegion() - CellsCumul is NULL!!!\n");
189 } else {//Normal SE Events
190 for(Int_t i = 0; i < cluster->GetNCells() ; i++){
191 Int_t absId = cluster->GetCellAbsId(i) ;
192 Float_t amp = cells->GetCellAmplitude(absId);
201 printf("AliCalorimeterUtils::CheckCellFiducialRegion() - Cluster Max AbsId %d, Cell Energy %2.2f, Cluster Energy %2.2f\n",
202 absIdMax, ampMax, cluster->E());
204 if(absIdMax==-1) return kFALSE;
206 //Check if the cell is close to the borders:
207 Bool_t okrow = kFALSE;
208 Bool_t okcol = kFALSE;
210 if(cells->GetType()==AliVCaloCells::kEMCALCell){
212 Int_t iTower = -1, iIphi = -1, iIeta = -1, iphi = -1, ieta = -1, iSM = -1;
213 fEMCALGeo->GetCellIndex(absIdMax,iSM,iTower,iIphi,iIeta);
214 fEMCALGeo->GetCellPhiEtaIndexInSModule(iSM,iTower,iIphi, iIeta,iphi,ieta);
215 if(iSM < 0 || iphi < 0 || ieta < 0 ) {
216 Fatal("CheckCellFidutialRegion","Negative value for super module: %d, or cell ieta: %d, or cell iphi: %d, check EMCAL geometry name\n",iSM,ieta,iphi);
220 Int_t nborder = fEMCALRecoUtils->GetNumberOfCellsFromEMCALBorder();
222 if(iphi >= nborder && iphi < 24-nborder) okrow =kTRUE;
225 if(iphi >= nborder && iphi < 12-nborder) okrow =kTRUE;
229 if(!fEMCALRecoUtils->IsEMCALNoBorderAtEta0()){
230 if(ieta > nborder && ieta < 48-nborder) okcol =kTRUE;
234 if(ieta >= nborder) okcol = kTRUE;
237 if(ieta < 48-nborder) okcol = kTRUE;
242 printf("AliCalorimeterUtils::CheckCellFiducialRegion() - EMCAL Cluster in %d cells fiducial volume: ieta %d, iphi %d, SM %d ?",
243 nborder, ieta, iphi, iSM);
244 if (okcol && okrow ) printf(" YES \n");
245 else printf(" NO: column ok? %d, row ok? %d \n",okcol,okrow);
248 else if(cells->GetType()==AliVCaloCells::kPHOSCell){
250 Int_t irow = -1, icol = -1;
251 fPHOSGeo->AbsToRelNumbering(absIdMax,relId);
255 if(irow >= fNCellsFromPHOSBorder && irow < 64-fNCellsFromPHOSBorder) okrow =kTRUE;
256 if(icol >= fNCellsFromPHOSBorder && icol < 56-fNCellsFromPHOSBorder) okcol =kTRUE;
259 printf("AliCalorimeterUtils::CheckCellFiducialRegion() - PHOS Cluster in %d cells fiducial volume: icol %d, irow %d, Module %d?",
260 fNCellsFromPHOSBorder, icol, irow, relId[0]-1);
261 if (okcol && okrow ) printf(" YES \n");
262 else printf(" NO: column ok? %d, row ok? %d \n",okcol,okrow);
266 if (okcol && okrow) return kTRUE;
271 //_________________________________________________________________________________________________________
272 Bool_t AliCalorimeterUtils::ClusterContainsBadChannel(TString calorimeter,UShort_t* cellList, Int_t nCells)
274 // Check that in the cluster cells, there is no bad channel of those stored
275 // in fEMCALBadChannelMap or fPHOSBadChannelMap
277 if (!fRemoveBadChannels) return kFALSE;
278 //printf("fEMCALBadChannelMap %p, fPHOSBadChannelMap %p \n",fEMCALBadChannelMap,fPHOSBadChannelMap);
279 if(calorimeter == "EMCAL" && !fEMCALRecoUtils->GetEMCALChannelStatusMap(0)) return kFALSE;
280 if(calorimeter == "PHOS" && !fPHOSBadChannelMap) return kFALSE;
285 for(Int_t iCell = 0; iCell<nCells; iCell++){
287 //Get the column and row
288 if(calorimeter == "EMCAL"){
289 return fEMCALRecoUtils->ClusterContainsBadChannel((AliEMCALGeometry*)fEMCALGeo,cellList,nCells);
291 else if(calorimeter=="PHOS"){
293 fPHOSGeo->AbsToRelNumbering(cellList[iCell],relId);
297 if(fPHOSBadChannelMap->GetEntries() <= imod)continue;
298 //printf("PHOS bad channels imod %d, icol %d, irow %d\n",imod, irow, icol);
299 if(GetPHOSChannelStatus(imod, irow, icol)) return kTRUE;
303 }// cell cluster loop
309 //_______________________________________________________________
310 void AliCalorimeterUtils::CorrectClusterEnergy(AliVCluster *clus)
312 // Correct cluster energy non linearity
314 clus->SetE(fEMCALRecoUtils->CorrectClusterEnergyLinearity(clus));
318 //________________________________________________________________________________________
319 Int_t AliCalorimeterUtils::GetMaxEnergyCell(AliVCaloCells* cells, const AliVCluster* clu,
320 Float_t & clusterFraction) const
323 //For a given CaloCluster gets the absId of the cell
324 //with maximum energy deposit.
326 if( !clu || !cells ){
327 AliInfo("Cluster or cells pointer is null!");
334 Float_t fraction = 1.;
335 Float_t recalFactor = 1.;
336 Int_t cellAbsId =-1 , absId =-1 ;
337 Int_t iSupMod =-1 , ieta =-1 , iphi = -1, iRCU = -1;
339 TString calo = "EMCAL";
340 if(clu->IsPHOS()) calo = "PHOS";
342 for (Int_t iDig=0; iDig< clu->GetNCells(); iDig++) {
344 cellAbsId = clu->GetCellAbsId(iDig);
346 fraction = clu->GetCellAmplitudeFraction(iDig);
347 if(fraction < 1e-4) fraction = 1.; // in case unfolding is off
349 iSupMod = GetModuleNumberCellIndexes(cellAbsId, calo, ieta, iphi, iRCU);
351 if(IsRecalibrationOn()) {
352 if(calo=="EMCAL") recalFactor = GetEMCALChannelRecalibrationFactor(iSupMod,ieta,iphi);
353 else recalFactor = GetPHOSChannelRecalibrationFactor (iSupMod,iphi,ieta);
356 eCell = cells->GetCellAmplitude(cellAbsId)*fraction*recalFactor;
367 clusterFraction = (eTot-eMax)/eTot; //Do not use cluster energy in case it was corrected for non linearity.
373 //__________________________________________________________________________
374 AliVTrack * AliCalorimeterUtils::GetMatchedTrack(const AliVCluster* cluster,
375 const AliVEvent* event,
376 const Int_t index) const
378 // Get the matched track given its index, usually just the first match
379 // Since it is different for ESDs and AODs here it is a wrap method to do it
381 AliVTrack *track = 0;
383 // EMCAL case only when matching is recalculated
384 if(cluster->IsEMCAL() && IsRecalculationOfClusterTrackMatchingOn())
386 Int_t trackIndex = fEMCALRecoUtils->GetMatchedTrackIndex(cluster->GetID());
387 //printf("track index %d, cluster ID %d \n ",trackIndex,cluster->GetID());
391 printf("AliCalorimeterUtils::GetMatchedTrack() - Wrong track index %d, from recalculation\n", trackIndex);
395 track = dynamic_cast<AliVTrack*> (event->GetTrack(trackIndex));
402 // Normal case, get info from ESD or AOD
404 if(!strcmp("AliESDCaloCluster",Form("%s",cluster->ClassName())))
406 Int_t iESDtrack = cluster->GetTrackMatchedIndex();
410 printf("AliCalorimeterUtils::GetMatchedTrack() - Wrong track index %d\n", index);
414 track = dynamic_cast<AliVTrack*> (event->GetTrack(iESDtrack));
419 if(cluster->GetNTracksMatched() > 0 )
420 track = dynamic_cast<AliVTrack*>(cluster->GetTrackMatched(index));
427 //_____________________________________________________________________________________________________
428 Int_t AliCalorimeterUtils::GetModuleNumber(AliAODPWG4Particle * particle, AliVEvent * inputEvent) const
430 //Get the EMCAL/PHOS module number that corresponds to this particle
433 if(particle->GetDetector()=="EMCAL"){
434 fEMCALGeo->GetAbsCellIdFromEtaPhi(particle->Eta(),particle->Phi(), absId);
436 printf("AliCalorimeterUtils::GetModuleNumber(PWG4AOD) - EMCAL: cluster eta %f, phi %f, absid %d, SuperModule %d\n",
437 particle->Eta(), particle->Phi()*TMath::RadToDeg(),absId, fEMCALGeo->GetSuperModuleNumber(absId));
438 return fEMCALGeo->GetSuperModuleNumber(absId) ;
440 else if(particle->GetDetector()=="PHOS"){
441 // In case we use the MC reader, the input are TParticles,
442 // in this case use the corresponing method in PHOS Geometry to get the particle.
443 if(strcmp(inputEvent->ClassName(), "AliMCEvent") == 0 )
446 Double_t z = 0., x=0.;
447 TParticle* primary = 0x0;
448 AliStack * stack = ((AliMCEvent*)inputEvent)->Stack();
450 primary = stack->Particle(particle->GetCaloLabel(0));
453 Fatal("GetModuleNumber(PWG4AOD)", "Stack not available, stop!");
457 fPHOSGeo->ImpactOnEmc(primary,mod,z,x) ;
460 Fatal("GetModuleNumber(PWG4AOD)", "Primary not available, stop!");
464 // Input are ESDs or AODs, get the PHOS module number like this.
467 //AliVCluster *cluster = inputEvent->GetCaloCluster(particle->GetCaloLabel(0));
468 //return GetModuleNumber(cluster);
477 //_____________________________________________________________________
478 Int_t AliCalorimeterUtils::GetModuleNumber(AliVCluster * cluster) const
480 //Get the EMCAL/PHOS module number that corresponds to this cluster
482 Double_t v[]={0.,0.,0.}; //not necessary to pass the real vertex.
484 if(fDebug > 1) printf("AliCalorimeterUtils::GetModuleNumber() - NUL Cluster, please check!!!");
487 cluster->GetMomentum(lv,v);
488 Float_t phi = lv.Phi();
489 if(phi < 0) phi+=TMath::TwoPi();
491 if(cluster->IsEMCAL()){
492 fEMCALGeo->GetAbsCellIdFromEtaPhi(lv.Eta(),phi, absId);
494 printf("AliCalorimeterUtils::GetModuleNumber() - EMCAL: cluster eta %f, phi %f, absid %d, SuperModule %d\n",
495 lv.Eta(), phi*TMath::RadToDeg(),absId, fEMCALGeo->GetSuperModuleNumber(absId));
496 return fEMCALGeo->GetSuperModuleNumber(absId) ;
498 else if(cluster->IsPHOS()) {
500 if ( cluster->GetNCells() > 0) {
501 absId = cluster->GetCellAbsId(0);
503 printf("AliCalorimeterUtils::GetModuleNumber() - PHOS: cluster eta %f, phi %f, e %f, absId %d\n",
504 lv.Eta(), phi*TMath::RadToDeg(), lv.E(), absId);
509 fPHOSGeo->AbsToRelNumbering(absId,relId);
511 printf("AliCalorimeterUtils::GetModuleNumber() - PHOS: Module %d\n",relId[0]-1);
520 //___________________________________________________________________________________________________
521 Int_t AliCalorimeterUtils::GetModuleNumberCellIndexes(const Int_t absId, const TString calo,
522 Int_t & icol, Int_t & irow, Int_t & iRCU) const
524 //Get the EMCAL/PHOS module, columns, row and RCU number that corresponds to this absId
528 Int_t iTower = -1, iIphi = -1, iIeta = -1;
529 fEMCALGeo->GetCellIndex(absId,imod,iTower,iIphi,iIeta);
530 fEMCALGeo->GetCellPhiEtaIndexInSModule(imod,iTower,iIphi, iIeta,irow,icol);
531 if(imod < 0 || irow < 0 || icol < 0 ) {
532 Fatal("GetModuleNumberCellIndexes()","Negative value for super module: %d, or cell icol: %d, or cell irow: %d, check EMCAL geometry name\n",imod,icol,irow);
536 if (0<=irow&&irow<8) iRCU=0; // first cable row
537 else if (8<=irow&&irow<16 && 0<=icol&&icol<24) iRCU=0; // first half;
540 else if(8<=irow&&irow<16 && 24<=icol&&icol<48) iRCU=1; // second half;
542 else if(16<=irow&&irow<24) iRCU=1; // third cable row
544 if (imod%2==1) iRCU = 1 - iRCU; // swap for odd=C side, to allow us to cable both sides the same
546 Fatal("GetModuleNumberCellIndexes()","Wrong EMCAL RCU number = %d\n", iRCU);
553 fPHOSGeo->AbsToRelNumbering(absId,relId);
557 iRCU= (Int_t)(relId[2]-1)/16 ;
558 //Int_t iBranch= (Int_t)(relid[3]-1)/28 ; //0 to 1
560 Fatal("GetModuleNumberCellIndexes()","Wrong PHOS RCU number = %d\n", iRCU);
569 //___________________________________________________________________________________________
570 Int_t AliCalorimeterUtils::GetNumberOfLocalMaxima(AliVCluster* cluster, AliVCaloCells* cells)
572 // Find local maxima in cluster
574 const Int_t nc = cluster->GetNCells();
575 Int_t *absIdList = new Int_t [nc];
576 Float_t *maxEList = new Float_t[nc];
578 Int_t nMax = GetNumberOfLocalMaxima(cluster, cells, absIdList, maxEList);
587 //___________________________________________________________________________________________
588 Int_t AliCalorimeterUtils::GetNumberOfLocalMaxima(AliVCluster* cluster, AliVCaloCells* cells,
589 Int_t *absIdList, Float_t *maxEList)
591 // Find local maxima in cluster
597 const Int_t nCells = cluster->GetNCells();
599 TString calorimeter = "EMCAL";
600 if(!cluster->IsEMCAL()) calorimeter = "PHOS";
602 //printf("cluster : ncells %d \n",nCells);
606 for(iDigit = 0; iDigit < nCells ; iDigit++)
608 absIdList[iDigit] = cluster->GetCellsAbsId()[iDigit] ;
609 Float_t en = cells->GetCellAmplitude(absIdList[iDigit]);
610 RecalibrateCellAmplitude(en,calorimeter,absIdList[iDigit]);
614 idmax = absIdList[iDigit] ;
616 //Int_t icol = -1, irow = -1, iRCU = -1;
617 //Int_t sm = GetModuleNumberCellIndexes(absIdList[iDigit], calorimeter, icol, irow, iRCU) ;
618 //printf("\t cell %d, id %d, sm %d, col %d, row %d, e %f\n", iDigit, absIdList[iDigit], sm, icol, irow, en );
621 for(iDigit = 0 ; iDigit < nCells; iDigit++)
623 if(absIdList[iDigit]>=0)
625 absId1 = cluster->GetCellsAbsId()[iDigit];
627 Float_t en1 = cells->GetCellAmplitude(absId1);
628 RecalibrateCellAmplitude(en1,calorimeter,absId1);
630 //printf("%d : absIDi %d, E %f\n",iDigit, absId1,en1);
632 for(iDigitN = 0; iDigitN < nCells; iDigitN++)
634 absId2 = cluster->GetCellsAbsId()[iDigitN] ;
636 if(absId2==-1 || absId2==absId1) continue;
638 //printf("\t %d : absIDj %d\n",iDigitN, absId2);
640 Float_t en2 = cells->GetCellAmplitude(absId2);
641 RecalibrateCellAmplitude(en2,calorimeter,absId2);
643 //printf("\t %d : absIDj %d, E %f\n",iDigitN, absId2,en2);
645 if ( AreNeighbours(calorimeter, absId1, absId2) )
647 // printf("\t \t Neighbours \n");
650 absIdList[iDigitN] = -1 ;
651 //printf("\t \t indexN %d not local max\n",iDigitN);
652 // but may be digit too is not local max ?
653 if(en1 < en2 + fLocMaxCutEDiff) {
654 //printf("\t \t index %d not local max cause locMaxCutEDiff\n",iDigit);
655 absIdList[iDigit] = -1 ;
660 absIdList[iDigit] = -1 ;
661 //printf("\t \t index %d not local max\n",iDigitN);
662 // but may be digitN too is not local max ?
663 if(en1 > en2 - fLocMaxCutEDiff)
665 absIdList[iDigitN] = -1 ;
666 //printf("\t \t indexN %d not local max cause locMaxCutEDiff\n",iDigit);
669 } // if Are neighbours
670 //else printf("\t \t NOT Neighbours \n");
676 for(iDigit = 0; iDigit < nCells; iDigit++)
678 if(absIdList[iDigit]>=0 )
680 absIdList[iDigitN] = absIdList[iDigit] ;
681 Float_t en = cells->GetCellAmplitude(absIdList[iDigit]);
682 RecalibrateCellAmplitude(en,calorimeter,absIdList[iDigit]);
683 if(en < fLocMaxCutE) continue; // Maxima only with seed energy at least
684 maxEList[iDigitN] = en ;
685 //printf("Local max %d, id %d, en %f\n", iDigit,absIdList[iDigitN],en);
693 printf("AliCalorimeterUtils::GetNumberOfLocalMaxima() - No local maxima found, assign highest energy cell as maxima, id %d, en cell %2.2f, en cluster %2.2f\n",
694 idmax,emax,cluster->E());
697 absIdList[0] = idmax ;
702 printf("AliCalorimeterUtils::GetNumberOfLocalMaxima() - In cluster E %2.2f, M02 %2.2f, M20 %2.2f, N maxima %d \n",
703 cluster->E(),cluster->GetM02(),cluster->GetM20(), iDigitN);
705 if(fDebug > 1) for(Int_t imax = 0; imax < iDigitN; imax++)
707 printf(" \t i %d, absId %d, Ecell %f\n",imax,absIdList[imax],maxEList[imax]);
715 //________________________________________
716 void AliCalorimeterUtils::InitParameters()
718 //Initialize the parameters of the analysis.
720 fEMCALGeoName = "EMCAL_COMPLETEV1";
721 fPHOSGeoName = "PHOSgeo";
723 fEMCALGeoMatrixSet = kFALSE;
724 fPHOSGeoMatrixSet = kFALSE;
726 fRemoveBadChannels = kFALSE;
728 fNCellsFromPHOSBorder = 0;
731 fLocMaxCutEDiff = 0.0 ;
733 // fMaskCellColumns = new Int_t[fNMaskCellColumns];
734 // fMaskCellColumns[0] = 6 ; fMaskCellColumns[1] = 7 ; fMaskCellColumns[2] = 8 ;
735 // fMaskCellColumns[3] = 35; fMaskCellColumns[4] = 36; fMaskCellColumns[5] = 37;
736 // fMaskCellColumns[6] = 12+AliEMCALGeoParams::fgkEMCALCols; fMaskCellColumns[7] = 13+AliEMCALGeoParams::fgkEMCALCols;
737 // fMaskCellColumns[8] = 40+AliEMCALGeoParams::fgkEMCALCols; fMaskCellColumns[9] = 41+AliEMCALGeoParams::fgkEMCALCols;
738 // fMaskCellColumns[10]= 42+AliEMCALGeoParams::fgkEMCALCols;
743 //_____________________________________________________
744 void AliCalorimeterUtils::InitPHOSBadChannelStatusMap()
746 //Init PHOS bad channels map
747 if(fDebug > 0 )printf("AliCalorimeterUtils::InitPHOSBadChannelStatusMap()\n");
748 //In order to avoid rewriting the same histograms
749 Bool_t oldStatus = TH1::AddDirectoryStatus();
750 TH1::AddDirectory(kFALSE);
752 fPHOSBadChannelMap = new TObjArray(5);
753 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));
755 fPHOSBadChannelMap->SetOwner(kTRUE);
756 fPHOSBadChannelMap->Compress();
758 //In order to avoid rewriting the same histograms
759 TH1::AddDirectory(oldStatus);
762 //______________________________________________________
763 void AliCalorimeterUtils::InitPHOSRecalibrationFactors()
765 //Init EMCAL recalibration factors
766 if(fDebug > 0 )printf("AliCalorimeterUtils::InitPHOSRecalibrationFactors()\n");
767 //In order to avoid rewriting the same histograms
768 Bool_t oldStatus = TH1::AddDirectoryStatus();
769 TH1::AddDirectory(kFALSE);
771 fPHOSRecalibrationFactors = new TObjArray(5);
772 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));
773 //Init the histograms with 1
774 for (Int_t m = 0; m < 5; m++) {
775 for (Int_t i = 0; i < 56; i++) {
776 for (Int_t j = 0; j < 64; j++) {
777 SetPHOSChannelRecalibrationFactor(m,j,i,1.);
781 fPHOSRecalibrationFactors->SetOwner(kTRUE);
782 fPHOSRecalibrationFactors->Compress();
784 //In order to avoid rewriting the same histograms
785 TH1::AddDirectory(oldStatus);
789 //___________________________________________
790 void AliCalorimeterUtils::InitEMCALGeometry()
792 //Initialize EMCAL geometry if it did not exist previously
794 fEMCALGeo = AliEMCALGeometry::GetInstance(fEMCALGeoName);
796 printf("AliCalorimeterUtils::InitEMCALGeometry()");
797 if (!gGeoManager) printf(" - Careful!, gGeoManager not loaded, load misalign matrices");
803 //__________________________________________
804 void AliCalorimeterUtils::InitPHOSGeometry()
806 //Initialize PHOS geometry if it did not exist previously
808 fPHOSGeo = new AliPHOSGeoUtils(fPHOSGeoName);
810 printf("AliCalorimeterUtils::InitPHOSGeometry()");
811 if (!gGeoManager) printf(" - Careful!, gGeoManager not loaded, load misalign matrices");
817 //_________________________________________________________
818 void AliCalorimeterUtils::Print(const Option_t * opt) const
821 //Print some relevant parameters set for the analysis
825 printf("***** Print: %s %s ******\n", GetName(), GetTitle() ) ;
826 printf("Remove Clusters with bad channels? %d\n",fRemoveBadChannels);
827 printf("Remove Clusters with max cell at less than %d cells from EMCAL border and %d cells from PHOS border\n",
828 fEMCALRecoUtils->GetNumberOfCellsFromEMCALBorder(), fNCellsFromPHOSBorder);
829 if(fEMCALRecoUtils->IsEMCALNoBorderAtEta0()) printf("Do not remove EMCAL clusters at Eta = 0\n");
830 printf("Recalibrate Clusters? %d\n",fRecalibration);
831 printf("Recalculate Clusters Position? %d\n",fRecalculatePosition);
832 printf("Recalculate Clusters Energy? %d\n",fCorrectELinearity);
833 printf("Matching criteria: dR < %2.2f[cm], dZ < %2.2f[cm]\n",fCutR,fCutZ);
835 printf("Loc. Max. E > %2.2f\n", fLocMaxCutE);
836 printf("Loc. Max. E Diff > %2.2f\n", fLocMaxCutEDiff);
841 //__________________________________________________________________
842 Bool_t AliCalorimeterUtils::MaskFrameCluster(const Int_t iSM,
843 const Int_t ieta) const
845 //Check if cell is in one of the regions where we have significant amount
846 //of material in front. Only EMCAL
849 if(iSM%2) icol+=48; // Impair SM, shift index [0-47] to [48-96]
851 if (fNMaskCellColumns && fMaskCellColumns) {
852 for (Int_t imask = 0; imask < fNMaskCellColumns; imask++) {
853 if(icol==fMaskCellColumns[imask]) return kTRUE;
861 //__________________________________________________________________________________________
862 void AliCalorimeterUtils::RecalibrateCellAmplitude(Float_t & amp,
863 const TString calo, const Int_t id) const
865 //Recaculate cell energy if recalibration factor
867 Int_t icol = -1; Int_t irow = -1; Int_t iRCU = -1;
868 Int_t nModule = GetModuleNumberCellIndexes(id,calo, icol, irow, iRCU);
870 if (IsRecalibrationOn())
874 amp *= GetPHOSChannelRecalibrationFactor(nModule,icol,irow);
878 amp *= GetEMCALChannelRecalibrationFactor(nModule,icol,irow);
883 //_________________________________________________________________________________
884 void AliCalorimeterUtils::RecalibrateCellTime(Double_t & time,
886 const Int_t id, const Int_t bc) const
888 // Recalculate time if time recalibration available for EMCAL
889 // not ready for PHOS
891 if(calo == "EMCAL" && GetEMCALRecoUtils()->IsTimeRecalibrationOn())
893 GetEMCALRecoUtils()->RecalibrateCellTime(id,bc,time);
899 //__________________________________________________________________________
900 Float_t AliCalorimeterUtils::RecalibrateClusterEnergy(AliVCluster * cluster,
901 AliVCaloCells * cells)
903 // Recalibrate the cluster energy, considering the recalibration map and the energy of the cells that compose the cluster.
905 //Initialize some used variables
906 Float_t frac = 0., energy = 0.;
910 //Get the cluster number of cells and list of absId, check what kind of cluster do we have.
912 UShort_t * index = cluster->GetCellsAbsId() ;
913 Double_t * fraction = cluster->GetCellsAmplitudeFraction() ;
915 Int_t ncells = cluster->GetNCells();
917 TString calo = "EMCAL";
918 if(cluster->IsPHOS())
921 //Loop on the cells, get the cell amplitude and recalibration factor, multiply and and to the new energy
922 for(Int_t icell = 0; icell < ncells; icell++){
924 Int_t absId = index[icell];
926 frac = fraction[icell];
927 if(frac < 1e-3) frac = 1; //in case of EMCAL, this is set as 0, not used.
929 Float_t amp = cells->GetCellAmplitude(absId);
930 RecalibrateCellAmplitude(amp,calo, absId);
933 printf("AliCalorimeterUtils::RecalibrateClusterEnergy() - recalibrate cell: %s, cell fraction %f, cell energy %f\n",
934 calo.Data(),frac,cells->GetCellAmplitude(absId));
940 printf("AliCalorimeterUtils::RecalibrateClusterEnergy() - Energy before %f, after %f\n",cluster->E(),energy);
945 Fatal("RecalibrateClusterEnergy()","Cells pointer does not exist!");
951 //________________________________________________________________________________
952 void AliCalorimeterUtils::SetGeometryTransformationMatrices(AliVEvent* inputEvent)
954 //Set the calorimeters transformation matrices
956 //Get the EMCAL transformation geometry matrices from ESD
957 if(!fEMCALGeoMatrixSet && fEMCALGeo){
958 if(fLoadEMCALMatrices){
959 printf("AliCalorimeterUtils::SetGeometryTransformationMatrices() - Load user defined EMCAL geometry matrices\n");
960 for(Int_t mod=0; mod < (fEMCALGeo->GetEMCGeometry())->GetNumberOfSuperModules(); mod++){
961 if(fEMCALMatrix[mod]){
963 fEMCALMatrix[mod]->Print();
964 fEMCALGeo->SetMisalMatrix(fEMCALMatrix[mod],mod) ;
967 fEMCALGeoMatrixSet = kTRUE;//At least one, so good
970 else if (!gGeoManager) {
973 printf(" AliCalorimeterUtils::SetGeometryTransformationMatrices() - Load EMCAL misalignment matrices. \n");
974 if(!strcmp(inputEvent->GetName(),"AliESDEvent")) {
975 for(Int_t mod=0; mod < (fEMCALGeo->GetEMCGeometry())->GetNumberOfSuperModules(); mod++){
976 //printf("Load ESD matrix %d, %p\n",mod,((AliESDEvent*)inputEvent)->GetEMCALMatrix(mod));
977 if(((AliESDEvent*)inputEvent)->GetEMCALMatrix(mod)) {
978 fEMCALGeo->SetMisalMatrix(((AliESDEvent*)inputEvent)->GetEMCALMatrix(mod),mod) ;
980 }// loop over super modules
982 fEMCALGeoMatrixSet = kTRUE;//At least one, so good
987 printf("AliCalorimeterUtils::SetGeometryTransformationMatrices() - Setting of EMCAL transformation matrixes for AODs not implemented yet. \n Import geometry.root file\n");
989 }//Get matrix from data
990 else if(gGeoManager){
991 fEMCALGeoMatrixSet = kTRUE;
993 }//EMCAL geo && no geoManager
995 //Get the PHOS transformation geometry matrices from ESD
996 if(!fPHOSGeoMatrixSet && fPHOSGeo){
998 if(fLoadPHOSMatrices){
999 printf("AliCalorimeterUtils::SetGeometryTransformationMatrices() - Load user defined PHOS geometry matrices\n");
1000 for(Int_t mod = 0 ; mod < 5 ; mod++){
1001 if(fPHOSMatrix[mod]){
1003 fPHOSMatrix[mod]->Print();
1004 fPHOSGeo->SetMisalMatrix(fPHOSMatrix[mod],mod) ;
1007 fPHOSGeoMatrixSet = kTRUE;//At least one, so good
1010 else if (!gGeoManager) {
1012 printf(" AliCalorimeterUtils::SetGeometryTransformationMatrices() - Load PHOS misalignment matrices. \n");
1013 if(!strcmp(inputEvent->GetName(),"AliESDEvent")) {
1014 for(Int_t mod = 0; mod < 5; mod++){
1015 if( ((AliESDEvent*)inputEvent)->GetPHOSMatrix(mod)) {
1016 //printf("PHOS: mod %d, matrix %p\n",mod, ((AliESDEvent*)inputEvent)->GetPHOSMatrix(mod));
1017 fPHOSGeo->SetMisalMatrix( ((AliESDEvent*)inputEvent)->GetPHOSMatrix(mod),mod) ;
1019 }// loop over modules
1020 fPHOSGeoMatrixSet = kTRUE; //At least one so good
1024 printf("AliCalorimeterUtils::SetGeometryTransformationMatrices() - Setting of EMCAL transformation matrixes for AODs not implemented yet. \n Import geometry.root file\n");
1026 }// get matrix from data
1027 else if(gGeoManager){
1028 fPHOSGeoMatrixSet = kTRUE;
1030 }//PHOS geo and geoManager was not set
1034 //__________________________________________________________________________________________
1035 void AliCalorimeterUtils::RecalculateClusterPosition(AliVCaloCells* cells, AliVCluster* clu)
1038 //Recalculate EMCAL cluster position
1040 fEMCALRecoUtils->RecalculateClusterPosition((AliEMCALGeometry*)fEMCALGeo, cells,clu);
1044 //________________________________________________________________________________
1045 void AliCalorimeterUtils::RecalculateClusterTrackMatching(AliVEvent * event,
1046 TObjArray* clusterArray)
1048 //Recalculate track matching
1050 if (fRecalculateMatching) {
1051 fEMCALRecoUtils->FindMatches(event,clusterArray,fEMCALGeo) ;
1052 //AliESDEvent* esdevent = dynamic_cast<AliESDEvent*> (event);
1054 // fEMCALRecoUtils->SetClusterMatchedToTrack(esdevent) ;
1055 // fEMCALRecoUtils->SetTracksMatchedToCluster(esdevent) ;