]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - PWG2/RESONANCES/AliRsnDaughter.cxx
Some bug fixes, removal of some duplicates and clarified the logic of some pieces...
[u/mrichter/AliRoot.git] / PWG2 / RESONANCES / AliRsnDaughter.cxx
index b65c7db6d5a4bfa3a9f875d80f0d82a31a2aa2ed..e17b09296d80b6460d832c573626be8eac196f34 100644 (file)
@@ -1,69 +1,45 @@
 //
-// Class AliRsnDaughter
-//
-// Interface to candidate daughters of a resonance (tracks).
-// Points to the source of information, which is generally an AliVParticle-derived object
-// and contains few internal data-members to store "on fly" some important information
-// for the computations required during resonance analysis.
-// ---
-// Since the package revision, this object is not supposed to be stacked in memory
-// but created "on fly" during analysis and used just for computations, as an interface.
-//
-// authors: A. Pulvirenti (alberto.pulvirenti@ct.infn.it)
-//          M. Vala (martin.vala@cern.ch)
+//  This class works as generic interface to each candidate resonance daughter.
+//  Its main purpose is to provide a unique reference which includes all the
+//  facilities available in the AliVParticle generic base class, plus all info
+//  which could be needed during analysis, which are not in AliVParticle but
+//  need to be accessed from ESD or AOD objects, usually in different ways.
+//  When MC is available, AliRsnDaughter matches each reconstructed object with
+//  its corresponding MC particle.
+//  
+//  Currently, this interface can point to all kinds of single-particle object
+//  which one can have in the reconstructed event: charged tracks, V0s and 
+//  cascades. It is care of the user to treat each of them in the correct way,
+//  regarding cuts, functions to be computed, etc.
+//
+//  authors: A. Pulvirenti (alberto.pulvirenti@ct.infn.it)
+//           M. Vala (martin.vala@cern.ch)
 //
 
-#include <Riostream.h>
 #include <TParticle.h>
+#include <TDatabasePDG.h>
 
-#include "AliStack.h"
-#include "AliESDtrack.h"
-#include "AliAODEvent.h"
-#include "AliAODVertex.h"
-#include "AliAODTrack.h"
-
-#include "AliRsnPIDDefESD.h"
 #include "AliRsnDaughter.h"
 
 ClassImp(AliRsnDaughter)
 
-AliRsnDaughter::EPIDMethod AliRsnDaughter::fgPIDMethod = AliRsnDaughter::kRealistic;
-
-//_____________________________________________________________________________
-AliRsnDaughter::AliRsnDaughter(AliVParticle *ref, TParticle *refMC) :
-    fOK((ref != 0)),
-    fKinkIndex(0),
-    fParticle(refMC),
-    fMotherPDG(0),
-    fStatus(0),
-    fPairIndex(0),
-    fDr(0.0),
-    fDz(0.0),
-    fReqPID(AliPID::kUnknown),
-    fRef(ref)
-{
-//
-// Default constructor.
-//
-}
-
 //_____________________________________________________________________________
 AliRsnDaughter::AliRsnDaughter(const AliRsnDaughter &copy) :
-    TObject(copy),
-    fOK(copy.fOK),
-    fKinkIndex(copy.fKinkIndex),
-    fParticle(copy.fParticle),
-    fMotherPDG(copy.fMotherPDG),
-    fStatus(copy.fStatus),
-    fPairIndex(copy.fPairIndex),
-    fDr(copy.fDr),
-    fDz(copy.fDz),
-    fReqPID(copy.fReqPID),
-    fRef(copy.fRef)
+   TObject(copy),
+   fOK(copy.fOK),
+   fLabel(copy.fLabel),
+   fMotherPDG(copy.fMotherPDG),
+   fRsnID(copy.fRsnID),
+   fPrec(copy.fPrec),
+   fPsim(copy.fPsim),
+   fRef(copy.fRef),
+   fRefMC(copy.fRefMC),
+   fOwnerEvent(copy.fOwnerEvent)
 {
 //
 // Copy constructor.
-// Pointers are NOT duplicated.
+// Pointers are NOT duplicated, since they don't come from a 'new'
+// statement, but from just referencing something in the data source.
 //
 }
 
@@ -72,439 +48,217 @@ AliRsnDaughter& AliRsnDaughter::operator=(const AliRsnDaughter &copy)
 {
 //
 // Assignment operator.
+// Pointers are NOT duplicated, since they don't come from a 'new'
+// statement, but from just referencing something in the data source.
 //
 
-  (TObject)(*this) = (TObject)copy;
-
-  fOK = copy.fOK;
-  fKinkIndex = copy.fKinkIndex;
-  fParticle  = copy.fParticle;
-  fMotherPDG = copy.fMotherPDG;
-  fStatus = copy.fStatus;
-  fPairIndex = copy.fPairIndex;
-  fDr = copy.fDr;
-  fDz = copy.fDz;
-
-  fReqPID = copy.fReqPID;
+   fOK         = copy.fOK;
+   fLabel      = copy.fLabel;
+   fMotherPDG  = copy.fMotherPDG;
+   fRsnID      = copy.fRsnID;
+   fPsim       = copy.fPsim;
+   fPrec       = copy.fPrec;
+   fRef        = copy.fRef;
+   fRefMC      = copy.fRefMC;
+   fOwnerEvent = copy.fOwnerEvent;
 
-  fRef = copy.fRef;
-
-  return (*this);
+   return (*this);
 }
 
 //_____________________________________________________________________________
-AliRsnDaughter::~AliRsnDaughter()
-{
-//
-// Destructor.
-// Since pointers do not allocate new objects, nothing is done.
-//
-}
-
-//_____________________________________________________________________________
-void AliRsnDaughter::RotateP
-(Double_t angle, Double_t &x, Double_t &y, Bool_t isDegrees) const
+void AliRsnDaughter::Reset()
 {
 //
-// Rotate the transverse momentum by an angle (in DEGREES)
-// around Z axis (does not change the Z component).
-// Rotated values are stored in the two arguments passed by reference.
+// Reset this track to meaningless values and to a 'bad' status.
+// After this has been done, this object should not be used
+// for analysis unless initialized properly.
 //
 
-  if (isDegrees) angle *= TMath::DegToRad();
-
-  Double_t s = TMath::Sin(angle);
-  Double_t c = TMath::Cos(angle);
+   fOK        = kFALSE;
+   fLabel     = -1;
+   fMotherPDG =  0;
+   fRsnID     = -1;
+   
+   fPsim.SetXYZT(0.0, 0.0, 0.0, 0.0);
+   fPrec.SetXYZT(0.0, 0.0, 0.0, 0.0);
 
-  x = c*Px() - s*Py();
-  y = s*Px() + c*Py();
+   fRef = fRefMC = 0x0;
+   fOwnerEvent = 0x0;
 }
 
 //_____________________________________________________________________________
-Double_t AliRsnDaughter::AngleTo(AliRsnDaughter d, Bool_t outInDegrees)
+Int_t AliRsnDaughter::GetPDG()
 {
 //
-// Compute angle between the vector momentum of this
-// and the one of argument.
+// Return the PDG code of the particle from MC ref (if any).
+// If argument is kTRUE, returns its absolute value.
 //
 
-  Double_t arg, dot, ptot2 = P2() * d.P2();
-
-  if (ptot2 <= 0) {
-    return 0.0;
-  } else {
-    dot = Px()*d.Px() + Py()*d.Py() + Pz()*d.Pz();
-    arg = dot / TMath::Sqrt(ptot2);
-    if (arg >  1.0) arg =  1.0;
-    if (arg < -1.0) arg = -1.0;
-    if (outInDegrees) return TMath::ACos(arg) * TMath::RadToDeg();
-    else return TMath::ACos(arg);
-  }
+   if (Match(fRefMC, AliMCParticle::Class()))
+      return ((AliMCParticle*)fRefMC)->Particle()->GetPdgCode();
+   else if (Match(fRefMC, AliAODMCParticle::Class()))
+      return ((AliAODMCParticle*)fRefMC)->GetPdgCode();
+   else {
+      AliWarning("Cannot retrieve PDG");
+      return 0;
+   }
 }
 
 //_____________________________________________________________________________
-Int_t AliRsnDaughter::GetID() const
+Int_t AliRsnDaughter::GetID()
 {
 //
 // Return reference index, using the "GetID" method
 // of the possible source object.
+// When this method is unsuccessful (e.g.: V0s), return the label.
 //
 
-  AliESDtrack *esd = dynamic_cast<AliESDtrack*>(fRef);
-  if (esd) return esd->GetID();
+   // ESD tracks
+   AliESDtrack *esd = Ref2ESDtrack();
+   if (esd) return esd->GetID();
 
-  AliAODTrack *aod = dynamic_cast<AliAODTrack*>(fRef);
-  if (aod) return aod->GetID();
+   // AOD tracks
+   AliAODTrack *aod = Ref2AODtrack();
+   if (aod) return aod->GetID();
 
-  return GetLabel();
+   // whatever else
+   return GetLabel();
 }
 
 //_____________________________________________________________________________
-AliPID::EParticleType AliRsnDaughter::RealisticPID() const
+Int_t AliRsnDaughter::GetMother()
 {
 //
-// Return the "realistic" PID of this track,
-// i.e. the particle species to which corresponds the largest PID probability.
+// Return index of the first mother of the MC reference, if any.
+// Otherwise, returns -1 (the same as for primary tracks)
 //
 
-  AliPID::EParticleType pid = AliPID::kElectron;
-  Double_t prob = fPID[0];
-
-  Int_t i;
-  for (i = 1; i < AliPID::kSPECIES; i++) {
-    if (fPID[i] > prob) {
-      prob = fPID[i];
-      pid = (AliPID::EParticleType)i;
-    }
-  }
+   if (!fRefMC) return -1;
 
-  return pid;
+   if (fRefMC->InheritsFrom(AliMCParticle::Class())) {
+      AliMCParticle *mc = (AliMCParticle*)fRefMC;
+      return mc->Particle()->GetFirstMother();
+   } else if (fRefMC->InheritsFrom(AliAODMCParticle::Class())) {
+      AliAODMCParticle *mc = (AliAODMCParticle*)fRefMC;
+      return mc->GetMother();
+   }
+   else
+      return -1;
 }
+   
+   
 
-//_____________________________________________________________________________
-AliPID::EParticleType AliRsnDaughter::PerfectPID() const
+//______________________________________________________________________________
+void AliRsnDaughter::Print(Option_t *opt) const
 {
 //
-// Return the "perfect" PID of this track,
-// reading it from the MC information, if available.
+// Override of TObject::Print()
 //
 
-  if (!fParticle) return AliPID::kUnknown;
-
-  Int_t absPDG = TMath::Abs(fParticle->GetPdgCode());
-  switch (absPDG) {
-  case   11:
-    return AliPID::kElectron;
-  case   13:
-    return AliPID::kMuon;
-  case  211:
-    return AliPID::kPion;
-  case  321:
-    return AliPID::kKaon;
-  case 2212:
-    return AliPID::kProton;
-  default:
-    AliDebug(2, Form("PDG code = %d not recognized. Return 'AliPID::kUnknown'", absPDG));
-    return AliPID::kUnknown;
-  }
+   AliInfo("=== DAUGHTER INFO ======================================================================");
+   AliInfo(Form(" (sim) px,py,pz = %6.2f %6.2f %6.2f", fPsim.X(), fPsim.Y(), fPsim.Z()));
+   AliInfo(Form(" (rec) px,py,pz = %6.2f %6.2f %6.2f", fPrec.X(), fPrec.Y(), fPrec.Z()));
+   AliInfo(Form(" OK, RsnID, Label, MotherPDG = %s, %5d, %5d, %4d", (fOK ? "true " : "false"), fRsnID, fLabel, fMotherPDG));
+   AliInfo("========================================================================================");
 }
 
-//_____________________________________________________________________________
-AliPID::EParticleType AliRsnDaughter::PIDType(Double_t &prob) const
+//______________________________________________________________________________
+const char* AliRsnDaughter::SpeciesName(ESpecies species)
 {
 //
-// Return the PID type according to the selected method
-// in the argument passed by reference, the probability is stored.
-// It will be realistic for realistic PID and 1 for perfect PID.
-//
-
-  AliPID::EParticleType pid = AssignedPID();
-
-  prob = 1.0;
-  if (fgPIDMethod == kRealistic) prob = fPID[(Int_t)pid];
-
-  return pid;
+// Return a string with the short name of the particle
+//
+
+   switch (species) {
+      case kElectron: return "E";
+      case kMuon:     return "Mu";
+      case kPion:     return "Pi";
+      case kKaon:     return "K";
+      case kProton:   return "P";
+      case kKaon0:    return "K0s";
+      case kLambda:   return "Lambda";
+      case kXi:       return "Xi";
+      case kOmega:    return "Omega";
+      default:        return "Undef";
+   }
 }
 
-//_____________________________________________________________________________
-AliPID::EParticleType AliRsnDaughter::AssignedPID() const
+//______________________________________________________________________________
+Int_t AliRsnDaughter::SpeciesPDG(ESpecies species)
 {
 //
-// Return the PID type according to the selected method
-// in the argument passed by reference, the probability is stored.
-// It will be realistic for realistic PID and 1 for perfect PID.
-//
-
-  switch (fgPIDMethod) {
-  case kNoPID:
-    return AliPID::kUnknown;
-  case kPerfect:
-    return PerfectPID();
-  case kRealistic:
-    return RealisticPID();
-  default:
-    AliWarning("PID method not properly set. Returning realistic PID");
-    return RealisticPID();
-  }
+// Return the PDG code of a particle species (abs value)
+//
+
+   switch (species) {
+      case kElectron: return 11;
+      case kMuon:     return 13;
+      case kPion:     return 211;
+      case kKaon:     return 321;
+      case kProton:   return 2212;
+      case kKaon0:    return 310;
+      case kLambda:   return 3122;
+      case kXi:       return 3312;
+      case kOmega:    return 3334;
+      default:        return 0;
+   }
 }
 
-//_____________________________________________________________________________
-Bool_t AliRsnDaughter::CombineWithPriors(const Double_t *priors, AliRsnPIDDefESD *pidDef)
+//______________________________________________________________________________
+Double_t AliRsnDaughter::SpeciesMass(ESpecies species)
 {
 //
-// Combine current PID weights (assumed to be them) with prior probs
+// Return the mass of a particle species
 //
 
-  Int_t       i;
-  Double_t    sum = 0.0;
-
-  // get PID weights according to definition
-  // if the reference is not ESD or the pidDef is null
-  // of it is not null but is requires the ESD pid,
-  // the standard PID value is used, otherwise
-  if (pidDef && GetRefESD()) {
-    pidDef->ComputeWeights(GetRefESD(), fPID);
-  } else {
-    if (fRef->PID())
-      for (i = 0; i < AliPID::kSPECIES; i++) fPID[i] = fRef->PID()[i];
-    else if (fParticle) {
-      // if the PID() returns 0x0, this is a MC particle
-      // and we set the weight corresponding to its species to 1
-      // and the others to zero
-      for (i = 0; i < AliPID::kSPECIES; i++) fPID[i] = 0.0;
-      i = (Int_t)AliRsnDaughter::InternalType(TMath::Abs(fParticle->GetPdgCode()));
-      fPID[i] = 1.0;
-    }
-  }
-
-  // multiply weights and priors
-  for (i = 0; i < AliPID::kSPECIES; i++) {
-    fPID[i] *= priors[i];
-    sum += fPID[i];
-  }
-  if (sum <= 0.0) {
-    if (sum < 0.0) AliError(Form("Sum of weights = %f < 0", sum));
-    return kFALSE;
-  }
-
-  // normalize
-  for (i = 0; i < AliPID::kSPECIES; i++) fPID[i] /= sum;
-
-  return kTRUE;
+   TDatabasePDG *db = TDatabasePDG::Instance();
+   TParticlePDG *part = 0x0;
+   
+   Int_t pdg = SpeciesPDG(species);
+   if (pdg) {
+      part = db->GetParticle(pdg);
+      return part->Mass();
+   }
+   else
+      return 0.0;
 }
 
-//_____________________________________________________________________________
-void AliRsnDaughter::FindMotherPDG(AliStack *const stack)
+//______________________________________________________________________________
+EPARTYPE AliRsnDaughter::ToAliPID(ESpecies species)
 {
 //
-// Searches the stack to find the mother and retrieve its PDG code.
+// Convert an enum element from this object
+// into the enumeration of AliPID.
+// If no match are cound 'kUnknown' is returned.
 //
 
-  if (!stack || !fParticle) return;
-
-  const Int_t mLabel = fParticle->GetFirstMother();
-  if (mLabel < 0) {
-    fMotherPDG = 0;
-  } else {
-    TParticle *mum = stack->Particle(mLabel);
-    if (mum) fMotherPDG = mum->GetPdgCode();
-    else fMotherPDG = 0;
-  }
+   switch (species) {
+      case kElectron: return AliPID::kElectron;
+      case kMuon:     return AliPID::kMuon;
+      case kPion:     return AliPID::kPion;
+      case kKaon:     return AliPID::kKaon;
+      case kProton:   return AliPID::kProton;
+      case kKaon0:    return AliPID::kKaon0;
+      default:        return AliPID::kUnknown;
+   }
 }
 
-//_____________________________________________________________________________
-Double_t AliRsnDaughter::GetMCEnergy(Double_t mass)
-{
-//
-// Uses the argument to compute 4-momentum energy
-//
-
-  if (!fParticle) return 0.0;
-
-  Double_t p2 = fParticle->Px()*fParticle->Px();
-  p2 += fParticle->Py()*fParticle->Py();
-  p2 += fParticle->Pz()*fParticle->Pz();
-
-  return TMath::Sqrt(mass*mass + p2);
-}
-
-//_____________________________________________________________________________
-void AliRsnDaughter::FindKinkIndex(const AliESDtrack *esdTrack)
-{
-//
-// Assign kink index from an ESD track
-//
-
-  Int_t i, ik[3];
-  for (i = 0; i < 3; i++) ik[i] = esdTrack->GetKinkIndex(i);
-
-  if (ik[0] < 0 || ik[1] < 0 || ik[2] < 0) {
-    SetKinkMother();
-  } else if (ik[0] > 0 || ik[1] > 0 || ik[2] > 0) {
-    SetKinkDaughter();
-  } else SetNoKink();
-}
-
-//_____________________________________________________________________________
-void AliRsnDaughter::FindKinkIndex(AliAODEvent *const event)
-{
-//
-// Assign kink index from an AOD event
-//
-
-  Int_t iv, id, nD, nV = event->GetNumberOfVertices();
-  for (iv = 0; iv < nV; iv++) {
-    AliAODVertex *v = event->GetVertex(iv);
-    AliAODVertex::AODVtx_t type = (AliAODVertex::AODVtx_t)v->GetType();
-    if (type != AliAODVertex::kKink) continue;
-    AliAODTrack *mother = (AliAODTrack*)v->GetParent();
-    if (mother == (AliAODTrack*)fRef) {
-      SetKinkMother();
-      return;
-    } else {
-      nD = v->GetNDaughters();
-      for (id = 0; id < nD; id++) {
-        AliAODTrack *son = (AliAODTrack*)v->GetDaughter(id);
-        if (son == (AliAODTrack*)fRef) {
-          SetKinkDaughter();
-          return;
-        }
-      }
-    }
-  }
-
-  SetNoKink();
-}
-
-//_____________________________________________________________________________
-void AliRsnDaughter::Reset()
-{
-//
-// Reset this track to meaningless values
-//
-
-  fOK = kFALSE;
-  fKinkIndex = 0;
-  fParticle = 0x0;
-  fMotherPDG = 0;
-  fStatus = 0;
-  fRef = 0x0;
-}
-
-//_____________________________________________________________________________
-void AliRsnDaughter::Print(Option_t * const option) const
-{
-//
-// Prints the values of data members, using the options:
-// - P --> momentum
-// - V --> DCA vertex
-// - C --> electric charge
-// - F --> flags
-// - I --> identification (PID, probability and mass)
-// - W --> PID weights
-// - M --> Montecarlo
-// - L --> index & label
-// - A --> angles
-// - ALL --> All oprions switched on
-//
-// Index and label are printed by default.
-//
-
-  TString opt(option);
-  opt.ToUpper();
-
-  if (opt.Contains("L") || opt.Contains("ALL")) {
-    cout << ".......Index            : " << GetID() << endl;
-    cout << ".......Label            : " << GetLabel() << endl;
-  }
-  if (opt.Contains("P") || opt.Contains("ALL")) {
-    cout << ".......Px, Py, Pz, Pt   : " << Px() << ' ' << Py() << ' ' << Pz() << ' ' << Pt() << endl;
-  }
-  if (opt.Contains("A") || opt.Contains("ALL")) {
-    cout << ".......Phi, Theta       : " << Phi() << ' ' << Theta() << endl;
-  }
-  if (opt.Contains("V") || opt.Contains("ALL")) {
-    cout << ".......Vx, Vy, Vz       : " << Xv() << ' ' << Yv() << ' ' << Zv() << endl;
-  }
-  if (opt.Contains("I") || opt.Contains("ALL")) {
-    AliPID::EParticleType type;
-    Double_t prob;
-    type = PIDType(prob);
-    cout << ".......PID & prob       : " << AliPID::ParticleName(type) << ' ' << prob << endl;
-  }
-  if (opt.Contains("C") || opt.Contains("ALL")) {
-    cout << ".......Charge           : " << Charge() << endl;
-  }
-  if (opt.Contains("F") || opt.Contains("ALL")) {
-    cout << ".......Flags            : " << fStatus << endl;
-  }
-  if (opt.Contains("W") || opt.Contains("ALL")) {
-    cout << ".......Weights          : ";
-    Int_t i;
-    for (i = 0; i < AliPID::kSPECIES; i++) cout << fPID[i] << ' ';
-    cout << endl;
-  }
-  if (opt.Contains("M") || opt.Contains("ALL")) {
-    if (fParticle) {
-      cout << ".......PDG code         : " << fParticle->GetPdgCode() << endl;
-      cout << ".......Mother (label)   : " << fParticle->GetFirstMother() << endl;
-      cout << ".......Mother (PDG code): " << fMotherPDG << endl;
-    } else {
-      cout << ".......MC info not present" << endl;
-    }
-  }
-}
-
-//_____________________________________________________________________________
-AliPID::EParticleType AliRsnDaughter::InternalType(Int_t pdg)
-{
-//
-// Return the internal enum value corresponding to the PDG
-// code passed as argument, if possible.
-// Otherwise, returns 'AliPID::kSPECIES' by default.
-//
-
-  AliPID::EParticleType value;
-  Int_t absPDG = TMath::Abs(pdg);
-
-  switch (absPDG) {
-  case 11:
-    value = AliPID::kElectron;
-    break;
-  case 13:
-    value = AliPID::kMuon;
-    break;
-  case 211:
-    value = AliPID::kPion;
-    break;
-  case 321:
-    value = AliPID::kKaon;
-    break;
-  case 2212:
-    value = AliPID::kProton;
-    break;
-  default:
-    value = AliPID::kUnknown;
-  }
-  return value;
-}
-
-//_____________________________________________________________________________
-const char* AliRsnDaughter::MethodName(EPIDMethod method)
+//______________________________________________________________________________
+AliRsnDaughter::ESpecies AliRsnDaughter::FromAliPID(EPARTYPE pid)
 {
 //
-// Returns a string with the method name
+// Convert an enum element from AliPID
+// into the enumeration of this object.
+// If no match are cound 'kUnknown' is returned.
 //
 
-  switch (method)
-  {
-    case kNoPID:
-      return "No PID";
-    case kRealistic:
-      return "Realistic";
-    case kPerfect:
-      return "Perfect";
-    default:
-      return "Unknown";
-  }
+   switch (pid) {
+      case AliPID::kElectron: return kElectron;
+      case AliPID::kMuon:     return kMuon;
+      case AliPID::kPion:     return kPion;
+      case AliPID::kKaon:     return kKaon;
+      case AliPID::kProton:   return kProton;
+      case AliPID::kKaon0:    return kKaon0;
+      default:                return kUnknown;
+   }
 }