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>
18 #include <TParticle.h>
23 #include "AliESDtrack.h"
24 #include "AliAODEvent.h"
25 #include "AliAODVertex.h"
26 #include "AliAODTrack.h"
28 #include "AliRsnPIDDefESD.h"
29 #include "AliRsnDaughter.h"
31 ClassImp(AliRsnDaughter)
33 AliRsnDaughter::EPIDMethod AliRsnDaughter::fgPIDMethod = AliRsnDaughter::kRealistic;
35 //_____________________________________________________________________________
36 AliRsnDaughter::AliRsnDaughter(AliVParticle *ref, TParticle *refMC) :
44 fReqPID(AliPID::kUnknown),
48 // Default constructor.
52 //_____________________________________________________________________________
53 AliRsnDaughter::AliRsnDaughter(const AliRsnDaughter ©) :
56 fKinkIndex(copy.fKinkIndex),
57 fParticle(copy.fParticle),
58 fMotherPDG(copy.fMotherPDG),
59 fStatus(copy.fStatus),
62 fReqPID(copy.fReqPID),
67 // Pointers are NOT duplicated.
71 //_____________________________________________________________________________
72 AliRsnDaughter& AliRsnDaughter::operator=(const AliRsnDaughter ©)
75 // Assignment operator.
78 (TObject)(*this) = (TObject)copy;
81 fKinkIndex = copy.fKinkIndex;
82 fParticle = copy.fParticle;
83 fMotherPDG = copy.fMotherPDG;
84 fStatus = copy.fStatus;
88 fReqPID = copy.fReqPID;
95 //_____________________________________________________________________________
96 AliRsnDaughter::~AliRsnDaughter()
100 // Since pointers do not allocate new objects, nothing is done.
104 //_____________________________________________________________________________
105 void AliRsnDaughter::RotateP
106 (Double_t angle, Double_t &x, Double_t &y, Bool_t isDegrees)
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.
114 if (isDegrees) angle *= TMath::DegToRad();
116 Double_t s = TMath::Sin(angle);
117 Double_t c = TMath::Cos(angle);
123 //_____________________________________________________________________________
124 Double_t AliRsnDaughter::AngleTo(AliRsnDaughter d, Bool_t outInDegrees)
127 // Compute angle between the vector momentum of this
128 // and the one of argument.
131 Double_t arg, dot, ptot2 = P2() * d.P2();
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);
145 //_____________________________________________________________________________
146 Int_t AliRsnDaughter::GetID() const
149 // Return reference index, using the "GetID" method
150 // of the possible source object.
153 AliESDtrack *esd = dynamic_cast<AliESDtrack*>(fRef);
154 if (esd) return esd->GetID();
156 AliAODTrack *aod = dynamic_cast<AliAODTrack*>(fRef);
157 if (aod) return aod->GetID();
162 //_____________________________________________________________________________
163 AliPID::EParticleType AliRsnDaughter::RealisticPID() const
166 // Return the "realistic" PID of this track,
167 // i.e. the particle species to which corresponds the largest PID probability.
170 AliPID::EParticleType pid = AliPID::kElectron;
171 Double_t prob = fPID[0];
174 for (i = 1; i < AliPID::kSPECIES; i++) {
175 if (fPID[i] > prob) {
177 pid = (AliPID::EParticleType)i;
184 //_____________________________________________________________________________
185 AliPID::EParticleType AliRsnDaughter::PerfectPID() const
188 // Return the "perfect" PID of this track,
189 // reading it from the MC information, if available.
192 if (!fParticle) return AliPID::kUnknown;
194 Int_t absPDG = TMath::Abs(fParticle->GetPdgCode());
197 return AliPID::kElectron;
199 return AliPID::kMuon;
201 return AliPID::kPion;
203 return AliPID::kKaon;
205 return AliPID::kProton;
207 AliDebug(2, Form("PDG code = %d not recognized. Return 'AliPID::kUnknown'", absPDG));
208 return AliPID::kUnknown;
212 //_____________________________________________________________________________
213 AliPID::EParticleType AliRsnDaughter::PIDType(Double_t &prob) const
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.
221 AliPID::EParticleType pid = AssignedPID();
224 if (fgPIDMethod == kRealistic) prob = fPID[(Int_t)pid];
229 //_____________________________________________________________________________
230 AliPID::EParticleType AliRsnDaughter::AssignedPID() const
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.
238 switch (fgPIDMethod) {
240 return AliPID::kUnknown;
244 return RealisticPID();
246 AliWarning("PID method not properly set. Returning realistic PID");
247 return RealisticPID();
251 //_____________________________________________________________________________
252 Bool_t AliRsnDaughter::CombineWithPriors(Double_t *priors, AliRsnPIDDefESD *pidDef)
255 // Combine current PID weights (assumed to be them) with prior probs
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
267 AliESDtrack *esdTrack = GetRefESD();
268 if (esdTrack) pidDef->ComputeWeights(esdTrack, fPID);
272 for (i = 0; i < AliPID::kSPECIES; i++) fPID[i] = fRef->PID()[i];
275 // multiply weights and priors
276 for (i = 0; i < AliPID::kSPECIES; i++) {
277 fPID[i] *= priors[i];
280 if (sum <= (Double_t) 0.) {
281 AliError(Form("Sum of weights = %f <= 0", sum));
286 for (i = 0; i < AliPID::kSPECIES; i++) fPID[i] /= sum;
291 //_____________________________________________________________________________
292 AliESDtrack* AliRsnDaughter::GetRefESD()
295 // Return a reference in format of ESD track
298 return dynamic_cast<AliESDtrack *>(fRef);
301 //_____________________________________________________________________________
302 void AliRsnDaughter::FindMotherPDG(AliStack *stack)
305 // Searches the stack to find the mother and retrieve its PDG code.
308 if (!stack || !fParticle) return;
310 Int_t mLabel = fParticle->GetFirstMother();
315 TParticle *mum = stack->Particle(mLabel);
316 if (mum) fMotherPDG = mum->GetPdgCode();
321 //_____________________________________________________________________________
322 Double_t AliRsnDaughter::GetMCEnergy(Double_t mass)
325 // Uses the argument to compute 4-momentum energy
328 if (!fParticle) return 0.0;
330 Double_t p2 = fParticle->Px()*fParticle->Px();
331 p2 += fParticle->Py()*fParticle->Py();
332 p2 += fParticle->Pz()*fParticle->Pz();
334 return TMath::Sqrt(mass*mass + p2);
337 //_____________________________________________________________________________
338 void AliRsnDaughter::FindKinkIndex(AliESDtrack *esdTrack)
341 // Assign kink index from an ESD track
345 for (i = 0; i < 3; i++) ik[i] = esdTrack->GetKinkIndex(i);
347 if (ik[0] < 0 || ik[1] < 0 || ik[2] < 0) {
350 else if (ik[0] > 0 || ik[1] > 0 || ik[2] > 0) {
356 //_____________________________________________________________________________
357 void AliRsnDaughter::FindKinkIndex(AliAODEvent *event)
360 // Assign kink index from an AOD event
363 Int_t iv, id, nD, nV = event->GetNumberOfVertices();
364 for (iv = 0; iv < nV; iv++) {
365 AliAODVertex *v = event->GetVertex(iv);
366 AliAODVertex::AODVtx_t type = (AliAODVertex::AODVtx_t)v->GetType();
367 if (type != AliAODVertex::kKink) continue;
368 AliAODTrack *mother = (AliAODTrack*)v->GetParent();
369 if (mother == (AliAODTrack*)fRef) {
373 nD = v->GetNDaughters();
374 for (id = 0; id < nD; id++) {
375 AliAODTrack *son = (AliAODTrack*)v->GetDaughter(id);
376 if (son == (AliAODTrack*)fRef) {
387 //_____________________________________________________________________________
388 void AliRsnDaughter::Reset()
391 // Reset this track to meaningless values
402 //_____________________________________________________________________________
403 void AliRsnDaughter::Print(Option_t *option) const
406 // Prints the values of data members, using the options:
408 // - V --> DCA vertex
409 // - C --> electric charge
411 // - I --> identification (PID, probability and mass)
412 // - W --> PID weights
413 // - M --> Montecarlo
414 // - L --> index & label
416 // - ALL --> All oprions switched on
418 // Index and label are printed by default.
424 if (opt.Contains("L") || opt.Contains("ALL")) {
425 cout << ".......Index : " << GetID() << endl;
426 cout << ".......Label : " << GetLabel() << endl;
428 if (opt.Contains("P") || opt.Contains("ALL")) {
429 cout << ".......Px, Py, Pz, Pt : " << Px() << ' ' << Py() << ' ' << Pz() << ' ' << Pt() << endl;
431 if (opt.Contains("A") || opt.Contains("ALL")) {
432 cout << ".......Phi, Theta : " << Phi() << ' ' << Theta() << endl;
434 if (opt.Contains("V") || opt.Contains("ALL")) {
435 cout << ".......Vx, Vy, Vz : " << Xv() << ' ' << Yv() << ' ' << Zv() << endl;
437 if (opt.Contains("I") || opt.Contains("ALL")) {
438 AliPID::EParticleType type;
440 type = PIDType(prob);
441 cout << ".......PID & prob : " << AliPID::ParticleName(type) << ' ' << prob << endl;
443 if (opt.Contains("C") || opt.Contains("ALL")) {
444 cout << ".......Charge : " << Charge() << endl;
446 if (opt.Contains("F") || opt.Contains("ALL")) {
447 cout << ".......Flags : " << fStatus << endl;
449 if (opt.Contains("W") || opt.Contains("ALL")) {
450 cout << ".......Weights : ";
452 for (i = 0; i < AliPID::kSPECIES; i++) cout << fPID[i] << ' ';
455 if (opt.Contains("M") || opt.Contains("ALL")) {
457 cout << ".......PDG code : " << fParticle->GetPdgCode() << endl;
458 cout << ".......Mother (label) : " << fParticle->GetFirstMother() << endl;
459 cout << ".......Mother (PDG code): " << fMotherPDG << endl;
461 cout << ".......MC info not present" << endl;
466 //_____________________________________________________________________________
467 AliPID::EParticleType AliRsnDaughter::InternalType(Int_t pdg)
469 // Return the internal enum value corresponding to the PDG
470 // code passed as argument, if possible.
471 // Otherwise, returns 'AliPID::kSPECIES' by default.
474 AliPID::EParticleType value;
475 Int_t absPDG = TMath::Abs(pdg);
479 value = AliPID::kElectron;
482 value = AliPID::kMuon;
485 value = AliPID::kPion;
488 value = AliPID::kKaon;
491 value = AliPID::kProton;
494 value = AliPID::kUnknown;