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