]> git.uio.no Git - u/mrichter/AliRoot.git/blob - EMCAL/AliEMCALAodCluster.cxx
Use the same Array for digits and RecPoints in all the events, just clear it per...
[u/mrichter/AliRoot.git] / EMCAL / AliEMCALAodCluster.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 //  AliAODCaloCluster extension for EMCAL to recalculate cluster 
18 //  parameters in case of recalibration.
19 //  Copy-paste from methods in AliEMCALRecPoint.
20 //*--
21 //*-- Author: Dmitri Peressounko (RRC KI) for PHOS
22 //*-- Adapted for EMCAL: Gustavo Conesa (INFN-LNF)
23
24 // --- ROOT system ---
25 #include "TVector3.h"
26 #include "TMath.h"
27
28 // --- Standard library ---
29
30 // --- AliRoot header files ---
31 #include "AliLog.h" 
32 #include "AliEMCALGeometry.h" 
33 #include "AliEMCALPID.h" 
34 #include "AliEMCALAodCluster.h" 
35 #include "AliEMCALCalibData.h"
36 #include "AliAODCaloCells.h"
37
38 ClassImp(AliEMCALAodCluster)
39
40 //____________________________________________________________________________
41 AliEMCALAodCluster::AliEMCALAodCluster() : 
42   AliAODCaloCluster(),fRecalibrated(0)
43 {
44   // ctor
45 }
46 //____________________________________________________________________________
47 AliEMCALAodCluster::AliEMCALAodCluster(const AliAODCaloCluster & clu) : 
48   AliAODCaloCluster(clu),fRecalibrated(0)
49 {
50   // cpy ctor
51 }
52
53 //____________________________________________________________________________
54 AliEMCALAodCluster::~AliEMCALAodCluster()
55 {
56   // dtor
57 }
58 //____________________________________________________________________________
59 void AliEMCALAodCluster::Recalibrate(AliEMCALCalibData * calibData, AliAODCaloCells *emcCells, TString emcalGeoName){
60   //If not done yet, apply recalibration coefficients to energies list
61   //NOTE that after recalibration fCellsAmpFraction contains not FRACTION but FULL energy 
62   
63   if(fRecalibrated)
64    return ;
65   
66   if(!calibData)
67     return ;
68
69   AliEMCALGeometry * emcalgeo =  AliEMCALGeometry::GetInstance(emcalGeoName) ;
70   if(!emcalgeo)
71     AliFatal("AliEMCALGeometry was not constructed\n") ;
72         
73   Double32_t * cellsAmpFraction = GetCellsAmplitudeFraction(); 
74   Int_t iSupMod = -1;
75   Int_t iTower  = -1;
76   Int_t iIphi   = -1;
77   Int_t iIeta   = -1;
78   Int_t iphi    = -1;
79   Int_t ieta    = -1;
80         
81   for(Int_t i=0; i < GetNCells(); i++){
82     
83     //Get from the absid the supermodule, tower and eta/phi numbers
84     emcalgeo->GetCellIndex(GetCellAbsId(i),iSupMod,iTower,iIphi,iIeta); 
85     //Gives SuperModule and Tower numbers
86     emcalgeo->GetCellPhiEtaIndexInSModule(iSupMod,iTower,
87                                           iIphi, iIeta,iphi,ieta);      
88     
89     Double_t energy = emcCells->GetCellAmplitude(GetCellAbsId(i)) ;
90     //AliDebug(2,Form("Recalibrate: cell %f, calib %f, fraction %f\n",energy,calibData->GetADCchannel(iSupMod,ieta,iphi),cellsAmpFraction[i]));
91         if(cellsAmpFraction[i]< 1e-4) cellsAmpFraction[i] = 1; //Unfolding off, took all the cell energy 
92         cellsAmpFraction[i]*=energy*calibData->GetADCchannel(iSupMod,ieta,iphi);
93   }
94         
95   SetCellsAmplitudeFraction(cellsAmpFraction);
96   fRecalibrated=kTRUE; 
97 }
98 //____________________________________________________________________________
99 void  AliEMCALAodCluster::EvalAll(Float_t logWeight, TString geoname){
100     //If recalibrated - recalculate all cluster parameters
101   if(!fRecalibrated)
102     return ;
103   //printf("EvalAll e org %f\n",E());
104   EvalEnergy() ; //Energy should be evaluated first
105   //printf("EvalAll e2 %f\n",E());
106   EvalPositionAndShowerShape(logWeight, geoname) ;
107   //printf("EvalAll e3 %f\n",E());
108   EvalPID() ; //Should be evaluated after energy and shower shape recalculation
109   //printf("EvalAll e4 %f\n",E());
110 }
111 //____________________________________________________________________________
112 void AliEMCALAodCluster::EvalEnergy(){
113   //Evaluate energy
114   if(!fRecalibrated) // no need to recalibrate
115     return ;
116     
117   Float_t energy=0. ;
118   for(Int_t iDigit=0; iDigit < GetNCells(); iDigit++) {
119     energy+=GetCellAmplitudeFraction(iDigit) ;
120   }
121   //printf("EvalEnergy: e %f\n", energy);
122   SetE(energy);
123   
124    
125 }
126 ////____________________________________________________________________________
127 //void AliEMCALAodCluster::EnergyCorrection(AliEMCALPID * pid){
128 //  //apply nonlinearity correction same as in AliEMCALPID.
129 //  SetE(pid->GetCalibratedEnergy(E())) ;
130 //}
131
132 //____________________________________________________________________________
133 void AliEMCALAodCluster::EvalPID(){           
134         
135   //re-evaluate identification parameters
136 //  pid->CalculatePID(E(),GetDispersion(),GetEmcCpvDistance(),GetTOF(),GetPID()) ;  
137 //  pid->CalculatePID(E(),GetDispersion(),GetM20(),GetM02(),GetEmcCpvDistance(),GetTOF(),GetPID()) ;
138
139   //With bayesian
140   AliEMCALPID *pid = new AliEMCALPID(kFALSE);
141   pid->SetLowFluxParam(); // Need to be fixed
142   Float_t pidlist[AliPID::kSPECIESN+1];
143         for(Int_t i = 0; i < AliPID::kSPECIESN+1; i++) pidlist[i] = pid->GetPIDFinal(i);        
144   SetPIDFromESD(pidlist);
145         
146 }
147
148 //____________________________________________________________________________
149 void AliEMCALAodCluster::EvalPositionAndShowerShape(Float_t logWeight, TString emcalGeoName)
150 {
151   // Calculates new center of gravity in the local EMCAL-module coordinates 
152   // and tranfers into global ALICE coordinates
153   // Calculates Dispersion and main axis
154   if(!fRecalibrated) // no need to recalibrate
155     return ;
156   
157   Int_t nstat  = 0;
158   Float_t wtot = 0. ;
159
160   Int_t iSupMod = -1;
161   Int_t iTower  = -1;
162   Int_t iIphi   = -1;
163   Int_t iIeta   = -1;
164   Int_t iphi    = -1;
165   Int_t ieta    = -1;
166   Double_t etai = -1.;
167   Double_t phii = -1.;
168         
169   Double_t clXYZ[3] ={0.,0.,0.}; 
170   Double_t xyzi[3]  ={0.,0.,0.};
171  
172   Double_t d     = 0.;
173   Double_t dxx   = 0.;
174   Double_t dzz   = 0.;
175   Double_t dxz   = 0.;  
176   Double_t xmean = 0.;
177   Double_t zmean = 0.;
178
179   AliEMCALGeometry * emcalgeo =  AliEMCALGeometry::GetInstance(emcalGeoName) ;
180   if(!emcalgeo)
181     AliFatal("AliEMCALGeometry was not constructed\n") ;
182         
183   Double_t dist  = TmaxInCm(E(),0);
184   for(Int_t iDigit=0; iDigit < GetNCells(); iDigit++) {
185         
186         //Get from the absid the supermodule, tower and eta/phi numbers
187         emcalgeo->GetCellIndex(GetCellAbsId(iDigit),iSupMod,iTower,iIphi,iIeta); 
188         emcalgeo->RelPosCellInSModule(GetCellAbsId(iDigit), dist, xyzi[0], xyzi[1], xyzi[2]);
189         emcalgeo->GetCellPhiEtaIndexInSModule(iSupMod,iTower,iIphi,iIeta, iphi,ieta);
190
191     Double_t ei = GetCellAmplitudeFraction(iDigit) ;
192     if (E() > 0 && ei > 0) {
193                 Float_t w = ei;  
194                 if(logWeight > 0) w = TMath::Max( 0., logWeight + TMath::Log(ei/E()) ) ;
195                 etai=(Double_t)ieta;
196                 phii=(Double_t)iphi;            
197                 if(w > 0.0) {
198                         wtot += w ;
199                         nstat++;                
200                         for(Int_t i = 0; i < 3; i++ ) clXYZ[i]    += (w*xyzi[i]);
201         
202                         //Shower shape
203                         dxx  += w * etai * etai ;
204                         xmean+= w * etai ;
205                         dzz  += w * phii * phii ;
206                         zmean+= w * phii ; 
207                         dxz  += w * etai * phii ; 
208                 }
209     }
210     else
211       AliError(Form("Wrong energy %f and/or amplitude %f\n", ei, E()));
212   }
213
214   //Normalize to the weight     
215   if (wtot > 0) {
216                 for(Int_t i=0; i<3; i++ ) clXYZ[i] /= wtot;
217                 xmean /= wtot ;
218                 zmean /= wtot ;
219   }
220   else
221     AliError(Form("Wrong weight %f\n", wtot));
222
223   //Put cluster position in the global system
224   TVector3 gpos ;
225   emcalgeo->GetGlobal(clXYZ, gpos, iSupMod);
226
227   SetPositionAt(gpos[0],0) ;
228   SetPositionAt(gpos[1],1) ;  
229   SetPositionAt(gpos[2],2) ;
230
231   //Calculate dispersion        
232   for(Int_t iDigit=0; iDigit < GetNCells(); iDigit++) {
233                 //Get from the absid the supermodule, tower and eta/phi numbers
234                 emcalgeo->GetCellIndex(GetCellAbsId(iDigit),iSupMod,iTower,iIphi,iIeta); 
235                 emcalgeo->GetCellPhiEtaIndexInSModule(iSupMod,iTower,iIphi,iIeta, iphi,ieta);
236                 
237                 Double_t ei=GetCellAmplitudeFraction(iDigit) ;
238                 if (E() > 0 && ei > 0) {
239                         Float_t w = ei;  
240                         if(logWeight > 0) w = TMath::Max( 0., logWeight + TMath::Log(ei/E()) ) ;
241                         etai=(Double_t)ieta;
242                         phii=(Double_t)iphi;            
243                         if(w > 0.0)  d +=  w*((etai-xmean)*(etai-xmean)+(phii-zmean)*(phii-zmean)); 
244                 }
245                 else
246                         AliError(Form("Wrong energy %f and/or amplitude %f\n", ei, E()));
247   }
248         
249   //Normalize to the weigth and set shower shape parameters
250   if (wtot > 0 && nstat > 1) {
251     d /= wtot ;
252     dxx /= wtot ;
253     dzz /= wtot ;
254     dxz /= wtot ;
255     dxx -= xmean * xmean ;
256     dzz -= zmean * zmean ;
257     dxz -= xmean * zmean ;
258     SetM02(0.5 * (dxx + dzz) + TMath::Sqrt( 0.25 * (dxx - dzz) * (dxx - dzz) + dxz * dxz )) ;
259     SetM20(0.5 * (dxx + dzz) - TMath::Sqrt( 0.25 * (dxx - dzz) * (dxx - dzz) + dxz * dxz ));
260   }
261   else{
262     d=0. ;
263     SetM20(0.) ;
264     SetM02(0.) ;
265   }     
266         
267   if (d>=0)
268           SetDispersion(TMath::Sqrt(d)) ;
269   else    
270           SetDispersion(0) ;
271
272 }
273
274 //_____________________________________________________________________
275 Double_t AliEMCALAodCluster::TmaxInCm(const Double_t e , const Int_t key) const
276
277         // e energy in GeV)
278         // key  =  0(gamma, default)
279         //     !=  0(electron)
280         static Double_t ca = 4.82;  // shower max parameter - first guess; ca=TMath::Log(1000./8.07)
281         static Double_t x0 = 1.23;  // radiation lenght (cm)
282         static Double_t tmax = 0.;   // position of electromagnetic shower max in cm
283         
284         tmax = 0.0;
285         if(e>0.1) {
286                 tmax = TMath::Log(e) + ca;
287                 if      (key==0) tmax += 0.5; 
288                 else             tmax -= 0.5;
289                 tmax *= x0; // convert to cm
290         }
291         return tmax;
292 }
293