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