2 // Class AliRsnDaughter
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.
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.
12 // authors: A. Pulvirenti (alberto.pulvirenti@ct.infn.it)
13 // M. Vala (martin.vala@cern.ch)
16 #include <Riostream.h>
17 #include <TParticle.h>
20 #include "AliESDtrack.h"
21 #include "AliAODEvent.h"
22 #include "AliAODVertex.h"
23 #include "AliAODTrack.h"
25 #include "AliRsnPIDDefESD.h"
26 #include "AliRsnDaughter.h"
28 ClassImp(AliRsnDaughter)
30 AliRsnDaughter::EPIDMethod AliRsnDaughter::fgPIDMethod = AliRsnDaughter::kRealistic;
32 //_____________________________________________________________________________
33 AliRsnDaughter::AliRsnDaughter(AliVParticle *ref, TParticle *refMC) :
41 fReqPID(AliPID::kUnknown),
45 // Default constructor.
49 //_____________________________________________________________________________
50 AliRsnDaughter::AliRsnDaughter(const AliRsnDaughter ©) :
53 fKinkIndex(copy.fKinkIndex),
54 fParticle(copy.fParticle),
55 fMotherPDG(copy.fMotherPDG),
56 fStatus(copy.fStatus),
59 fReqPID(copy.fReqPID),
64 // Pointers are NOT duplicated.
68 //_____________________________________________________________________________
69 AliRsnDaughter& AliRsnDaughter::operator=(const AliRsnDaughter ©)
72 // Assignment operator.
75 (TObject)(*this) = (TObject)copy;
78 fKinkIndex = copy.fKinkIndex;
79 fParticle = copy.fParticle;
80 fMotherPDG = copy.fMotherPDG;
81 fStatus = copy.fStatus;
85 fReqPID = copy.fReqPID;
92 //_____________________________________________________________________________
93 AliRsnDaughter::~AliRsnDaughter()
97 // Since pointers do not allocate new objects, nothing is done.
101 //_____________________________________________________________________________
102 void AliRsnDaughter::RotateP
103 (Double_t angle, Double_t &x, Double_t &y, Bool_t isDegrees)
106 // Rotate the transverse momentum by an angle (in DEGREES)
107 // around Z axis (does not change the Z component).
108 // Rotated values are stored in the two arguments passed by reference.
111 if (isDegrees) angle *= TMath::DegToRad();
113 Double_t s = TMath::Sin(angle);
114 Double_t c = TMath::Cos(angle);
120 //_____________________________________________________________________________
121 Double_t AliRsnDaughter::AngleTo(AliRsnDaughter d, Bool_t outInDegrees)
124 // Compute angle between the vector momentum of this
125 // and the one of argument.
128 Double_t arg, dot, ptot2 = P2() * d.P2();
133 dot = Px()*d.Px() + Py()*d.Py() + Pz()*d.Pz();
134 arg = dot / TMath::Sqrt(ptot2);
135 if (arg > 1.0) arg = 1.0;
136 if (arg < -1.0) arg = -1.0;
137 if (outInDegrees) return TMath::ACos(arg) * TMath::RadToDeg();
138 else return TMath::ACos(arg);
142 //_____________________________________________________________________________
143 Int_t AliRsnDaughter::GetID() const
146 // Return reference index, using the "GetID" method
147 // of the possible source object.
150 AliESDtrack *esd = dynamic_cast<AliESDtrack*>(fRef);
151 if (esd) return esd->GetID();
153 AliAODTrack *aod = dynamic_cast<AliAODTrack*>(fRef);
154 if (aod) return aod->GetID();
159 //_____________________________________________________________________________
160 AliPID::EParticleType AliRsnDaughter::RealisticPID() const
163 // Return the "realistic" PID of this track,
164 // i.e. the particle species to which corresponds the largest PID probability.
167 AliPID::EParticleType pid = AliPID::kElectron;
168 Double_t prob = fPID[0];
171 for (i = 1; i < AliPID::kSPECIES; i++) {
172 if (fPID[i] > prob) {
174 pid = (AliPID::EParticleType)i;
181 //_____________________________________________________________________________
182 AliPID::EParticleType AliRsnDaughter::PerfectPID() const
185 // Return the "perfect" PID of this track,
186 // reading it from the MC information, if available.
189 if (!fParticle) return AliPID::kUnknown;
191 Int_t absPDG = TMath::Abs(fParticle->GetPdgCode());
194 return AliPID::kElectron;
196 return AliPID::kMuon;
198 return AliPID::kPion;
200 return AliPID::kKaon;
202 return AliPID::kProton;
204 AliDebug(2, Form("PDG code = %d not recognized. Return 'AliPID::kUnknown'", absPDG));
205 return AliPID::kUnknown;
209 //_____________________________________________________________________________
210 AliPID::EParticleType AliRsnDaughter::PIDType(Double_t &prob) const
213 // Return the PID type according to the selected method
214 // in the argument passed by reference, the probability is stored.
215 // It will be realistic for realistic PID and 1 for perfect PID.
218 AliPID::EParticleType pid = AssignedPID();
221 if (fgPIDMethod == kRealistic) prob = fPID[(Int_t)pid];
226 //_____________________________________________________________________________
227 AliPID::EParticleType AliRsnDaughter::AssignedPID() const
230 // Return the PID type according to the selected method
231 // in the argument passed by reference, the probability is stored.
232 // It will be realistic for realistic PID and 1 for perfect PID.
235 switch (fgPIDMethod) {
237 return AliPID::kUnknown;
241 return RealisticPID();
243 AliWarning("PID method not properly set. Returning realistic PID");
244 return RealisticPID();
248 //_____________________________________________________________________________
249 Bool_t AliRsnDaughter::CombineWithPriors(const Double_t *priors, AliRsnPIDDefESD *pidDef)
252 // Combine current PID weights (assumed to be them) with prior probs
258 // get PID weights according to definition
259 // if the reference is not ESD or the pidDef is null
260 // of it is not null but is requires the ESD pid,
261 // the standard PID value is used, otherwise
262 if (pidDef && GetRefESD()) {
263 pidDef->ComputeWeights(GetRefESD(), fPID);
266 for (i = 0; i < AliPID::kSPECIES; i++) fPID[i] = fRef->PID()[i];
267 else if (fParticle) {
268 // if the PID() returns 0x0, this is a MC particle
269 // and we set the weight corresponding to its species to 1
270 // and the others to zero
271 for (i = 0; i < AliPID::kSPECIES; i++) fPID[i] = 0.0;
272 i = (Int_t)AliRsnDaughter::InternalType(TMath::Abs(fParticle->GetPdgCode()));
277 // multiply weights and priors
278 for (i = 0; i < AliPID::kSPECIES; i++) {
279 fPID[i] *= priors[i];
283 if (sum < 0.0) AliError(Form("Sum of weights = %f < 0", sum));
288 for (i = 0; i < AliPID::kSPECIES; i++) fPID[i] /= sum;
293 //_____________________________________________________________________________
294 void AliRsnDaughter::FindMotherPDG(AliStack *const stack)
297 // Searches the stack to find the mother and retrieve its PDG code.
300 if (!stack || !fParticle) return;
302 const Int_t mLabel = fParticle->GetFirstMother();
306 TParticle *mum = stack->Particle(mLabel);
307 if (mum) fMotherPDG = mum->GetPdgCode();
312 //_____________________________________________________________________________
313 Double_t AliRsnDaughter::GetMCEnergy(Double_t mass)
316 // Uses the argument to compute 4-momentum energy
319 if (!fParticle) return 0.0;
321 Double_t p2 = fParticle->Px()*fParticle->Px();
322 p2 += fParticle->Py()*fParticle->Py();
323 p2 += fParticle->Pz()*fParticle->Pz();
325 return TMath::Sqrt(mass*mass + p2);
328 //_____________________________________________________________________________
329 void AliRsnDaughter::FindKinkIndex(const AliESDtrack *esdTrack)
332 // Assign kink index from an ESD track
336 for (i = 0; i < 3; i++) ik[i] = esdTrack->GetKinkIndex(i);
338 if (ik[0] < 0 || ik[1] < 0 || ik[2] < 0) {
340 } else if (ik[0] > 0 || ik[1] > 0 || ik[2] > 0) {
345 //_____________________________________________________________________________
346 void AliRsnDaughter::FindKinkIndex(AliAODEvent *const event)
349 // Assign kink index from an AOD event
352 Int_t iv, id, nD, nV = event->GetNumberOfVertices();
353 for (iv = 0; iv < nV; iv++) {
354 AliAODVertex *v = event->GetVertex(iv);
355 AliAODVertex::AODVtx_t type = (AliAODVertex::AODVtx_t)v->GetType();
356 if (type != AliAODVertex::kKink) continue;
357 AliAODTrack *mother = (AliAODTrack*)v->GetParent();
358 if (mother == (AliAODTrack*)fRef) {
362 nD = v->GetNDaughters();
363 for (id = 0; id < nD; id++) {
364 AliAODTrack *son = (AliAODTrack*)v->GetDaughter(id);
365 if (son == (AliAODTrack*)fRef) {
376 //_____________________________________________________________________________
377 void AliRsnDaughter::Reset()
380 // Reset this track to meaningless values
391 //_____________________________________________________________________________
392 void AliRsnDaughter::Print(Option_t * const option) const
395 // Prints the values of data members, using the options:
397 // - V --> DCA vertex
398 // - C --> electric charge
400 // - I --> identification (PID, probability and mass)
401 // - W --> PID weights
402 // - M --> Montecarlo
403 // - L --> index & label
405 // - ALL --> All oprions switched on
407 // Index and label are printed by default.
413 if (opt.Contains("L") || opt.Contains("ALL")) {
414 cout << ".......Index : " << GetID() << endl;
415 cout << ".......Label : " << GetLabel() << endl;
417 if (opt.Contains("P") || opt.Contains("ALL")) {
418 cout << ".......Px, Py, Pz, Pt : " << Px() << ' ' << Py() << ' ' << Pz() << ' ' << Pt() << endl;
420 if (opt.Contains("A") || opt.Contains("ALL")) {
421 cout << ".......Phi, Theta : " << Phi() << ' ' << Theta() << endl;
423 if (opt.Contains("V") || opt.Contains("ALL")) {
424 cout << ".......Vx, Vy, Vz : " << Xv() << ' ' << Yv() << ' ' << Zv() << endl;
426 if (opt.Contains("I") || opt.Contains("ALL")) {
427 AliPID::EParticleType type;
429 type = PIDType(prob);
430 cout << ".......PID & prob : " << AliPID::ParticleName(type) << ' ' << prob << endl;
432 if (opt.Contains("C") || opt.Contains("ALL")) {
433 cout << ".......Charge : " << Charge() << endl;
435 if (opt.Contains("F") || opt.Contains("ALL")) {
436 cout << ".......Flags : " << fStatus << endl;
438 if (opt.Contains("W") || opt.Contains("ALL")) {
439 cout << ".......Weights : ";
441 for (i = 0; i < AliPID::kSPECIES; i++) cout << fPID[i] << ' ';
444 if (opt.Contains("M") || opt.Contains("ALL")) {
446 cout << ".......PDG code : " << fParticle->GetPdgCode() << endl;
447 cout << ".......Mother (label) : " << fParticle->GetFirstMother() << endl;
448 cout << ".......Mother (PDG code): " << fMotherPDG << endl;
450 cout << ".......MC info not present" << endl;
455 //_____________________________________________________________________________
456 AliPID::EParticleType AliRsnDaughter::InternalType(Int_t pdg)
459 // Return the internal enum value corresponding to the PDG
460 // code passed as argument, if possible.
461 // Otherwise, returns 'AliPID::kSPECIES' by default.
464 AliPID::EParticleType value;
465 Int_t absPDG = TMath::Abs(pdg);
469 value = AliPID::kElectron;
472 value = AliPID::kMuon;
475 value = AliPID::kPion;
478 value = AliPID::kKaon;
481 value = AliPID::kProton;
484 value = AliPID::kUnknown;
489 //_____________________________________________________________________________
490 const char* AliRsnDaughter::MethodName(EPIDMethod method)
493 // Returns a string with the method name