]> git.uio.no Git - u/mrichter/AliRoot.git/blame_incremental - PWG2/RESONANCES/AliRsnDaughter.cxx
// Macro to generate and update OCDB entries for a given run:
[u/mrichter/AliRoot.git] / PWG2 / RESONANCES / AliRsnDaughter.cxx
... / ...
CommitLineData
1//
2// Class AliRsnDaughter
3//
4// Interface to candidate daughters of a resonance (tracks).
5// Points to the source of information, which is generally an AliVParticle-derived object
6// and contains few internal data-members to store "on fly" some important information
7// for the computations required during resonance analysis.
8// ---
9// Since the package revision, this object is not supposed to be stacked in memory
10// but created "on fly" during analysis and used just for computations, as an interface.
11//
12// authors: A. Pulvirenti (alberto.pulvirenti@ct.infn.it)
13// M. Vala (martin.vala@cern.ch)
14//
15
16#include <Riostream.h>
17#include <TParticle.h>
18
19#include "AliStack.h"
20#include "AliESDtrack.h"
21#include "AliAODEvent.h"
22#include "AliAODVertex.h"
23#include "AliAODTrack.h"
24
25#include "AliRsnPIDDefESD.h"
26#include "AliRsnDaughter.h"
27
28ClassImp(AliRsnDaughter)
29
30AliRsnDaughter::EPIDMethod AliRsnDaughter::fgPIDMethod = AliRsnDaughter::kRealistic;
31
32//_____________________________________________________________________________
33AliRsnDaughter::AliRsnDaughter(AliVParticle *ref, TParticle *refMC) :
34 fOK((ref != 0)),
35 fKinkIndex(0),
36 fParticle(refMC),
37 fMotherPDG(0),
38 fStatus(0),
39 fPairIndex(0),
40 fDr(0.0),
41 fDz(0.0),
42 fReqPID(AliPID::kUnknown),
43 fRef(ref)
44{
45//
46// Default constructor.
47//
48}
49
50//_____________________________________________________________________________
51AliRsnDaughter::AliRsnDaughter(const AliRsnDaughter &copy) :
52 TObject(copy),
53 fOK(copy.fOK),
54 fKinkIndex(copy.fKinkIndex),
55 fParticle(copy.fParticle),
56 fMotherPDG(copy.fMotherPDG),
57 fStatus(copy.fStatus),
58 fPairIndex(copy.fPairIndex),
59 fDr(copy.fDr),
60 fDz(copy.fDz),
61 fReqPID(copy.fReqPID),
62 fRef(copy.fRef)
63{
64//
65// Copy constructor.
66// Pointers are NOT duplicated.
67//
68}
69
70//_____________________________________________________________________________
71AliRsnDaughter& AliRsnDaughter::operator=(const AliRsnDaughter &copy)
72{
73//
74// Assignment operator.
75//
76
77 (TObject)(*this) = (TObject)copy;
78
79 fOK = copy.fOK;
80 fKinkIndex = copy.fKinkIndex;
81 fParticle = copy.fParticle;
82 fMotherPDG = copy.fMotherPDG;
83 fStatus = copy.fStatus;
84 fPairIndex = copy.fPairIndex;
85 fDr = copy.fDr;
86 fDz = copy.fDz;
87
88 fReqPID = copy.fReqPID;
89
90 fRef = copy.fRef;
91
92 return (*this);
93}
94
95//_____________________________________________________________________________
96AliRsnDaughter::~AliRsnDaughter()
97{
98//
99// Destructor.
100// Since pointers do not allocate new objects, nothing is done.
101//
102}
103
104//_____________________________________________________________________________
105void AliRsnDaughter::RotateP
106(Double_t angle, Double_t &x, Double_t &y, Bool_t isDegrees) const
107{
108//
109// Rotate the transverse momentum by an angle (in DEGREES)
110// around Z axis (does not change the Z component).
111// Rotated values are stored in the two arguments passed by reference.
112//
113
114 if (isDegrees) angle *= TMath::DegToRad();
115
116 Double_t s = TMath::Sin(angle);
117 Double_t c = TMath::Cos(angle);
118
119 x = c*Px() - s*Py();
120 y = s*Px() + c*Py();
121}
122
123//_____________________________________________________________________________
124Double_t AliRsnDaughter::AngleTo(AliRsnDaughter d, Bool_t outInDegrees)
125{
126//
127// Compute angle between the vector momentum of this
128// and the one of argument.
129//
130
131 Double_t arg, dot, ptot2 = P2() * d.P2();
132
133 if (ptot2 <= 0) {
134 return 0.0;
135 } else {
136 dot = Px()*d.Px() + Py()*d.Py() + Pz()*d.Pz();
137 arg = dot / TMath::Sqrt(ptot2);
138 if (arg > 1.0) arg = 1.0;
139 if (arg < -1.0) arg = -1.0;
140 if (outInDegrees) return TMath::ACos(arg) * TMath::RadToDeg();
141 else return TMath::ACos(arg);
142 }
143}
144
145//_____________________________________________________________________________
146Int_t AliRsnDaughter::GetID() const
147{
148//
149// Return reference index, using the "GetID" method
150// of the possible source object.
151//
152
153 AliESDtrack *esd = dynamic_cast<AliESDtrack*>(fRef);
154 if (esd) return esd->GetID();
155
156 AliAODTrack *aod = dynamic_cast<AliAODTrack*>(fRef);
157 if (aod) return aod->GetID();
158
159 return GetLabel();
160}
161
162//_____________________________________________________________________________
163AliPID::EParticleType AliRsnDaughter::RealisticPID() const
164{
165//
166// Return the "realistic" PID of this track,
167// i.e. the particle species to which corresponds the largest PID probability.
168//
169
170 AliPID::EParticleType pid = AliPID::kElectron;
171 Double_t prob = fPID[0];
172
173 Int_t i;
174 for (i = 1; i < AliPID::kSPECIES; i++) {
175 if (fPID[i] > prob) {
176 prob = fPID[i];
177 pid = (AliPID::EParticleType)i;
178 }
179 }
180
181 return pid;
182}
183
184//_____________________________________________________________________________
185AliPID::EParticleType AliRsnDaughter::PerfectPID() const
186{
187//
188// Return the "perfect" PID of this track,
189// reading it from the MC information, if available.
190//
191
192 if (!fParticle) return AliPID::kUnknown;
193
194 Int_t absPDG = TMath::Abs(fParticle->GetPdgCode());
195 switch (absPDG) {
196 case 11:
197 return AliPID::kElectron;
198 case 13:
199 return AliPID::kMuon;
200 case 211:
201 return AliPID::kPion;
202 case 321:
203 return AliPID::kKaon;
204 case 2212:
205 return AliPID::kProton;
206 default:
207 AliDebug(2, Form("PDG code = %d not recognized. Return 'AliPID::kUnknown'", absPDG));
208 return AliPID::kUnknown;
209 }
210}
211
212//_____________________________________________________________________________
213AliPID::EParticleType AliRsnDaughter::PIDType(Double_t &prob) const
214{
215//
216// Return the PID type according to the selected method
217// in the argument passed by reference, the probability is stored.
218// It will be realistic for realistic PID and 1 for perfect PID.
219//
220
221 AliPID::EParticleType pid = AssignedPID();
222
223 prob = 1.0;
224 if (fgPIDMethod == kRealistic) prob = fPID[(Int_t)pid];
225
226 return pid;
227}
228
229//_____________________________________________________________________________
230AliPID::EParticleType AliRsnDaughter::AssignedPID() const
231{
232//
233// Return the PID type according to the selected method
234// in the argument passed by reference, the probability is stored.
235// It will be realistic for realistic PID and 1 for perfect PID.
236//
237
238 switch (fgPIDMethod) {
239 case kNoPID:
240 return AliPID::kUnknown;
241 case kPerfect:
242 return PerfectPID();
243 case kRealistic:
244 return RealisticPID();
245 default:
246 AliWarning("PID method not properly set. Returning realistic PID");
247 return RealisticPID();
248 }
249}
250
251//_____________________________________________________________________________
252Bool_t AliRsnDaughter::CombineWithPriors(const Double_t *priors, AliRsnPIDDefESD *pidDef)
253{
254//
255// Combine current PID weights (assumed to be them) with prior probs
256//
257
258 Int_t i;
259 Double_t sum = 0.0;
260
261 // get PID weights according to definition
262 // if the reference is not ESD or the pidDef is null
263 // of it is not null but is requires the ESD pid,
264 // the standard PID value is used, otherwise
265 if (pidDef && GetRefESD()) {
266 pidDef->ComputeWeights(GetRefESD(), fPID);
267 } else {
268 if (fRef->PID())
269 for (i = 0; i < AliPID::kSPECIES; i++) fPID[i] = fRef->PID()[i];
270 else if (fParticle) {
271 // if the PID() returns 0x0, this is a MC particle
272 // and we set the weight corresponding to its species to 1
273 // and the others to zero
274 for (i = 0; i < AliPID::kSPECIES; i++) fPID[i] = 0.0;
275 i = (Int_t)AliRsnDaughter::InternalType(TMath::Abs(fParticle->GetPdgCode()));
276 fPID[i] = 1.0;
277 }
278 }
279
280 // multiply weights and priors
281 for (i = 0; i < AliPID::kSPECIES; i++) {
282 fPID[i] *= priors[i];
283 sum += fPID[i];
284 }
285 if (sum <= 0.0) {
286 if (sum < 0.0) AliError(Form("Sum of weights = %f < 0", sum));
287 return kFALSE;
288 }
289
290 // normalize
291 for (i = 0; i < AliPID::kSPECIES; i++) fPID[i] /= sum;
292
293 return kTRUE;
294}
295
296//_____________________________________________________________________________
297void AliRsnDaughter::FindMotherPDG(AliStack *const stack)
298{
299//
300// Searches the stack to find the mother and retrieve its PDG code.
301//
302
303 if (!stack || !fParticle) return;
304
305 const Int_t mLabel = fParticle->GetFirstMother();
306 if (mLabel < 0) {
307 fMotherPDG = 0;
308 } else {
309 TParticle *mum = stack->Particle(mLabel);
310 if (mum) fMotherPDG = mum->GetPdgCode();
311 else fMotherPDG = 0;
312 }
313}
314
315//_____________________________________________________________________________
316Double_t AliRsnDaughter::GetMCEnergy(Double_t mass)
317{
318//
319// Uses the argument to compute 4-momentum energy
320//
321
322 if (!fParticle) return 0.0;
323
324 Double_t p2 = fParticle->Px()*fParticle->Px();
325 p2 += fParticle->Py()*fParticle->Py();
326 p2 += fParticle->Pz()*fParticle->Pz();
327
328 return TMath::Sqrt(mass*mass + p2);
329}
330
331//_____________________________________________________________________________
332void AliRsnDaughter::FindKinkIndex(const AliESDtrack *esdTrack)
333{
334//
335// Assign kink index from an ESD track
336//
337
338 Int_t i, ik[3];
339 for (i = 0; i < 3; i++) ik[i] = esdTrack->GetKinkIndex(i);
340
341 if (ik[0] < 0 || ik[1] < 0 || ik[2] < 0) {
342 SetKinkMother();
343 } else if (ik[0] > 0 || ik[1] > 0 || ik[2] > 0) {
344 SetKinkDaughter();
345 } else SetNoKink();
346}
347
348//_____________________________________________________________________________
349void AliRsnDaughter::FindKinkIndex(AliAODEvent *const event)
350{
351//
352// Assign kink index from an AOD event
353//
354
355 Int_t iv, id, nD, nV = event->GetNumberOfVertices();
356 for (iv = 0; iv < nV; iv++) {
357 AliAODVertex *v = event->GetVertex(iv);
358 AliAODVertex::AODVtx_t type = (AliAODVertex::AODVtx_t)v->GetType();
359 if (type != AliAODVertex::kKink) continue;
360 AliAODTrack *mother = (AliAODTrack*)v->GetParent();
361 if (mother == (AliAODTrack*)fRef) {
362 SetKinkMother();
363 return;
364 } else {
365 nD = v->GetNDaughters();
366 for (id = 0; id < nD; id++) {
367 AliAODTrack *son = (AliAODTrack*)v->GetDaughter(id);
368 if (son == (AliAODTrack*)fRef) {
369 SetKinkDaughter();
370 return;
371 }
372 }
373 }
374 }
375
376 SetNoKink();
377}
378
379//_____________________________________________________________________________
380void AliRsnDaughter::Reset()
381{
382//
383// Reset this track to meaningless values
384//
385
386 fOK = kFALSE;
387 fKinkIndex = 0;
388 fParticle = 0x0;
389 fMotherPDG = 0;
390 fStatus = 0;
391 fRef = 0x0;
392}
393
394//_____________________________________________________________________________
395void AliRsnDaughter::Print(Option_t * const option) const
396{
397//
398// Prints the values of data members, using the options:
399// - P --> momentum
400// - V --> DCA vertex
401// - C --> electric charge
402// - F --> flags
403// - I --> identification (PID, probability and mass)
404// - W --> PID weights
405// - M --> Montecarlo
406// - L --> index & label
407// - A --> angles
408// - ALL --> All oprions switched on
409//
410// Index and label are printed by default.
411//
412
413 TString opt(option);
414 opt.ToUpper();
415
416 if (opt.Contains("L") || opt.Contains("ALL")) {
417 cout << ".......Index : " << GetID() << endl;
418 cout << ".......Label : " << GetLabel() << endl;
419 }
420 if (opt.Contains("P") || opt.Contains("ALL")) {
421 cout << ".......Px, Py, Pz, Pt : " << Px() << ' ' << Py() << ' ' << Pz() << ' ' << Pt() << endl;
422 }
423 if (opt.Contains("A") || opt.Contains("ALL")) {
424 cout << ".......Phi, Theta : " << Phi() << ' ' << Theta() << endl;
425 }
426 if (opt.Contains("V") || opt.Contains("ALL")) {
427 cout << ".......Vx, Vy, Vz : " << Xv() << ' ' << Yv() << ' ' << Zv() << endl;
428 }
429 if (opt.Contains("I") || opt.Contains("ALL")) {
430 AliPID::EParticleType type;
431 Double_t prob;
432 type = PIDType(prob);
433 cout << ".......PID & prob : " << AliPID::ParticleName(type) << ' ' << prob << endl;
434 }
435 if (opt.Contains("C") || opt.Contains("ALL")) {
436 cout << ".......Charge : " << Charge() << endl;
437 }
438 if (opt.Contains("F") || opt.Contains("ALL")) {
439 cout << ".......Flags : " << fStatus << endl;
440 }
441 if (opt.Contains("W") || opt.Contains("ALL")) {
442 cout << ".......Weights : ";
443 Int_t i;
444 for (i = 0; i < AliPID::kSPECIES; i++) cout << fPID[i] << ' ';
445 cout << endl;
446 }
447 if (opt.Contains("M") || opt.Contains("ALL")) {
448 if (fParticle) {
449 cout << ".......PDG code : " << fParticle->GetPdgCode() << endl;
450 cout << ".......Mother (label) : " << fParticle->GetFirstMother() << endl;
451 cout << ".......Mother (PDG code): " << fMotherPDG << endl;
452 } else {
453 cout << ".......MC info not present" << endl;
454 }
455 }
456}
457
458//_____________________________________________________________________________
459AliPID::EParticleType AliRsnDaughter::InternalType(Int_t pdg)
460{
461//
462// Return the internal enum value corresponding to the PDG
463// code passed as argument, if possible.
464// Otherwise, returns 'AliPID::kSPECIES' by default.
465//
466
467 AliPID::EParticleType value;
468 Int_t absPDG = TMath::Abs(pdg);
469
470 switch (absPDG) {
471 case 11:
472 value = AliPID::kElectron;
473 break;
474 case 13:
475 value = AliPID::kMuon;
476 break;
477 case 211:
478 value = AliPID::kPion;
479 break;
480 case 321:
481 value = AliPID::kKaon;
482 break;
483 case 2212:
484 value = AliPID::kProton;
485 break;
486 default:
487 value = AliPID::kUnknown;
488 }
489 return value;
490}
491
492//_____________________________________________________________________________
493const char* AliRsnDaughter::MethodName(EPIDMethod method)
494{
495//
496// Returns a string with the method name
497//
498
499 switch (method)
500 {
501 case kNoPID:
502 return "No PID";
503 case kRealistic:
504 return "Realistic";
505 case kPerfect:
506 return "Perfect";
507 default:
508 return "Unknown";
509 }
510}