-/**************************************************************************
- * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
- * *
- * Author: The ALICE Off-line Project. *
- * Contributors are mentioned in the code where appropriate. *
- * *
- * Permission to use, copy, modify and distribute this software and its *
- * documentation strictly for non-commercial purposes is hereby granted *
- * without fee, provided that the above copyright notice appears in all *
- * copies and that both the copyright notice and this permission notice *
- * appear in the supporting documentation. The authors make no claims *
- * about the suitability of this software for any purpose. It is *
- * provided "as is" without express or implied warranty. *
- **************************************************************************/
-
-//=========================================================================
+//
// 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.
+// It contains a useful TLorentzVector data-member which, provided that a meaningful mass was assigned,
+// eases a lot the computation of invariant masses from summing up several of these objects.
//
-// Light-weight 'track' object into an internal format used
-// for further steps of resonance analysis.
-// Provides converters from all kinds of input track type
-// (ESD, AOD and MC).
-// Contains also a facility to compute invariant mass of a pair.
+// authors: A. Pulvirenti (alberto.pulvirenti@ct.infn.it)
+// M. Vala (martin.vala@cern.ch)
//
-// author: A. Pulvirenti --- email: alberto.pulvirenti@ct.infn.it
-//=========================================================================
-
-#include <Riostream.h>
#include <TParticle.h>
-#include <TString.h>
-#include "AliLog.h"
+#include "AliStack.h"
+#include "AliMCEvent.h"
+#include "AliESDEvent.h"
+#include "AliAODEvent.h"
#include "AliESDtrack.h"
+#include "AliAODEvent.h"
+#include "AliAODVertex.h"
#include "AliAODTrack.h"
-#include "AliMCParticle.h"
-#include "AliRsnPID.h"
-#include "AliRsnMCInfo.h"
#include "AliRsnDaughter.h"
ClassImp(AliRsnDaughter)
//_____________________________________________________________________________
AliRsnDaughter::AliRsnDaughter() :
- AliVParticle(),
- fIndex(-1),
+ fOK(kFALSE),
fLabel(-1),
- fCharge(0),
- fFlags(0),
- fPIDType(AliRsnPID::kUnknown),
- fMass(0.0),
- fMCInfo(0x0)
+ fMotherPDG(0),
+ fP(0.0, 0.0, 0.0, 0.0),
+ fPMC(0.0, 0.0, 0.0, 0.0),
+ fRef(0x0),
+ fRefMC(0x0)
{
//
// 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 ©) :
- AliVParticle(copy),
- fIndex(copy.fIndex),
+ TObject(copy),
+ fOK(copy.fOK),
fLabel(copy.fLabel),
- fCharge(copy.fCharge),
- fFlags(copy.fFlags),
- fPIDType(copy.fPIDType),
- fMass(copy.fMass),
- fMCInfo(0x0)
+ fMotherPDG(copy.fMotherPDG),
+ fP(copy.fP),
+ fPMC(copy.fPMC),
+ fRef(copy.fRef),
+ fRefMC(copy.fRefMC)
{
//
// Copy constructor.
+// Pointers are NOT duplicated, since they don't come from a 'new'
+// statement, but from just referencing something in the data source.
//
-
- 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),
- fPIDType(AliRsnPID::kUnknown),
- fMass(0.0),
- 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, useTPC);
-}
-
-//_____________________________________________________________________________
-AliRsnDaughter::AliRsnDaughter(AliAODTrack *track) :
- AliVParticle(),
- fIndex(-1),
- fLabel(-1),
- fCharge(0),
- fFlags(0),
- fPIDType(AliRsnPID::kUnknown),
- fMass(0.0),
- 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),
- fPIDType(AliRsnPID::kUnknown),
- fMass(0.0),
- 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);
}
//_____________________________________________________________________________
{
//
// Assignment operator.
-// Works like the copy constructor and returns a reference
-// to the initialized object for which it is called.
+// Pointers are NOT duplicated, since they don't come from a 'new'
+// statement, but from just referencing something in the data source.
//
- fIndex = copy.fIndex;
- fLabel = copy.fLabel;
- fCharge = copy.fCharge;
- fFlags = copy.fFlags;
+ fOK = copy.fOK;
+ fLabel = copy.fLabel;
+ fMotherPDG = copy.fMotherPDG;
+ fP = copy.fP;
+ fPMC = copy.fPMC;
+ fRef = copy.fRef;
+ fRefMC = copy.fRefMC;
- 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];
- }
-
- fPIDType = copy.fPIDType;
- fMass = copy.fMass;
-
- // 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));
-
- return (*this);
+ return (*this);
}
//_____________________________________________________________________________
AliRsnDaughter::~AliRsnDaughter()
{
//
-// Destructor
-//
-
- if (fMCInfo) {
- delete fMCInfo;
- fMCInfo = 0;
- }
-}
-
-//_____________________________________________________________________________
-void AliRsnDaughter::SetPIDWeight(Int_t i, Double_t value)
-{
-//
-// I the argument 'i' is in the correct range,
-// sets the i-th PID weight to 'value'
+// Destructor.
+// Since pointers do not allocate new objects, no 'delete' is done.
//
-
- if (i >= 0 && i < AliRsnPID::kSpecies) fPIDWeight[i] = value;
- else {
- AliError(Form("Cannot set a weight related to slot %d", i));
- }
}
//_____________________________________________________________________________
-void AliRsnDaughter::SetPIDProb(Int_t i, Double_t value)
+void AliRsnDaughter::Reset()
{
//
-// I the argument 'i' is in the correct range,
-// sets the i-th PID probability to 'value'
+// 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 (i >= 0 && i < AliRsnPID::kSpecies) fPIDProb[i] = value;
- else {
- AliError(Form("Cannot set a weight related to slot %d", i));
- }
+ fOK = kFALSE;
+ fLabel = -1;
+ fMotherPDG = 0;
+ fRef = 0x0;
+ fRefMC = 0x0;
+
+ fP .SetXYZM(0.0, 0.0, 0.0, 0.0);
+ fPMC.SetXYZM(0.0, 0.0, 0.0, 0.0);
}
//_____________________________________________________________________________
-void AliRsnDaughter::SetPIDWeights(const Double_t *pid)
-{
-//
-// Sets ALL PID weights at once.
-// The passed array is supposed to have at least as many
-// slots as the number of allowed particle species.
-//
-
- Int_t i;
- for (i = 0; i < AliRsnPID::kSpecies; i++) fPIDWeight[i] = pid[i];
-}
-
-
-//_____________________________________________________________________________
-Bool_t AliRsnDaughter::Adopt(AliESDtrack* esdTrack, Bool_t useTPCInnerParam)
-{
-//
-// 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.
-//
-
- if (!esdTrack) {
- AliError("Passed NULL object: nothing done");
- return kFALSE;
- }
-
- // copy momentum and vertex
- if (!useTPCInnerParam) {
- esdTrack->GetPxPyPz(fP);
- esdTrack->GetXYZ(fV);
- }
- else {
- if (!esdTrack->GetTPCInnerParam()) return kFALSE;
- esdTrack->GetTPCInnerParam()->GetPxPyPz(fP);
- esdTrack->GetTPCInnerParam()->GetXYZ(fV);
- }
-
- // copy PID weights
- Int_t i;
- Double_t pid[5];
- if (!useTPCInnerParam) {
- esdTrack->GetESDpid(pid);
- }
- else {
- esdTrack->GetTPCpid(pid);
- }
- for (i = 0; i < 5; i++) fPIDWeight[i] = pid[i];
-
- // copy flags
- fFlags = esdTrack->GetStatus();
-
- // copy charge sign
- fCharge = (Short_t)esdTrack->Charge();
-
- return kTRUE;
-}
-
-
-//_____________________________________________________________________________
-Bool_t AliRsnDaughter::Adopt(AliAODTrack* aodTrack)
-{
-//
-// 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.
-//
-
- 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();
-
- // copy PID weights
- Int_t i;
- for (i = 0; i < 5; i++) fPIDWeight[i] = aodTrack->PID()[i];
-
- // copy sign
- fCharge = aodTrack->Charge();
-
- return kTRUE;
-}
-
-
-//_____________________________________________________________________________
-Bool_t AliRsnDaughter::Adopt(AliMCParticle *mcParticle)
-{
-//
-// 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.
-//
-
- 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;
- }
-
- // 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();
-
- // recognize charge sign from PDG code sign
- Int_t pdg = particle->GetPdgCode();
- Int_t absPDG = TMath::Abs(pdg);
- if (absPDG <= 15) {
- if (pdg > 0) fCharge = -1; else fCharge = 1;
- }
- else if (absPDG < 3000) {
- if (pdg > 0) fCharge = 1; else fCharge = -1;
- }
- else {
- fCharge = 0;
- return kFALSE;
- }
-
- // identify track perfectly using PDG code
- fPIDType = AliRsnPID::InternalType(pdg);
- fMass = AliRsnPID::ParticleMass(fPIDType);
-
- // flags and PID weights make no sense with MC tracks
- fFlags = 0;
- for (pdg = 0; pdg < AliRsnPID::kSpecies; pdg++) fPIDWeight[pdg] = 0.0;
- fPIDWeight[fPIDType] = 1.0;
-
- // copy other MC info (mother PDG code cannot be retrieved here)
- InitMCInfo(particle);
-
- return kTRUE;
-}
-
-//_____________________________________________________________________________
-void AliRsnDaughter::Print(Option_t *option) const
+void AliRsnDaughter::Print(Option_t * const /*option*/) const
{
//
// Prints the values of data members, using the options:
// - 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
//
// Index and label are printed by default.
//
-
- TString opt(option);
- opt.ToUpper();
-
- cout << ".......Index : " << fIndex << endl;
- cout << ".......Label : " << fLabel << endl;
-
- if (opt.Contains("P") || opt.Contains("ALL")) {
- cout << ".......Px, Py, Pz, Pt : " << Px() << ' ' << Py() << ' ' << Pz() << ' ' << Pt() << endl;
- }
- if (opt.Contains("V") || opt.Contains("ALL")) {
- cout << ".......Vx, Vy, Vz : " << Xv() << ' ' << Yv() << ' ' << Zv() << endl;
- }
- if (opt.Contains("C") || opt.Contains("ALL")) {
- cout << ".......Charge : " << fCharge << endl;
- }
- if (opt.Contains("F") || opt.Contains("ALL")) {
- cout << ".......Flags : " << fFlags << endl;
- }
- if (opt.Contains("I") || opt.Contains("ALL")) {
- cout << ".......PID : " << AliRsnPID::ParticleName(fPIDType) << endl;
- if (fPIDType > 0 && fPIDType < AliRsnPID::kSpecies) {
- cout << ".......PID probability : " << fPIDProb[fPIDType] << endl;
- }
- cout << ".......Mass : " << fMass << endl;
- }
- if (opt.Contains("W") || opt.Contains("ALL")) {
- cout << ".......Weights : ";
- Int_t i;
- for (i = 0; i < AliRsnPID::kSpecies; i++) cout << fPIDWeight[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 {
- cout << ".......MC info not present" << endl;
- }
- }
+
+ Char_t type[50], source[50];
+ if (IsTrack()) snprintf(type, 5, "track");
+ else if (IsV0()) snprintf(type, 2, "V0");
+ else snprintf(type, 4, "none");
+
+ if (IsESD()) snprintf(source, 3, "ESD");
+ else if (IsAOD()) snprintf(source, 3, "AOD");
+ else if (fRefMC != 0x0) snprintf(source, 7, "MC only");
+ else snprintf(source, 4, "none");
+
+ AliInfo("===== ALIRSNDAUGHTER INFORMATION ==============================================");
+ AliInfo(Form(".......Index : %d", GetID()));
+ AliInfo(Form(".......Label : %d", GetLabel()));
+ AliInfo(Form(".......Type, source : %s %s", type, source));
+ AliInfo(Form(".......Charge : %c", ChargeChar()));
+
+ if (fRef)
+ {
+ AliInfo(Form(".......Px, Py, Pz, Pt (ref) : %f %f %f %f", fP.X(), fP.Y(), fP.Z(), fP.Perp()));
+ } else AliInfo("....... absent REF");
+
+ if (fRefMC)
+ {
+ AliInfo(Form(".......Px, Py, Pz, Pt (ref MC): %f %f %f %f", fP.X(), fP.Y(), fP.Z(), fP.Perp()));
+ AliInfo(Form(".......PDG code : %d", fRefMC->Particle()->GetPdgCode()));
+ AliInfo(Form(".......Mother (label) : %d", fRefMC->Particle()->GetFirstMother()));
+ AliInfo(Form(".......Mother (PDG code) : %d", fMotherPDG));
+ } else AliInfo("....... absent REF MC");
+
+ AliInfo("===== END ALIRSNDAUGHTER INFORMATION ==========================================");
}
//_____________________________________________________________________________
-void AliRsnDaughter::InitMCInfo()
+Int_t AliRsnDaughter::GetID() const
{
//
-// Initializes the particle object with default constructor.
+// Return reference index, using the "GetID" method
+// of the possible source object.
+// In case of V0s, since this method is unsuccessful, return the label.
//
- fMCInfo = new AliRsnMCInfo;
+ const AliESDtrack *esd = GetRefESDtrack();
+ if (esd) return esd->GetID();
+
+ const AliAODTrack *aod = GetRefAODtrack();
+ if (aod) return aod->GetID();
+
+ return GetLabel();
}
//_____________________________________________________________________________
-Bool_t AliRsnDaughter::InitMCInfo(TParticle *particle)
+Bool_t AliRsnDaughter::HasFlag(ULong_t flag) const
{
//
-// 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.
+// Checks that the 'status' flag of the source object has one or
+// a combination of status flags combined with the bitwise OR.
+// Works only with track-like objects.
//
- // 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;
+ if (IsTrack())
+ {
+ AliVTrack *track = dynamic_cast<AliVTrack*>(fRef);
+ ULong_t status = (ULong_t)track->GetStatus();
+ return ((status & flag) != 0);
+ }
+
+ return kTRUE;
}
//_____________________________________________________________________________
-Bool_t AliRsnDaughter::InitMCInfo(AliMCParticle *mcParticle)
+Bool_t AliRsnDaughter::SetMass(Double_t mass)
{
//
-// 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.
+// The argument defines a mass to be assigned to the 4-momentum.
+// This value is not stored as a data-member, but serves just to modify
+// the energy of the 4-momentum both in the MC and non-MC objects,
+// while the vector momentum is taken from the respective references.
+// The method returns a BOOL outcome which is kFALSE in the case that
+// mass is meaningless or when both references are NULL or the goodness
+// flag is not positive.
//
- // retrieve the TParticle object pointed by this MC track
- TParticle *particle = mcParticle->Particle();
- return InitMCInfo(particle);
+ if (!fOK) return kFALSE;
+ if (mass < 0.) return kFALSE;
+ if (!fRef && !fRefMC) return kFALSE;
+
+ if (fRef) fP .SetXYZM(fRef ->Px(), fRef ->Py(), fRef ->Pz(), mass);
+ if (fRefMC) fPMC.SetXYZM(fRefMC->Px(), fRefMC->Py(), fRefMC->Pz(), mass);
+
+ return kTRUE;
}