e6b368095103921d33ff7072a90e946fd871d06a
[u/mrichter/AliRoot.git] / PWG2 / RESONANCES / AliRsnDaughter.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 // ***********************
17 // *** AliRsnDaughter ****
18 // ***********************
19 // 
20 // Light-weight 'track' object into an internal format used
21 // for further steps of resonance analysis.
22 // Provides converters from all kinds of input track type
23 // (ESD, AOD and MC).
24 // Contains also a facility to compute invariant mass of a pair.
25 //
26 // author: A. Pulvirenti --- email: alberto.pulvirenti@ct.infn.it
27
28 #include <Riostream.h>
29
30 #include <TParticle.h>
31 #include <TString.h>
32
33 #include "AliLog.h"
34 #include "AliESDtrack.h"
35 #include "AliAODTrack.h"
36 #include "AliMCParticle.h"
37
38 #include "AliRsnPID.h"
39 #include "AliRsnParticle.h"
40 #include "AliRsnDaughter.h"
41
42 ClassImp(AliRsnDaughter)
43
44 //_____________________________________________________________________________
45 AliRsnDaughter::AliRsnDaughter() :
46   AliVParticle(),
47   fIndex(-1),
48   fLabel(-1),
49   fCharge(0),
50   fFlags(0),
51   fPIDType(AliRsnPID::kUnknown),
52   fPIDProb(0.0),
53   fMass(0.0),
54   fParticle(0x0)
55 {
56 //=========================================================
57 // Default constructor.
58 // Initializes all data-members with meaningless values.
59 //=========================================================
60
61     Int_t i;
62     for (i = 0; i < AliRsnPID::kSpecies; i++) {
63         if (i < 3) {
64             fP[i] = 0.0;
65             fV[i] = 0.0;
66         }
67         fPIDWeight[i] = 0.0;
68     }
69 }
70
71 //_____________________________________________________________________________
72 AliRsnDaughter::AliRsnDaughter(const AliRsnDaughter &copy) :
73   AliVParticle(copy),
74   fIndex(copy.fIndex),
75   fLabel(copy.fLabel),
76   fCharge(copy.fCharge),
77   fFlags(copy.fFlags),
78   fPIDType(copy.fPIDType),
79   fPIDProb(copy.fPIDProb),
80   fMass(copy.fMass),
81   fParticle(0x0)
82 {
83 //=========================================================
84 // Copy constructor.
85 //=========================================================
86
87     Int_t i;
88     for (i = 0; i < AliRsnPID::kSpecies; i++) {
89         if (i < 3) {
90             fP[i] = copy.fP[i];
91             fV[i] = copy.fV[i];
92         }
93         fPIDWeight[i] = copy.fPIDWeight[i];
94     }
95
96     // initialize particle object 
97     // only if it is present in the template object
98     if (copy.fParticle) fParticle = new AliRsnParticle(*(copy.fParticle));
99 }
100
101 //_____________________________________________________________________________
102 AliRsnDaughter::AliRsnDaughter(AliESDtrack *track) :
103   AliVParticle(),
104   fIndex(-1),
105   fLabel(-1),
106   fCharge(0),
107   fFlags(0),
108   fPIDType(AliRsnPID::kUnknown),
109   fPIDProb(0.0),
110   fMass(0.0),
111   fParticle(0x0)
112 {
113 //=========================================================
114 // Constructor to get data from an ESD track.
115 //=========================================================
116
117     Adopt(track);
118 }
119
120 //_____________________________________________________________________________
121 AliRsnDaughter::AliRsnDaughter(AliAODTrack *track) :
122   AliVParticle(),
123   fIndex(-1),
124   fLabel(-1),
125   fCharge(0),
126   fFlags(0),
127   fPIDType(AliRsnPID::kUnknown),
128   fPIDProb(0.0),
129   fMass(0.0),
130   fParticle(0x0)
131 {
132 //=========================================================
133 // Constructor to get data from an AOD track.
134 //=========================================================
135
136     Adopt(track);
137 }
138
139 //_____________________________________________________________________________
140 AliRsnDaughter::AliRsnDaughter(AliMCParticle *track) :
141   AliVParticle(),
142   fIndex(-1),
143   fLabel(-1),
144   fCharge(0),
145   fFlags(0),
146   fPIDType(AliRsnPID::kUnknown),
147   fPIDProb(0.0),
148   fMass(0.0),
149   fParticle(0x0)
150 {
151 //=========================================================
152 // Constructor to get data from an MC track.
153 //=========================================================
154
155     Adopt(track);
156 }
157
158 //_____________________________________________________________________________
159 AliRsnDaughter& AliRsnDaughter::operator=(const AliRsnDaughter &copy)
160 {
161 //=========================================================
162 // Assignment operator.
163 // Works like the copy constructor and returns a reference
164 // to the initialized object for which it is called.
165 //=========================================================
166     
167     fIndex  = copy.fIndex;
168     fLabel  = copy.fLabel;
169     fCharge = copy.fCharge;
170     fFlags  = copy.fFlags;
171
172     Int_t i;
173     for (i = 0; i < AliRsnPID::kSpecies; i++) {
174         if (i < 3) {
175             fP[i] = copy.fP[i];
176             fV[i] = copy.fV[i];
177         }
178         fPIDWeight[i] = copy.fPIDWeight[i];
179     }
180     
181     fPIDType = copy.fPIDType;
182     fPIDProb = copy.fPIDProb;
183     fMass    = copy.fMass;
184     
185     // initialize particle object 
186     // only if it is present in the template object;
187     // otherwise, it is just cleared and not replaced with anything
188     if (fParticle) {
189         delete fParticle;
190         fParticle = 0x0;
191     }
192     if (copy.fParticle) fParticle = new AliRsnParticle(*(copy.fParticle));
193
194     return (*this);
195 }
196
197 //_____________________________________________________________________________
198 AliRsnDaughter::~AliRsnDaughter()
199 {
200 //=========================================================
201 // Destructor
202 //=========================================================
203
204     if (fParticle) {
205         delete fParticle;
206         fParticle = 0;
207     }
208 }
209
210 //_____________________________________________________________________________
211 void AliRsnDaughter::SetPIDWeight(Int_t i, Double_t value)
212 {
213 //=========================================================
214 // I the argument 'i' is in the correct range,
215 // sets the i-th PID weight to 'value'
216 //=========================================================
217
218     if (i >= 0 && i < AliRsnPID::kSpecies) fPIDWeight[i] = value;
219     else {
220         AliError(Form("Cannot set a weight related to slot %d", i));
221     }
222 }
223
224
225 //_____________________________________________________________________________
226 void AliRsnDaughter::SetPIDWeights(const Double_t *pid)
227 {
228 //=========================================================
229 // Sets ALL PID weights at once.
230 // The passed array is supposed to have at least as many
231 // slots as the number of allowed particle species.
232 //=========================================================
233
234    Int_t i;
235    for (i = 0; i < AliRsnPID::kSpecies; i++) fPIDWeight[i] = pid[i];
236 }
237
238
239 //_____________________________________________________________________________
240 Bool_t AliRsnDaughter::Adopt(AliESDtrack* esdTrack)
241 {
242 //=========================================================
243 // Copies data from an AliESDtrack into "this":
244 //  - charge sign
245 //  - momentum
246 //  - point of closest approach to primary vertex
247 //  - ESD pid weights
248 // In case of errors returns kFALSE, otherwise kTRUE.
249 //=========================================================
250
251     if (!esdTrack) {
252         AliError("Passed NULL object: nothing done");
253         return kFALSE;
254     }
255         
256     // copy momentum and vertex
257     esdTrack->GetPxPyPz(fP);
258     esdTrack->GetXYZ(fV);
259
260     // copy PID weights
261     Int_t    i;
262     Double_t pid[5];
263     esdTrack->GetESDpid(pid);
264     for (i = 0; i < 5; i++) fPIDWeight[i] = pid[i];
265     
266     // copy flags
267     fFlags = esdTrack->GetStatus();
268     
269     // copy charge sign
270     fCharge = (Short_t)esdTrack->Charge();
271  
272     return kTRUE;
273 }
274
275
276 //_____________________________________________________________________________
277 Bool_t AliRsnDaughter::Adopt(AliAODTrack* aodTrack)
278 {
279 //=========================================================
280 // Copies data from an AliAODtrack into "this":
281 //  - charge sign
282 //  - momentum
283 //  - point of closest approach to primary vertex
284 //  - ESD pid weights
285 // In case of errors returns kFALSE, otherwise kTRUE.
286 //=========================================================
287
288     if (!aodTrack) {
289         AliError("Passed NULL object: nothing done");
290         return kFALSE;
291     }
292         
293     // copy momentum  and vertex
294     fP[0] = aodTrack->Px();
295     fP[1] = aodTrack->Py();
296     fP[2] = aodTrack->Pz();
297     fV[0] = aodTrack->Xv();
298     fV[1] = aodTrack->Yv();
299     fV[2] = aodTrack->Zv();
300     
301     // copy PID weights
302     Int_t i;
303     for (i = 0; i < 5; i++) fPIDWeight[i] = aodTrack->PID()[i];
304     
305     // copy sign
306     fCharge = aodTrack->Charge();
307
308     return kTRUE;
309 }
310
311
312 //_____________________________________________________________________________
313 Bool_t AliRsnDaughter::Adopt(AliMCParticle *mcParticle)
314 {
315 //=========================================================
316 // Copies data from a MCParticle into "this":
317 //  - charge sign
318 //  - momentum
319 //  - point of closest approach to primary vertex
320 //  - ESD pid weights
321 //  - true PDG code
322 //  - mother
323 // In case of errors returns kFALSE, otherwise kTRUE.
324 //=========================================================
325
326     if (!mcParticle) {
327         AliError("Passed NULL object: nothing done");
328         return kFALSE;
329     }
330         
331         // retrieve the TParticle object from the argument
332         TParticle *particle = mcParticle->Particle();
333         if (!particle) {
334            AliError("AliMCParticle::Particle() returned NULL");
335            return kFALSE;
336     }
337         
338     // copy momentum  and vertex
339     fP[0] = particle->Px();
340     fP[1] = particle->Py();
341     fP[2] = particle->Pz();
342     fV[0] = particle->Vx();
343     fV[1] = particle->Vy();
344     fV[2] = particle->Vz();
345     
346     // recognize charge sign from PDG code sign
347     Int_t pdg = particle->GetPdgCode();
348     Int_t absPDG = TMath::Abs(pdg);
349     if (absPDG <= 15) {
350         if (pdg > 0) fCharge = -1; else fCharge = 1;
351     }
352     else if (absPDG < 3000) {
353         if (pdg > 0) fCharge = 1; else fCharge = -1;
354     }
355     else {
356         fCharge = 0;
357         return kFALSE;
358     }
359     
360     // identify track perfectly using PDG code
361     fPIDType = AliRsnPID::InternalType(pdg);
362     fPIDProb = 1.0;
363     fMass = AliRsnPID::ParticleMass(fPIDType);
364     
365     // flags and PID weights make no sense with MC tracks
366     fFlags = 0;
367     for (pdg = 0; pdg < AliRsnPID::kSpecies; pdg++) fPIDWeight[pdg] = 0.0;
368     fPIDWeight[fPIDType] = 1.0;
369     
370     // copy other MC info (mother PDG code cannot be retrieved here)
371     InitParticle(particle);
372
373     return kTRUE;
374 }
375
376 //_____________________________________________________________________________
377 void AliRsnDaughter::Print(Option_t *option) const
378 {
379 //=========================================================
380 // Prints the values of data members, using the options:
381 // - P --> momentum
382 // - V --> DCA vertex
383 // - C --> electric charge
384 // - F --> flags
385 // - I --> identification (PID, probability and mass)
386 // - W --> PID weights
387 // - M --> Montecarlo (from AliRsnParticle)
388 // - ALL --> All oprions switched on
389 //
390 // Index and label are printed by default.
391 //=========================================================
392
393     TString opt(option);
394     opt.ToUpper();
395     
396     cout << ".......Index            : " << fIndex << endl;
397     cout << ".......Label            : " << fLabel << endl;
398     
399     if (opt.Contains("P") || opt.Contains("ALL")) {
400         cout << ".......Px, Py, Pz, Pt   : " << Px() << ' ' << Py() << ' ' << Pz() << ' ' << Pt() << endl;
401     }
402     if (opt.Contains("V") || opt.Contains("ALL")) {
403         cout << ".......Vx, Vy, Vz       : " << Xv() << ' ' << Yv() << ' ' << Zv() << endl;
404     }
405     if (opt.Contains("C") || opt.Contains("ALL")) {
406         cout << ".......Charge           : " << fCharge << endl;
407     }
408     if (opt.Contains("F") || opt.Contains("ALL")) {
409         cout << ".......Flags            : " << fFlags << endl;
410     }
411     if (opt.Contains("I") || opt.Contains("ALL")) {
412         cout << ".......PID              : " << AliRsnPID::ParticleName(fPIDType) << endl;
413         cout << ".......PID probability  : " << fPIDProb << endl;
414         cout << ".......Mass             : " << fMass << endl;
415     }
416     if (opt.Contains("W") || opt.Contains("ALL")) {
417         cout << ".......Weights          : ";
418         Int_t i;
419         for (i = 0; i < AliRsnPID::kSpecies; i++) cout << fPIDWeight[i] << ' ';
420         cout << endl;
421     }
422     if (opt.Contains("M") || opt.Contains("ALL")) {
423         if (fParticle) {
424             cout << ".......PDG code         : " << fParticle->PDG() << endl;
425             cout << ".......Mother (label)   : " << fParticle->Mother() << endl;
426             cout << ".......Mother (PDG code): " << fParticle->MotherPDG() << endl;
427         }
428         else {
429             cout << ".......MC info not present" << endl;
430         }
431     }
432 }
433
434
435 //_____________________________________________________________________________
436 AliRsnDaughter AliRsnDaughter::Sum(AliRsnDaughter t1, AliRsnDaughter t2)
437 {
438 //=========================================================
439 // Creates an AliRsnDaughter object composing momenta
440 // of the particles passed as arguments.
441 // The vector momentum of the returned object is 
442 // the sum of the ones of the arguments.
443 // The mass of the object is set to the invariant mass
444 // computed from the relativistic sum of the 4-momenta
445 // of the two arguments.
446 // Finally, if both arguments have the same 'fMother' 
447 // (when this MC information is available), it is set
448 // also as the 'fMother' of the returned object, together
449 // with its PDG code.
450 //=========================================================
451
452     // create a 'default' new AliRsnDaughter
453     AliRsnDaughter out;
454     
455     // define the momentum of the sum as the 
456     // relativistic sum of 4-momenta of arguments
457     Double_t etot  = t1.E()  + t2.E();
458     Double_t pxTot = t1.Px() + t2.Px();
459     Double_t pyTot = t1.Py() + t2.Py();
460     Double_t pzTot = t1.Pz() + t2.Pz();
461     Double_t mass  = TMath::Sqrt(etot*etot - pxTot*pxTot - pyTot*pyTot - pzTot*pzTot);
462     out.SetM(mass);
463     out.SetP(pxTot, pyTot, pzTot);
464     
465     // if both arguments have MC info, it is used here
466     // to check if they (in the truth MC) are daughters
467     // of the same resonance and, if this is the case,
468     // details of that resonance are set into the 
469     // 'fParticle' object of the sum
470     Int_t mum1, mum2;
471     if (t1.GetParticle() && t2.GetParticle()) {
472         out.InitParticle();
473         mum1 = t1.GetParticle()->Mother();
474         mum2 = t2.GetParticle()->Mother();
475         if (mum1 == mum2 && mum1 >= 0) {
476             out.SetLabel(mum1);
477             out.GetParticle()->SetPDG(t1.GetParticle()->MotherPDG());
478         }
479     }
480
481     return out;
482 }
483
484
485 //_____________________________________________________________________________
486 void AliRsnDaughter::InitParticle()
487 {
488 //=========================================================
489 // Initializes the particle object with default constructor.
490 //=========================================================
491
492     fParticle = new AliRsnParticle;
493 }
494
495 //_____________________________________________________________________________
496 Bool_t AliRsnDaughter::InitParticle(TParticle *particle)
497 {
498 //=========================================================
499 // Copies data from an MC particle into the object which
500 // contains all MC details taken from kinematics info.
501 // If requested by second argument, momentum and vertex
502 // of the Particle are copied into the 'fP' and 'fV'
503 // data members, to simulate a perfect reconstruction.
504 // If something goes wrong, returns kFALSE, 
505 // otherwise returns kTRUE.
506 //=========================================================
507
508     // retrieve the TParticle object pointed by this MC track
509     if (!particle) {
510         AliError("Passed NULL particle object");
511         return kFALSE;
512     }
513         
514     // initialize object if not initialized yet
515     if (fParticle) delete fParticle;
516     fParticle = new AliRsnParticle;
517     fParticle->Adopt(particle);
518
519     return kTRUE;
520 }
521
522
523 //_____________________________________________________________________________
524 Bool_t AliRsnDaughter::InitParticle(AliMCParticle *mcParticle)
525 {
526 //=========================================================
527 // Copies data from an MC particle into the object which
528 // contains all MC details taken from kinematics info.
529 // If requested by second argument, momentum and vertex
530 // of the Particle are copied into the 'fP' and 'fV'
531 // data members, to simulate a perfect reconstruction.
532 // If something goes wrong, returns kFALSE, 
533 // otherwise returns kTRUE.
534 //=========================================================
535
536     // retrieve the TParticle object pointed by this MC track
537     TParticle *particle = mcParticle->Particle();
538     return InitParticle(particle);
539 }