]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWG/CaloTrackCorrBase/AliIsolationCut.cxx
Merge branch 'feature-movesplit'
[u/mrichter/AliRoot.git] / PWG / CaloTrackCorrBase / AliIsolationCut.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
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  **************************************************************************/
15
16 //_________________________________________________________________________
17 // Class containing methods for the isolation cut. 
18 // An AOD candidate (AliAODPWG4ParticleCorrelation type)
19 // is passed. Look in a cone around the candidate and study
20 // the hadronic activity inside to decide if the candidate is isolated
21 //
22 //
23 //*-- Author: Gustavo Conesa (LNF-INFN) 
24
25 //-Yaxian Mao (add the possibility for different IC method with different pt range, 01/10/2010)
26 //-Yaxian Mao (check the candidate particle is the leading particle or not at the same hemishere)
27
28 //////////////////////////////////////////////////////////////////////////////
29   
30   
31 // --- ROOT system --- 
32 #include <TObjArray.h>
33
34 // --- AliRoot system --- 
35 #include "AliIsolationCut.h" 
36 #include "AliAODPWG4ParticleCorrelation.h"
37 #include "AliEMCALGeometry.h"
38 #include "AliEMCALGeoParams.h"
39 #include "AliCalorimeterUtils.h"
40 #include "AliAODTrack.h"
41 #include "AliVCluster.h"
42 #include "AliCaloTrackReader.h"
43 #include "AliMixedEvent.h"
44 #include "AliCaloPID.h"
45 #include "AliLog.h"
46
47 ClassImp(AliIsolationCut)
48   
49 //____________________________________
50 AliIsolationCut::AliIsolationCut() : 
51 TObject(),
52 fConeSize(0.),
53 fPtThreshold(0.),
54 fPtThresholdMax(10000.), 
55 fSumPtThreshold(0.),
56 fSumPtThresholdMax(10000.),
57 fPtFraction(0.),
58 fICMethod(0),
59 fPartInCone(0),
60 fDebug(0),
61 fFracIsThresh(1),
62 fMomentum(),
63 fTrackVector()
64 {
65   //default ctor
66   
67   //Initialize parameters
68   InitParameters();
69   
70 }
71
72 //_________________________________________________________________________________________________________________________________
73 void AliIsolationCut::CalculateUEBandClusterNormalization(AliCaloTrackReader * /*reader*/, Float_t   etaC, Float_t /*phiC*/,
74                                                            Float_t   phiUEptsumCluster,     Float_t   etaUEptsumCluster,
75                                                            Float_t & phiUEptsumClusterNorm, Float_t & etaUEptsumClusterNorm,
76                                                            Float_t & excessFracEta,         Float_t & excessFracPhi         ) const
77 {
78   // Normalize cluster background band
79   
80   Float_t coneA     = fConeSize*fConeSize*TMath::Pi(); // A = pi R^2, isolation cone area
81   
82   //Careful here if EMCal limits changed .. 2010 (4 SM) to 2011-12 (10 SM), for the moment consider 100 deg in phi
83   Float_t emcEtaSize = 0.7*2; // TO FIX
84   Float_t emcPhiSize = TMath::DegToRad()*100.; // TO FIX
85   
86   /* //Catherine code
87    if(((((2*fConeSize*emcPhiSize)-coneA))*phiBandBadCellsCoeff)!=0)phiUEptsumClusterNorm = phiUEptsumCluster*(coneA*coneBadCellsCoeff / (((2*fConeSize*emcPhiSize)-coneA))*phiBandBadCellsCoeff); // pi * R^2 / (2 R * 2 100 deg) -  trigger cone
88    if(((((2*(fConeSize-excess)*emcPhiSize)-(coneA-excessFracEta))*etaBandBadCellsCoeff))!=0)phiUEptsumClusterNorm = phiUEptsumCluster*(coneA *coneBadCellsCoeff/ (((2*(fConeSize-excess)*emcPhiSize)-(coneA/excessFracEta))*etaBandBadCellsCoeff));
89    if(((2*(fConeSize-excess)*emcEtaSize)-(coneA-excessFracPhi))*phiBandBadCellsCoeff!=0) etaUEptsumClusterNorm = etaUEptsumCluster*(coneA*coneBadCellsCoeff / (((2*(fConeSize-excess)*emcEtaSize)-(coneA/excessFracPhi))*phiBandBadCellsCoeff));
90    */
91   
92   if((2*fConeSize*emcPhiSize-coneA)!=0) phiUEptsumClusterNorm = phiUEptsumCluster*(coneA / (((2*fConeSize*emcPhiSize)-coneA))); // pi * R^2 / (2 R * 2 100 deg) -  trigger cone
93   if((2*fConeSize*emcEtaSize-coneA)!=0) etaUEptsumClusterNorm = etaUEptsumCluster*(coneA / (((2*fConeSize*emcEtaSize)-coneA))); // pi * R^2 / (2 R * 2*0.7)  -  trigger cone
94   
95   //out of eta acceptance
96   excessFracEta = 1;
97   excessFracPhi = 1;
98
99   if(TMath::Abs(etaC)+fConeSize > emcEtaSize/2.)
100   {
101     Float_t excess = TMath::Abs(etaC) + fConeSize - emcEtaSize/2.;
102     excessFracEta  = CalculateExcessAreaFraction(excess);
103     
104     if ( excessFracEta != 0) coneA /=  excessFracEta;
105     
106     //UE band is also out of acceptance, need to estimate corrected area
107     if(((2*fConeSize-excess)*emcPhiSize-coneA) != 0 ) phiUEptsumClusterNorm = phiUEptsumCluster*(coneA / ((((2*fConeSize-excess)*emcPhiSize)-coneA)));
108     if(( 2*fConeSize        *emcEtaSize-coneA) != 0 ) etaUEptsumClusterNorm = etaUEptsumCluster*(coneA / ((( 2*fConeSize        *emcEtaSize)-coneA)));
109   }
110   
111 }
112
113 //________________________________________________________________________________________________________________________________
114 void AliIsolationCut::CalculateUEBandTrackNormalization  (AliCaloTrackReader * reader,    Float_t   etaC, Float_t /*phiC*/,
115                                                           Float_t   phiUEptsumTrack,      Float_t   etaUEptsumTrack,
116                                                           Float_t & phiUEptsumTrackNorm,  Float_t & etaUEptsumTrackNorm,
117                                                           Float_t & excessFracEta,        Float_t & excessFracPhi          ) const
118 {
119   // Normalize track background band
120   
121   Float_t coneA     = fConeSize*fConeSize*TMath::Pi(); // A = pi R^2, isolation cone area
122   
123   // Get the cut used for the TPC tracks in the reader, +-0.8, +-0.9 ...
124   // Only valid in simple fidutial cut case and if the cut is applied, careful!
125   Float_t tpcEtaSize = reader->GetFiducialCut()->GetCTSFidCutMaxEtaArray()->At(0) -
126   reader->GetFiducialCut()->GetCTSFidCutMinEtaArray()->At(0) ;
127   Float_t tpcPhiSize = TMath::TwoPi();
128   
129   /*//Catherine code
130    //phiUEptsumTrackNorm = phiUEptsumTrack*(coneA*coneBadCellsCoeff / (((2*fConeSize*tpcPhiSize)-coneA))*phiBandBadCellsCoeff); // pi * R^2 / (2 R * 2 pi) -  trigger cone
131    //etaUEptsumTrackNorm = etaUEptsumTrack*(coneA*coneBadCellsCoeff / (((2*fConeSize*tpcEtaSize)-coneA))*etaBandBadCellsCoeff); // pi * R^2 / (2 R * 1.6)  -  trigger cone
132    if((2*fConeSize*tpcPhiSize-coneA)!=0)phiUEptsumTrackNorm = phiUEptsumTrack*(coneA / (((2*fConeSize*tpcPhiSize)-coneA))); // pi * R^2 / (2 R * 2 pi) -  trigger cone
133    if((2*fConeSize*tpcEtaSize-coneA)!=0)etaUEptsumTrackNorm = etaUEptsumTrack*(coneA / (((2*fConeSize*tpcEtaSize)-coneA))); // pi * R^2 / (2 R * 1.6)  -  trigger cone
134    if((2*(fConeSize-excess)*tpcPhiSize)-(coneA-excessFracEta)!=0)phiUEptsumTrackNorm = phiUEptsumTrack*(coneA / (((2*(fConeSize-excess)*tpcPhiSize)-(coneA/excessFracEta))));
135    */ //end Catherine code
136   
137   //correct out of eta acceptance
138   excessFracEta = 1;
139   excessFracPhi = 1;
140
141   if((2*fConeSize*tpcPhiSize-coneA)!=0) phiUEptsumTrackNorm = phiUEptsumTrack*(coneA / (((2*fConeSize*tpcPhiSize)-coneA))); // pi * R^2 / (2 R * 2 pi) -  trigger cone
142   if((2*fConeSize*tpcEtaSize-coneA)!=0) etaUEptsumTrackNorm = etaUEptsumTrack*(coneA / (((2*fConeSize*tpcEtaSize)-coneA))); // pi * R^2 / (2 R * 1.6)  -  trigger cone
143   
144   if(TMath::Abs(etaC)+fConeSize > tpcEtaSize/2.)
145   {
146     Float_t excess = TMath::Abs(etaC) + fConeSize - tpcEtaSize/2.;
147     excessFracEta  = CalculateExcessAreaFraction(excess);
148     if (excessFracEta != 0) coneA /=  excessFracEta;
149     
150     //UE band is also out of acceptance, need to estimate corrected area
151     if(((2*fConeSize-excess)*tpcPhiSize - coneA) !=0 ) phiUEptsumTrackNorm = phiUEptsumTrack*(coneA / ((((2*fConeSize-excess)*tpcPhiSize)-coneA)));
152     if(( 2*fConeSize        *tpcEtaSize - coneA) !=0 ) etaUEptsumTrackNorm = etaUEptsumTrack*(coneA / ((( 2*fConeSize        *tpcEtaSize)-coneA)));
153   }
154   
155 }
156
157 //________________________________________________________________________
158 Float_t AliIsolationCut::CalculateExcessAreaFraction(Float_t excess) const
159 {
160   // Area of a circunference segment segment 1/2 R^2 (angle-sin(angle)), angle = 2*ACos((R-excess)/R)
161   
162   
163   Float_t angle   = 2*TMath::ACos( (fConeSize-excess) / fConeSize );
164   
165   Float_t coneA   = fConeSize*fConeSize*TMath::Pi(); // A = pi R^2, isolation cone area
166   
167   Float_t excessA = fConeSize*fConeSize / 2 * (angle-TMath::Sin(angle));
168   
169   if(coneA > excessA) return coneA / (coneA-excessA);
170   else
171   {
172     AliWarning(Form("Please Check : Excess Track %2.3f, coneA %2.2f,  excessA %2.2f, angle %2.2f,factor %2.2f",
173                     excess,coneA, excessA, angle*TMath::RadToDeg(), coneA / (coneA-excessA)));
174     return  1;
175   }
176 }
177
178 //_______________________________________________________________________________________
179 Float_t AliIsolationCut::GetCellDensity(AliAODPWG4ParticleCorrelation * pCandidate,
180                                         AliCaloTrackReader * reader) const
181 {
182   // Get good cell density (number of active cells over all cells in cone)
183   
184   Double_t coneCells    = 0.; //number of cells in cone with radius fConeSize
185   Double_t coneCellsBad = 0.; //number of bad cells in cone with radius fConeSize
186   Double_t cellDensity  = 1.;
187
188   Float_t phiC  = pCandidate->Phi() ;
189   if(phiC<0) phiC+=TMath::TwoPi();
190   Float_t etaC  = pCandidate->Eta() ;
191   
192   if(pCandidate->GetDetectorTag() == AliCaloTrackReader::kEMCAL)
193   {
194     AliEMCALGeometry* eGeom = AliEMCALGeometry::GetInstance();
195     AliCalorimeterUtils *cu = reader->GetCaloUtils();
196     
197     Int_t absId = -999;
198     if (eGeom->GetAbsCellIdFromEtaPhi(etaC,phiC,absId))
199     {
200       //Get absolute (col,row) of candidate
201       Int_t iEta=-1, iPhi=-1, iRCU = -1;      
202       Int_t nSupMod = cu->GetModuleNumberCellIndexes(absId, pCandidate->GetDetectorTag(), iEta, iPhi, iRCU);
203       
204       Int_t colC = iEta;
205       if (nSupMod % 2) colC =  AliEMCALGeoParams::fgkEMCALCols + iEta ;
206       Int_t rowC = iPhi + AliEMCALGeoParams::fgkEMCALRows*int(nSupMod/2);
207       
208       Int_t sqrSize = int(fConeSize/0.0143) ; // Size of cell in radians
209       //loop on cells in a square of side fConeSize to check cells in cone    
210       for(Int_t icol = colC-sqrSize; icol < colC+sqrSize;icol++)
211       {
212         for(Int_t irow = rowC-sqrSize; irow < rowC+sqrSize; irow++)
213         {
214           if (Radius(colC, rowC, icol, irow) < sqrSize)
215           {
216             coneCells += 1.;
217             
218             Int_t cellSM  = -999;
219             Int_t cellEta = -999;
220             Int_t cellPhi = -999;
221             if(icol > AliEMCALGeoParams::fgkEMCALCols-1) 
222             {
223               cellSM = 0+int(irow/AliEMCALGeoParams::fgkEMCALRows)*2;
224               cellEta = icol-AliEMCALGeoParams::fgkEMCALCols;
225               cellPhi = irow-AliEMCALGeoParams::fgkEMCALRows*int(cellSM/2);
226             }
227             if(icol < AliEMCALGeoParams::fgkEMCALCols) 
228             {
229               cellSM = 1+int(irow/AliEMCALGeoParams::fgkEMCALRows)*2;
230               cellEta = icol;
231               cellPhi = irow-AliEMCALGeoParams::fgkEMCALRows*int(cellSM/2);
232             }
233             
234             //Count as bad "cells" out of EMCAL acceptance
235             if(icol < 0 || icol > AliEMCALGeoParams::fgkEMCALCols*2 || 
236                irow < 0 || irow > AliEMCALGeoParams::fgkEMCALRows*16./3) //5*nRows+1/3*nRows
237             {
238               coneCellsBad += 1.;
239             }
240             //Count as bad "cells" marked as bad in the DataBase
241             else if (cu->GetEMCALChannelStatus(cellSM,cellEta,cellPhi)==1) 
242             {
243               coneCellsBad += 1. ;
244             }
245           }
246         }
247       }//end of cells loop
248     }
249     else AliWarning("Cluster with bad (eta,phi) in EMCal for energy density calculation");
250     
251     if (coneCells > 0.) 
252     {
253       cellDensity = (coneCells-coneCellsBad)/coneCells;
254       //printf("Energy density = %f\n", cellDensity);
255     }
256   }
257
258   return cellDensity;
259   
260 }
261
262 //__________________________________________________________________________________
263 void AliIsolationCut::GetCoeffNormBadCell(AliAODPWG4ParticleCorrelation * pCandidate,
264                                           AliCaloTrackReader * reader,
265                                           Float_t &  coneBadCellsCoeff,
266                                           Float_t &  etaBandBadCellsCoeff,
267                                           Float_t & phiBandBadCellsCoeff)
268 {
269   // Get good cell density (number of active cells over all cells in cone)
270   
271   Double_t coneCells    = 0.; //number of cells in cone with radius fConeSize
272   Double_t phiBandCells = 0.; //number of cells in band phi
273   Double_t etaBandCells = 0.; //number of cells in band eta
274   
275   Float_t phiC  = pCandidate->Phi() ;
276   if(phiC<0) phiC+=TMath::TwoPi();
277   Float_t etaC  = pCandidate->Eta() ;
278   
279   if(pCandidate->GetDetectorTag() == AliCaloTrackReader::kEMCAL)
280   {
281     AliEMCALGeometry* eGeom = AliEMCALGeometry::GetInstance();
282     AliCalorimeterUtils *cu = reader->GetCaloUtils();
283     
284     Int_t absId = -999;
285     if (eGeom->GetAbsCellIdFromEtaPhi(etaC,phiC,absId))
286     {
287       //Get absolute (col,row) of candidate
288       Int_t iEta=-1, iPhi=-1, iRCU = -1;
289       Int_t nSupMod = cu->GetModuleNumberCellIndexes(absId, pCandidate->GetDetectorTag(),
290                                                      iEta, iPhi, iRCU);
291       
292       Int_t colC = iEta;
293       if (nSupMod % 2) colC =  AliEMCALGeoParams::fgkEMCALCols + iEta ;
294       Int_t rowC = iPhi + AliEMCALGeoParams::fgkEMCALRows*int(nSupMod/2);
295       
296       Int_t sqrSize = int(fConeSize/0.0143) ; // Size of cell in radians
297       for(Int_t icol = 0; icol < 2*AliEMCALGeoParams::fgkEMCALCols-1;icol++)
298       {
299         for(Int_t irow = 0; irow < 5*AliEMCALGeoParams::fgkEMCALRows -1; irow++)
300         {
301           //loop on cells in a square of side fConeSize to check cells in cone
302           if     ( Radius(colC, rowC, icol, irow) < sqrSize ) { coneCells    += 1.; }
303           else if( icol>colC-sqrSize  &&  icol<colC+sqrSize ) { phiBandCells += 1 ; }
304           else if( irow>rowC-sqrSize  &&  irow<rowC+sqrSize ) { etaBandCells += 1 ; }
305           
306           Int_t cellSM  = -999;
307           Int_t cellEta = -999;
308           Int_t cellPhi = -999;
309           if(icol > AliEMCALGeoParams::fgkEMCALCols-1)
310           {
311             cellSM = 0+int(irow/AliEMCALGeoParams::fgkEMCALRows)*2;
312             cellEta = icol-AliEMCALGeoParams::fgkEMCALCols;
313             cellPhi = irow-AliEMCALGeoParams::fgkEMCALRows*int(cellSM/2);
314           }
315           if(icol < AliEMCALGeoParams::fgkEMCALCols)
316           {
317             cellSM = 1+int(irow/AliEMCALGeoParams::fgkEMCALRows)*2;
318             cellEta = icol;
319             cellPhi = irow-AliEMCALGeoParams::fgkEMCALRows*int(cellSM/2);
320           }
321           
322           if( (icol < 0 || icol > AliEMCALGeoParams::fgkEMCALCols*2-1 ||
323                irow < 0 || irow > AliEMCALGeoParams::fgkEMCALRows*5 - 1) //5*nRows+1/3*nRows //Count as bad "cells" out of EMCAL acceptance
324              || (cu->GetEMCALChannelStatus(cellSM,cellEta,cellPhi)==1))  //Count as bad "cells" marked as bad in the DataBase
325           {
326             if     ( Radius(colC, rowC, icol, irow) < sqrSize ) coneBadCellsCoeff    += 1.;
327             else if( icol>colC-sqrSize  &&  icol<colC+sqrSize ) phiBandBadCellsCoeff += 1 ;
328                   else if( irow>rowC-sqrSize  &&  irow<rowC+sqrSize ) etaBandBadCellsCoeff += 1 ;
329           }
330         }
331       }//end of cells loop
332     }
333     else AliWarning("Cluster with bad (eta,phi) in EMCal for energy density coeff calculation");
334     
335     if (coneCells > 0.)
336     {
337       //   printf("Energy density coneBadCellsCoeff= %.2f coneCells%.2f\n", coneBadCellsCoeff,coneCells);
338       coneBadCellsCoeff = (coneCells-coneBadCellsCoeff)/coneCells;
339       //  printf("coneBadCellsCoeff= %.2f\n", coneBadCellsCoeff);
340     }
341     if (phiBandCells > 0.)
342     {
343       // printf("Energy density phiBandBadCellsCoeff = %.2f phiBandCells%.2f\n", phiBandBadCellsCoeff,phiBandCells);
344       phiBandBadCellsCoeff = (phiBandCells-phiBandBadCellsCoeff)/phiBandCells;
345       // printf("phiBandBadCellsCoeff = %.2f\n", phiBandBadCellsCoeff);
346     }
347     if (etaBandCells > 0.)
348     {
349       //printf("Energy density etaBandBadCellsCoeff = %.2f etaBandCells%.2f\n", etaBandBadCellsCoeff,etaBandCells);
350       etaBandBadCellsCoeff = (etaBandCells-etaBandBadCellsCoeff)/etaBandCells;
351       // printf("etaBandBadCellsCoeff = %.2f\n",etaBandBadCellsCoeff);
352     }
353     
354   }
355   
356 }
357
358 //____________________________________________
359 TString AliIsolationCut::GetICParametersList()
360 {
361   //Put data member values in string to keep in output container
362   
363   TString parList ; //this will be list of parameters used for this analysis.
364   const Int_t buffersize = 255;
365   char onePar[buffersize] ;
366   
367   snprintf(onePar,buffersize,"--- AliIsolationCut ---\n") ;
368   parList+=onePar ;     
369   snprintf(onePar,buffersize,"fConeSize: (isolation cone size) %1.2f\n",fConeSize) ;
370   parList+=onePar ;
371   snprintf(onePar,buffersize,"fPtThreshold >%2.2f;<%2.2f (isolation pt threshold) \n",fPtThreshold,fPtThresholdMax) ;
372   parList+=onePar ;
373   snprintf(onePar,buffersize,"fSumPtThreshold >%2.2f;<%2.2f (isolation sum pt threshold) \n",fSumPtThreshold,fSumPtThresholdMax) ;
374   parList+=onePar ;
375   snprintf(onePar,buffersize,"fPtFraction=%2.2f (isolation pt threshold fraction) \n",fPtFraction) ;
376   parList+=onePar ;
377   snprintf(onePar,buffersize,"fICMethod=%d (isolation cut case) \n",fICMethod) ;
378   parList+=onePar ;
379   snprintf(onePar,buffersize,"fPartInCone=%d \n",fPartInCone) ;
380   parList+=onePar ;
381   snprintf(onePar,buffersize,"fFracIsThresh=%i \n",fFracIsThresh) ;
382   parList+=onePar ;
383  
384   return parList; 
385 }
386
387 //____________________________________
388 void AliIsolationCut::InitParameters()
389 {
390   //Initialize the parameters of the analysis.
391   
392   fConeSize       = 0.4 ; 
393   fPtThreshold    = 0.5  ;
394   fPtThresholdMax = 10000.  ;
395   fSumPtThreshold    = 1.0 ;
396   fSumPtThresholdMax = 10000. ;
397   fPtFraction     = 0.1 ;
398   fPartInCone     = kNeutralAndCharged;
399   fICMethod       = kSumPtIC; // 0 pt threshol method, 1 cone pt sum method
400   fFracIsThresh   = 1; 
401 }
402
403 //________________________________________________________________________________
404 void  AliIsolationCut::MakeIsolationCut(TObjArray * plCTS, 
405                                         TObjArray * plNe, 
406                                         AliCaloTrackReader * reader, 
407                                         AliCaloPID * pid,
408                                         Bool_t bFillAOD,
409                                         AliAODPWG4ParticleCorrelation  *pCandidate, 
410                                         TString aodArrayRefName,
411                                         Int_t   & n, 
412                                         Int_t   & nfrac, 
413                                         Float_t & coneptsum, Float_t & ptLead,
414                                         Bool_t  & isolated) 
415 {
416   //Search in cone around a candidate particle if it is isolated 
417   Float_t ptC   = pCandidate->Pt() ;
418   Float_t phiC  = pCandidate->Phi() ;
419   if(phiC<0) phiC+=TMath::TwoPi();
420   Float_t etaC  = pCandidate->Eta() ;
421   
422   Float_t pt     = -100. ;
423   Float_t eta    = -100. ;
424   Float_t phi    = -100. ;
425   Float_t rad    = -100. ;
426   
427   Float_t coneptsumCluster = 0;
428   Float_t coneptsumTrack   = 0;
429   
430   Float_t  etaBandPtSumTrack   = 0;
431   Float_t  phiBandPtSumTrack   = 0;
432   Float_t  etaBandPtSumCluster = 0;
433   Float_t  phiBandPtSumCluster = 0;
434   
435   n         = 0 ;
436   nfrac     = 0 ;
437   isolated  = kFALSE;
438   
439   AliDebug(1,Form("Candidate pT %2.2f, eta %2.2f, phi %2.2f, cone %1.2f, thres %2.2f, Fill AOD? %d",
440                   pCandidate->Pt(), pCandidate->Eta(), pCandidate->Phi()*TMath::RadToDeg(), fConeSize,fPtThreshold,bFillAOD));
441
442   //Initialize the array with refrences
443   TObjArray * refclusters  = 0x0;
444   TObjArray * reftracks    = 0x0;
445   Int_t       ntrackrefs   = 0;
446   Int_t       nclusterrefs = 0;
447   
448   //Check charged particles in cone.
449   if(plCTS && 
450      (fPartInCone==kOnlyCharged || fPartInCone==kNeutralAndCharged))
451   {
452     for(Int_t ipr = 0;ipr < plCTS->GetEntries() ; ipr ++ )
453     {
454       AliVTrack* track = dynamic_cast<AliVTrack*>(plCTS->At(ipr)) ; 
455       
456       if(track)
457       {
458         //Do not count the candidate (pion, conversion photon) or the daughters of the candidate
459         if(track->GetID() == pCandidate->GetTrackLabel(0) || track->GetID() == pCandidate->GetTrackLabel(1) || 
460            track->GetID() == pCandidate->GetTrackLabel(2) || track->GetID() == pCandidate->GetTrackLabel(3)   ) continue ;
461         
462         fTrackVector.SetXYZ(track->Px(),track->Py(),track->Pz());
463         pt  = fTrackVector.Pt();
464         eta = fTrackVector.Eta();
465         phi = fTrackVector.Phi() ;
466       }
467       else
468       {// Mixed event stored in AliAODPWG4Particles
469         AliAODPWG4Particle * trackmix = dynamic_cast<AliAODPWG4Particle*>(plCTS->At(ipr)) ; 
470         if(!trackmix)
471         {
472           AliWarning("Wrong track data type, continue");
473           continue;
474         }
475         
476         pt  = trackmix->Pt();
477         eta = trackmix->Eta();
478         phi = trackmix->Phi() ;
479       }
480
481       if( phi < 0 ) phi+=TMath::TwoPi();
482       
483       rad = Radius(etaC, phiC, eta, phi);
484       
485       // ** For the background out of cone **
486       
487       if(rad > fConeSize)
488       {
489         if(eta > (etaC-fConeSize) && eta < (etaC+fConeSize)) phiBandPtSumTrack += pt;
490         if(phi > (phiC-fConeSize) && phi < (phiC+fConeSize)) etaBandPtSumTrack += pt;
491       }
492       
493       // ** For the isolated particle **
494       
495       // Only loop the particle at the same side of candidate
496       if(TMath::Abs(phi-phiC) > TMath::PiOver2()) continue ;
497       
498 //      // If at the same side has particle larger than candidate, 
499 //      // then candidate can not be the leading, skip such events
500 //      if(pt > ptC)
501 //      {
502 //        n         = -1;
503 //        nfrac     = -1;
504 //        coneptsumTrack = -1;
505 //        isolated  = kFALSE;
506 //        
507 //        pCandidate->SetLeadingParticle(kFALSE);
508 //        
509 //        if(bFillAOD && reftracks) 
510 //        {
511 //          reftracks->Clear(); 
512 //          delete reftracks;
513 //        }
514 //        
515 //        return ;
516 //      }
517       
518       // // Check if there is any particle inside cone with pt larger than  fPtThreshold
519       // Check if the leading particule inside the cone has a ptLead larger than fPtThreshold
520       
521       AliDebug(2,Form("\t Track %d, pT %2.2f, eta %1.2f, phi %2.2f, R candidate %2.2f", ipr,pt,eta,phi,rad));
522       
523       if(rad < fConeSize)
524       {
525         AliDebug(2,"Inside candidate cone");
526         
527         if(bFillAOD)
528         {
529           ntrackrefs++;
530           if(ntrackrefs == 1)
531           {
532             reftracks = new TObjArray(0);
533             //reftracks->SetName(Form("Tracks%s",aodArrayRefName.Data()));
534             TString tempo(aodArrayRefName)  ; 
535             tempo += "Tracks" ; 
536             reftracks->SetName(tempo);
537             reftracks->SetOwner(kFALSE);
538           }
539           reftracks->Add(track);
540         }
541         
542         coneptsumTrack+=pt;
543
544         if( ptLead < pt ) ptLead = pt;
545
546 //        // *Before*, count particles in cone
547 //        if(pt > fPtThreshold && pt < fPtThresholdMax)  n++;
548 //        
549 //        //if fPtFraction*ptC<fPtThreshold then consider the fPtThreshold directly
550 //        if(fFracIsThresh)
551 //        {
552 //          if( fPtFraction*ptC < fPtThreshold )
553 //          {
554 //            if( pt > fPtThreshold )    nfrac++ ;
555 //          }
556 //          else
557 //          {
558 //            if( pt > fPtFraction*ptC ) nfrac++;
559 //          }
560 //        }
561 //        else
562 //        {
563 //          if( pt > fPtFraction*ptC ) nfrac++;
564 //        }
565
566       } // Inside cone
567       
568     }// charged particle loop
569     
570   }//Tracks
571   
572   
573   //Check neutral particles in cone.  
574   if(plNe &&
575      (fPartInCone==kOnlyNeutral || fPartInCone==kNeutralAndCharged))
576   {
577     
578     for(Int_t ipr = 0;ipr < plNe->GetEntries() ; ipr ++ )
579     {
580       AliVCluster * calo = dynamic_cast<AliVCluster *>(plNe->At(ipr)) ;
581       
582       if(calo)
583       {
584         //Get the index where the cluster comes, to retrieve the corresponding vertex
585         Int_t evtIndex = 0 ; 
586         if (reader->GetMixedEvent()) 
587           evtIndex=reader->GetMixedEvent()->EventIndexForCaloCluster(calo->GetID()) ; 
588         
589         
590         //Do not count the candidate (photon or pi0) or the daughters of the candidate
591         if(calo->GetID() == pCandidate->GetCaloLabel(0) || 
592            calo->GetID() == pCandidate->GetCaloLabel(1)   ) continue ;      
593         
594         //Skip matched clusters with tracks in case of neutral+charged analysis
595         if( fPartInCone == kNeutralAndCharged && 
596            pid->IsTrackMatched(calo,reader->GetCaloUtils(),reader->GetInputEvent()) ) continue ;
597         
598         //Assume that come from vertex in straight line
599         calo->GetMomentum(fMomentum,reader->GetVertex(evtIndex)) ;
600         
601         pt  = fMomentum.Pt()  ;
602         eta = fMomentum.Eta() ;
603         phi = fMomentum.Phi() ;
604       }
605       else 
606       {// Mixed event stored in AliAODPWG4Particles
607         AliAODPWG4Particle * calomix = dynamic_cast<AliAODPWG4Particle*>(plNe->At(ipr)) ; 
608         if(!calomix)
609         {
610           AliWarning("Wrong calo data type, continue");
611           continue;
612         }
613         
614         pt  = calomix->Pt();
615         eta = calomix->Eta();
616         phi = calomix->Phi() ;
617       }
618       
619       if( phi < 0 ) phi+=TMath::TwoPi();
620       
621       rad = Radius(etaC, phiC, eta, phi);
622       
623       // ** For the background out of cone **
624       
625       if(rad > fConeSize)
626       {
627         if(eta > (etaC-fConeSize) && eta < (etaC+fConeSize)) phiBandPtSumCluster += pt;
628         if(phi > (phiC-fConeSize) && phi < (phiC+fConeSize)) etaBandPtSumCluster += pt;
629       }
630       
631       // ** For the isolated particle **
632       
633       // Only loop the particle at the same side of candidate
634       if(TMath::Abs(phi-phiC)>TMath::PiOver2()) continue ;
635       
636 //      // If at the same side has particle larger than candidate,
637 //      // then candidate can not be the leading, skip such events
638 //      if(pt > ptC)
639 //      {
640 //        n         = -1;
641 //        nfrac     = -1;
642 //        coneptsumCluster = -1;
643 //        isolated  = kFALSE;
644 //        
645 //        pCandidate->SetLeadingParticle(kFALSE);
646 //        
647 //        if(bFillAOD)
648 //        {
649 //          if(reftracks)
650 //          {  
651 //            reftracks  ->Clear();
652 //            delete reftracks;
653 //          }
654 //          
655 //          if(refclusters)
656 //          {
657 //            refclusters->Clear(); 
658 //            delete refclusters;
659 //          }
660 //        }
661 //        return ;
662 //      }
663       
664       //Check if there is any particle inside cone with pt larger than  fPtThreshold
665       
666       AliDebug(2,Form("\t Cluster %d, pT %2.2f, eta %1.2f, phi %2.2f, R candidate %2.2f", ipr,pt,eta,phi,rad));
667       
668       if(rad < fConeSize)
669       {
670         AliDebug(2,"Inside candidate cone");
671         
672         if(bFillAOD) 
673         {
674           nclusterrefs++;
675           if(nclusterrefs==1)
676           {
677             refclusters = new TObjArray(0);
678             //refclusters->SetName(Form("Clusters%s",aodArrayRefName.Data()));
679             TString tempo(aodArrayRefName)  ; 
680             tempo += "Clusters" ; 
681             refclusters->SetName(tempo);
682             refclusters->SetOwner(kFALSE);
683           }
684           refclusters->Add(calo);
685         }
686         
687         coneptsumCluster+=pt;
688         
689         if( ptLead < pt ) ptLead = pt;
690         
691 //        // *Before*, count particles in cone
692 //        if(pt > fPtThreshold && pt < fPtThresholdMax)  n++;
693 //
694 //        //if fPtFraction*ptC<fPtThreshold then consider the fPtThreshold directly
695 //        if(fFracIsThresh)
696 //        {
697 //          if( fPtFraction*ptC < fPtThreshold )
698 //          {
699 //            if( pt > fPtThreshold )    nfrac++ ;
700 //          }
701 //          else 
702 //          {
703 //            if( pt > fPtFraction*ptC ) nfrac++;
704 //          }
705 //        }
706 //        else
707 //        {
708 //          if( pt > fPtFraction*ptC ) nfrac++;
709 //        }
710         
711       }//in cone
712       
713     }// neutral particle loop
714     
715   }//neutrals
716   
717   //Add reference arrays to AOD when filling AODs only
718   if(bFillAOD)
719   {
720     if(refclusters)     pCandidate->AddObjArray(refclusters);
721     if(reftracks)         pCandidate->AddObjArray(reftracks);
722   }
723   
724   coneptsum = coneptsumCluster + coneptsumTrack;
725
726   // *Now*, just check the leading particle in the cone if the threshold is passed
727   if(ptLead > fPtThreshold && ptLead < fPtThresholdMax)  n = 1;
728   
729   //if fPtFraction*ptC<fPtThreshold then consider the fPtThreshold directly
730   if(fFracIsThresh)
731   {
732     if( fPtFraction*ptC < fPtThreshold )
733     {
734       if( ptLead > fPtThreshold )    nfrac = 1 ;
735     }
736     else
737     {
738       if( ptLead > fPtFraction*ptC ) nfrac = 1;
739     }
740   }
741   else
742   {
743     if( ptLead > fPtFraction*ptC ) nfrac = 1;
744   }
745   
746   //-------------------------------------------------------------------
747   //Check isolation, depending on selected isolation criteria requested
748   
749   if( fICMethod == kPtThresIC)
750   {
751     if( n == 0 ) isolated = kTRUE ;
752     
753     AliDebug(1,Form("pT Cand %2.2f, pT Lead %2.2f, %2.2f<pT Lead< %2.2f, isolated %d",
754                     ptC,ptLead,fPtThreshold,fPtThresholdMax,isolated));
755   }
756   else if( fICMethod == kSumPtIC )
757   {
758     if( coneptsum > fSumPtThreshold &&
759         coneptsum < fSumPtThresholdMax )
760       isolated  =  kFALSE ;
761     else
762       isolated  =  kTRUE  ;
763     
764      AliDebug(1,Form("pT Cand %2.2f, SumPt %2.2f, %2.2f<Sum pT< %2.2f, isolated %d",
765                      ptC,ptLead,fSumPtThreshold,fSumPtThresholdMax,isolated));
766   }
767   else if( fICMethod == kPtFracIC )
768   {
769     if(nfrac == 0 ) isolated = kTRUE ;
770   }
771   else if( fICMethod == kSumPtFracIC )
772   {
773     //when the fPtFraction*ptC < fSumPtThreshold then consider the later case
774     // printf("photon analysis IsDataMC() ?%i\n",IsDataMC());
775     if( fFracIsThresh )
776     {
777       if( fPtFraction*ptC < fSumPtThreshold  && coneptsum < fSumPtThreshold ) isolated  =  kTRUE ;
778       if( fPtFraction*ptC > fSumPtThreshold  && coneptsum < fPtFraction*ptC ) isolated  =  kTRUE ;
779     }
780     else 
781     {
782       if( coneptsum < fPtFraction*ptC ) isolated  =  kTRUE ;
783     }
784   }
785   else if( fICMethod == kSumDensityIC )
786   {    
787     // Get good cell density (number of active cells over all cells in cone)
788     // and correct energy in cone
789     
790     Float_t cellDensity = GetCellDensity(pCandidate,reader);
791     
792     if( coneptsum < fSumPtThreshold*cellDensity )
793       isolated = kTRUE;
794   }
795   else if( fICMethod == kSumBkgSubIC )
796   {
797     Double_t coneptsumBkg = 0.;
798     Float_t  etaBandPtSumTrackNorm   = 0;
799     Float_t  phiBandPtSumTrackNorm   = 0;
800     Float_t  etaBandPtSumClusterNorm = 0;
801     Float_t  phiBandPtSumClusterNorm = 0;
802     
803     Float_t  excessFracEtaTrack   = 1;
804     Float_t  excessFracPhiTrack   = 1;
805     Float_t  excessFracEtaCluster = 1;
806     Float_t  excessFracPhiCluster = 1;
807     
808     // Normalize background to cone area
809     if     (fPartInCone != kOnlyCharged       )
810       CalculateUEBandClusterNormalization(reader, etaC, phiC,
811                                           phiBandPtSumCluster    , etaBandPtSumCluster,
812                                           phiBandPtSumClusterNorm, etaBandPtSumClusterNorm,
813                                           excessFracEtaCluster   , excessFracPhiCluster    );
814     if     (fPartInCone != kOnlyNeutral       )
815       CalculateUEBandTrackNormalization(reader, etaC, phiC,
816                                           phiBandPtSumTrack    , etaBandPtSumTrack  ,
817                                           phiBandPtSumTrackNorm, etaBandPtSumTrackNorm,
818                                           excessFracEtaTrack   , excessFracPhiTrack    );
819     
820     if     (fPartInCone == kOnlyCharged       ) coneptsumBkg = etaBandPtSumTrackNorm;
821     else if(fPartInCone == kOnlyNeutral       ) coneptsumBkg = etaBandPtSumClusterNorm;
822     else if(fPartInCone == kNeutralAndCharged ) coneptsumBkg = etaBandPtSumClusterNorm + etaBandPtSumTrackNorm;
823     
824     //coneptsumCluster*=(coneBadCellsCoeff*excessFracEtaCluster*excessFracPhiCluster) ; // apply this correction earlier???
825     // line commented out in last modif!!!
826     
827     coneptsum = coneptsumCluster+coneptsumTrack;
828     
829     coneptsum -= coneptsumBkg;
830     
831     if( coneptsum > fSumPtThreshold && coneptsum < fSumPtThresholdMax )
832       isolated  =  kFALSE ;
833     else
834       isolated  =  kTRUE  ;
835
836   }
837   
838 }
839
840 //_____________________________________________________
841 void AliIsolationCut::Print(const Option_t * opt) const
842 {
843   
844   //Print some relevant parameters set for the analysis
845   if(! opt)
846     return;
847   
848   printf("**** Print %s %s **** \n", GetName(), GetTitle() ) ;
849   
850   printf("IC method          =     %d\n",    fICMethod   ) ; 
851   printf("Cone Size          =     %1.2f\n", fConeSize   ) ; 
852   printf("pT threshold       =     >%2.1f;<%2.1f\n", fPtThreshold   ,   fPtThresholdMax) ;
853   printf("Sum pT threshold   =     >%2.1f;<%2.1f\n", fSumPtThreshold,fSumPtThresholdMax) ;
854   printf("pT fraction        =     %3.1f\n", fPtFraction ) ;
855   printf("particle type in cone =  %d\n",    fPartInCone ) ;
856   printf("using fraction for high pt leading instead of frac ? %i\n",fFracIsThresh);
857   printf("    \n") ;
858   
859
860
861 //___________________________________________________________________________
862 Float_t AliIsolationCut::Radius(Float_t etaC, Float_t phiC,
863                                 Float_t eta , Float_t phi) const
864 {
865   // Calculate the distance to trigger from any particle
866
867   Float_t dEta = etaC-eta;
868   Float_t dPhi = phiC-phi;
869   
870   if(TMath::Abs(dPhi) >= TMath::Pi()) 
871     dPhi = TMath::TwoPi()-TMath::Abs(dPhi);
872   
873   return TMath::Sqrt( dEta*dEta + dPhi*dPhi );
874   
875 }
876
877
878