]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - PWG2/RESONANCES/AliRsnDaughter.cxx
Upgrades for setting up a working version of ME task
[u/mrichter/AliRoot.git] / PWG2 / RESONANCES / AliRsnDaughter.cxx
index f244305e3456d2672a58854d8a2ae7a3b168d3a4..872c5c4d7c85d3a4102e2c8ca6199500a8f64360 100644 (file)
 //
 // Class AliRsnDaughter
 //
-// Light-weight AOD object which contains all required track details
-// which are used for resonance analysis.
-// Provides converters from all kinds of input track type: ESD, AOD and MC.
+// 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)
 //
 
 #include <Riostream.h>
-
 #include <TParticle.h>
-#include <TString.h>
 
-#include "AliLog.h"
+#include "AliStack.h"
 #include "AliESDtrack.h"
+#include "AliAODEvent.h"
+#include "AliAODVertex.h"
 #include "AliAODTrack.h"
-#include "AliMCParticle.h"
 
-#include "AliRsnMCInfo.h"
+#include "AliRsnPIDDefESD.h"
 #include "AliRsnDaughter.h"
 
 ClassImp(AliRsnDaughter)
 
-AliRsnDaughter::EPIDMethod AliRsnDaughter::fgPIDMethod = AliRsnDaughter::kNoPID;
+AliRsnDaughter::EPIDMethod AliRsnDaughter::fgPIDMethod = AliRsnDaughter::kRealistic;
 
 //_____________________________________________________________________________
-AliRsnDaughter::AliRsnDaughter() :
-    AliVParticle(),
-    fIndex(-1),
-    fLabel(-1),
-    fCharge(0),
-    fFlags(0),
-    fKink(0),
-    fMass(0.0),
-    fChi2(0.0),
-    fNSigmaToVertex(-1.0),
-    fITSnum(0),
-    fTPCnum(0),
-    fRealisticPID(AliRsnPID::kUnknown),
-    fMCInfo(0x0)
+AliRsnDaughter::AliRsnDaughter(AliVParticle *ref, TParticle *refMC) :
+    fOK((ref != 0)),
+    fKinkIndex(0),
+    fParticle(refMC),
+    fMotherPDG(0),
+    fStatus(0),
+    fDr(0.0),
+    fDz(0.0),
+    fReqPID(AliPID::kUnknown),
+    fRef(ref)
 {
 //
 // Default constructor.
-// Initializes all data-members with meaningless values.
 //
-
-  Int_t i;
-  for (i = 0; i < AliRsnPID::kSpecies; i++)
-  {
-    if (i < 3)
-    {
-      fP[i] = 0.0;
-      fV[i] = 0.0;
-    }
-    fPIDWeight[i] = 0.0;
-    fPIDProb[i] = 0.0;
-  }
 }
 
 //_____________________________________________________________________________
 AliRsnDaughter::AliRsnDaughter(const AliRsnDaughter &copy) :
-    AliVParticle(copy),
-    fIndex(copy.fIndex),
-    fLabel(copy.fLabel),
-    fCharge(copy.fCharge),
-    fFlags(copy.fFlags),
-    fKink(copy.fKink),
-    fMass(copy.fMass),
-    fChi2(copy.fChi2),
-    fNSigmaToVertex(copy.fNSigmaToVertex),
-    fITSnum(copy.fITSnum),
-    fTPCnum(copy.fTPCnum),
-    fRealisticPID(copy.fRealisticPID),
-    fMCInfo(0x0)
+    TObject(copy),
+    fOK(copy.fOK),
+    fKinkIndex(copy.fKinkIndex),
+    fParticle(copy.fParticle),
+    fMotherPDG(copy.fMotherPDG),
+    fStatus(copy.fStatus),
+    fDr(copy.fDr),
+    fDz(copy.fDz),
+    fReqPID(copy.fReqPID),
+    fRef(copy.fRef)
 {
 //
 // Copy constructor.
+// Pointers are NOT duplicated.
 //
-
-  Int_t i;
-  for (i = 0; i < AliRsnPID::kSpecies; i++)
-  {
-    if (i < 3)
-    {
-      fP[i] = copy.fP[i];
-      fV[i] = copy.fV[i];
-    }
-    fPIDWeight[i] = copy.fPIDWeight[i];
-    fPIDProb[i] = copy.fPIDProb[i];
-  }
-
-  // initialize particle object
-  // only if it is present in the template object
-  if (copy.fMCInfo) fMCInfo = new AliRsnMCInfo(*(copy.fMCInfo));
-}
-
-//_____________________________________________________________________________
-AliRsnDaughter::AliRsnDaughter(AliESDtrack *track, Bool_t useTPC) :
-    AliVParticle(),
-    fIndex(-1),
-    fLabel(-1),
-    fCharge(0),
-    fFlags(0),
-    fKink(0),
-    fMass(0.0),
-    fChi2(0.0),
-    fNSigmaToVertex(-1.0),
-    fITSnum(0),
-    fTPCnum(0),
-    fRealisticPID(AliRsnPID::kUnknown),
-    fMCInfo(0x0)
-{
-//
-// Constructor to get data from an ESD track.
-//
-
-  Int_t i;
-  for (i = 0; i < AliRsnPID::kSpecies; i++) fPIDProb[i] = 0.0;
-  Adopt(track, kEsd,0.0,useTPC);
-}
-
-//_____________________________________________________________________________
-AliRsnDaughter::AliRsnDaughter(AliAODTrack *track) :
-    AliVParticle(),
-    fIndex(-1),
-    fLabel(-1),
-    fCharge(0),
-    fFlags(0),
-    fKink(0),
-    fMass(0.0),
-    fChi2(0.0),
-    fNSigmaToVertex(-1.0),
-    fITSnum(0),
-    fTPCnum(0),
-    fRealisticPID(AliRsnPID::kUnknown),
-    fMCInfo(0x0)
-{
-//
-// Constructor to get data from an AOD track.
-//
-
-  Int_t i;
-  for (i = 0; i < AliRsnPID::kSpecies; i++) fPIDProb[i] = 0.0;
-  Adopt(track);
-}
-
-//_____________________________________________________________________________
-AliRsnDaughter::AliRsnDaughter(AliMCParticle *track) :
-    AliVParticle(),
-    fIndex(-1),
-    fLabel(-1),
-    fCharge(0),
-    fFlags(0),
-    fKink(0),
-    fMass(0.0),
-    fChi2(0.0),
-    fNSigmaToVertex(-1.0),
-    fITSnum(0),
-    fTPCnum(0),
-    fRealisticPID(AliRsnPID::kUnknown),
-    fMCInfo(0x0)
-{
-//
-// Constructor to get data from an MC track.
-//
-
-  Int_t i;
-  for (i = 0; i < AliRsnPID::kSpecies; i++) fPIDProb[i] = 0.0;
-  Adopt(track);
 }
 
 //_____________________________________________________________________________
@@ -177,44 +70,21 @@ AliRsnDaughter& AliRsnDaughter::operator=(const AliRsnDaughter &copy)
 {
 //
 // Assignment operator.
-// Works like the copy constructor and returns a reference
-// to the initialized object for which it is called.
 //
 
-  fIndex  = copy.fIndex;
-  fLabel  = copy.fLabel;
-  fCharge = copy.fCharge;
-  fFlags  = copy.fFlags;
-  fKink   = copy.fKink;
-  fChi2   = copy.fChi2;
-  fNSigmaToVertex = copy.fNSigmaToVertex;
-  fITSnum = copy.fITSnum;
-  fTPCnum = copy.fTPCnum;
+  (TObject)(*this) = (TObject)copy;
 
-  Int_t i;
-  for (i = 0; i < AliRsnPID::kSpecies; i++)
-  {
-    if (i < 3)
-    {
-      fP[i] = copy.fP[i];
-      fV[i] = copy.fV[i];
-    }
-    fPIDWeight[i] = copy.fPIDWeight[i];
-    fPIDProb[i] = copy.fPIDProb[i];
-  }
+  fOK = copy.fOK;
+  fKinkIndex = copy.fKinkIndex;
+  fParticle  = copy.fParticle;
+  fMotherPDG = copy.fMotherPDG;
+  fStatus = copy.fStatus;
+  fDr = copy.fDr;
+  fDz = copy.fDz;
 
-  fMass = copy.fMass;
-  fRealisticPID = copy.fRealisticPID;
+  fReqPID = copy.fReqPID;
 
-  // initialize particle object
-  // only if it is present in the template object;
-  // otherwise, it is just cleared and not replaced with anything
-  if (fMCInfo)
-  {
-    delete fMCInfo;
-    fMCInfo = 0x0;
-  }
-  if (copy.fMCInfo) fMCInfo = new AliRsnMCInfo(*(copy.fMCInfo));
+  fRef = copy.fRef;
 
   return (*this);
 }
@@ -223,331 +93,303 @@ AliRsnDaughter& AliRsnDaughter::operator=(const AliRsnDaughter &copy)
 AliRsnDaughter::~AliRsnDaughter()
 {
 //
-// Destructor
+// Destructor.
+// Since pointers do not allocate new objects, nothing is done.
 //
-
-  if (fMCInfo)
-  {
-    delete fMCInfo;
-    fMCInfo = 0;
-  }
 }
 
 //_____________________________________________________________________________
-void AliRsnDaughter::RotateP(Double_t angle)
+void AliRsnDaughter::RotateP
+(Double_t angle, Double_t &x, Double_t &y, Bool_t isDegrees) const
 {
 //
-// Rotate the momentum along Z axis by an angle
+// 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.
 //
 
+  if (isDegrees) angle *= TMath::DegToRad();
+
   Double_t s = TMath::Sin(angle);
   Double_t c = TMath::Cos(angle);
-  Double_t xx = fP[0];
-  fP[0] = c*xx - s*fP[1];
-  fP[1] = s*xx + c*fP[1];
+
+  x = c*Px() - s*Py();
+  y = s*Px() + c*Py();
 }
 
 //_____________________________________________________________________________
-Double_t AliRsnDaughter::AngleTo(AliRsnDaughter *d)
+Double_t AliRsnDaughter::AngleTo(AliRsnDaughter d, Bool_t outInDegrees)
 {
 //
-// Compute angle in DEGREES between the vector momentum of (this)
+// Compute angle between the vector momentum of this
 // and the one of argument.
 //
 
-  Double_t arg, dot, ptot2 = P2() * d->P2();
-  
-  if(ptot2 <= 0) {
+  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();
+  } 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;
-    return TMath::ACos(arg) * TMath::RadToDeg();
+    if (outInDegrees) return TMath::ACos(arg) * TMath::RadToDeg();
+    else return TMath::ACos(arg);
   }
 }
 
 //_____________________________________________________________________________
-void AliRsnDaughter::SetPIDWeight(Int_t i, Double_t value)
+Int_t AliRsnDaughter::GetID() const
 {
 //
-// I the argument 'i' is in the correct range,
-// sets the i-th PID weight to 'value'
+// Return reference index, using the "GetID" method
+// of the possible source object.
 //
 
-  if (i >= 0 && i < AliRsnPID::kSpecies) fPIDWeight[i] = value;
-  else
-  {
-    AliError(Form("Cannot set a weight related to slot %d", i));
-  }
+  AliESDtrack *esd = dynamic_cast<AliESDtrack*>(fRef);
+  if (esd) return esd->GetID();
+
+  AliAODTrack *aod = dynamic_cast<AliAODTrack*>(fRef);
+  if (aod) return aod->GetID();
+
+  return GetLabel();
 }
 
 //_____________________________________________________________________________
-void  AliRsnDaughter::AssignRealisticPID()
+AliPID::EParticleType AliRsnDaughter::RealisticPID() const
 {
 //
-// Assign realistic PID from largest probability
+// Return the "realistic" PID of this track,
+// i.e. the particle species to which corresponds the largest PID probability.
 //
 
-  Int_t i, imax = 0;
-  Double_t pmax = fPIDProb[0];
+  AliPID::EParticleType pid = AliPID::kElectron;
+  Double_t prob = fPID[0];
 
-  // search for maximum
-  for (i = 1; i < AliRsnPID::kSpecies; i++)
-  {
-    if (fPIDProb[i] > pmax)
-    {
-      imax = i;
-      pmax = fPIDProb[i];
+  Int_t i;
+  for (i = 1; i < AliPID::kSPECIES; i++) {
+    if (fPID[i] > prob) {
+      prob = fPID[i];
+      pid = (AliPID::EParticleType)i;
     }
   }
 
-  fRealisticPID = (AliRsnPID::EType)imax;
+  return pid;
 }
 
 //_____________________________________________________________________________
-AliRsnPID::EType AliRsnDaughter::PIDType(Double_t &prob) const
+AliPID::EParticleType AliRsnDaughter::PerfectPID() const
 {
 //
-// 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.
+// Return the "perfect" PID of this track,
+// reading it from the MC information, if available.
 //
 
-  switch (fgPIDMethod)
-  {
-    case kNoPID:
-      AliWarning("Requested a PIDtype call in NoPID mode");
-      return AliRsnPID::kUnknown;
-    case kPerfect:
-      if (fMCInfo) return AliRsnPID::InternalType(fMCInfo->PDG());
-      else return AliRsnPID::kUnknown;
-    default:
-      if (fRealisticPID > 0 && fRealisticPID < AliRsnPID::kSpecies)
-      {
-        prob = fPIDProb[fRealisticPID];
-        return fRealisticPID;
-      }
-      else
-      {
-        prob = 1.0;
-        return AliRsnPID::kUnknown;
-      }
+  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;
   }
 }
 
 //_____________________________________________________________________________
-void AliRsnDaughter::SetPIDProb(Int_t i, Double_t value)
+AliPID::EParticleType AliRsnDaughter::PIDType(Double_t &prob) const
 {
 //
-// I the argument 'i' is in the correct range,
-// sets the i-th PID probability to 'value'
+// 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.
 //
 
-  if (i >= 0 && i < AliRsnPID::kSpecies) fPIDProb[i] = value;
-  else
-  {
-    AliError(Form("Cannot set a weight related to slot %d", i));
-  }
+  AliPID::EParticleType pid = AssignedPID();
+
+  prob = 1.0;
+  if (fgPIDMethod == kRealistic) prob = fPID[(Int_t)pid];
+
+  return pid;
 }
 
 //_____________________________________________________________________________
-Bool_t AliRsnDaughter::Adopt(AliESDtrack* esdTrack,EPIDType pidType ,Double_t divValue, Bool_t useTPCInnerParam)
+AliPID::EParticleType AliRsnDaughter::AssignedPID() const
 {
 //
-// Copies data from an AliESDtrack into "this":
-//  - charge sign
-//  - momentum
-//  - point of closest approach to primary vertex
-//  - ESD pid weights
-// In case of errors returns kFALSE, otherwise kTRUE.
+// 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.
 //
 
-  if (!esdTrack)
-  {
-    AliError("Passed NULL object: nothing done");
-    return kFALSE;
+  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();
   }
+}
 
-  // copy momentum, vertex, chi2 and number of clusters
-  if (!useTPCInnerParam)
-  {
-    esdTrack->GetPxPyPz(fP);
-    esdTrack->GetXYZ(fV);
-    fChi2 = esdTrack->GetConstrainedChi2();
-    fITSnum = esdTrack->GetITSclusters(0x0);
-    fTPCnum = esdTrack->GetTPCclusters(0x0);
-  }
-  else
-  {
-    if (!esdTrack->GetTPCInnerParam()) return kFALSE;
-    esdTrack->GetTPCInnerParam()->GetPxPyPz(fP);
-    esdTrack->GetTPCInnerParam()->GetXYZ(fV);
-    fChi2 = esdTrack->GetTPCchi2();
-    fITSnum = 0;
-    fTPCnum = esdTrack->GetTPCclusters(0x0);
+//_____________________________________________________________________________
+Bool_t AliRsnDaughter::CombineWithPriors(const Double_t *priors, AliRsnPIDDefESD *pidDef)
+{
+//
+// Combine current PID weights (assumed to be them) with prior probs
+//
+
+  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;
+    }
   }
 
-  // define the kink index:
-  //  0 = no kink
-  //  1 = kink daughter
-  // -1 = kink mother
-  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) fKink = -1;
-  else if (ik[0] > 0 || ik[1] > 0 || ik[2] > 0) fKink = 1;
-  else fKink = 0;
-
-  Double_t p = esdTrack->P();
-  // copy PID weights
-  Double_t pid[5];
-  if (!useTPCInnerParam)
-  {
-    GetESDPID(esdTrack,pid,pidType,divValue,p);
-  }
-  else
-  {
-//     fCurrentESDPID = kTPC;
-    GetESDPID(esdTrack,pid,kTPC,0.0,p);
+  // multiply weights and priors
+  for (i = 0; i < AliPID::kSPECIES; i++) {
+    fPID[i] *= priors[i];
+    sum += fPID[i];
   }
-//   for (i = 0; i < 5; i++) fPIDWeight[i] = pid[i];
-
-  Double_t sum = 0.0;
-  for (i = 0; i < 5; i++)
-  {
-    fPIDWeight[i] = pid[i];
-    sum += fPIDWeight[i];
+  if (sum <= 0.0) {
+    if (sum < 0.0) AliError(Form("Sum of weights = %f < 0", sum));
+    return kFALSE;
   }
-  
-  if (sum<=0.0) return kFALSE;
-  
-  // copy flags
-  fFlags = esdTrack->GetStatus();
 
-  // copy charge sign
-  fCharge = (Short_t)esdTrack->Charge();
-
-  // calculate N sigma to vertex
-  AliESDtrackCuts trkCut;
-  SetNSigmaToVertex(trkCut.GetSigmaToVertex(esdTrack));
+  // normalize
+  for (i = 0; i < AliPID::kSPECIES; i++) fPID[i] /= sum;
 
   return kTRUE;
 }
 
-
 //_____________________________________________________________________________
-Bool_t AliRsnDaughter::Adopt(AliAODTrack* aodTrack)
+void AliRsnDaughter::FindMotherPDG(AliStack *const stack)
 {
 //
-// Copies data from an AliAODtrack into "this":
-//  - charge sign
-//  - momentum
-//  - point of closest approach to primary vertex
-//  - ESD pid weights
-// In case of errors returns kFALSE, otherwise kTRUE.
+// Searches the stack to find the mother and retrieve its PDG code.
 //
 
-  if (!aodTrack)
-  {
-    AliError("Passed NULL object: nothing done");
-    return kFALSE;
-  }
-
-  // copy momentum  and vertex
-  fP[0] = aodTrack->Px();
-  fP[1] = aodTrack->Py();
-  fP[2] = aodTrack->Pz();
-  fV[0] = aodTrack->Xv();
-  fV[1] = aodTrack->Yv();
-  fV[2] = aodTrack->Zv();
+  if (!stack || !fParticle) return;
 
-  // chi2
-  fChi2 = aodTrack->Chi2perNDF();
+  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;
+  }
+}
 
-  // copy PID weights
-  Int_t i;
-  for (i = 0; i < 5; i++) fPIDWeight[i] = aodTrack->PID()[i];
+//_____________________________________________________________________________
+Double_t AliRsnDaughter::GetMCEnergy(Double_t mass)
+{
+//
+// Uses the argument to compute 4-momentum energy
+//
 
-  // copy flags
-  fFlags = aodTrack->GetStatus();
+  if (!fParticle) return 0.0;
 
-  // copy sign
-  fCharge = aodTrack->Charge();
+  Double_t p2 = fParticle->Px()*fParticle->Px();
+  p2 += fParticle->Py()*fParticle->Py();
+  p2 += fParticle->Pz()*fParticle->Pz();
 
-  return kTRUE;
+  return TMath::Sqrt(mass*mass + p2);
 }
 
-
 //_____________________________________________________________________________
-Bool_t AliRsnDaughter::Adopt(AliMCParticle *mcParticle)
+void AliRsnDaughter::FindKinkIndex(const AliESDtrack *esdTrack)
 {
 //
-// Copies data from a MCParticle into "this":
-//  - charge sign
-//  - momentum
-//  - point of closest approach to primary vertex
-//  - ESD pid weights
-//  - true PDG code
-//  - mother
-// In case of errors returns kFALSE, otherwise kTRUE.
+// Assign kink index from an ESD track
 //
 
-  if (!mcParticle)
-  {
-    AliError("Passed NULL object: nothing done");
-    return kFALSE;
-  }
-
-  // retrieve the TParticle object from the argument
-  TParticle *particle = mcParticle->Particle();
-  if (!particle)
-  {
-    AliError("AliMCParticle::Particle() returned NULL");
-    return kFALSE;
-  }
+  Int_t i, ik[3];
+  for (i = 0; i < 3; i++) ik[i] = esdTrack->GetKinkIndex(i);
 
-  // copy momentum  and vertex
-  fP[0] = particle->Px();
-  fP[1] = particle->Py();
-  fP[2] = particle->Pz();
-  fV[0] = particle->Vx();
-  fV[1] = particle->Vy();
-  fV[2] = particle->Vz();
+  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();
+}
 
-  // recognize charge sign from PDG code sign
-  Int_t pdg = particle->GetPdgCode();
-  Int_t absPDG = TMath::Abs(pdg);
-  if (absPDG == 11 || absPDG == 13)
-  {
-    if (pdg > 0) fCharge = -1; else fCharge = 1;
-  }
-  else if (absPDG == 211 || absPDG == 321 || absPDG == 2212)
-  {
-    if (pdg > 0) fCharge = 1; else fCharge = -1;
-  }
-  else
-  {
-    // when trying to "adopt" a neutral track (photon, neutron, etc.)
-    // for the moment a "failed" message is returned
-    fCharge = 0;
-    return kFALSE;
+//_____________________________________________________________________________
+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;
+        }
+      }
+    }
   }
 
-  // flags and PID weights make no sense with MC tracks
-  fFlags = 0;
-  for (pdg = 0; pdg < AliRsnPID::kSpecies; pdg++) fPIDWeight[pdg] = 0.0;
-  fPIDWeight[AliRsnPID::InternalType(absPDG)] = 1.0;
+  SetNoKink();
+}
 
-  // copy other MC info (mother PDG code cannot be retrieved here)
-  InitMCInfo(particle);
+//_____________________________________________________________________________
+void AliRsnDaughter::Reset()
+{
+//
+// Reset this track to meaningless values
+//
 
-  return kTRUE;
+  fOK = kFALSE;
+  fKinkIndex = 0;
+  fParticle = 0x0;
+  fMotherPDG = 0;
+  fStatus = 0;
+  fRef = 0x0;
 }
 
 //_____________________________________________________________________________
-void AliRsnDaughter::Print(Option_t *option) const
+void AliRsnDaughter::Print(Option_t * const option) const
 {
 //
 // Prints the values of data members, using the options:
@@ -557,7 +399,7 @@ void AliRsnDaughter::Print(Option_t *option) const
 // - F --> flags
 // - I --> identification (PID, probability and mass)
 // - W --> PID weights
-// - M --> Montecarlo (from AliRsnMCInfo)
+// - M --> Montecarlo
 // - L --> index & label
 // - A --> angles
 // - ALL --> All oprions switched on
@@ -568,200 +410,98 @@ void AliRsnDaughter::Print(Option_t *option) const
   TString opt(option);
   opt.ToUpper();
 
-  if (opt.Contains("L") || opt.Contains("ALL"))
-  {
-    cout << ".......Index            : " << fIndex << endl;
-    cout << ".......Label            : " << fLabel << endl;
+  if (opt.Contains("L") || opt.Contains("ALL")) {
+    cout << ".......Index            : " << GetID() << endl;
+    cout << ".......Label            : " << GetLabel() << endl;
   }
-  if (opt.Contains("P") || opt.Contains("ALL"))
-  {
+  if (opt.Contains("P") || opt.Contains("ALL")) {
     cout << ".......Px, Py, Pz, Pt   : " << Px() << ' ' << Py() << ' ' << Pz() << ' ' << Pt() << endl;
   }
-  if (opt.Contains("A") || opt.Contains("ALL"))
-  {
+  if (opt.Contains("A") || opt.Contains("ALL")) {
     cout << ".......Phi, Theta       : " << Phi() << ' ' << Theta() << endl;
   }
-  if (opt.Contains("V") || opt.Contains("ALL"))
-  {
+  if (opt.Contains("V") || opt.Contains("ALL")) {
     cout << ".......Vx, Vy, Vz       : " << Xv() << ' ' << Yv() << ' ' << Zv() << endl;
   }
-  if (opt.Contains("I") || opt.Contains("ALL"))
-  {
-    AliRsnPID::EType type;
+  if (opt.Contains("I") || opt.Contains("ALL")) {
+    AliPID::EParticleType type;
     Double_t prob;
     type = PIDType(prob);
-    cout << ".......PID & prob       : " << AliRsnPID::ParticleName(type) << ' ' << prob << endl;
+    cout << ".......PID & prob       : " << AliPID::ParticleName(type) << ' ' << prob << endl;
   }
-  if (opt.Contains("C") || opt.Contains("ALL"))
-  {
-    cout << ".......Charge           : " << fCharge << endl;
+  if (opt.Contains("C") || opt.Contains("ALL")) {
+    cout << ".......Charge           : " << Charge() << endl;
   }
-  if (opt.Contains("F") || opt.Contains("ALL"))
-  {
-    cout << ".......Flags            : " << fFlags << endl;
+  if (opt.Contains("F") || opt.Contains("ALL")) {
+    cout << ".......Flags            : " << fStatus << endl;
   }
-  if (opt.Contains("W") || opt.Contains("ALL"))
-  {
+  if (opt.Contains("W") || opt.Contains("ALL")) {
     cout << ".......Weights          : ";
     Int_t i;
-    for (i = 0; i < AliRsnPID::kSpecies; i++) cout << fPIDWeight[i] << ' ';
+    for (i = 0; i < AliPID::kSPECIES; i++) cout << fPID[i] << ' ';
     cout << endl;
   }
-  if (opt.Contains("M") || opt.Contains("ALL"))
-  {
-    if (fMCInfo)
-    {
-      cout << ".......PDG code         : " << fMCInfo->PDG() << endl;
-      cout << ".......Mother (label)   : " << fMCInfo->Mother() << endl;
-      cout << ".......Mother (PDG code): " << fMCInfo->MotherPDG() << endl;
-    }
-    else
-    {
+  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;
     }
   }
 }
 
 //_____________________________________________________________________________
-void AliRsnDaughter::InitMCInfo()
-{
-//
-// Initializes the particle object with default constructor.
-//
-
-  fMCInfo = new AliRsnMCInfo;
-}
-
-//_____________________________________________________________________________
-Bool_t AliRsnDaughter::InitMCInfo(TParticle *particle)
-{
-//
-// Copies data from an MC particle into the object which
-// contains all MC details taken from kinematics info.
-// If requested by second argument, momentum and vertex
-// of the Particle are copied into the 'fP' and 'fV'
-// data members, to simulate a perfect reconstruction.
-// If something goes wrong, returns kFALSE,
-// otherwise returns kTRUE.
-//
-
-  // retrieve the TParticle object pointed by this MC track
-  if (!particle)
-  {
-    AliError("Passed NULL particle object");
-    return kFALSE;
-  }
-
-  // initialize object if not initialized yet
-  if (fMCInfo) delete fMCInfo;
-  fMCInfo = new AliRsnMCInfo;
-  fMCInfo->Adopt(particle);
-
-  return kTRUE;
-}
-
-//_____________________________________________________________________________
-Bool_t AliRsnDaughter::InitMCInfo(AliMCParticle *mcParticle)
+AliPID::EParticleType AliRsnDaughter::InternalType(Int_t pdg)
 {
 //
-// Copies data from an MC particle into the object which
-// contains all MC details taken from kinematics info.
-// If requested by second argument, momentum and vertex
-// of the Particle are copied into the 'fP' and 'fV'
-// data members, to simulate a perfect reconstruction.
-// If something goes wrong, returns kFALSE,
-// otherwise returns kTRUE.
+// Return the internal enum value corresponding to the PDG
+// code passed as argument, if possible.
+// Otherwise, returns 'AliPID::kSPECIES' by default.
 //
 
-  // retrieve the TParticle object pointed by this MC track
-  TParticle *particle = mcParticle->Particle();
-  return InitMCInfo(particle);
-}
-
-//_____________________________________________________________________________
-Int_t AliRsnDaughter::Compare(const TObject* obj) const
-{
-//
-// Compare two tracks with respect to their transverse momentum.
-// Citation from ROOT reference:
-// "Must return -1 if this is smaller than obj, 0 if objects are equal
-//  and 1 if this is larger than obj".
-//
+  AliPID::EParticleType value;
+  Int_t absPDG = TMath::Abs(pdg);
 
-  AliRsnDaughter *that = (AliRsnDaughter*)obj;
-  if (Pt() < that->Pt()) return 1;
-  else if (Pt() > that->Pt()) return -1;
-  else return 0;
+  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;
 }
 
 //_____________________________________________________________________________
-void AliRsnDaughter::GetESDPID
-(AliESDtrack * track, Double_t * pid, EPIDType pidType, Double_t divValue, Double_t val)
+const char* AliRsnDaughter::MethodName(EPIDMethod method)
 {
 //
-// A simple method to define PID weights by combining the ones
-// from single detectors by multiplication.
-// In the case when 'kITS_TPC_TOF_SP' option is chosen, a separation value
-// defines if the TOF signal must be included or not.
-// This value is usually the transverse momentum, but here it is left undefined.
+// Returns a string with the method name
 //
 
-  Int_t i;
-  Double_t ctmp[AliRsnPID::kSpecies];
-
-  switch (pidType)
+  switch (method)
   {
-    case kEsd :
-      track->GetESDpid(pid);
-      break;
-    case kITS :
-      track->GetITSpid(pid);
-      break;
-    case kTPC :
-      track->GetTPCpid(pid);
-      break;
-    case kTOF :
-      track->GetTOFpid(pid);
-      break;
-    case kITS_TPC :
-      track->GetITSpid(pid);
-      track->GetTPCpid(ctmp);
-      for (i = 0; i < 5; i++) pid[i] *= ctmp[i];
-      break;
-    case kITS_TOF :
-      track->GetITSpid(pid);
-      track->GetTOFpid(ctmp);
-      for (i = 0; i < AliRsnPID::kSpecies; i++) pid[i] *= ctmp[i];
-      break;
-    case kTPC_TOF :
-      track->GetTPCpid(pid);
-      track->GetTOFpid(ctmp);
-      for (i = 0; i < AliRsnPID::kSpecies; i++) pid[i] *= ctmp[i];
-      break;
-    case kITS_TPC_TOF :
-      track->GetITSpid(pid);
-      track->GetTPCpid(ctmp);
-      for (i = 0; i < AliRsnPID::kSpecies; i++) pid[i] *= ctmp[i];
-      track->GetTOFpid(ctmp);
-      for (i = 0; i < AliRsnPID::kSpecies; i++) pid[i] *= ctmp[i];
-      break;
-    case kITS_TPC_TOF_SP :
-      if (val < divValue)
-      {
-        track->GetITSpid(pid);
-        track->GetTPCpid(ctmp);
-        for (i = 0; i < AliRsnPID::kSpecies; i++) pid[i] *= ctmp[i];
-      }
-      else
-      {
-        track->GetTOFpid(pid);
-      }
-      break;
+    case kNoPID:
+      return "No PID";
+    case kRealistic:
+      return "Realistic";
+    case kPerfect:
+      return "Perfect";
     default:
-      AliLog::Message(AliLog::kError,
-                      "Unrecognized value of EPIDType argument",
-                      "", "AliRsnDaughter", "GetESDPID", __FILE__, __LINE__);
-      for (i = 0; i < AliRsnPID::kSpecies; i++) pid[i] = 1.0;
-      break;
+      return "Unknown";
   }
 }