]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PHOS/AliPHOSPIDv1.cxx
Add minus first version of TPC DAQ calibration algorithm (Marian)
[u/mrichter/AliRoot.git] / PHOS / AliPHOSPIDv1.cxx
CommitLineData
6ad0bfa0 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
b2a60966 16/* $Id$ */
17
702ab87e 18/* History of cvs commits:
19 *
20 * $Log$
753b19cd 21 * Revision 1.107 2007/04/02 15:00:16 cvetan
22 * No more calls to gAlice in the reconstruction
23 *
999f9a8f 24 * Revision 1.106 2007/04/01 15:40:15 kharlov
25 * Correction for actual vertex position implemented
26 *
407d15b3 27 * Revision 1.105 2007/03/06 06:57:46 kharlov
28 * DP:calculation of distance to CPV done in TSM
29 *
26aa7e4a 30 * Revision 1.104 2006/12/15 10:46:26 hristov
31 * Using TMath::Abs instead of fabs
32 *
e4df4b30 33 * Revision 1.103 2006/09/07 18:31:08 kharlov
34 * Effective c++ corrections (T.Pocheptsov)
35 *
3f7dbdb7 36 * Revision 1.102 2006/01/23 17:51:48 hristov
37 * Using the recommended way of forward declarations for TVector and TMatrix (see v5-08-00 release notes). Additional clean-up
38 *
e8d02863 39 * Revision 1.101 2005/05/28 14:19:04 schutz
40 * Compilation warnings fixed by T.P.
41 *
702ab87e 42 */
43
6ad0bfa0 44//_________________________________________________________________________
b2a60966 45// Implementation version v1 of the PHOS particle identifier
7acf6008 46// Particle identification based on the
148b2bba 47// - RCPV: distance from CPV recpoint to EMCA recpoint.
48// - TOF
49// - PCA: Principal Components Analysis..
50// The identified particle has an identification number corresponding
51// to a 9 bits number:
bc0c084c 52// -Bit 0 to 2: bit set if RCPV > CpvEmcDistance (each bit corresponds
148b2bba 53// to a different efficiency-purity point of the photon identification)
bc0c084c 54// -Bit 3 to 5: bit set if TOF < TimeGate (each bit corresponds
148b2bba 55// to a different efficiency-purity point of the photon identification)
56// -Bit 6 to 9: bit set if Principal Components are
50739f15 57// inside an ellipse defined by the parameters a, b, c, x0 and y0.
148b2bba 58// (each bit corresponds to a different efficiency-purity point of the
50739f15 59// photon identification)
60// The PCA (Principal components analysis) needs a file that contains
61// a previous analysis of the correlations between the particles. This
bc0c084c 62// file is $ALICE_ROOT/PHOS/PCA8pa15_0.5-100.root. Analysis done for
50739f15 63// energies between 0.5 and 100 GeV.
9fa5f1d0 64// A calibrated energy is calculated. The energy of the reconstructed
50739f15 65// cluster is corrected with the formula A + B * E + C * E^2, whose
bc0c084c 66// parameters where obtained through the study of the reconstructed
50739f15 67// energy distribution of monoenergetic photons.
a4e98857 68//
bc0c084c 69// All the parameters (RCPV(2 rows-3 columns),TOF(1r-3c),PCA(5r-4c)
50739f15 70// and calibration(1r-3c))are stored in a file called
71// $ALICE_ROOT/PHOS/Parameters.dat. Each time that AliPHOSPIDv1 is
bc0c084c 72// initialized, this parameters are copied to a Matrix (9,4), a
50739f15 73// TMatrixD object.
7acf6008 74//
a4e98857 75// use case:
50739f15 76// root [0] AliPHOSPIDv1 * p = new AliPHOSPIDv1("galice1.root")
a4e98857 77// Warning in <TDatabasePDG::TDatabasePDG>: object already instantiated
50739f15 78// // reading headers from file galice1.root and create RecParticles
79 // TrackSegments and RecPoints are used
80// // set file name for the branch RecParticles
f0a4c9e9 81// root [1] p->ExecuteTask("deb all time")
50739f15 82// // available options
83// // "deb" - prints # of reconstructed particles
84// // "deb all" - prints # and list of RecParticles
85// // "time" - prints benchmarking results
7acf6008 86//
50739f15 87// root [2] AliPHOSPIDv1 * p2 = new AliPHOSPIDv1("galice1.root","v1",kTRUE)
148b2bba 88// Warning in <TDatabasePDG::TDatabasePDG>: object already instantiated
50739f15 89// //Split mode.
f0a4c9e9 90// root [3] p2->ExecuteTask()
91//
50739f15 92
f0a4c9e9 93
7acf6008 94//*-- Author: Yves Schutz (SUBATECH) & Gines Martinez (SUBATECH) &
148b2bba 95// Gustavo Conesa April 2002
50739f15 96// PCA redesigned by Gustavo Conesa October 2002:
97// The way of using the PCA has changed. Instead of 2
98// files with the PCA, each one with different energy ranges
99// of application, we use the wide one (0.5-100 GeV), and instead
bc0c084c 100// of fixing 3 ellipses for different ranges of energy, it has been
50739f15 101// studied the dependency of the ellipses parameters with the
102// energy, and they are implemented in the code as a funtion
103// of the energy.
104//
105//
106//
6ad0bfa0 107// --- ROOT system ---
c947e71a 108
109
110// --- Standard library ---
e8d02863 111#include <TMatrixF.h>
acb5beb7 112#include "TFormula.h"
7acf6008 113#include "TBenchmark.h"
148b2bba 114#include "TPrincipal.h"
c947e71a 115#include "TFile.h"
e3817e5f 116#include "TSystem.h"
407d15b3 117#include "TVector3.h"
148b2bba 118
6ad0bfa0 119// --- AliRoot header files ---
c947e71a 120 //#include "AliLog.h"
e3817e5f 121#include "AliPHOS.h"
26d4b141 122#include "AliPHOSPIDv1.h"
7b7c1533 123#include "AliPHOSGetter.h"
407d15b3 124#include "AliESD.h"
125#include "AliESDVertex.h"
6ad0bfa0 126
26d4b141 127ClassImp( AliPHOSPIDv1)
6ad0bfa0 128
1cb7c1ee 129//____________________________________________________________________________
3f7dbdb7 130AliPHOSPIDv1::AliPHOSPIDv1() :
131 fBayesian(kFALSE),
132 fDefaultInit(kFALSE),
133 fWrite(kFALSE),
134 fNEvent(0),
135 fFileNamePrincipalPhoton(),
136 fFileNamePrincipalPi0(),
137 fFileNameParameters(),
138 fPrincipalPhoton(0),
139 fPrincipalPi0(0),
140 fX(0),
141 fPPhoton(0),
142 fPPi0(0),
143 fRecParticlesInRun(0),
144 fParameters(0),
145 fTFphoton(0),
146 fTFpiong(0),
147 fTFkaong(0),
148 fTFkaonl(0),
149 fTFhhadrong(0),
150 fTFhhadronl(0),
151 fDFmuon(0),
152 fERecWeight(0),
153 fChargedNeutralThreshold(0.),
154 fTOFEnThreshold(0),
155 fDispEnThreshold(0),
156 fDispMultThreshold(0)
1cb7c1ee 157{
a4e98857 158 // default ctor
148b2bba 159
8d0f3f77 160 InitParameters() ;
92f521a9 161 fDefaultInit = kTRUE ;
7acf6008 162}
163
581354c5 164//____________________________________________________________________________
3f7dbdb7 165AliPHOSPIDv1::AliPHOSPIDv1(const AliPHOSPIDv1 & pid ) :
166 AliPHOSPID(pid),
167 fBayesian(kFALSE),
168 fDefaultInit(kFALSE),
169 fWrite(kFALSE),
170 fNEvent(0),
171 fFileNamePrincipalPhoton(),
172 fFileNamePrincipalPi0(),
173 fFileNameParameters(),
174 fPrincipalPhoton(0),
175 fPrincipalPi0(0),
176 fX(0),
177 fPPhoton(0),
178 fPPi0(0),
179 fRecParticlesInRun(0),
180 fParameters(0),
181 fTFphoton(0),
182 fTFpiong(0),
183 fTFkaong(0),
184 fTFkaonl(0),
185 fTFhhadrong(0),
186 fTFhhadronl(0),
187 fDFmuon(0),
188 fERecWeight(0),
189 fChargedNeutralThreshold(0.),
190 fTOFEnThreshold(0),
191 fDispEnThreshold(0),
192 fDispMultThreshold(0)
193
581354c5 194{
386aef34 195 // ctor
581354c5 196 InitParameters() ;
581354c5 197 Init() ;
581354c5 198
199}
200
7acf6008 201//____________________________________________________________________________
3f7dbdb7 202AliPHOSPIDv1::AliPHOSPIDv1(const TString alirunFileName, const TString eventFolderName) :
203 AliPHOSPID(alirunFileName, eventFolderName),
204 fBayesian(kFALSE),
205 fDefaultInit(kFALSE),
206 fWrite(kFALSE),
207 fNEvent(0),
208 fFileNamePrincipalPhoton(),
209 fFileNamePrincipalPi0(),
210 fFileNameParameters(),
211 fPrincipalPhoton(0),
212 fPrincipalPi0(0),
213 fX(0),
214 fPPhoton(0),
215 fPPi0(0),
216 fRecParticlesInRun(0),
217 fParameters(0),
218 fTFphoton(0),
219 fTFpiong(0),
220 fTFkaong(0),
221 fTFkaonl(0),
222 fTFhhadrong(0),
223 fTFhhadronl(0),
224 fDFmuon(0),
225 fERecWeight(0),
226 fChargedNeutralThreshold(0.),
227 fTOFEnThreshold(0),
228 fDispEnThreshold(0),
229 fDispMultThreshold(0)
230
7acf6008 231{
a4e98857 232 //ctor with the indication on where to look for the track segments
7b7c1533 233
8d0f3f77 234 InitParameters() ;
2bd5457f 235 Init() ;
92f521a9 236 fDefaultInit = kFALSE ;
7acf6008 237}
7b7c1533 238
7acf6008 239//____________________________________________________________________________
240AliPHOSPIDv1::~AliPHOSPIDv1()
241{
79bb1b62 242 // dtor
acb5beb7 243 fPrincipalPhoton = 0;
244 fPrincipalPi0 = 0;
9fa5f1d0 245
e3817e5f 246 delete [] fX ; // Principal input
247 delete [] fPPhoton ; // Photon Principal components
248 delete [] fPPi0 ; // Pi0 Principal components
acb5beb7 249
250 delete fParameters;
251 delete fTFphoton;
252 delete fTFpiong;
253 delete fTFkaong;
254 delete fTFkaonl;
255 delete fTFhhadrong;
256 delete fTFhhadronl;
257 delete fDFmuon;
7acf6008 258}
a496c46c 259//____________________________________________________________________________
260const TString AliPHOSPIDv1::BranchName() const
261{
88cb7938 262
263 return GetName() ;
a496c46c 264}
265
148b2bba 266//____________________________________________________________________________
267void AliPHOSPIDv1::Init()
268{
269 // Make all memory allocations that are not possible in default constructor
270 // Add the PID task to the list of PHOS tasks
a496c46c 271
adcca1e6 272 AliPHOSGetter * gime = AliPHOSGetter::Instance() ;
273 if(!gime)
274 gime = AliPHOSGetter::Instance(GetTitle(), fEventFolderName.Data()) ;
88cb7938 275
276 if ( !gime->PID() )
277 gime->PostPID(this) ;
148b2bba 278}
8d0f3f77 279
280//____________________________________________________________________________
281void AliPHOSPIDv1::InitParameters()
282{
e3817e5f 283 // Initialize PID parameters
adcca1e6 284 fWrite = kTRUE ;
8d0f3f77 285 fRecParticlesInRun = 0 ;
8d0f3f77 286 fNEvent = 0 ;
8d0f3f77 287 fRecParticlesInRun = 0 ;
35adb638 288 fBayesian = kTRUE ;
9fa5f1d0 289 SetParameters() ; // fill the parameters matrix from parameters file
eabde521 290 SetEventRange(0,-1) ;
35adb638 291
cc1fe362 292 // initialisation of response function parameters
293 // Tof
2924941c 294
295// // Photons
296// fTphoton[0] = 0.218 ;
297// fTphoton[1] = 1.55E-8 ;
298// fTphoton[2] = 5.05E-10 ;
299// fTFphoton = new TFormula("ToF response to photons" , "gaus") ;
300// fTFphoton->SetParameters( fTphoton[0], fTphoton[1], fTphoton[2]) ;
301
302// // Pions
303// //Gaus (0 to max probability)
304// fTpiong[0] = 0.0971 ;
305// fTpiong[1] = 1.58E-8 ;
306// fTpiong[2] = 5.69E-10 ;
307// fTFpiong = new TFormula("ToF response to pions" , "gaus") ;
308// fTFpiong->SetParameters( fTpiong[0], fTpiong[1], fTpiong[2]) ;
309
310// // Kaons
311// //Gaus (0 to max probability)
312// fTkaong[0] = 0.0542 ;
313// fTkaong[1] = 1.64E-8 ;
314// fTkaong[2] = 6.07E-10 ;
315// fTFkaong = new TFormula("ToF response to kaon" , "gaus") ;
316// fTFkaong->SetParameters( fTkaong[0], fTkaong[1], fTkaong[2]) ;
317// //Landau (max probability to inf)
318// fTkaonl[0] = 0.264 ;
319// fTkaonl[1] = 1.68E-8 ;
320// fTkaonl[2] = 4.10E-10 ;
321// fTFkaonl = new TFormula("ToF response to kaon" , "landau") ;
322// fTFkaonl->SetParameters( fTkaonl[0], fTkaonl[1], fTkaonl[2]) ;
323
324// //Heavy Hadrons
325// //Gaus (0 to max probability)
326// fThhadrong[0] = 0.0302 ;
327// fThhadrong[1] = 1.73E-8 ;
328// fThhadrong[2] = 9.52E-10 ;
329// fTFhhadrong = new TFormula("ToF response to heavy hadrons" , "gaus") ;
330// fTFhhadrong->SetParameters( fThhadrong[0], fThhadrong[1], fThhadrong[2]) ;
331// //Landau (max probability to inf)
332// fThhadronl[0] = 0.139 ;
333// fThhadronl[1] = 1.745E-8 ;
334// fThhadronl[2] = 1.00E-9 ;
335// fTFhhadronl = new TFormula("ToF response to heavy hadrons" , "landau") ;
336// fTFhhadronl->SetParameters( fThhadronl[0], fThhadronl[1], fThhadronl[2]) ;
337
cc1fe362 338 // Photons
2924941c 339 fTphoton[0] = 7.83E8 ;
35adb638 340 fTphoton[1] = 1.55E-8 ;
2924941c 341 fTphoton[2] = 5.09E-10 ;
35adb638 342 fTFphoton = new TFormula("ToF response to photons" , "gaus") ;
cc1fe362 343 fTFphoton->SetParameters( fTphoton[0], fTphoton[1], fTphoton[2]) ;
35adb638 344
345 // Pions
346 //Gaus (0 to max probability)
2924941c 347 fTpiong[0] = 6.73E8 ;
35adb638 348 fTpiong[1] = 1.58E-8 ;
2924941c 349 fTpiong[2] = 5.87E-10 ;
35adb638 350 fTFpiong = new TFormula("ToF response to pions" , "gaus") ;
351 fTFpiong->SetParameters( fTpiong[0], fTpiong[1], fTpiong[2]) ;
35adb638 352
353 // Kaons
354 //Gaus (0 to max probability)
2924941c 355 fTkaong[0] = 3.93E8 ;
35adb638 356 fTkaong[1] = 1.64E-8 ;
2924941c 357 fTkaong[2] = 6.07E-10 ;
35adb638 358 fTFkaong = new TFormula("ToF response to kaon" , "gaus") ;
359 fTFkaong->SetParameters( fTkaong[0], fTkaong[1], fTkaong[2]) ;
360 //Landau (max probability to inf)
2924941c 361 fTkaonl[0] = 2.0E9 ;
35adb638 362 fTkaonl[1] = 1.68E-8 ;
363 fTkaonl[2] = 4.10E-10 ;
364 fTFkaonl = new TFormula("ToF response to kaon" , "landau") ;
365 fTFkaonl->SetParameters( fTkaonl[0], fTkaonl[1], fTkaonl[2]) ;
366
367 //Heavy Hadrons
368 //Gaus (0 to max probability)
2924941c 369 fThhadrong[0] = 2.02E8 ;
35adb638 370 fThhadrong[1] = 1.73E-8 ;
371 fThhadrong[2] = 9.52E-10 ;
372 fTFhhadrong = new TFormula("ToF response to heavy hadrons" , "gaus") ;
373 fTFhhadrong->SetParameters( fThhadrong[0], fThhadrong[1], fThhadrong[2]) ;
374 //Landau (max probability to inf)
2924941c 375 fThhadronl[0] = 1.10E9 ;
376 fThhadronl[1] = 1.74E-8 ;
377 fThhadronl[2] = 1.00E-9 ;
35adb638 378 fTFhhadronl = new TFormula("ToF response to heavy hadrons" , "landau") ;
379 fTFhhadronl->SetParameters( fThhadronl[0], fThhadronl[1], fThhadronl[2]) ;
380
35adb638 381
382
383 // Shower shape: dispersion gaussian parameters
384 // Photons
2924941c 385
386// fDphoton[0] = 4.62e-2; fDphoton[1] = 1.39e-2 ; fDphoton[2] = -3.80e-2;//constant
387// fDphoton[3] = 1.53 ; fDphoton[4] =-6.62e-2 ; fDphoton[5] = 0.339 ;//mean
388// fDphoton[6] = 6.89e-2; fDphoton[7] =-6.59e-2 ; fDphoton[8] = 0.194 ;//sigma
389
390// fDpi0[0] = 0.0586 ; fDpi0[1] = 1.06E-3 ; fDpi0[2] = 0. ;//constant
391// fDpi0[3] = 2.67 ; fDpi0[4] =-2.00E-2 ; fDpi0[5] = 9.37E-5 ;//mean
392// fDpi0[6] = 0.153 ; fDpi0[7] = 9.34E-4 ; fDpi0[8] =-1.49E-5 ;//sigma
393
394// fDhadron[0] = 1.61E-2 ; fDhadron[1] = 3.03E-3 ; fDhadron[2] = 1.01E-2 ;//constant
395// fDhadron[3] = 3.81 ; fDhadron[4] = 0.232 ; fDhadron[5] =-1.25 ;//mean
396// fDhadron[6] = 0.897 ; fDhadron[7] = 0.0987 ; fDhadron[8] =-0.534 ;//sigma
397
398 fDphoton[0] = 1.5 ; fDphoton[1] = 0.49 ; fDphoton[2] =-1.7E-2 ;//constant
399 fDphoton[3] = 1.5 ; fDphoton[4] = 4.0E-2 ; fDphoton[5] = 0.21 ;//mean
400 fDphoton[6] = 4.8E-2 ; fDphoton[7] =-0.12 ; fDphoton[8] = 0.27 ;//sigma
401 fDphoton[9] = 16.; //for E> fDphoton[9] parameters calculated at fDphoton[9]
402
403 fDpi0[0] = 0.25 ; fDpi0[1] = 3.3E-2 ; fDpi0[2] =-1.0e-5 ;//constant
404 fDpi0[3] = 1.50 ; fDpi0[4] = 398. ; fDpi0[5] = 12. ;//mean
405 fDpi0[6] =-7.0E-2 ; fDpi0[7] =-524. ; fDpi0[8] = 22. ;//sigma
406 fDpi0[9] = 110.; //for E> fDpi0[9] parameters calculated at fDpi0[9]
407
408 fDhadron[0] = 6.5 ; fDhadron[1] =-5.3 ; fDhadron[2] = 1.5 ;//constant
409 fDhadron[3] = 3.8 ; fDhadron[4] = 0.23 ; fDhadron[5] =-1.2 ;//mean
410 fDhadron[6] = 0.88 ; fDhadron[7] = 9.3E-2 ; fDhadron[8] =-0.51 ;//sigma
411 fDhadron[9] = 2.; //for E> fDhadron[9] parameters calculated at fDhadron[9]
412
413 fDmuon[0] = 0.0631 ;
414 fDmuon[1] = 1.4 ;
35adb638 415 fDmuon[2] = 0.0557 ;
416 fDFmuon = new TFormula("Shower shape response to muons" , "landau") ;
417 fDFmuon->SetParameters( fDmuon[0], fDmuon[1], fDmuon[2]) ;
418
35adb638 419
c947e71a 420 // x(CPV-EMC) distance gaussian parameters
421
2924941c 422// fXelectron[0] = 8.06e-2 ; fXelectron[1] = 1.00e-2; fXelectron[2] =-5.14e-2;//constant
423// fXelectron[3] = 0.202 ; fXelectron[4] = 8.15e-3; fXelectron[5] = 4.55 ;//mean
424// fXelectron[6] = 0.334 ; fXelectron[7] = 0.186 ; fXelectron[8] = 4.32e-2;//sigma
c947e71a 425
2924941c 426// //charged hadrons gaus
427// fXcharged[0] = 6.43e-3 ; fXcharged[1] =-4.19e-5; fXcharged[2] = 1.42e-3;//constant
428// fXcharged[3] = 2.75 ; fXcharged[4] =-0.40 ; fXcharged[5] = 1.68 ;//mean
429// fXcharged[6] = 3.135 ; fXcharged[7] =-9.41e-2; fXcharged[8] = 1.31e-2;//sigma
c947e71a 430
2924941c 431// // z(CPV-EMC) distance gaussian parameters
432
433// fZelectron[0] = 8.22e-2 ; fZelectron[1] = 5.11e-3; fZelectron[2] =-3.05e-2;//constant
434// fZelectron[3] = 3.09e-2 ; fZelectron[4] = 5.87e-2; fZelectron[5] =-9.49e-2;//mean
435// fZelectron[6] = 0.263 ; fZelectron[7] =-9.02e-3; fZelectron[8] = 0.151 ;//sigma
c947e71a 436
2924941c 437// //charged hadrons gaus
c947e71a 438
2924941c 439// fZcharged[0] = 1.00e-2 ; fZcharged[1] = 2.82E-4 ; fZcharged[2] = 2.87E-3 ;//constant
440// fZcharged[3] =-4.68e-2 ; fZcharged[4] =-9.21e-3 ; fZcharged[5] = 4.91e-2 ;//mean
441// fZcharged[6] = 1.425 ; fZcharged[7] =-5.90e-2 ; fZcharged[8] = 5.07e-2 ;//sigma
442
443
444 fXelectron[0] =-1.6E-2 ; fXelectron[1] = 0.77 ; fXelectron[2] =-0.15 ;//constant
445 fXelectron[3] = 0.35 ; fXelectron[4] = 0.25 ; fXelectron[5] = 4.12 ;//mean
446 fXelectron[6] = 0.30 ; fXelectron[7] = 0.11 ; fXelectron[8] = 0.16 ;//sigma
447 fXelectron[9] = 3.; //for E> fXelectron[9] parameters calculated at fXelectron[9]
448
c947e71a 449 //charged hadrons gaus
2924941c 450 fXcharged[0] = 0.14 ; fXcharged[1] =-3.0E-2 ; fXcharged[2] = 0 ;//constant
451 fXcharged[3] = 1.4 ; fXcharged[4] =-9.3E-2 ; fXcharged[5] = 1.4 ;//mean
452 fXcharged[6] = 5.7 ; fXcharged[7] = 0.27 ; fXcharged[8] =-1.8 ;//sigma
453 fXcharged[9] = 1.2; //for E> fXcharged[9] parameters calculated at fXcharged[9]
454
455 // z(CPV-EMC) distance gaussian parameters
c947e71a 456
2924941c 457 fZelectron[0] = 0.49 ; fZelectron[1] = 0.53 ; fZelectron[2] =-9.8E-2 ;//constant
458 fZelectron[3] = 2.8E-2 ; fZelectron[4] = 5.0E-2 ; fZelectron[5] =-8.2E-2 ;//mean
459 fZelectron[6] = 0.25 ; fZelectron[7] =-1.7E-2 ; fZelectron[8] = 0.17 ;//sigma
460 fZelectron[9] = 3.; //for E> fZelectron[9] parameters calculated at fZelectron[9]
461
462 //charged hadrons gaus
c947e71a 463
2924941c 464 fZcharged[0] = 0.46 ; fZcharged[1] =-0.65 ; fZcharged[2] = 0.52 ;//constant
465 fZcharged[3] = 1.1E-2 ; fZcharged[4] = 0. ; fZcharged[5] = 0. ;//mean
466 fZcharged[6] = 0.60 ; fZcharged[7] =-8.2E-2 ; fZcharged[8] = 0.45 ;//sigma
467 fZcharged[9] = 1.2; //for E> fXcharged[9] parameters calculated at fXcharged[9]
468
fb7b51ad 469 //Threshold to differentiate between charged and neutral
470 fChargedNeutralThreshold = 1e-5;
2924941c 471 fTOFEnThreshold = 2; //Maximum energy to use TOF
472 fDispEnThreshold = 0.5; //Minimum energy to use shower shape
473 fDispMultThreshold = 3; //Minimum multiplicity to use shower shape
fb7b51ad 474
475 //Weight to hadrons recontructed energy
476
477 fERecWeightPar[0] = 0.32 ;
478 fERecWeightPar[1] = 3.8 ;
479 fERecWeightPar[2] = 5.4E-3 ;
480 fERecWeightPar[3] = 5.6E-2 ;
481 fERecWeight = new TFormula("Weight for hadrons" , "[0]*exp(-x*[1])+[2]*exp(-x*[3])") ;
482 fERecWeight ->SetParameters(fERecWeightPar[0],fERecWeightPar[1] ,fERecWeightPar[2] ,fERecWeightPar[3]) ;
483
484
304864ab 485 for (Int_t i =0; i< AliPID::kSPECIESN ; i++)
35adb638 486 fInitPID[i] = 1.;
fb7b51ad 487
8d0f3f77 488}
489
88cb7938 490//________________________________________________________________________
eabde521 491void AliPHOSPIDv1::Exec(Option_t *option)
88cb7938 492{
eabde521 493 // Steering method to perform particle reconstruction and identification
494 // for the event range from fFirstEvent to fLastEvent.
495 // This range is optionally set by SetEventRange().
496 // if fLastEvent=-1 (by default), then process events until the end.
61d3d6aa 497
88cb7938 498 if(strstr(option,"tim"))
499 gBenchmark->Start("PHOSPID");
500
501 if(strstr(option,"print")) {
502 Print() ;
503 return ;
504 }
505
506
adcca1e6 507 AliPHOSGetter * gime = AliPHOSGetter::Instance() ;
88cb7938 508
71cee46d 509 if (fLastEvent == -1)
510 fLastEvent = gime->MaxEvent() - 1 ;
511 else
512 fLastEvent = TMath::Min(fLastEvent,gime->MaxEvent());
eabde521 513 Int_t nEvents = fLastEvent - fFirstEvent + 1;
88cb7938 514
71cee46d 515 Int_t ievent ;
516 for (ievent = fFirstEvent; ievent <= fLastEvent; ievent++) {
88cb7938 517 gime->Event(ievent,"TR") ;
518 if(gime->TrackSegments() && //Skip events, where no track segments made
519 gime->TrackSegments()->GetEntriesFast()) {
7fb46731 520
407d15b3 521 GetVertex() ;
88cb7938 522 MakeRecParticles() ;
35adb638 523
524 if(fBayesian)
525 MakePID() ;
526
90cceaf6 527 WriteRecParticles();
88cb7938 528 if(strstr(option,"deb"))
529 PrintRecParticles(option) ;
530 //increment the total number of rec particles per run
531 fRecParticlesInRun += gime->RecParticles()->GetEntriesFast() ;
532 }
533 }
ff417097 534 if(strstr(option,"deb"))
535 PrintRecParticles(option);
88cb7938 536 if(strstr(option,"tim")){
537 gBenchmark->Stop("PHOSPID");
351dd634 538 AliInfo(Form("took %f seconds for PID %f seconds per event",
88cb7938 539 gBenchmark->GetCpuTime("PHOSPID"),
351dd634 540 gBenchmark->GetCpuTime("PHOSPID")/nEvents)) ;
88cb7938 541 }
adcca1e6 542 if(fWrite)
543 Unload();
88cb7938 544}
545
35adb638 546//________________________________________________________________________
17323043 547Double_t AliPHOSPIDv1::GausF(Double_t x, Double_t y, Double_t * par)
35adb638 548{
c947e71a 549 //Given the energy x and the parameter y (tof, shower dispersion or cpv-emc distance),
550 //this method returns a density probability of this parameter, given by a gaussian
551 //function whose parameters depend with the energy with a function: a/(x*x)+b/x+b
2924941c 552 //Float_t xorg = x;
553 if (x > par[9]) x = par[9];
554
555 //Double_t cnt = par[1] / (x*x) + par[2] / x + par[0] ;
556 Double_t cnt = par[0] + par[1] * x + par[2] * x * x ;
35adb638 557 Double_t mean = par[4] / (x*x) + par[5] / x + par[3] ;
558 Double_t sigma = par[7] / (x*x) + par[8] / x + par[6] ;
c947e71a 559
2924941c 560// if(xorg > 30)
561// cout<<"En_in = "<<xorg<<"; En_out = "<<x<<"; cnt = "<<cnt
562// <<"; mean = "<<mean<<"; sigma = "<<sigma<<endl;
563
35adb638 564 // Double_t arg = - (y-mean) * (y-mean) / (2*sigma*sigma) ;
565 // return cnt * TMath::Exp(arg) ;
c947e71a 566 if(TMath::Abs(sigma) > 1.e-10){
acb5beb7 567 return cnt*TMath::Gaus(y,mean,sigma);
35adb638 568 }
569 else
570 return 0.;
c947e71a 571
35adb638 572}
573//________________________________________________________________________
17323043 574Double_t AliPHOSPIDv1::GausPol2(Double_t x, Double_t y, Double_t * par)
35adb638 575{
c947e71a 576 //Given the energy x and the parameter y (tof, shower dispersion or cpv-emc distance),
577 //this method returns a density probability of this parameter, given by a gaussian
578 //function whose parameters depend with the energy like second order polinomial
579
35adb638 580 Double_t cnt = par[0] + par[1] * x + par[2] * x * x ;
581 Double_t mean = par[3] + par[4] * x + par[5] * x * x ;
582 Double_t sigma = par[6] + par[7] * x + par[8] * x * x ;
583
c947e71a 584 if(TMath::Abs(sigma) > 1.e-10){
acb5beb7 585 return cnt*TMath::Gaus(y,mean,sigma);
35adb638 586 }
587 else
588 return 0.;
c947e71a 589
590
591
35adb638 592}
593
69183710 594//____________________________________________________________________________
e3817e5f 595const TString AliPHOSPIDv1::GetFileNamePrincipal(TString particle) const
148b2bba 596{
e3817e5f 597 //Get file name that contains the PCA for a particle ("photon or pi0")
598 particle.ToLower();
599 TString name;
351dd634 600 if (particle=="photon")
601 name = fFileNamePrincipalPhoton ;
602 else if (particle=="pi0" )
603 name = fFileNamePrincipalPi0 ;
604 else
605 AliError(Form("Wrong particle name: %s (choose from pi0/photon)\n",
606 particle.Data()));
e3817e5f 607 return name;
608}
bc0c084c 609
e3817e5f 610//____________________________________________________________________________
fc7e2f43 611Float_t AliPHOSPIDv1::GetParameterCalibration(Int_t i) const
e3817e5f 612{
613 // Get the i-th parameter "Calibration"
614 Float_t param = 0.;
351dd634 615 if (i>2 || i<0) {
616 AliError(Form("Invalid parameter number: %d",i));
617 } else
e3817e5f 618 param = (*fParameters)(0,i);
619 return param;
620}
bc0c084c 621
88cb7938 622//____________________________________________________________________________
fc7e2f43 623Float_t AliPHOSPIDv1::GetCalibratedEnergy(Float_t e) const
88cb7938 624{
625// It calibrates Energy depending on the recpoint energy.
626// The energy of the reconstructed cluster is corrected with
627// the formula A + B* E + C* E^2, whose parameters where obtained
628// through the study of the reconstructed energy distribution of
629// monoenergetic photons.
630
631 Float_t p[]={0.,0.,0.};
632 for (Int_t i=0; i<3; i++) p[i] = GetParameterCalibration(i);
633 Float_t enerec = p[0] + p[1]*e + p[2]*e*e;
634 return enerec ;
635
636}
637
e3817e5f 638//____________________________________________________________________________
fc7e2f43 639Float_t AliPHOSPIDv1::GetParameterCpv2Emc(Int_t i, TString axis) const
e3817e5f 640{
641 // Get the i-th parameter "CPV-EMC distance" for the specified axis
642 Float_t param = 0.;
351dd634 643 if(i>2 || i<0) {
644 AliError(Form("Invalid parameter number: %d",i));
645 } else {
e3817e5f 646 axis.ToLower();
351dd634 647 if (axis == "x")
648 param = (*fParameters)(1,i);
649 else if (axis == "z")
650 param = (*fParameters)(2,i);
651 else {
652 AliError(Form("Invalid axis name: %s",axis.Data()));
653 }
e3817e5f 654 }
655 return param;
656}
657
658//____________________________________________________________________________
fc7e2f43 659Float_t AliPHOSPIDv1::GetCpv2EmcDistanceCut(TString axis, Float_t e) const
e3817e5f 660{
88cb7938 661 // Get CpvtoEmcDistance Cut depending on the cluster energy, axis and
662 // Purity-Efficiency point
663
664 axis.ToLower();
665 Float_t p[]={0.,0.,0.};
666 for (Int_t i=0; i<3; i++) p[i] = GetParameterCpv2Emc(i,axis);
667 Float_t sig = p[0] + TMath::Exp(p[1] - p[2]*e);
668 return sig;
e3817e5f 669}
670
88cb7938 671//____________________________________________________________________________
fc7e2f43 672Float_t AliPHOSPIDv1::GetEllipseParameter(TString particle, TString param, Float_t e) const
88cb7938 673{
674 // Calculates the parameter param of the ellipse
e3817e5f 675
676 particle.ToLower();
677 param. ToLower();
88cb7938 678 Float_t p[4]={0.,0.,0.,0.};
679 Float_t value = 0.0;
680 for (Int_t i=0; i<4; i++) p[i] = GetParameterToCalculateEllipse(particle,param,i);
681 if (particle == "photon") {
682 if (param.Contains("a")) e = TMath::Min((Double_t)e,70.);
683 else if (param.Contains("b")) e = TMath::Min((Double_t)e,70.);
684 else if (param.Contains("x0")) e = TMath::Max((Double_t)e,1.1);
685 }
e3817e5f 686
443caba9 687 if (particle == "photon")
688 value = p[0]/TMath::Sqrt(e) + p[1]*e + p[2]*e*e + p[3];
689 else if (particle == "pi0")
690 value = p[0] + p[1]*e + p[2]*e*e;
691
88cb7938 692 return value;
e3817e5f 693}
694
695//_____________________________________________________________________________
fc7e2f43 696Float_t AliPHOSPIDv1::GetParameterPhotonBoundary (Int_t i) const
e3817e5f 697{
698 // Get the parameter "i" to calculate the boundary on the moment M2x
699 // for photons at high p_T
700 Float_t param = 0;
351dd634 701 if (i>3 || i<0) {
702 AliError(Form("Wrong parameter number: %d\n",i));
703 } else
e3817e5f 704 param = (*fParameters)(14,i) ;
705 return param;
148b2bba 706}
e3817e5f 707
148b2bba 708//____________________________________________________________________________
fc7e2f43 709Float_t AliPHOSPIDv1::GetParameterPi0Boundary (Int_t i) const
e3817e5f 710{
711 // Get the parameter "i" to calculate the boundary on the moment M2x
712 // for pi0 at high p_T
713 Float_t param = 0;
351dd634 714 if (i>2 || i<0) {
715 AliError(Form("Wrong parameter number: %d\n",i));
716 } else
e3817e5f 717 param = (*fParameters)(15,i) ;
718 return param;
719}
148b2bba 720
e3817e5f 721//____________________________________________________________________________
fc7e2f43 722Float_t AliPHOSPIDv1::GetParameterTimeGate(Int_t i) const
e3817e5f 723{
88cb7938 724 // Get TimeGate parameter depending on Purity-Efficiency i:
725 // i=0 - Low purity, i=1 - Medium purity, i=2 - High purity
726 Float_t param = 0.;
351dd634 727 if(i>2 || i<0) {
728 AliError(Form("Invalid Efficiency-Purity choice %d",i));
729 } else
88cb7938 730 param = (*fParameters)(3,i) ;
731 return param;
e3817e5f 732}
733
148b2bba 734//_____________________________________________________________________________
fc7e2f43 735Float_t AliPHOSPIDv1::GetParameterToCalculateEllipse(TString particle, TString param, Int_t i) const
88cb7938 736{
737 // Get the parameter "i" that is needed to calculate the ellipse
738 // parameter "param" for the particle "particle" ("photon" or "pi0")
739
e3817e5f 740 particle.ToLower();
741 param. ToLower();
88cb7938 742 Int_t offset = -1;
351dd634 743 if (particle == "photon")
744 offset=0;
745 else if (particle == "pi0")
746 offset=5;
e3817e5f 747 else
351dd634 748 AliError(Form("Wrong particle name: %s (choose from pi0/photon)\n",
749 particle.Data()));
88cb7938 750
751 Int_t p= -1;
752 Float_t par = 0;
e3817e5f 753
754 if (param.Contains("a")) p=4+offset;
755 else if(param.Contains("b")) p=5+offset;
756 else if(param.Contains("c")) p=6+offset;
757 else if(param.Contains("x0"))p=7+offset;
758 else if(param.Contains("y0"))p=8+offset;
12022e83 759
351dd634 760 if (i>4 || i<0) {
761 AliError(Form("No parameter with index %d", i)) ;
762 } else if (p==-1) {
763 AliError(Form("No parameter with name %s", param.Data() )) ;
764 } else
88cb7938 765 par = (*fParameters)(p,i) ;
766
767 return par;
12022e83 768}
769
12022e83 770
26aa7e4a 771//DP____________________________________________________________________________
772//Float_t AliPHOSPIDv1::GetDistance(AliPHOSEmcRecPoint * emc,AliPHOSCpvRecPoint * cpv, Option_t * axis)const
773//{
774// // Calculates the distance between the EMC RecPoint and the PPSD RecPoint
775//
776// const AliPHOSGeometry * geom = AliPHOSGetter::Instance()->PHOSGeometry() ;
777// TVector3 vecEmc ;
778// TVector3 vecCpv ;
779// if(cpv){
780// emc->GetLocalPosition(vecEmc) ;
781// cpv->GetLocalPosition(vecCpv) ;
782//
783// if(emc->GetPHOSMod() == cpv->GetPHOSMod()){
784// // Correct to difference in CPV and EMC position due to different distance to center.
785// // we assume, that particle moves from center
786// Float_t dCPV = geom->GetIPtoOuterCoverDistance();
787// Float_t dEMC = geom->GetIPtoCrystalSurface() ;
788// dEMC = dEMC / dCPV ;
789// vecCpv = dEMC * vecCpv - vecEmc ;
790// if (axis == "X") return vecCpv.X();
791// if (axis == "Y") return vecCpv.Y();
792// if (axis == "Z") return vecCpv.Z();
793// if (axis == "R") return vecCpv.Mag();
794// }
795// return 100000000 ;
796// }
797// return 100000000 ;
798//}
12022e83 799//____________________________________________________________________________
26aa7e4a 800Int_t AliPHOSPIDv1::GetCPVBit(AliPHOSTrackSegment * ts, Int_t effPur, Float_t e) const
bc0c084c 801{
c947e71a 802 //Calculates the pid bit for the CPV selection per each purity.
e3817e5f 803 if(effPur>2 || effPur<0)
351dd634 804 AliError(Form("Invalid Efficiency-Purity choice %d",effPur));
26aa7e4a 805
407d15b3 806//DP if(ts->GetCpvIndex()<0)
807//DP return 1 ; //no CPV cluster
bc0c084c 808
e3817e5f 809 Float_t sigX = GetCpv2EmcDistanceCut("X",e);
810 Float_t sigZ = GetCpv2EmcDistanceCut("Z",e);
bc0c084c 811
26aa7e4a 812 Float_t deltaX = TMath::Abs(ts->GetCpvDistance("X"));
813 Float_t deltaZ = TMath::Abs(ts->GetCpvDistance("Z"));
407d15b3 814// Info("GetCPVBit"," xdist %f, sigx %f, zdist %f, sigz %f",deltaX, sigX, deltaZ,sigZ) ;
7fb46731 815
816 //if(deltaX>sigX*(effPur+1))
817 //if((deltaX>sigX*(effPur+1)) || (deltaZ>sigZ*(effPur+1)))
818 if((deltaX>sigX*(effPur+1)) && (deltaZ>sigZ*(effPur+1)))
bc0c084c 819 return 1;//Neutral
820 else
821 return 0;//Charged
bc0c084c 822}
69183710 823
6ad0bfa0 824//____________________________________________________________________________
fc7e2f43 825Int_t AliPHOSPIDv1::GetPrincipalBit(TString particle, const Double_t* p, Int_t effPur, Float_t e)const
148b2bba 826{
50739f15 827 //Is the particle inside de PCA ellipse?
581354c5 828
e3817e5f 829 particle.ToLower();
830 Int_t prinbit = 0 ;
7fb46731 831 Float_t a = GetEllipseParameter(particle,"a" , e);
832 Float_t b = GetEllipseParameter(particle,"b" , e);
833 Float_t c = GetEllipseParameter(particle,"c" , e);
e3817e5f 834 Float_t x0 = GetEllipseParameter(particle,"x0", e);
835 Float_t y0 = GetEllipseParameter(particle,"y0", e);
836
837 Float_t r = TMath::Power((p[0] - x0)/a,2) +
838 TMath::Power((p[1] - y0)/b,2) +
839 c*(p[0] - x0)*(p[1] - y0)/(a*b) ;
50739f15 840 //3 different ellipses defined
e3817e5f 841 if((effPur==2) && (r<1./2.)) prinbit= 1;
842 if((effPur==1) && (r<2. )) prinbit= 1;
843 if((effPur==0) && (r<9./2.)) prinbit= 1;
50739f15 844
581354c5 845 if(r<0)
351dd634 846 AliError("Negative square?") ;
1f0e7ccd 847
848 return prinbit;
148b2bba 849
148b2bba 850}
1f0e7ccd 851//____________________________________________________________________________
fc7e2f43 852Int_t AliPHOSPIDv1::GetHardPhotonBit(AliPHOSEmcRecPoint * emc) const
1f0e7ccd 853{
e3817e5f 854 // Set bit for identified hard photons (E > 30 GeV)
855 // if the second moment M2x is below the boundary
856
857 Float_t e = emc->GetEnergy();
858 if (e < 30.0) return 0;
859 Float_t m2x = emc->GetM2x();
860 Float_t m2xBoundary = GetParameterPhotonBoundary(0) *
861 TMath::Exp(-TMath::Power(e-GetParameterPhotonBoundary(1),2)/2.0/
862 TMath::Power(GetParameterPhotonBoundary(2),2)) +
863 GetParameterPhotonBoundary(3);
351dd634 864 AliDebug(1, Form("GetHardPhotonBit","E=%f, m2x=%f, boundary=%f",
865 e,m2x,m2xBoundary));
e3817e5f 866 if (m2x < m2xBoundary)
867 return 1;// A hard photon
868 else
869 return 0;// Not a hard photon
1f0e7ccd 870}
92f521a9 871
e3817e5f 872//____________________________________________________________________________
fc7e2f43 873Int_t AliPHOSPIDv1::GetHardPi0Bit(AliPHOSEmcRecPoint * emc) const
e3817e5f 874{
875 // Set bit for identified hard pi0 (E > 30 GeV)
876 // if the second moment M2x is above the boundary
877
878 Float_t e = emc->GetEnergy();
879 if (e < 30.0) return 0;
880 Float_t m2x = emc->GetM2x();
881 Float_t m2xBoundary = GetParameterPi0Boundary(0) +
882 e * GetParameterPi0Boundary(1);
351dd634 883 AliDebug(1,Form("E=%f, m2x=%f, boundary=%f",e,m2x,m2xBoundary));
e3817e5f 884 if (m2x > m2xBoundary)
885 return 1;// A hard pi0
bc0c084c 886 else
e3817e5f 887 return 0;// Not a hard pi0
f0a4c9e9 888}
e3817e5f 889
890//____________________________________________________________________________
8d4608b5 891TVector3 AliPHOSPIDv1::GetMomentumDirection(AliPHOSEmcRecPoint * emc, AliPHOSCpvRecPoint * )const
88cb7938 892{
893 // Calculates the momentum direction:
894 // 1. if only a EMC RecPoint, direction is given by IP and this RecPoint
895 // 2. if a EMC RecPoint and CPV RecPoint, direction is given by the line through the 2 recpoints
896 // However because of the poor position resolution of PPSD the direction is always taken as if we were
897 // in case 1.
f0a4c9e9 898
88cb7938 899 TVector3 dir(0,0,0) ;
e8d02863 900 TMatrixF dummy ;
bf8f1fbd 901
fb7b51ad 902 emc->GetGlobalPosition(dir, dummy) ;
e3817e5f 903
407d15b3 904 TVector3 local ;
905 emc->GetLocalPosition(local) ;
906
907 AliPHOSGeometry * phosgeom = AliPHOSGeometry::GetInstance() ;
908 //Correct for the non-perpendicular incidence
909 // Correction for the depth of the shower starting point (TDR p 127)
910 Float_t para = 0.925 ;
911 Float_t parb = 6.52 ;
912
913 //Remove Old correction (vertex at 0,0,0)
914 TVector3 vtxOld(0.,0.,0.) ;
915 TVector3 vInc ;
916 Float_t x=local.X() ;
917 Float_t z=local.Z() ;
918 phosgeom->GetIncidentVector(vtxOld,emc->GetPHOSMod(),x,z,vInc) ;
919 Float_t depthxOld = 0.;
920 Float_t depthzOld = 0.;
921 Float_t energy = emc->GetEnergy() ;
922 if (energy > 0 && vInc.Y()!=0.) {
753b19cd 923 depthxOld = ( para * TMath::Log(energy) + parb ) * vInc.X()/TMath::Abs(vInc.Y()) ;
924 depthzOld = ( para * TMath::Log(energy) + parb ) * vInc.Z()/TMath::Abs(vInc.Y()) ;
7fb46731 925 }
adcca1e6 926 else{
407d15b3 927 AliError("Cluster with zero energy \n");
928 }
929 //Apply Real vertex
930 phosgeom->GetIncidentVector(fVtx,emc->GetPHOSMod(),x,z,vInc) ;
931 Float_t depthx = 0.;
932 Float_t depthz = 0.;
933 if (energy > 0 && vInc.Y()!=0.) {
934 depthx = ( para * TMath::Log(energy) + parb ) * vInc.X()/vInc.Y() ;
935 depthz = ( para * TMath::Log(energy) + parb ) * vInc.Z()/vInc.Y() ;
adcca1e6 936 }
407d15b3 937
938 dir.SetXYZ(dir.X()-(depthxOld-depthx)*TMath::Sin(dir.Phi()),
939 dir.Y()-(depthxOld-depthx)*TMath::Cos(dir.Phi()),
940 dir.Z()+depthzOld-depthz) ;
941
942 //Correct for the vertex position
943 dir = dir - fVtx ;
7fb46731 944 dir.SetMag(1.) ;
e3817e5f 945
88cb7938 946 return dir ;
7b7c1533 947}
948
35adb638 949//________________________________________________________________________
17323043 950Double_t AliPHOSPIDv1::LandauF(Double_t x, Double_t y, Double_t * par)
35adb638 951{
c947e71a 952 //Given the energy x and the parameter y (tof, shower dispersion or cpv-emc distance),
953 //this method returns a density probability of this parameter, given by a landau
954 //function whose parameters depend with the energy with a function: a/(x*x)+b/x+b
955
2924941c 956 if (x > par[9]) x = par[9];
957
958 //Double_t cnt = par[1] / (x*x) + par[2] / x + par[0] ;
959 Double_t cnt = par[0] + par[1] * x + par[2] * x * x ;
35adb638 960 Double_t mean = par[4] / (x*x) + par[5] / x + par[3] ;
961 Double_t sigma = par[7] / (x*x) + par[8] / x + par[6] ;
c947e71a 962
963 if(TMath::Abs(sigma) > 1.e-10){
acb5beb7 964 return cnt*TMath::Landau(y,mean,sigma);
35adb638 965 }
966 else
967 return 0.;
968
969}
970//________________________________________________________________________
17323043 971Double_t AliPHOSPIDv1::LandauPol2(Double_t x, Double_t y, Double_t * par)
35adb638 972{
c947e71a 973
974 //Given the energy x and the parameter y (tof, shower dispersion or cpv-emc distance),
975 //this method returns a density probability of this parameter, given by a landau
976 //function whose parameters depend with the energy like second order polinomial
977
35adb638 978 Double_t cnt = par[2] * (x*x) + par[1] * x + par[0] ;
c947e71a 979 Double_t mean = par[5] * (x*x) + par[4] * x + par[3] ;
980 Double_t sigma = par[8] * (x*x) + par[7] * x + par[6] ;
35adb638 981
c947e71a 982 if(TMath::Abs(sigma) > 1.e-10){
acb5beb7 983 return cnt*TMath::Landau(y,mean,sigma);
35adb638 984 }
985 else
986 return 0.;
c947e71a 987
988
35adb638 989}
990// //________________________________________________________________________
991// Double_t AliPHOSPIDv1::ChargedHadronDistProb(Double_t x, Double_t y, Double_t * parg, Double_t * parl)
992// {
993// Double_t cnt = 0.0 ;
994// Double_t mean = 0.0 ;
995// Double_t sigma = 0.0 ;
996// Double_t arg = 0.0 ;
997// if (y < parl[4] / (x*x) + parl[5] / x + parl[3]){
998// cnt = parg[1] / (x*x) + parg[2] / x + parg[0] ;
999// mean = parg[4] / (x*x) + parg[5] / x + parg[3] ;
1000// sigma = parg[7] / (x*x) + parg[8] / x + parg[6] ;
1001// TF1 * f = new TF1("gaus","gaus",0.,100.);
1002// f->SetParameters(cnt,mean,sigma);
1003// arg = f->Eval(y) ;
1004// }
1005// else{
1006// cnt = parl[1] / (x*x) + parl[2] / x + parl[0] ;
1007// mean = parl[4] / (x*x) + parl[5] / x + parl[3] ;
1008// sigma = parl[7] / (x*x) + parl[8] / x + parl[6] ;
1009// TF1 * f = new TF1("landau","landau",0.,100.);
1010// f->SetParameters(cnt,mean,sigma);
1011// arg = f->Eval(y) ;
1012// }
1013// // Double_t mean = par[3] + par[4] * x + par[5] * x * x ;
1014// // Double_t sigma = par[6] + par[7] * x + par[8] * x * x ;
1015
1016// //Double_t arg = -(y-mean)*(y-mean)/(2*sigma*sigma) ;
1017// //return cnt * TMath::Exp(arg) ;
1018
1019// return arg;
1020
1021// }
2cc71c1e 1022//____________________________________________________________________________
1023void AliPHOSPIDv1::MakePID()
1024{
1025 // construct the PID weight from a Bayesian Method
c947e71a 1026
304864ab 1027 const Int_t kSPECIES = AliPID::kSPECIESN ;
7fb46731 1028
1029 AliPHOSGetter * gime = AliPHOSGetter::Instance() ;
1030
1031 Int_t nparticles = gime->RecParticles()->GetEntriesFast() ;
1032
7fb46731 1033 TObjArray * emcRecPoints = gime->EmcRecPoints() ;
1034 TObjArray * cpvRecPoints = gime->CpvRecPoints() ;
1035 TClonesArray * trackSegments = gime->TrackSegments() ;
1036 if ( !emcRecPoints || !cpvRecPoints || !trackSegments ) {
1037 AliFatal("RecPoints or TrackSegments not found !") ;
1038 }
1039 TIter next(trackSegments) ;
1040 AliPHOSTrackSegment * ts ;
1041 Int_t index = 0 ;
1042
35adb638 1043 Double_t * stof[kSPECIES] ;
1044 Double_t * sdp [kSPECIES] ;
1045 Double_t * scpv[kSPECIES] ;
fb7b51ad 1046 Double_t * sw [kSPECIES] ;
35adb638 1047 //Info("MakePID","Begin MakePID");
1048
1049 for (Int_t i =0; i< kSPECIES; i++){
1050 stof[i] = new Double_t[nparticles] ;
1051 sdp [i] = new Double_t[nparticles] ;
1052 scpv[i] = new Double_t[nparticles] ;
fb7b51ad 1053 sw [i] = new Double_t[nparticles] ;
35adb638 1054 }
1055
7fb46731 1056
1057 while ( (ts = (AliPHOSTrackSegment *)next()) ) {
1058
1059 //cout<<">>>>>> Bayesian Index "<<index<<endl;
1060
1061 AliPHOSEmcRecPoint * emc = 0 ;
1062 if(ts->GetEmcIndex()>=0)
1063 emc = (AliPHOSEmcRecPoint *) emcRecPoints->At(ts->GetEmcIndex()) ;
1064
407d15b3 1065// AliPHOSCpvRecPoint * cpv = 0 ;
1066// if(ts->GetCpvIndex()>=0)
1067// cpv = (AliPHOSCpvRecPoint *) cpvRecPoints->At(ts->GetCpvIndex()) ;
1068//
1069//// Int_t track = 0 ;
1070//// track = ts->GetTrackIndex() ; //TPC tracks ?
cc1fe362 1071
7fb46731 1072 if (!emc) {
1073 AliFatal(Form("-> emc(%d) = %d", ts->GetEmcIndex(), emc )) ;
1074 }
c947e71a 1075
2924941c 1076
7fb46731 1077 // ############Tof#############################
c947e71a 1078
7fb46731 1079 // Info("MakePID", "TOF");
fb7b51ad 1080 Float_t en = emc->GetEnergy();
7fb46731 1081 Double_t time = emc->GetTime() ;
1082 // cout<<">>>>>>>Energy "<<en<<"Time "<<time<<endl;
fb7b51ad 1083
35adb638 1084 // now get the signals probability
1085 // s(pid) in the Bayesian formulation
cc1fe362 1086
304864ab 1087 stof[AliPID::kPhoton][index] = 1.;
1088 stof[AliPID::kElectron][index] = 1.;
304864ab 1089 stof[AliPID::kEleCon][index] = 1.;
7fb46731 1090 //We assing the same prob to charged hadrons, sum is 1
1091 stof[AliPID::kPion][index] = 1./3.;
1092 stof[AliPID::kKaon][index] = 1./3.;
1093 stof[AliPID::kProton][index] = 1./3.;
1094 //We assing the same prob to neutral hadrons, sum is 1
1095 stof[AliPID::kNeutron][index] = 1./2.;
1096 stof[AliPID::kKaon0][index] = 1./2.;
304864ab 1097 stof[AliPID::kMuon][index] = 1.;
2924941c 1098
1099 if(en < fTOFEnThreshold) {
7fb46731 1100
1101 Double_t pTofPion = fTFpiong ->Eval(time) ; //gaus distribution
1102 Double_t pTofKaon = 0;
1103
35adb638 1104 if(time < fTkaonl[1])
fb7b51ad 1105 pTofKaon = fTFkaong ->Eval(time) ; //gaus distribution
35adb638 1106 else
fb7b51ad 1107 pTofKaon = fTFkaonl ->Eval(time) ; //landau distribution
7fb46731 1108
1109 Double_t pTofNucleon = 0;
1110
35adb638 1111 if(time < fThhadronl[1])
7fb46731 1112 pTofNucleon = fTFhhadrong ->Eval(time) ; //gaus distribution
35adb638 1113 else
7fb46731 1114 pTofNucleon = fTFhhadronl ->Eval(time) ; //landau distribution
7fb46731 1115 //We assing the same prob to neutral hadrons, sum is the average prob
fb7b51ad 1116 Double_t pTofNeHadron = (pTofKaon + pTofNucleon)/2. ;
1117 //We assing the same prob to charged hadrons, sum is the average prob
1118 Double_t pTofChHadron = (pTofPion + pTofKaon + pTofNucleon)/3. ;
7fb46731 1119
fb7b51ad 1120 stof[AliPID::kPhoton][index] = fTFphoton ->Eval(time) ;
1121 //gaus distribution
1122 stof[AliPID::kEleCon][index] = stof[AliPID::kPhoton][index] ;
1123 //a conversion electron has the photon ToF
304864ab 1124 stof[AliPID::kMuon][index] = stof[AliPID::kPhoton][index] ;
7fb46731 1125
fb7b51ad 1126 stof[AliPID::kElectron][index] = pTofPion ;
7fb46731 1127
1128 stof[AliPID::kPion][index] = pTofChHadron ;
1129 stof[AliPID::kKaon][index] = pTofChHadron ;
1130 stof[AliPID::kProton][index] = pTofChHadron ;
1131
1132 stof[AliPID::kKaon0][index] = pTofNeHadron ;
1133 stof[AliPID::kNeutron][index] = pTofNeHadron ;
cc1fe362 1134 }
c947e71a 1135
1136 // Info("MakePID", "Dispersion");
cc1fe362 1137
7fb46731 1138 // ###########Shower shape: Dispersion####################
35adb638 1139 Float_t dispersion = emc->GetDispersion();
407d15b3 1140 //DP: Correct for non-perpendicular incidence
1141 //DP: still to be done
1142
35adb638 1143 //dispersion is not well defined if the cluster is only in few crystals
cc1fe362 1144
304864ab 1145 sdp[AliPID::kPhoton][index] = 1. ;
1146 sdp[AliPID::kElectron][index] = 1. ;
1147 sdp[AliPID::kPion][index] = 1. ;
1148 sdp[AliPID::kKaon][index] = 1. ;
1149 sdp[AliPID::kProton][index] = 1. ;
1150 sdp[AliPID::kNeutron][index] = 1. ;
1151 sdp[AliPID::kEleCon][index] = 1. ;
1152 sdp[AliPID::kKaon0][index] = 1. ;
1153 sdp[AliPID::kMuon][index] = 1. ;
c947e71a 1154
2924941c 1155 if(en > fDispEnThreshold && emc->GetMultiplicity() > fDispMultThreshold){
7fb46731 1156 sdp[AliPID::kPhoton][index] = GausF(en , dispersion, fDphoton) ;
304864ab 1157 sdp[AliPID::kElectron][index] = sdp[AliPID::kPhoton][index] ;
1158 sdp[AliPID::kPion][index] = LandauF(en , dispersion, fDhadron ) ;
1159 sdp[AliPID::kKaon][index] = sdp[AliPID::kPion][index] ;
1160 sdp[AliPID::kProton][index] = sdp[AliPID::kPion][index] ;
1161 sdp[AliPID::kNeutron][index] = sdp[AliPID::kPion][index] ;
1162 sdp[AliPID::kEleCon][index] = sdp[AliPID::kPhoton][index];
1163 sdp[AliPID::kKaon0][index] = sdp[AliPID::kPion][index] ;
fb7b51ad 1164 sdp[AliPID::kMuon][index] = fDFmuon ->Eval(dispersion) ;
1165 //landau distribution
35adb638 1166 }
cc1fe362 1167
7fb46731 1168// Info("MakePID","multiplicity %d, dispersion %f", emc->GetMultiplicity(), dispersion);
1169// Info("MakePID","ss: photon %f, hadron %f ", sdp[AliPID::kPhoton][index], sdp[AliPID::kPion][index]);
c947e71a 1170// cout<<">>>>>multiplicity "<<emc->GetMultiplicity()<<", dispersion "<< dispersion<<endl ;
304864ab 1171// cout<<"<<<<<ss: photon "<<sdp[AliPID::kPhoton][index]<<", hadron "<<sdp[AliPID::kPion][index]<<endl;
c947e71a 1172
7fb46731 1173 //########## CPV-EMC Distance#######################
1174 // Info("MakePID", "Distance");
fb7b51ad 1175
26aa7e4a 1176 Float_t x = TMath::Abs(ts->GetCpvDistance("X")) ;
1177 Float_t z = ts->GetCpvDistance("Z") ;
fb7b51ad 1178
7fb46731 1179 Double_t pcpv = 0 ;
c947e71a 1180 Double_t pcpvneutral = 0. ;
7fb46731 1181
1182 Double_t elprobx = GausF(en , x, fXelectron) ;
1183 Double_t elprobz = GausF(en , z, fZelectron) ;
1184 Double_t chprobx = GausF(en , x, fXcharged) ;
1185 Double_t chprobz = GausF(en , z, fZcharged) ;
c947e71a 1186 Double_t pcpvelectron = elprobx * elprobz;
1187 Double_t pcpvcharged = chprobx * chprobz;
7fb46731 1188
1189// cout<<">>>>energy "<<en<<endl;
c947e71a 1190// cout<<">>>>electron : x "<<x<<" xprob "<<elprobx<<" z "<<z<<" zprob "<<elprobz<<endl;
1191// cout<<">>>>hadron : x "<<x<<" xprob "<<chprobx<<" z "<<z<<" zprob "<<chprobz<<endl;
1192// cout<<">>>>electron : px*pz "<<pcpvelectron <<" hadron: px*pz "<<pcpvcharged<<endl;
1193
2924941c 1194 // Is neutral or charged?
35adb638 1195 if(pcpvelectron >= pcpvcharged)
1196 pcpv = pcpvelectron ;
1197 else
1198 pcpv = pcpvcharged ;
1199
fb7b51ad 1200 if(pcpv < fChargedNeutralThreshold)
35adb638 1201 {
1202 pcpvneutral = 1. ;
1203 pcpvcharged = 0. ;
1204 pcpvelectron = 0. ;
1205 }
c947e71a 1206 // else
1207 // cout<<">>>>>>>>>>>CHARGED>>>>>>>>>>>"<<endl;
35adb638 1208
304864ab 1209 scpv[AliPID::kPion][index] = pcpvcharged ;
1210 scpv[AliPID::kKaon][index] = pcpvcharged ;
1211 scpv[AliPID::kProton][index] = pcpvcharged ;
7fb46731 1212
1213 scpv[AliPID::kMuon][index] = pcpvelectron ;
304864ab 1214 scpv[AliPID::kElectron][index] = pcpvelectron ;
304864ab 1215 scpv[AliPID::kEleCon][index] = pcpvelectron ;
7fb46731 1216
1217 scpv[AliPID::kPhoton][index] = pcpvneutral ;
1218 scpv[AliPID::kNeutron][index] = pcpvneutral ;
304864ab 1219 scpv[AliPID::kKaon0][index] = pcpvneutral ;
7fb46731 1220
35adb638 1221
1222 // Info("MakePID", "CPV passed");
c947e71a 1223
7fb46731 1224 //############## Pi0 #############################
304864ab 1225 stof[AliPID::kPi0][index] = 0. ;
1226 scpv[AliPID::kPi0][index] = 0. ;
1227 sdp [AliPID::kPi0][index] = 0. ;
c947e71a 1228
35adb638 1229 if(en > 30.){
1230 // pi0 are detected via decay photon
2924941c 1231 stof[AliPID::kPi0][index] = stof[AliPID::kPhoton][index];
304864ab 1232 scpv[AliPID::kPi0][index] = pcpvneutral ;
2924941c 1233 if(emc->GetMultiplicity() > fDispMultThreshold)
1234 sdp [AliPID::kPi0][index] = GausF(en , dispersion, fDpi0) ;
1235 //sdp [AliPID::kPi0][index] = GausPol2(en , dispersion, fDpi0) ;
1236// cout<<"E = "<<en<<" GeV; disp = "<<dispersion<<"; mult = "
1237// <<emc->GetMultiplicity()<<endl;
1238// cout<<"PDF: photon = "<<sdp [AliPID::kPhoton][index]<<"; pi0 = "
1239// <<sdp [AliPID::kPi0][index]<<endl;
35adb638 1240 }
1241
2924941c 1242
7fb46731 1243
2924941c 1244
7fb46731 1245 //############## muon #############################
1246
35adb638 1247 if(en > 0.5){
1248 //Muons deposit few energy
304864ab 1249 scpv[AliPID::kMuon][index] = 0 ;
1250 stof[AliPID::kMuon][index] = 0 ;
1251 sdp [AliPID::kMuon][index] = 0 ;
c947e71a 1252 }
1253
fb7b51ad 1254 //Weight to apply to hadrons due to energy reconstruction
1255
1256 Float_t weight = fERecWeight ->Eval(en) ;
1257
1258 sw[AliPID::kPhoton][index] = 1. ;
1259 sw[AliPID::kElectron][index] = 1. ;
1260 sw[AliPID::kPion][index] = weight ;
1261 sw[AliPID::kKaon][index] = weight ;
1262 sw[AliPID::kProton][index] = weight ;
1263 sw[AliPID::kNeutron][index] = weight ;
1264 sw[AliPID::kEleCon][index] = 1. ;
1265 sw[AliPID::kKaon0][index] = weight ;
1266 sw[AliPID::kMuon][index] = weight ;
1267 sw[AliPID::kPi0][index] = 1. ;
1268
7fb46731 1269// if(en > 0.5){
1270// cout<<"######################################################"<<endl;
1271// //cout<<"MakePID: energy "<<en<<", tof "<<time<<", distance "<<distance<<", dispersion "<<dispersion<<endl ;
1272// cout<<"MakePID: energy "<<en<<", tof "<<time<<", dispersion "<<dispersion<<", x "<<x<<", z "<<z<<endl ;
1273// cout<<">>>>>multiplicity "<<emc->GetMultiplicity()<<endl;
1274// cout<<">>>>electron : xprob "<<elprobx<<" zprob "<<elprobz<<endl;
1275// cout<<">>>>hadron : xprob "<<chprobx<<" zprob "<<chprobz<<endl;
1276// cout<<">>>>electron : px*pz "<<pcpvelectron <<" hadron: px*pz "<<pcpvcharged<<endl;
c947e71a 1277
2924941c 1278// cout<<"Photon , pid "<< fInitPID[AliPID::kPhoton]<<" tof "<<stof[AliPID::kPhoton][index]
1279// <<", cpv "<<scpv[AliPID::kPhoton][index]<<", ss "<<sdp[AliPID::kPhoton][index]<<endl;
7fb46731 1280// cout<<"EleCon , pid "<< fInitPID[AliPID::kEleCon]<<", tof "<<stof[AliPID::kEleCon][index]
1281// <<", cpv "<<scpv[AliPID::kEleCon][index]<<" ss "<<sdp[AliPID::kEleCon][index]<<endl;
1282// cout<<"Electron , pid "<< fInitPID[AliPID::kElectron]<<", tof "<<stof[AliPID::kElectron][index]
1283// <<", cpv "<<scpv[AliPID::kElectron][index]<<" ss "<<sdp[AliPID::kElectron][index]<<endl;
1284// cout<<"Muon , pid "<< fInitPID[AliPID::kMuon]<<", tof "<<stof[AliPID::kMuon][index]
1285// <<", cpv "<<scpv[AliPID::kMuon][index]<<" ss "<<sdp[AliPID::kMuon][index]<<endl;
2924941c 1286// cout<<"Pi0 , pid "<< fInitPID[AliPID::kPi0]<<", tof "<<stof[AliPID::kPi0][index]
1287// <<", cpv "<<scpv[AliPID::kPi0][index]<<" ss "<<sdp[AliPID::kPi0][index]<<endl;
7fb46731 1288// cout<<"Pion , pid "<< fInitPID[AliPID::kPion]<<", tof "<<stof[AliPID::kPion][index]
1289// <<", cpv "<<scpv[AliPID::kPion][index]<<" ss "<<sdp[AliPID::kPion][index]<<endl;
1290// cout<<"Kaon0 , pid "<< fInitPID[AliPID::kKaon0]<<", tof "<<stof[AliPID::kKaon0][index]
1291// <<", cpv "<<scpv[AliPID::kKaon0][index]<<" ss "<<sdp[AliPID::kKaon0][index]<<endl;
1292// cout<<"Kaon , pid "<< fInitPID[AliPID::kKaon]<<", tof "<<stof[AliPID::kKaon][index]
1293// <<", cpv "<<scpv[AliPID::kKaon][index]<<" ss "<<sdp[AliPID::kKaon][index]<<endl;
1294// cout<<"Neutron , pid "<< fInitPID[AliPID::kNeutron]<<", tof "<<stof[AliPID::kNeutron][index]
1295// <<", cpv "<<scpv[AliPID::kNeutron][index]<<" ss "<<sdp[AliPID::kNeutron][index]<<endl;
1296// cout<<"Proton , pid "<< fInitPID[AliPID::kProton]<<", tof "<<stof[AliPID::kProton][index]
1297// <<", cpv "<<scpv[AliPID::kProton][index]<<" ss "<<sdp[AliPID::kProton][index]<<endl;
1298// cout<<"######################################################"<<endl;
1299// }
1300 index++;
cc1fe362 1301 }
35adb638 1302
1303 //for (index = 0 ; index < kSPECIES ; index++)
1304 // pid[index] /= nparticles ;
1305
7fb46731 1306
35adb638 1307 // Info("MakePID", "Total Probability calculation");
1308
cc1fe362 1309 for(index = 0 ; index < nparticles ; index ++) {
2924941c 1310
1311 AliPHOSRecParticle * recpar = gime->RecParticle(index) ;
1312
1313 //Conversion electron?
1314
1315 if(recpar->IsEleCon()){
1316 fInitPID[AliPID::kEleCon] = 1. ;
1317 fInitPID[AliPID::kPhoton] = 0. ;
1318 fInitPID[AliPID::kElectron] = 0. ;
1319 }
1320 else{
1321 fInitPID[AliPID::kEleCon] = 0. ;
1322 fInitPID[AliPID::kPhoton] = 1. ;
1323 fInitPID[AliPID::kElectron] = 1. ;
1324 }
1325 // fInitPID[AliPID::kEleCon] = 0. ;
1326
1327
cc1fe362 1328 // calculates the Bayesian weight
7fb46731 1329
cc1fe362 1330 Int_t jndex ;
1331 Double_t wn = 0.0 ;
1332 for (jndex = 0 ; jndex < kSPECIES ; jndex++)
2924941c 1333 wn += stof[jndex][index] * sdp[jndex][index] * scpv[jndex][index] *
1334 sw[jndex][index] * fInitPID[jndex] ;
1335
7fb46731 1336 // cout<<"*************wn "<<wn<<endl;
e74ea0e9 1337 if (TMath::Abs(wn)>0)
1338 for (jndex = 0 ; jndex < kSPECIES ; jndex++) {
35adb638 1339 //cout<<"jndex "<<jndex<<" wn "<<wn<<" SetPID * wn"
1340 //<<stof[jndex][index] * sdp[jndex][index] * pid[jndex] << endl;
1341 //cout<<" tof "<<stof[jndex][index] << " disp " <<sdp[jndex][index] << " pid "<< fInitPID[jndex] << endl;
2924941c 1342 // if(jndex == AliPID::kPi0 || jndex == AliPID::kPhoton){
1343 // cout<<"Particle "<<jndex<<" final prob * wn "
1344 // <<stof[jndex][index] * sdp[jndex][index] * scpv[jndex][index] *
1345 // fInitPID[jndex] <<" wn "<< wn<<endl;
1346 // cout<<"pid "<< fInitPID[jndex]<<", tof "<<stof[jndex][index]
1347 // <<", cpv "<<scpv[jndex][index]<<" ss "<<sdp[jndex][index]<<endl;
1348 // }
1349 recpar->SetPID(jndex, stof[jndex][index] * sdp[jndex][index] *
1350 sw[jndex][index] * scpv[jndex][index] *
1351 fInitPID[jndex] / wn) ;
e74ea0e9 1352 }
2cc71c1e 1353 }
35adb638 1354 // Info("MakePID", "Delete");
1355
2924941c 1356 for (Int_t i =0; i< kSPECIES; i++){
1357 delete [] stof[i];
1358 delete [] sdp [i];
1359 delete [] scpv[i];
1360 delete [] sw [i];
1361 }
35adb638 1362 // Info("MakePID","End MakePID");
2cc71c1e 1363}
1364
7acf6008 1365//____________________________________________________________________________
e3817e5f 1366void AliPHOSPIDv1::MakeRecParticles()
1367{
b2a60966 1368 // Makes a RecParticle out of a TrackSegment
148b2bba 1369
88cb7938 1370 AliPHOSGetter * gime = AliPHOSGetter::Instance() ;
fbf811ec 1371 TObjArray * emcRecPoints = gime->EmcRecPoints() ;
1372 TObjArray * cpvRecPoints = gime->CpvRecPoints() ;
1373 TClonesArray * trackSegments = gime->TrackSegments() ;
148b2bba 1374 if ( !emcRecPoints || !cpvRecPoints || !trackSegments ) {
351dd634 1375 AliFatal("RecPoints or TrackSegments not found !") ;
148b2bba 1376 }
fbf811ec 1377 TClonesArray * recParticles = gime->RecParticles() ;
01a599c9 1378 recParticles->Clear();
148b2bba 1379
7b7c1533 1380 TIter next(trackSegments) ;
7acf6008 1381 AliPHOSTrackSegment * ts ;
6ad0bfa0 1382 Int_t index = 0 ;
09fc14a0 1383 AliPHOSRecParticle * rp ;
7acf6008 1384 while ( (ts = (AliPHOSTrackSegment *)next()) ) {
7fb46731 1385 // cout<<">>>>>>>>>>>>>>>PCA Index "<<index<<endl;
7b7c1533 1386 new( (*recParticles)[index] ) AliPHOSRecParticle() ;
1387 rp = (AliPHOSRecParticle *)recParticles->At(index) ;
f0a4c9e9 1388 rp->SetTrackSegment(index) ;
9688c1dd 1389 rp->SetIndexInList(index) ;
148b2bba 1390
7acf6008 1391 AliPHOSEmcRecPoint * emc = 0 ;
1392 if(ts->GetEmcIndex()>=0)
7b7c1533 1393 emc = (AliPHOSEmcRecPoint *) emcRecPoints->At(ts->GetEmcIndex()) ;
fad3e5b9 1394
8d4608b5 1395 AliPHOSCpvRecPoint * cpv = 0 ;
7acf6008 1396 if(ts->GetCpvIndex()>=0)
8d4608b5 1397 cpv = (AliPHOSCpvRecPoint *) cpvRecPoints->At(ts->GetCpvIndex()) ;
fad3e5b9 1398
bd76890a 1399 Int_t track = 0 ;
1400 track = ts->GetTrackIndex() ;
1401
148b2bba 1402 // Now set type (reconstructed) of the particle
1403
1404 // Choose the cluster energy range
9fa5f1d0 1405
fbf811ec 1406 if (!emc) {
351dd634 1407 AliFatal(Form("-> emc(%d) = %d", ts->GetEmcIndex(), emc )) ;
fbf811ec 1408 }
50739f15 1409
e3817e5f 1410 Float_t e = emc->GetEnergy() ;
bc0c084c 1411
6f969528 1412 Float_t lambda[2] ;
1413 emc->GetElipsAxis(lambda) ;
407d15b3 1414
50739f15 1415 if((lambda[0]>0.01) && (lambda[1]>0.01)){
1416 // Looking PCA. Define and calculate the data (X),
bc0c084c 1417 // introduce in the function X2P that gives the components (P).
1418
c947e71a 1419 Float_t spher = 0. ;
1420 Float_t emaxdtotal = 0. ;
50739f15 1421
bc0c084c 1422 if((lambda[0]+lambda[1])!=0)
e4df4b30 1423 spher=TMath::Abs(lambda[0]-lambda[1])/(lambda[0]+lambda[1]);
50739f15 1424
c947e71a 1425 emaxdtotal=emc->GetMaximalEnergy()/emc->GetEnergy();
50739f15 1426
1427 fX[0] = lambda[0] ;
1428 fX[1] = lambda[1] ;
1429 fX[2] = emc->GetDispersion() ;
c947e71a 1430 fX[3] = spher ;
50739f15 1431 fX[4] = emc->GetMultiplicity() ;
c947e71a 1432 fX[5] = emaxdtotal ;
50739f15 1433 fX[6] = emc->GetCoreEnergy() ;
1434
e3817e5f 1435 fPrincipalPhoton->X2P(fX,fPPhoton);
1436 fPrincipalPi0 ->X2P(fX,fPPi0);
1f0e7ccd 1437
50739f15 1438 }
1439 else{
e3817e5f 1440 fPPhoton[0]=-100.0; //We do not accept clusters with
1441 fPPhoton[1]=-100.0; //one cell as a photon-like
1442 fPPi0[0] =-100.0;
1443 fPPi0[1] =-100.0;
50739f15 1444 }
1445
2cc71c1e 1446 Float_t time = emc->GetTime() ;
1447 rp->SetTof(time) ;
9fa5f1d0 1448
bc0c084c 1449 // Loop of Efficiency-Purity (the 3 points of purity or efficiency
1450 // are taken into account to set the particle identification)
e3817e5f 1451 for(Int_t effPur = 0; effPur < 3 ; effPur++){
50739f15 1452
bc0c084c 1453 // Looking at the CPV detector. If RCPV greater than CpvEmcDistance,
1454 // 1st,2nd or 3rd bit (depending on the efficiency-purity point )
1455 // is set to 1
26aa7e4a 1456 if(GetCPVBit(ts, effPur,e) == 1 ){
e3817e5f 1457 rp->SetPIDBit(effPur) ;
35adb638 1458 //cout<<"CPV bit "<<effPur<<endl;
1459 }
50739f15 1460 // Looking the TOF. If TOF smaller than gate, 4th, 5th or 6th
1461 // bit (depending on the efficiency-purity point )is set to 1
2cc71c1e 1462 if(time< (*fParameters)(3,effPur))
e3817e5f 1463 rp->SetPIDBit(effPur+3) ;
2cc71c1e 1464
e3817e5f 1465 //Photon PCA
50739f15 1466 //If we are inside the ellipse, 7th, 8th or 9th
1467 // bit (depending on the efficiency-purity point )is set to 1
e3817e5f 1468 if(GetPrincipalBit("photon",fPPhoton,effPur,e) == 1)
1469 rp->SetPIDBit(effPur+6) ;
1f0e7ccd 1470
e3817e5f 1471 //Pi0 PCA
1f0e7ccd 1472 //If we are inside the ellipse, 10th, 11th or 12th
1473 // bit (depending on the efficiency-purity point )is set to 1
e3817e5f 1474 if(GetPrincipalBit("pi0" ,fPPi0 ,effPur,e) == 1)
1475 rp->SetPIDBit(effPur+9) ;
f0a4c9e9 1476 }
e3817e5f 1477 if(GetHardPhotonBit(emc))
1478 rp->SetPIDBit(12) ;
1479 if(GetHardPi0Bit (emc))
1480 rp->SetPIDBit(13) ;
1f0e7ccd 1481
bd76890a 1482 if(track >= 0)
1483 rp->SetPIDBit(14) ;
1484
9fa5f1d0 1485 //Set momentum, energy and other parameters
50739f15 1486 Float_t encal = GetCalibratedEnergy(e);
9fa5f1d0 1487 TVector3 dir = GetMomentumDirection(emc,cpv) ;
1488 dir.SetMag(encal) ;
1489 rp->SetMomentum(dir.X(),dir.Y(),dir.Z(),encal) ;
1490 rp->SetCalcMass(0);
e0ed2e49 1491 rp->Name(); //If photon sets the particle pdg name to gamma
407d15b3 1492 rp->SetProductionVertex(fVtx.X(),fVtx.Y(),fVtx.Z(),0);
e747b8da 1493 rp->SetFirstMother(-1);
1494 rp->SetLastMother(-1);
1495 rp->SetFirstDaughter(-1);
1496 rp->SetLastDaughter(-1);
1497 rp->SetPolarisation(0,0,0);
d956e9b7 1498 //Set the position in global coordinate system from the RecPoint
1499 AliPHOSGeometry * geom = gime->PHOSGeometry() ;
1500 AliPHOSTrackSegment * ts = gime->TrackSegment(rp->GetPHOSTSIndex()) ;
1501 AliPHOSEmcRecPoint * erp = gime->EmcRecPoint(ts->GetEmcIndex()) ;
1502 TVector3 pos ;
1503 geom->GetGlobal(erp, pos) ;
1504 rp->SetPos(pos);
6ad0bfa0 1505 index++ ;
1506 }
6ad0bfa0 1507}
e3817e5f 1508
09fc14a0 1509//____________________________________________________________________________
702ab87e 1510void AliPHOSPIDv1::Print(const Option_t *) const
09fc14a0 1511{
b2a60966 1512 // Print the parameters used for the particle type identification
bc0c084c 1513
351dd634 1514 AliInfo("=============== AliPHOSPIDv1 ================") ;
88cb7938 1515 printf("Making PID\n") ;
1516 printf(" Pricipal analysis file from 0.5 to 100 %s\n", fFileNamePrincipalPhoton.Data() ) ;
1517 printf(" Name of parameters file %s\n", fFileNameParameters.Data() ) ;
1518 printf(" Matrix of Parameters: 14x4\n") ;
1519 printf(" Energy Calibration 1x3 [3 parametres to calibrate energy: A + B* E + C * E^2]\n") ;
1520 printf(" RCPV 2x3 rows x and z, columns function cut parameters\n") ;
1521 printf(" TOF 1x3 [High Eff-Low Pur,Medium Eff-Pur, Low Eff-High Pur]\n") ;
1522 printf(" PCA 5x4 [5 ellipse parametres and 4 parametres to calculate them: A/Sqrt(E) + B* E + C * E^2 + D]\n") ;
407d15b3 1523 printf(" Pi0 PCA 5x3 [5 ellipse parametres and 3 parametres to calculate them: A + B* E + C * E^2]\n") ;
50739f15 1524 fParameters->Print() ;
09fc14a0 1525}
1526
a496c46c 1527
69183710 1528
7acf6008 1529//____________________________________________________________________________
a4e98857 1530void AliPHOSPIDv1::PrintRecParticles(Option_t * option)
1531{
dd5c4038 1532 // Print table of reconstructed particles
1533
88cb7938 1534 AliPHOSGetter *gime = AliPHOSGetter::Instance() ;
bf8f1fbd 1535
88cb7938 1536 TClonesArray * recParticles = gime->RecParticles() ;
21cd0c07 1537
1538 TString message ;
3bf72d32 1539 message = "\nevent " ;
999f9a8f 1540 message += gime->EventNumber();
3bf72d32 1541 message += " found " ;
1542 message += recParticles->GetEntriesFast();
1543 message += " RecParticles\n" ;
1544
7acf6008 1545 if(strstr(option,"all")) { // printing found TS
3bf72d32 1546 message += "\n PARTICLE Index \n" ;
7acf6008 1547
1548 Int_t index ;
7b7c1533 1549 for (index = 0 ; index < recParticles->GetEntries() ; index++) {
21cd0c07 1550 AliPHOSRecParticle * rp = (AliPHOSRecParticle * ) recParticles->At(index) ;
3bf72d32 1551 message += "\n" ;
1552 message += rp->Name().Data() ;
1553 message += " " ;
1554 message += rp->GetIndexInList() ;
1555 message += " " ;
1556 message += rp->GetType() ;
7acf6008 1557 }
3bf72d32 1558 }
351dd634 1559 AliInfo(message.Data() ) ;
69183710 1560}
88cb7938 1561
1562//____________________________________________________________________________
1563void AliPHOSPIDv1::SetParameters()
1564{
1565 // PCA : To do the Principal Components Analysis it is necessary
1566 // the Principal file, which is opened here
1567 fX = new double[7]; // Data for the PCA
1568 fPPhoton = new double[7]; // Eigenvalues of the PCA
1569 fPPi0 = new double[7]; // Eigenvalues of the Pi0 PCA
1570
1571 // Read photon principals from the photon file
1572
1573 fFileNamePrincipalPhoton = "$ALICE_ROOT/PHOS/PCA8pa15_0.5-100.root" ;
1574 TFile f( fFileNamePrincipalPhoton.Data(), "read" ) ;
1575 fPrincipalPhoton = dynamic_cast<TPrincipal*> (f.Get("principal")) ;
1576 f.Close() ;
1577
1578 // Read pi0 principals from the pi0 file
1579
1580 fFileNamePrincipalPi0 = "$ALICE_ROOT/PHOS/PCA_pi0_40-120.root" ;
1581 TFile fPi0( fFileNamePrincipalPi0.Data(), "read" ) ;
1582 fPrincipalPi0 = dynamic_cast<TPrincipal*> (fPi0.Get("principal")) ;
1583 fPi0.Close() ;
1584
1585 // Open parameters file and initialization of the Parameters matrix.
1586 // In the File Parameters.dat are all the parameters. These are introduced
1587 // in a matrix of 16x4
1588 //
1589 // All the parameters defined in this file are, in order of row:
1590 // line 0 : calibration
1591 // lines 1,2 : CPV rectangular cat for X and Z
1592 // line 3 : TOF cut
1593 // lines 4-8 : parameters to calculate photon PCA ellipse
1594 // lines 9-13: parameters to calculate pi0 PCA ellipse
1595 // lines 14-15: parameters to calculate border for high-pt photons and pi0
1596
1597 fFileNameParameters = gSystem->ExpandPathName("$ALICE_ROOT/PHOS/Parameters.dat");
e8d02863 1598 fParameters = new TMatrixF(16,4) ;
c947e71a 1599 const Int_t kMaxLeng=255;
1600 char string[kMaxLeng];
88cb7938 1601
1602 // Open a text file with PID parameters
1603 FILE *fd = fopen(fFileNameParameters.Data(),"r");
1604 if (!fd)
351dd634 1605 AliFatal(Form("File %s with a PID parameters cannot be opened\n",
1606 fFileNameParameters.Data()));
88cb7938 1607
1608 Int_t i=0;
1609 // Read parameter file line-by-line and skip empty line and comments
c947e71a 1610 while (fgets(string,kMaxLeng,fd) != NULL) {
88cb7938 1611 if (string[0] == '\n' ) continue;
1612 if (string[0] == '!' ) continue;
1613 sscanf(string, "%f %f %f %f",
1614 &(*fParameters)(i,0), &(*fParameters)(i,1),
1615 &(*fParameters)(i,2), &(*fParameters)(i,3));
1616 i++;
351dd634 1617 AliDebug(1, Form("SetParameters", "line %d: %s",i,string));
88cb7938 1618 }
1619 fclose(fd);
1620}
1621
1622//____________________________________________________________________________
1623void AliPHOSPIDv1::SetParameterCalibration(Int_t i,Float_t param)
1624{
1625 // Set parameter "Calibration" i to a value param
351dd634 1626 if(i>2 || i<0) {
1627 AliError(Form("Invalid parameter number: %d",i));
1628 } else
88cb7938 1629 (*fParameters)(0,i) = param ;
1630}
1631
1632//____________________________________________________________________________
1633void AliPHOSPIDv1::SetParameterCpv2Emc(Int_t i, TString axis, Float_t cut)
1634{
1635 // Set the parameters to calculate Cpv-to-Emc Distance Cut depending on
1636 // Purity-Efficiency point i
1637
351dd634 1638 if(i>2 || i<0) {
1639 AliError(Form("Invalid parameter number: %d",i));
1640 } else {
88cb7938 1641 axis.ToLower();
1642 if (axis == "x") (*fParameters)(1,i) = cut;
1643 else if (axis == "z") (*fParameters)(2,i) = cut;
351dd634 1644 else {
1645 AliError(Form("Invalid axis name: %s",axis.Data()));
1646 }
88cb7938 1647 }
1648}
1649
1650//____________________________________________________________________________
1651void AliPHOSPIDv1::SetParameterPhotonBoundary(Int_t i,Float_t param)
1652{
1653 // Set parameter "Hard photon boundary" i to a value param
351dd634 1654 if(i>4 || i<0) {
1655 AliError(Form("Invalid parameter number: %d",i));
1656 } else
88cb7938 1657 (*fParameters)(14,i) = param ;
1658}
1659
1660//____________________________________________________________________________
1661void AliPHOSPIDv1::SetParameterPi0Boundary(Int_t i,Float_t param)
1662{
1663 // Set parameter "Hard pi0 boundary" i to a value param
351dd634 1664 if(i>1 || i<0) {
1665 AliError(Form("Invalid parameter number: %d",i));
1666 } else
88cb7938 1667 (*fParameters)(15,i) = param ;
1668}
1669
1670//_____________________________________________________________________________
1671void AliPHOSPIDv1::SetParameterTimeGate(Int_t i, Float_t gate)
1672{
1673 // Set the parameter TimeGate depending on Purity-Efficiency point i
351dd634 1674 if (i>2 || i<0) {
1675 AliError(Form("Invalid Efficiency-Purity choice %d",i));
1676 } else
88cb7938 1677 (*fParameters)(3,i)= gate ;
1678}
1679
1680//_____________________________________________________________________________
1681void AliPHOSPIDv1::SetParameterToCalculateEllipse(TString particle, TString param, Int_t i, Float_t par)
1682{
1683 // Set the parameter "i" that is needed to calculate the ellipse
1684 // parameter "param" for a particle "particle"
1685
1686 particle.ToLower();
1687 param. ToLower();
1688 Int_t p= -1;
1689 Int_t offset=0;
1690
1691 if (particle == "photon") offset=0;
1692 else if (particle == "pi0") offset=5;
1693 else
351dd634 1694 AliError(Form("Wrong particle name: %s (choose from pi0/photon)\n",
1695 particle.Data()));
88cb7938 1696
1697 if (param.Contains("a")) p=4+offset;
1698 else if(param.Contains("b")) p=5+offset;
1699 else if(param.Contains("c")) p=6+offset;
1700 else if(param.Contains("x0"))p=7+offset;
1701 else if(param.Contains("y0"))p=8+offset;
351dd634 1702 if((i>4)||(i<0)) {
1703 AliError(Form("No parameter with index %d", i)) ;
1704 } else if(p==-1) {
1705 AliError(Form("No parameter with name %s", param.Data() )) ;
1706 } else
88cb7938 1707 (*fParameters)(p,i) = par ;
1708}
1709
1710//____________________________________________________________________________
1711void AliPHOSPIDv1::Unload()
1712{
c947e71a 1713 //Unloads RecPoints, Tracks and RecParticles
88cb7938 1714 AliPHOSGetter * gime = AliPHOSGetter::Instance() ;
1715 gime->PhosLoader()->UnloadRecPoints() ;
1716 gime->PhosLoader()->UnloadTracks() ;
1717 gime->PhosLoader()->UnloadRecParticles() ;
1718}
1719
1720//____________________________________________________________________________
90cceaf6 1721void AliPHOSPIDv1::WriteRecParticles()
88cb7938 1722{
c947e71a 1723 //It writes reconstructed particles and pid to file
1724
88cb7938 1725 AliPHOSGetter *gime = AliPHOSGetter::Instance() ;
1726
1727 TClonesArray * recParticles = gime->RecParticles() ;
1728 recParticles->Expand(recParticles->GetEntriesFast() ) ;
adcca1e6 1729 if(fWrite){
1730 TTree * treeP = gime->TreeP();
1731
1732 //First rp
1733 Int_t bufferSize = 32000 ;
1734 TBranch * rpBranch = treeP->Branch("PHOSRP",&recParticles,bufferSize);
1735 rpBranch->SetTitle(BranchName());
1736
1737 rpBranch->Fill() ;
1738
1739 gime->WriteRecParticles("OVERWRITE");
1740 gime->WritePID("OVERWRITE");
1741 }
88cb7938 1742}
407d15b3 1743//____________________________________________________________________________
1744void AliPHOSPIDv1::GetVertex(void)
1745{ //extract vertex either using ESD or generator
1746
1747 //Try to extract vertex from data
1748 if(fESD){
1749 const AliESDVertex *esdVtx = fESD->GetVertex() ;
1750 if(esdVtx){
1751 fVtx.SetXYZ(esdVtx->GetXv(),esdVtx->GetYv(),esdVtx->GetZv()) ;
1752 return ;
1753 }
1754 }
1755
1756 AliWarning("Can not read vertex from data, use fixed \n") ;
1757 fVtx.SetXYZ(0.,0.,0.) ;
1758
1759}
35adb638 1760//_______________________________________________________________________
1761void AliPHOSPIDv1::SetInitPID(const Double_t *p) {
1762 // Sets values for the initial population of each particle type
304864ab 1763 for (Int_t i=0; i<AliPID::kSPECIESN; i++) fInitPID[i] = p[i];
35adb638 1764}
1765//_______________________________________________________________________
1766void AliPHOSPIDv1::GetInitPID(Double_t *p) const {
1767 // Gets values for the initial population of each particle type
304864ab 1768 for (Int_t i=0; i<AliPID::kSPECIESN; i++) p[i] = fInitPID[i];
35adb638 1769}