]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWG2/FLOW/AliFlowTrack.cxx
Improved version, kinetree included
[u/mrichter/AliRoot.git] / PWG2 / FLOW / AliFlowTrack.cxx
CommitLineData
30a892e3 1//////////////////////////////////////////////////////////////////////
2//
3// $Id$
4//
5// Author: Emanuele Simili
6//
7//////////////////////////////////////////////////////////////////////
8//
9//_____________________________________________________________
10//
11// Description:
12// an array of AliFlowTrack is the core of the AliFlowEvent.
13// The object AliFlowTrack contains data members wich summarize the track
4e566f2f 14// information most useful for flow study (such as Pt, eta, phi angle), some
15// detector signals (fitpoints, chi2 of the track fit, energy loss, time of
16// flight, ecc.), the p.id is stored as the detector response function, for
17// each detector (with the possibility to costomly combine them), and the
18// combined one (see bayesian P.Id. - chap.5 of the ALICE PPR).
30a892e3 19// This class is optimized for reaction plane calculation and sub-event
20// selection, through the appropriate methods in AliFlowEvent.
21// Two arrays of flags in the AliFlowTrack object (fSelection[][] and
22// fSubevent[][]) specify whether a track is included or not in a certain
23// Selection or Subevent. Those flags are switched on/off by the method
24// AliFlowEvent::SetSelection(), according to Eta, Pt, dca, constrainability
25// of the track, number of TPC hits, and p.id hypotesis (static member of the
26// AliFlowEvent class (fEtaTpcCuts[][][], fPtTpcCuts[][][], fDcaGlobalCuts[],
27// fPid[], ecc.).
28//
29// The AliFlowTrack Class is adapted from the original StFlowTrack,
30// succesfully employed to study flow in the STAR experiment at RICH.
31// Original Authors: Raimond Snellings & Art Poskanzer
32//
33
34#include "AliFlowTrack.h"
35#include "AliFlowConstants.h"
92016a03 36
37#include "TMath.h"
30a892e3 38#include <iostream>
39using namespace std; //required for resolving the 'cout' symbol
40
92016a03 41ClassImp(AliFlowTrack)
42//-------------------------------------------------------------
30a892e3 43AliFlowTrack::AliFlowTrack()
44{
45 // Default constructor
46
47 fPhi = 0. ;
48 fEta = 0. ;
49 fPt = 0. ;
50 fPhiGlobal = 0. ;
51 fEtaGlobal = 0. ;
52 fPtGlobal = 0. ;
53 fChi2 = 0. ;
54 fZFirstPoint = 0. ;
55 fZLastPoint = 0. ;
56 fTrackLength = 0. ;
57 fMostLikelihoodPID = 0 ;
4e566f2f 58 for(Int_t dd=0;dd<2;dd++) { fDcaSigned[dd] = 0. ; }
59 for(Int_t ii=0;ii<AliFlowConstants::kPid;ii++) { fCombRespFun[ii] = 0. ; }
60 for(Int_t det=0;det<4;det++)
30a892e3 61 {
4e566f2f 62 fFitPts[det] = 0 ; fMaxPts[det] = 0 ;
63 fFitChi2[det] = 0. ; fDedx[det] = 0. ; fMom[det] = 0. ;
64 for(Int_t ii=0;ii<AliFlowConstants::kPid;ii++) { fRespFun[det][ii] = -1. ; }
30a892e3 65 }
66 ResetSelection() ;
67}
92016a03 68//-------------------------------------------------------------
30a892e3 69AliFlowTrack::AliFlowTrack(const Char_t* name)
70{
71 // TNamed constructor
72
73 SetName(name) ;
74 AliFlowTrack() ;
75}
92016a03 76//-------------------------------------------------------------
30a892e3 77AliFlowTrack::~AliFlowTrack()
78{
79 // default destructor (dummy)
80}
92016a03 81//-------------------------------------------------------------
30a892e3 82
92016a03 83//-------------------------------------------------------------
30a892e3 84Float_t AliFlowTrack::P() const
85{
92016a03 86 // Returns the total momentum of the constrained track (calculated from Pt & Eta).
87 // If the track is not constrainable or eta is infinite, returns 0.
30a892e3 88
92016a03 89 if(!IsConstrainable()) { return 0. ; }
90
91 Float_t momentum = 0. ;
92 Float_t conv = 1 - ( TMath::TanH(Eta()) * TMath::TanH(Eta()) ) ;
93 if(conv>0) { momentum = Pt() / TMath::Sqrt(conv) ; }
94
30a892e3 95 return momentum;
96}
92016a03 97//-------------------------------------------------------------
98Float_t AliFlowTrack::PGlobal() const
30a892e3 99{
92016a03 100 // Returns the total momentum of the unconstrained track (calculated from PtGlobal & EtaGlobal).
101 // If etaGlobal is infinite, returns 0.
102
103 Float_t momentum = 0. ;
104 Float_t conv = 1 - ( TMath::TanH(EtaGlobal()) * TMath::TanH(EtaGlobal()) ) ;
105 if(conv>0) { momentum = PtGlobal() / TMath::Sqrt(conv) ; }
30a892e3 106
30a892e3 107 return momentum;
108}
92016a03 109//-------------------------------------------------------------
30a892e3 110Float_t AliFlowTrack::Mass() const
111{
112 // Returns the mass of the track, basing on its P.Id. hypotesis
113
92016a03 114 Float_t mass = 0.13957 ; // pion mass
30a892e3 115
92016a03 116 if(MostLikelihoodPID() == 0) { mass = -1. ; }
117 else if(TMath::Abs(MostLikelihoodPID()) == 11) { mass = 0.00051; }
118 else if(TMath::Abs(MostLikelihoodPID()) == 13) { mass = 0.10566; }
119 else if(TMath::Abs(MostLikelihoodPID()) == 211) { mass = 0.49368; }
120 else if(TMath::Abs(MostLikelihoodPID()) == 321) { mass = 0.13957; }
121 else if(TMath::Abs(MostLikelihoodPID()) == 2212) { mass = 0.93827; }
122 else if(TMath::Abs(MostLikelihoodPID()) == 10010020) { mass = 1.87505; }
30a892e3 123
92016a03 124 return mass ;
30a892e3 125}
92016a03 126//-------------------------------------------------------------
30a892e3 127Float_t AliFlowTrack::InvMass() const
128{
129 // Returns the invariant mass of the track, calculated from T.O.F. and P_tot
130
92016a03 131 Float_t mass = -1 ; // if no calculation possible, it returns -1
30a892e3 132 Float_t c = TMath::Ccgs()/1e+12 ; // = 0.02998 ; --> speed of light in cm/psec
133 Float_t tof = TofTOF() ; // in pico-seconds
134 Float_t lenght = TrackLength() ; // in cm
92016a03 135 Float_t ptot = 0 ; // constrained parameters are used if there, otherwise unconstrained
136 Float_t beta, gamma ;
137 if(IsConstrainable()) { ptot = P() ; }
138 else { ptot = PGlobal() ; }
30a892e3 139 if(tof>0 && lenght>0)
92016a03 140 {
141 beta = lenght / (tof * c) ;
30a892e3 142 if(beta<1)
143 {
92016a03 144 gamma = 1 / TMath::Sqrt( 1 - (beta * beta) ) ;
145 mass = TMath::Abs( ptot / (beta * gamma) ) ;
146 }
147 //cout << " (yes) Mass = " << mass << " , t/l = " << (tof/lenght) << " , beta = " << beta << " , gamma = " << gamma << endl ;
148 }
149 //else { cout << " (no) TOF = " << tof << " , Lenght = " << lenght << endl ; }
30a892e3 150
92016a03 151 return mass ;
30a892e3 152}
92016a03 153//-------------------------------------------------------------
30a892e3 154Float_t AliFlowTrack::Y() const
155{
156 // Rapidity of the constrained track.
157 // If track is not constrainable, the unconstrained rapidity is returned.
158
159 if(!IsConstrainable()) { return YGlobal() ; }
160 if(TMath::Abs((Float_t)P()) == TMath::Abs((Float_t)Pt())) { return 0. ; }
161 else if(TMath::Abs((Float_t)P()) < TMath::Abs((Float_t)Pt())) { cout << "track: " << GetName() << "has Pt() > P() !!!" << endl ; }
162 // -
92016a03 163 Float_t mass = Mass() ;
164 Double_t pz = TMath::Sqrt(P()*P() - Pt()*Pt());
165 if(Eta()<0) { pz = -pz ; }
166 Double_t e = TMath::Sqrt(P()*P() + mass*mass) ;
167 Float_t rapidity = 0.5*TMath::Log((e + pz)/(e - pz)) ;
30a892e3 168
169 return rapidity ;
170}
92016a03 171//-------------------------------------------------------------
30a892e3 172Float_t AliFlowTrack::YGlobal() const
173{
174 // Rapidity of the unconstrained track
175
176 if(TMath::Abs((Float_t)PGlobal()) == TMath::Abs((Float_t)PtGlobal())) { return 0. ; }
177 else if(TMath::Abs((Float_t)PGlobal()) < TMath::Abs((Float_t)PtGlobal())) { cout << "track: " << GetName() << "has Pt() > P() !!!" << endl ; }
178 // -
92016a03 179 Float_t mass = Mass() ;
180 Double_t pz = TMath::Sqrt(PGlobal()*PGlobal() - PtGlobal()*PtGlobal());
181 if(EtaGlobal()<0) { pz = -pz ; }
182 Double_t e = TMath::Sqrt(PGlobal()*PGlobal() + mass*mass) ;
183 Float_t rapidity = 0.5*TMath::Log((e + pz)/(e - pz)) ;
30a892e3 184
185 return rapidity ;
186}
92016a03 187//-------------------------------------------------------------
188const Char_t* AliFlowTrack::Pid() const
30a892e3 189{
190 // Returns the P.Id. in characters (e,mu,pi,k,p,d) basing on the stored pdg code
191 // and its sign (both stored in MostLikelihoodPID() ) .
192
92016a03 193 const Char_t *name[] = {"e","mu","pi","k","pr","d"} ;
194 Int_t pdgCode = TMath::Abs(MostLikelihoodPID()) ;
195 Int_t charge = Charge() ;
30a892e3 196
92016a03 197 TString pId = "" ;
198 if(pdgCode == 11) { pId = name[0] ; }
199 else if(pdgCode == 13) { pId = name[1] ; }
200 else if(pdgCode == 211) { pId = name[2] ; }
201 else if(pdgCode == 321) { pId = name[3] ; }
202 else if(pdgCode == 2212) { pId = name[4] ; }
203 else if(pdgCode == 10010020) { pId = name[5] ; }
204 else { pId = "0" ; }
30a892e3 205
92016a03 206 if(charge>0) { pId += "+" ; }
207 else if(charge<0) { pId += "-" ; }
208 else { pId += "" ; }
30a892e3 209
92016a03 210 return pId.Data() ;
30a892e3 211}
92016a03 212//-------------------------------------------------------------
4e566f2f 213void AliFlowTrack::PidProbs(Float_t *pidN) const
30a892e3 214{
4e566f2f 215 // Returns the normalized probability (the "bayesian weights") for the given track to be [e,mu,pi,k,p,d] .
216 // The COMBINED detector response function is scaled by the a priori probabilities
217 // (the normalised particle abundances is stored in AliFlowConstants::fgBayesian[]) .
30a892e3 218
219 Double_t sum = 0 ;
4e566f2f 220 for(Int_t n=0;n<AliFlowConstants::kPid;n++) { pidN[n] = PidProb(n) ; sum += pidN[n] ; }
221 if(sum)
222 {
223 for(Int_t n=0;n<AliFlowConstants::kPid;n++) { pidN[n] /= sum ; }
30a892e3 224 }
225 else { cout << " ERROR - Empty Bayesian Vector !!! " << endl ; }
226}
92016a03 227//-------------------------------------------------------------
4e566f2f 228void AliFlowTrack::PidProbsC(Float_t *pidN) const
229{
230 // Returns the normalized probability (the "bayesian weights") for the given track to be [e,mu,pi,k,p,d] .
231 // The CUSTOM detector response function (see AliFlowTrack) is scaled by the a priori probabilities
232 // (the normalised particle abundances is stored in AliFlowConstants::fgBayesian[]) .
233
234 Double_t sum = 0 ;
235 for(Int_t n=0;n<AliFlowConstants::kPid;n++) { pidN[n] = PidProbC(n) ; sum += pidN[n] ; }
236 if(sum)
237 {
238 for(Int_t n=0;n<AliFlowConstants::kPid;n++) { pidN[n] /= sum ; }
239 }
240 else { cout << " ERROR - Empty Bayesian Vector !!! " << endl ; }
241}
242//-------------------------------------------------------------
243Float_t AliFlowTrack::PidProb(Int_t nPid) const
30a892e3 244{
4e566f2f 245 // Returns the bayesian weight of the track to be [nPid = e,mu,pi,k,pi,d].
246 // The detector response function in use is the combined one (from the ESD)
247
248 if(nPid > AliFlowConstants::kPid) { return 0. ; }
30a892e3 249
4e566f2f 250 return (fCombRespFun[nPid] * AliFlowConstants::fgBayesian[nPid]) ;
30a892e3 251}
92016a03 252//-------------------------------------------------------------
4e566f2f 253Float_t AliFlowTrack::PidProbC(Int_t nPid) const
30a892e3 254{
4e566f2f 255 // Returns the bayesian weight of the track to be [nPid = e,mu,pi,k,pi,d].
256 // The detector response function in use is the custom one ...
30a892e3 257
4e566f2f 258 if(nPid > AliFlowConstants::kPid) { return 0. ; }
30a892e3 259
4e566f2f 260 Float_t customRespFun[AliFlowConstants::kPid] ;
261 GetCustomRespFun(customRespFun) ;
30a892e3 262
4e566f2f 263 return (customRespFun[nPid] * AliFlowConstants::fgBayesian[nPid]) ;
264}
92016a03 265//-------------------------------------------------------------
4e566f2f 266Float_t AliFlowTrack::MostLikelihoodRespFunc() const
30a892e3 267{
4e566f2f 268 // Returns the detector response function for the most probable P.id. hypothesis
269 // (Warning: THIS IS NOT THE BAYESIAN WEIGHT !)
30a892e3 270
92016a03 271 Int_t pdgCode = TMath::Abs(MostLikelihoodPID()) ;
4e566f2f 272 if(pdgCode == 11) { return fCombRespFun[0] ; }
273 else if(pdgCode == 13) { return fCombRespFun[1] ; }
274 else if(pdgCode == 211) { return fCombRespFun[2] ; }
275 else if(pdgCode == 321) { return fCombRespFun[3] ; }
276 else if(pdgCode == 2212) { return fCombRespFun[4] ; }
277 else if(pdgCode == 10010020) { return fCombRespFun[5] ; }
30a892e3 278 else { return 0. ; }
279}
92016a03 280//-------------------------------------------------------------
4e566f2f 281void AliFlowTrack::SetRespFun(Int_t det, Float_t *r)
282{
283 // This function fills "AliFlowConstants::kPid" PID weights
284 // (detector response functions) of the track .
285 // The method is private, cause it is called by the public
286 // methods: SetRespFunITS, SetRespFunTPC, ...
287
288 for(Int_t i=0;i<AliFlowConstants::kPid;i++)
289 {
290 fRespFun[det][i] = r[i] ;
291 }
292}
293//-------------------------------------------------------------
294void AliFlowTrack::GetRespFun(Int_t det, Float_t *r) const
295{
296 // This function returns the response functions of the
297 // detector [det] for the P.Id. of the track .
298 // The method is private, and it is called by the public
299 // methods: GetRespFunITS, GetRespFunTPC, ...
300
301 for(Int_t i=0;i<AliFlowConstants::kPid;i++)
302 {
303 r[i] = fRespFun[det][i] ;
304 }
305}
306//-------------------------------------------------------------
307void AliFlowTrack::GetCombinedRespFun(Float_t *r) const
308{
309 // This function returns the combined response functions for
310 // [e,mu,pi,k,pi,d] as it is stored in the ESD .
311
312 for(Int_t i=0;i<AliFlowConstants::kPid;i++)
313 {
314 r[i] = fCombRespFun[i] ;
315 }
316}
317//-------------------------------------------------------------
318void AliFlowTrack::GetCustomRespFun(Float_t *r) const
319{
320 // This function returns a combined response functions as setted
321 // by the user ... at the moment just the sum of single responses ...
322 // for the track to be [e,mu,pi,k,pi,d] .
323
324 Int_t sum ;
325 for(Int_t i=0;i<AliFlowConstants::kPid;i++)
326 {
327 r[i] = 0. ; sum = 0 ;
328 for(Int_t det=0;det<4;det++)
329 {
330 if(fRespFun[det][i]>0) { r[i] += fRespFun[det][i] ; sum += 1 ; }
331 }
332 if(sum) { r[i] /= sum ; }
333 }
334}
335//-------------------------------------------------------------
30a892e3 336void AliFlowTrack::SetPid(const Char_t* pid)
337{
338 // Sets the P.Id. hypotesis of the track from a String imput (that should be
339 // ("e","mu","pi","k","pr","d"). Sign is allowed as well. The string itself
340 // is not stored, what is stored is the signed PDG code.
341
342 if(strstr(pid,"e")) { fMostLikelihoodPID = 11 ; }
343 else if(strstr(pid,"mu")) { fMostLikelihoodPID = 13 ; }
344 else if(strstr(pid,"pi")) { fMostLikelihoodPID = 211 ; }
345 else if(strstr(pid,"k")) { fMostLikelihoodPID = 321 ; }
346 else if(strstr(pid,"pr")) { fMostLikelihoodPID = 2212 ; }
347 else if(strstr(pid,"d")) { fMostLikelihoodPID = 10010020 ; }
348 else { fMostLikelihoodPID = 0 ; cout << "AliFlowTrack - !BAD IMPUT!" << endl ; }
349
350 if(strchr(pid,'+')) { fMostLikelihoodPID = TMath::Abs(fMostLikelihoodPID) * 1 ; }
351 else if(strchr(pid,'-')) { fMostLikelihoodPID = TMath::Abs(fMostLikelihoodPID) * -1 ; }
352}
92016a03 353//-------------------------------------------------------------
4e566f2f 354void AliFlowTrack::SetPid(Int_t pdgCode)
355{
356 // Sets the P.Id. hypotesis of the track from the PDG code.
357 // Sign can be given as well.
358
359 fMostLikelihoodPID = pdgCode ;
360}
361//-------------------------------------------------------------
30a892e3 362Bool_t AliFlowTrack::IsConstrainable() const
363{
364 // Returns kTRUE if the track is constrainable.
365 // If the track is constrainable -> the constrained parameters are stored (and the
366 // unconstrained ones as well in ...Global).
367 // Otherwise (if track is not constrainable) -> just the unconstrained parameters
368 // are stored, and returned instead of the constrained ones .
369
370 if(fPt==0 && fEta==0) { return kFALSE ; }
371 else { return kTRUE ; }
372}
92016a03 373//-------------------------------------------------------------
374Float_t AliFlowTrack::Dca() const
30a892e3 375{
92016a03 376 // distance of closest approach (norm(dca[2]))
377
30a892e3 378 Double_t mag = 0 ;
379 for(Int_t ii=0;ii<2;ii++) { mag += (fDcaSigned[ii]*fDcaSigned[ii]) ; }
380 return TMath::Sqrt(mag) ;
381}
92016a03 382//-------------------------------------------------------------
383Float_t AliFlowTrack::DcaError() const
30a892e3 384{
92016a03 385 // error on the distance of closest approach
386
387 Double_t err = 0 ;
388 for(Int_t ii=0;ii<2;ii++) { err = (fDcaError[ii]*fDcaError[ii]) ; }
389 return TMath::Sqrt(err) ;
30a892e3 390}
92016a03 391//-------------------------------------------------------------
392void AliFlowTrack::DcaError3(Float_t err[3]) const
393{
394 // Dca Error (xy, z, cov(xy,z)) ...
30a892e3 395
92016a03 396 for(Int_t ii=0;ii<2;ii++) { err[ii] = TMath::Abs(fDcaError[ii]) ; }
397}
398//-------------------------------------------------------------
30a892e3 399
92016a03 400//-------------------------------------------------------------
401Bool_t AliFlowTrack::Select(Int_t harmonic,Int_t selection,Int_t subevent) const
402{
403 // Returns the selection flag for [harmonic] [selection] [sub-event]
30a892e3 404
92016a03 405 if((subevent == -1) || (subevent == fSubevent[harmonic][selection]))
406 {
407 return fSelection[harmonic][selection] ;
408 }
409 return kFALSE ;
410}
411//-------------------------------------------------------------
412void AliFlowTrack::PrintSelection() const
413{
414 // Prints a short string of 0 & 1 to visualize the selections' flags
415 // [har1][sel0],[har1][sel1],[har1][sel2],...,[har2][sel0],...
416
417 for(Int_t i=0;i<AliFlowConstants::kHars;i++)
418 {
419 for(Int_t j=0;j<AliFlowConstants::kSels;j++)
420 {
421 if(Select(i,j)) { cout << 1 ; }
422 else { cout << 0 ; }
423 }
424 }
425 cout << endl ;
426}
427//-------------------------------------------------------------
428void AliFlowTrack::ResetSelection()
429{
430 // Re-sets all the selection/sub-event flags to 0
431 // (track won't be used in any R.P. calculation)
30a892e3 432
92016a03 433 for(Int_t ii=0;ii<AliFlowConstants::kHars;ii++)
434 {
435 for(Int_t jj=0;jj<AliFlowConstants::kSels;jj++)
436 {
437 fSelection[ii][jj] = kFALSE ;
438 fSubevent[ii][jj] = -1 ;
439 }
440 }
441}
442//-------------------------------------------------------------
443
444//-------------------------------------------------------------
30a892e3 445void AliFlowTrack::SetConstrainable()
446{
4e566f2f 447 // fills the constrained parameters with the unconstrained ones,
448 // making the track a constrainable track.
449 // !!! TRICKY METHOD !!!
30a892e3 450
451 if(!IsConstrainable())
452 {
453 fPhi = fPhiGlobal ;
454 fEta = fEtaGlobal ;
455 fPt = fPtGlobal ;
456 }
457}
92016a03 458//-------------------------------------------------------------
30a892e3 459void AliFlowTrack::SetUnConstrainable()
460{
4e566f2f 461 // deletes the constrained parameters making the track an
462 // unconstrainable track.
463 // !!! TRICKY METHOD !!!
30a892e3 464
465 if(IsConstrainable())
466 {
467 fPhi = 0. ;
468 fEta = 0. ;
469 fPt = 0. ;
470 }
471}
92016a03 472//-------------------------------------------------------------