First version of Raw Data reconstruction. Added appropriate Reconstruct method to...
[u/mrichter/AliRoot.git] / EMCAL / AliEMCALPID.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 /* $Id$ */
17 /* History of cvs commits:
18  *
19  * $Log$
20  * Revision 1.9  2007/02/20 20:17:43  hristov
21  * Corrected array size, removed warnings (icc)
22  *
23  * Revision 1.8  2006/12/19 08:49:35  gustavo
24  * New PID class for EMCAL, bayesian analysis done with ESD data, PID information filled when calling AliEMCALPID in AliEMCALReconstructor::FillESD()
25  *
26  *
27  */
28 //    to compute PID for all the clusters in ESDs.root file
29 //     the ESDs.root have to be in the same directory as the class
30 //
31 //
32 //
33 //
34 //
35 //      AliEMCALPID::CalculPID(Energy,Lambda0)
36 //        Calcul PID for all clusters in AliESDs.root file
37 //        keep this function for the moment for a simple verification, could be removed
38 //
39 //
40 //
41 //   AliEMCALPID::CalculPID(Energy,Lambda0)
42 //    calcul PID Weght for a cluster with Energy, Lambda0 .
43 //    Double_t PIDFinal[AliPID::kSPECIESN]  is the standard PID for :
44 //
45 //
46 //
47 //      kElectron :  fPIDFinal[0]
48 //      kMuon     :  fPIDFinal[1]
49 //      kPion     :  fPIDFinal[2]
50 //      kKaon     :  fPIDFinal[3]
51 //      kProton   :  fPIDFinal[4]
52 //      kPhoton   :  fPIDFinal[5]
53 //      kPi0      :  fPIDFinal[6]
54 //      kNeutron  :  fPIDFinal[7]
55 //      kKaon0    :  fPIDFinal[8]
56 //      kEleCon   :  fPIDFinal[9]
57 //      kUnknown  :  fPIDFinal[10]
58 //
59 //
60 //    PID[3] is a simple PID for
61 //      Electron & Photon  PID[0]
62 //                    Pi0  PID[1]
63 //                 Hadron  PID[2]
64 //
65 //  
66 //
67 //
68 //
69 // --- ROOT system ---
70
71 // standard C++ includes
72 #include <Riostream.h>
73 // #include <cstdlib>
74 // #include <cmath>
75
76 // ROOT includes
77 #include "TTree.h"
78 #include "TStyle.h"
79 #include "TVector3.h"
80 #include "TBranch.h"
81 #include "TClonesArray.h"
82 #include "TCanvas.h"
83 #include "TLorentzVector.h"
84 #include "TMath.h"
85 #include "TFile.h"
86 #include "TH1.h"
87 #include "TH2.h"
88 #include "TParticle.h"
89
90 // // STEER includes
91 // #include "AliRun.h"
92 // #include "AliRunLoader.h"
93 // #include "AliHeader.h"
94 // #include "AliLoader.h"
95 // #include "AliStack.h"
96 // #include "AliESDtrack.h"
97 // #include "AliESD.h"
98 #include "AliLog.h"
99 #include "AliEMCALPID.h"
100   
101 ClassImp(AliEMCALPID)
102
103 //______________________________________________
104   AliEMCALPID::AliEMCALPID():
105     fPrintInfo(kFALSE), fProbGamma(0.),fProbPiZero(0.),fProbHadron(0.),fReconstructor(kFALSE)
106 {
107   //
108   // Constructor.
109   // Initialize all constant values which have to be used
110   // during PID algorithm execution
111   //
112   
113   // set flag for printing to FALSE by default
114   fPrintInfo = kFALSE;
115   
116   // as a first step, all array elements are initialized to 0.0
117   Int_t i, j;
118   for (i = 0; i < 6; i++) {
119     for (j = 0; j < 6; j++) {
120       fGamma[i][j] = fHadron[i][j] = fPiZero5to10[i][j] = fPiZero10to60[i][j] = 0.;
121     }
122   }
123   
124   // then, only the ones which must be not zero are initialized
125   // while the others will remain to the value 0.0
126   
127   fGamma[0][0] =  0.038022;
128   fGamma[0][1] = -0.0001883;
129   fGamma[0][2] =  5.449e-06;
130   
131   fGamma[1][0] =  0.207313;
132   fGamma[1][1] = -0.000978;
133   fGamma[1][2] =  0.00001634;
134   
135   fGamma[2][0] =  0.043364;
136   fGamma[2][1] = -0.0002048;
137   fGamma[2][2] =  8.661e-06;
138   fGamma[2][3] = -1.353e-07;
139   
140   fGamma[3][0] =  0.265004;
141   fGamma[3][1] =  0.061298;
142   fGamma[3][2] = -0.003203;
143   fGamma[3][3] =  4.73e-05;
144   
145   fGamma[4][0] =  0.243579;
146   fGamma[4][1] = -1.614e-05;
147   
148   fGamma[5][0] =  0.002942;
149   fGamma[5][1] = -3.976e-05;
150   
151   fHadron[0][0] =  0.011945 / 3.;
152   fHadron[0][1] =  0.000386 / 3.;
153   fHadron[0][2] = -0.000014 / 3.;
154   fHadron[0][3] =  1.336e-07 / 3.;
155   
156   fHadron[1][0] =  0.496544;
157   fHadron[1][1] = -0.003226;
158   fHadron[1][2] =  0.00001678;
159   
160   fHadron[2][0] =  0.144838;
161   fHadron[2][1] = -0.002954;
162   fHadron[2][2] =  0.00008754;
163   fHadron[2][3] = -7.587e-07;
164   
165   fHadron[3][0] =  1.264461 / 7.;
166   fHadron[3][1] =  0.002097 / 7.;
167   
168   fHadron[4][0] =  0.261950;
169   fHadron[4][1] = -0.001078;
170   fHadron[4][2] =  0.00003237;
171   fHadron[4][3] = -3.241e-07;
172   fHadron[4][4] =  0.;
173   fHadron[4][5] =  0.;
174   fHadron[5][0] =  0.010317;
175   fHadron[5][1] =  0.;
176   fHadron[5][2] =  0.;
177   fHadron[5][3] =  0.;
178   fHadron[5][4] =  0.;
179   fHadron[5][5] =  0.;
180   
181   fPiZero5to10[0][0] = 0.009138;
182   fPiZero5to10[0][1] = 0.0006377;
183   
184   fPiZero5to10[1][0] = 0.08;
185   
186   fPiZero5to10[2][0] = -0.061119;
187   fPiZero5to10[2][1] =  0.019013;
188   
189   fPiZero5to10[3][0] =  0.2;
190   
191   fPiZero5to10[4][0] =  0.252044;
192   fPiZero5to10[4][1] = -0.002315;
193   
194   fPiZero5to10[5][0] =  0.002942;
195   fPiZero5to10[5][1] = -3.976e-05;
196   
197   fPiZero10to60[0][0] =  0.009138;
198   fPiZero10to60[0][1] =  0.0006377;
199   
200   fPiZero10to60[1][0] =  1.272837;
201   fPiZero10to60[1][1] = -0.069708;
202   fPiZero10to60[1][2] =  0.001568;
203   fPiZero10to60[1][3] = -1.162e-05;
204   
205   fPiZero10to60[2][0] =  0.139703;
206   fPiZero10to60[2][1] =  0.003687;
207   fPiZero10to60[2][2] = -0.000568;
208   fPiZero10to60[2][3] =  1.498e-05;
209   fPiZero10to60[2][4] = -1.174e-07;
210   
211   fPiZero10to60[3][0] = -0.826367;
212   fPiZero10to60[3][1] =  0.096951;
213   fPiZero10to60[3][2] = -0.002215;
214   fPiZero10to60[3][3] =  2.523e-05;
215   
216   fPiZero10to60[4][0] =  0.249890;
217   fPiZero10to60[4][1] = -0.000063;
218   
219   fPiZero10to60[5][0] =  0.002942;
220   fPiZero10to60[5][1] = -3.976e-05;
221   
222   fPIDWeight[0] = -1;
223   fPIDWeight[1] = -1;
224   fPIDWeight[2] = -1;
225   fReconstructor = kFALSE;
226 }
227
228 //______________________________________________
229 void AliEMCALPID::RunPID(AliESD *esd)
230 {
231 //
232 // Make the PID for all the EMCAL clusters containedin the ESDs File
233 // but just gamma/PiO/Hadron
234 //
235         // trivial check against NULL object passed
236   
237   if (esd == 0x0) {
238     AliInfo("NULL ESD object passed!!" );
239     return ;
240   }
241
242   Int_t nClusters = esd->GetNumberOfEMCALClusters();
243   Int_t firstCluster = esd->GetFirstEMCALCluster();
244   Double_t energy, lambda0;
245   for (Int_t iCluster = firstCluster; iCluster < (nClusters + firstCluster); iCluster++) {
246     
247     AliESDCaloCluster *clust = esd->GetCaloCluster(iCluster);
248     energy = clust->GetClusterEnergy();
249     lambda0 = clust->GetM02();
250     // verify cluster type
251     Int_t clusterType= clust->GetClusterType();
252     if (clusterType == AliESDCaloCluster::kClusterv1 && lambda0 != 0 && energy > 5 && energy < 1000) {
253       // reject clusters with lambda0 = 0
254       // reject clusters with energy < 5 GeV
255       ComputePID(energy, lambda0);
256       if (fPrintInfo) {
257         AliInfo("___________________________________________________");
258         AliInfo(Form( "Particle Energy = %f",energy));
259         AliInfo(Form( "Particle Lambda0 of the particle = %f", lambda0) );
260         AliInfo("PIDWeight of the particle :" );
261         AliInfo(Form( " GAMMA  : %f",fPID[0] ));
262         AliInfo(Form( " PiZero : %f",fPID[1] ));
263         AliInfo(Form( " HADRON : %f", fPID[2] ));
264         AliInfo("_________________________________________");
265         AliInfo(Form( " kElectron : %f", fPIDFinal[0]) );
266         AliInfo(Form( " kMuon     : %f", fPIDFinal[1] ));
267         AliInfo(Form( " kPion       : %f", fPIDFinal[2] ));
268         AliInfo(Form( " kKaon       : %f", fPIDFinal[3] ));
269         AliInfo(Form( " kProton   : %f", fPIDFinal[4] ));
270         AliInfo(Form( " kPhoton   : %f", fPIDFinal[5] ));
271         AliInfo(Form( " kPi0        : %f", fPIDFinal[6] ));
272         AliInfo(Form( " kNeutron  : %f", fPIDFinal[7] ));
273         AliInfo(Form( " kKaon0  : %f", fPIDFinal[8] ));
274         AliInfo(Form( " kEleCon   : %f", fPIDFinal[9] ));
275         AliInfo(Form( " kUnknown  : %f", fPIDFinal[10] ));
276         AliInfo("___________________________________________________");
277       }
278
279       if(fReconstructor) // In case it is called during reconstruction.
280         clust->SetPid(fPIDFinal);
281     } // end if (clusterType...)
282   } // end for (iCluster...)
283 }
284
285 //__________________________________________________________
286 void AliEMCALPID::ComputePID(Double_t energy, Double_t lambda0)
287 {
288 //
289 // This is the main command, which uses the distributions computed and parametrised, 
290 // and gives the PID by the bayesian method.
291 //
292   TArrayD paramDistribGamma  = DistLambda0(energy, 1);
293   TArrayD paramDistribPiZero = DistLambda0(energy, 2);
294   TArrayD paramDistribHadron = DistLambda0(energy, 3);
295   
296   Bool_t norm = kFALSE;
297   
298   fProbGamma   = TMath::Gaus(lambda0, paramDistribGamma[1], paramDistribGamma[2], norm) * paramDistribGamma[0];
299   fProbGamma  += TMath::Landau(lambda0, paramDistribGamma[4], paramDistribGamma[5], norm) * paramDistribGamma[3];
300   fProbPiZero  = TMath::Gaus(lambda0, paramDistribPiZero[1], paramDistribPiZero[2], norm) * paramDistribPiZero[0];
301   fProbPiZero += TMath::Landau(lambda0, paramDistribPiZero[4], paramDistribPiZero[5], norm) * paramDistribPiZero[3];
302   fProbHadron  = TMath::Gaus(lambda0, paramDistribHadron[1], paramDistribHadron[2], norm) * paramDistribHadron[0];
303   fProbHadron += TMath::Landau(lambda0, paramDistribHadron[4], paramDistribHadron[5], norm) * paramDistribHadron[3];
304   
305   // compute PID Weight
306   fPIDWeight[0] = fProbGamma / (fProbGamma + fProbPiZero + fProbHadron);
307   fPIDWeight[1] = fProbPiZero / (fProbGamma+fProbPiZero+fProbHadron);
308   fPIDWeight[2] = fProbHadron / (fProbGamma+fProbPiZero+fProbHadron);
309   
310   SetPID(fPIDWeight[0], 0);
311   SetPID(fPIDWeight[1], 1);
312   SetPID(fPIDWeight[2], 2);
313   
314   // sortie ecran pid Weight only for control (= in english ???)
315   if (fPrintInfo) {
316     AliInfo(Form( "Energy in loop = %f", energy) );
317     AliInfo(Form( "Lambda0 in loop = %f", lambda0) );
318     AliInfo(Form( "fProbGamma in loop = %f", fProbGamma) );
319     //  AliInfo(Form( "fParametresDistribGamma[2] = %f", fParamDistribGamma[2]) );
320     AliInfo(Form( "fProbaPiZero = %f", fProbPiZero ));
321     AliInfo(Form( "fProbaHadron = %f", fProbHadron) );
322     AliInfo(Form( "PIDWeight in loop = %f ||| %f ||| %f",  fPIDWeight[0] , fPIDWeight[1], fPIDWeight[2]) );
323     AliInfo(Form( "fGamma[2][2] = %f", fGamma[2][2] ));
324     AliInfo("********************************************************" );
325   }
326   
327   fPIDFinal[0]  = fPIDWeight[0]/2;
328   fPIDFinal[1]  = fPIDWeight[2]/8;
329   fPIDFinal[2]  = fPIDWeight[2]/8;
330   fPIDFinal[3]  = fPIDWeight[2]/8;
331   fPIDFinal[4]  = fPIDWeight[2]/8;
332   fPIDFinal[5]  = fPIDWeight[0]/2;
333   fPIDFinal[6]  = fPIDWeight[1]  ;
334   fPIDFinal[7]  = fPIDWeight[2]/8;
335   fPIDFinal[8]  = fPIDWeight[2]/8;
336   fPIDFinal[9]  = fPIDWeight[2]/8;
337   fPIDFinal[10] = fPIDWeight[2]/8;
338 }
339
340 //________________________________________________________
341 TArrayD AliEMCALPID::DistLambda0(Double_t energy, Int_t type)
342 {
343   //
344   // Compute the values of the parametrised distributions using the data initialised before.
345   //
346   Double_t constGauss = 0., meanGauss = 0., sigmaGauss = 0.;
347   Double_t constLandau=0., mpvLandau=0., sigmaLandau=0.;
348   TArrayD  distributionParam(6);
349   
350   switch (type) {
351   case 1:
352     constGauss  = Polynomial(energy, fGamma[0]);
353     meanGauss   = Polynomial(energy, fGamma[1]);
354     sigmaGauss  = Polynomial(energy, fGamma[2]);
355     constLandau = Polynomial(energy, fGamma[3]);
356     mpvLandau   = Polynomial(energy, fGamma[4]);
357     sigmaLandau = Polynomial(energy, fGamma[5]);
358     break;
359   case 2:
360     if (energy < 10) {
361       constGauss  = Polynomial(energy, fPiZero5to10[0]);
362       meanGauss   = Polynomial(energy, fPiZero5to10[1]);
363       sigmaGauss  = Polynomial(energy, fPiZero5to10[2]);
364       constLandau = Polynomial(energy, fPiZero5to10[3]);
365       mpvLandau   = Polynomial(energy, fPiZero5to10[4]);
366       sigmaLandau = Polynomial(energy, fPiZero5to10[5]);
367     }
368     else {
369       constGauss  = Polynomial(energy, fPiZero10to60[0]);
370       meanGauss   = Polynomial(energy, fPiZero10to60[1]);
371       sigmaGauss  = Polynomial(energy, fPiZero10to60[2]);
372       constLandau = Polynomial(energy, fPiZero10to60[3]);
373       mpvLandau   = Polynomial(energy, fPiZero10to60[4]);
374       sigmaLandau = Polynomial(energy, fPiZero10to60[5]);
375     }
376     break;
377   case 3:
378     constGauss  = Polynomial(energy, fHadron[0]);
379     meanGauss   = Polynomial(energy, fHadron[1]);
380     sigmaGauss  = Polynomial(energy, fHadron[2]);
381     constLandau = Polynomial(energy, fHadron[3]);
382     mpvLandau   = Polynomial(energy, fHadron[4]);
383     sigmaLandau = Polynomial(energy, fHadron[5]);
384     break;
385   }
386   
387   distributionParam[0] = constGauss;
388   distributionParam[1] = meanGauss;
389   distributionParam[2] = sigmaGauss;
390   distributionParam[3] = constLandau;
391   distributionParam[4] = mpvLandau;
392   distributionParam[5] = sigmaLandau;
393   
394   return distributionParam;
395 }
396
397 //_______________________________________________________
398 Double_t AliEMCALPID::Polynomial(Double_t x, Double_t *params)
399 {
400   //
401   // Compute a polynomial for a given value of 'x'
402   // with the array of parameters passed as the second arg
403   //
404   Double_t y;
405   y  = params[0];
406   y += params[1] * x;
407   y += params[2] * x * x;
408   y += params[3] * x * x * x;
409   y += params[4] * x * x * x * x;
410   y += params[5] * x * x * x * x * x;
411   
412   return y;
413 }