Splitted the values into three groups, for daughters/pairs/events only, to avoid confusion and too long switch statements.
Added some new cuts, and corrected some old ones (removed a bug in cut on primary vertex, and adjusted cuts on track quality).
Introduced the loop for pair efficiency computation.
RESONANCES/AliRsnTarget.cxx
RESONANCES/AliRsnValue.cxx
RESONANCES/AliRsnCut.cxx
- RESONANCES/AliRsnValueStd.cxx
- RESONANCES/AliRsnValuePID.cxx
+ RESONANCES/AliRsnValueDaughter.cxx
+ RESONANCES/AliRsnValuePair.cxx
+ RESONANCES/AliRsnValueEvent.cxx
RESONANCES/AliRsnCutPrimaryVertex.cxx
RESONANCES/AliRsnCutTrackQuality.cxx
RESONANCES/AliRsnCutValue.cxx
RESONANCES/AliRsnCutPIDTOF.cxx
RESONANCES/AliRsnCutPIDNSigma.cxx
RESONANCES/AliRsnCutMomentumComparison.cxx
+ RESONANCES/AliRsnCutKaonForPhi2010.cxx
RESONANCES/AliRsnCutSet.cxx
RESONANCES/AliRsnExpression.cxx
RESONANCES/AliRsnVariableExpression.cxx
#pragma link C++ class AliRsnValue+;
#pragma link C++ class AliRsnCut+;
-#pragma link C++ class AliRsnValueStd+;
-#pragma link C++ class AliRsnValuePID+;
+#pragma link C++ class AliRsnValueDaughter+;
+#pragma link C++ class AliRsnValuePair+;
+#pragma link C++ class AliRsnValueEvent+;
#pragma link C++ class AliRsnCutPrimaryVertex+;
#pragma link C++ class AliRsnCutTrackQuality+;
#pragma link C++ class AliRsnCutPIDTOF+;
#pragma link C++ class AliRsnCutPIDNSigma+;
#pragma link C++ class AliRsnCutMomentumComparison+;
+#pragma link C++ class AliRsnCutKaonForPhi2010+;
+
#pragma link C++ class AliRsnCutSet+;
#pragma link C++ class AliRsnExpression+;
Bool_t useDefault = fUseDefault;
Bool_t perfectPID = fPerfect;
if (perfectPID && !daughter->GetRefMC()) return kFALSE;
- if (!daughter->GetRefESDtrack()) useDefault = kTRUE;
- if (!daughter->GetRefESDtrack() && !daughter->GetRefAODtrack()) return kFALSE;
+ if (!daughter->Ref2ESDtrack()) useDefault = kTRUE;
+ if (!daughter->Ref2ESDtrack() && !daughter->Ref2AODtrack()) return kFALSE;
// if perfect PID ise required,
// compare the PDG code of the type stored in 'fMinI' of the cut
// if default weights are (or need to be) used,
// they are taken directly and function exits
if (useDefault) {
- if (daughter->GetRefESDtrack())
- daughter->GetRefESDtrack()->GetESDpid(fWeight);
+ if (daughter->Ref2ESDtrack())
+ daughter->Ref2ESDtrack()->GetESDpid(fWeight);
else {
for (i = 0; i < AliPID::kSPECIES; i++)
- fWeight[i] = daughter->GetRefAODtrack()->PID()[i];
+ fWeight[i] = daughter->Ref2AODtrack()->PID()[i];
}
return kTRUE;
}
// if we arrive here, this means that we have an ESD track
// and we want to customize the PID
- AliESDtrack *track = daughter->GetRefESDtrack();
+ AliESDtrack *track = daughter->Ref2ESDtrack();
Double_t w[kDetectors][AliPID::kSPECIES];
track->GetITSpid(w[kITS]);
track->GetTPCpid(w[kTPC]);
// reject not ITS tracks
// status is checked in the same way for all tracks
- AliVTrack *vtrack = fDaughter->GetRefVtrack();
+ AliVTrack *vtrack = fDaughter->Ref2Vtrack();
if (!vtrack) {
AliDebug(AliLog::kDebug + 2, Form("Impossible to process an object of type '%s'. Cut applicable only to ESD/AOD tracks", fDaughter->GetRef()->ClassName()));
return kFALSE;
// common evaluation variables
Int_t k, nITSpidLayers = 0;
Double_t mom = vtrack->P();
- AliESDtrack *esdTrack = fDaughter->GetRefESDtrack();
- AliAODTrack *aodTrack = fDaughter->GetRefAODtrack();
+ AliESDtrack *esdTrack = fDaughter->Ref2ESDtrack();
+ AliAODTrack *aodTrack = fDaughter->Ref2AODtrack();
// count number of PID layers...
if (esdTrack) {
fSpecies(species),
fDetector(det),
fMomMin(0.0),
- fMomMax(0.0),
- fRejectOutside(kFALSE),
+ fMomMax(1E20),
fRejectUnmatched(kFALSE)
{
//
fDetector(copy.fDetector),
fMomMin(copy.fMomMin),
fMomMax(copy.fMomMax),
- fRejectOutside(copy.fRejectOutside),
fRejectUnmatched(copy.fRejectUnmatched)
{
//
fDetector = copy.fDetector;
fMomMin = copy.fMomMin;
fMomMax = copy.fMomMax;
- fRejectOutside = copy.fRejectOutside;
fRejectUnmatched = copy.fRejectUnmatched;
return (*this);
// get reference momentum, for range cut
Double_t momentum = -1.0;
- if (!fDaughter->GetRefVtrack()) {
+ if (!fDaughter->Ref2Vtrack()) {
AliDebugClass(2, "Referenced daughter is not a track");
return kFALSE;
}
if (fDetector == kTPC)
- momentum = fDaughter->GetRefVtrack()->GetTPCmomentum();
+ momentum = fDaughter->Ref2Vtrack()->GetTPCmomentum();
else
momentum = fDaughter->GetRef()->P();
// check momentum range, if required
- if (fRejectOutside) {
- if (momentum < fMomMin || momentum > fMomMax) {
- AliDebugClass(2, Form("Track momentum = %.5f, outside allowed range [%.2f - %.2f]", momentum, fMomMin, fMomMax));
- return kFALSE;
- }
+ if (momentum < fMomMin || momentum > fMomMax) {
+ AliDebugClass(2, Form("Track momentum = %.5f, outside allowed range [%.2f - %.2f]", momentum, fMomMin, fMomMax));
+ return kFALSE;
}
// matching check, if required
if (fRejectUnmatched) {
switch (fDetector) {
case kITS:
- if (!IsITS()) {
+ if (!IsITS(fDaughter->Ref2Vtrack())) {
AliDebug(3, "Rejecting track not matched in ITS");
return kFALSE;
}
break;
case kTPC:
- if (!IsTPC()) {
+ if (!IsTPC(fDaughter->Ref2Vtrack())) {
AliDebug(3, "Rejecting track not matched in TPC");
return kFALSE;
}
break;
case kTOF:
- if (!IsTOF()) {
+ if (!IsTOF(fDaughter->Ref2Vtrack())) {
AliDebug(3, "Rejecting track not matched in TOF");
return kFALSE;
}
fCutValueD = pid->NumberOfSigmasTOF(fDaughter->GetRef(), fSpecies);
break;
default:
- fCutValueD = 1E20;
return kFALSE;
}
//
Char_t mom[200], det[100], match[200];
-
- if (fRejectOutside)
- snprintf(mom, 200, "Tracks are accepted only in the momentum range %.2f --> %.2f", fMomMin, fMomMax);
- else
- snprintf(mom, 200, "No check in momentum range");
if (fRejectUnmatched)
snprintf(match, 200, "Unmatched tracks are rejected");
#include "AliRsnCut.h"
+class AliVTrack;
class AliPIDResponse;
class AliRsnCutPIDNSigma : public AliRsnCut {
AliRsnCutPIDNSigma& operator=(const AliRsnCutPIDNSigma& copy);
virtual ~AliRsnCutPIDNSigma() { }
- void SetRejectOutside(Bool_t yn = kTRUE) {fRejectOutside = yn;}
void SetRejectUnmatched(Bool_t yn = kTRUE) {fRejectUnmatched = yn;}
void SetMomentumRange(Double_t min, Double_t max) {fMomMin = min; fMomMax = max;}
void SetNSigmaRange(Double_t min, Double_t max) {AliRsnCut::SetRangeD(min, max);}
void SetSpecies(AliPID::EParticleType type) {fSpecies = type;}
- Bool_t IsITS();
- Bool_t IsTPC();
- Bool_t IsTOF();
+ Bool_t IsITS(AliVTrack *vtrack);
+ Bool_t IsTPC(AliVTrack *vtrack);
+ Bool_t IsTOF(AliVTrack *vtrack);
virtual Bool_t IsSelected(TObject *object);
virtual void Print(const Option_t *option = "") const;
EDetector fDetector; // detector used for PID
Double_t fMomMin; // momentum range (for ITS and TOF it is vertex momentum, for TPC it is inner wall)
Double_t fMomMax; // momentum range (for ITS and TOF it is vertex momentum, for TPC it is inner wall)
- Bool_t fRejectOutside; // tracks outside momentum range do pass the cut?
Bool_t fRejectUnmatched; // tracks not matched to this detector do pass the cut?
ClassDef(AliRsnCutPIDNSigma, 1)
};
-inline Bool_t AliRsnCutPIDNSigma::IsITS()
+inline Bool_t AliRsnCutPIDNSigma::IsITS(AliVTrack *vtrack)
{
//
// Checks if the track has the status flags required for an ITS standalone track
//
- AliVTrack *vtrack = fDaughter->GetRefVtrack();
-
- if (!vtrack) {
- AliWarning("NULL argument: impossible to check status");
- return kFALSE;
- }
-
- Bool_t isITSin = ((vtrack->GetStatus() & AliESDtrack::kTPCin) != 0);
- Bool_t isITSpid = ((vtrack->GetStatus() & AliESDtrack::kITSpid) != 0);
+ if ((vtrack->GetStatus() & AliESDtrack::kITSin) == 0) return kFALSE;
+ if ((vtrack->GetStatus() & AliESDtrack::kITSpid) == 0) return kFALSE;
- return (isITSin && isITSpid);
+ return kTRUE;
}
-inline Bool_t AliRsnCutPIDNSigma::IsTPC()
+inline Bool_t AliRsnCutPIDNSigma::IsTPC(AliVTrack *vtrack)
{
//
// Checks if the track has the status flags required for a TPC track
//
- AliVTrack *vtrack = fDaughter->GetRefVtrack();
-
- if (!vtrack) {
- AliWarning("NULL argument: impossible to check status");
- return kFALSE;
- }
-
- return ((vtrack->GetStatus() & AliESDtrack::kTPCin) != 0);
+ if ((vtrack->GetStatus() & AliESDtrack::kTPCin) == 0) return kFALSE;
+
+ return kTRUE;
}
-inline Bool_t AliRsnCutPIDNSigma::IsTOF()
+inline Bool_t AliRsnCutPIDNSigma::IsTOF(AliVTrack *vtrack)
{
//
// Checks if the track has the status flags required for an ITS standalone track
//
- AliVTrack *vtrack = fDaughter->GetRefVtrack();
-
- if (!vtrack) {
- AliWarning("NULL argument: impossible to check status");
- return kFALSE;
- }
-
- Bool_t isTOFout = ((vtrack->GetStatus() & AliESDtrack::kTOFout) != 0);
- Bool_t isTIME = ((vtrack->GetStatus() & AliESDtrack::kTIME) != 0);
+ if ((vtrack->GetStatus() & AliESDtrack::kTOFout) == 0) return kFALSE;
+ if ((vtrack->GetStatus() & AliESDtrack::kTIME) == 0) return kFALSE;
- return (isTOFout && isTIME);
+ return kTRUE;
}
#endif
if (!TargetOK(object)) return kFALSE;
// reject always non-track objects
- AliVTrack *vtrack = fDaughter->GetRefVtrack();
+ AliVTrack *vtrack = fDaughter->Ref2Vtrack();
if (!vtrack) {
AliDebug(AliLog::kDebug + 2, Form("Impossible to process an object of type '%s'. Cut applicable only to ESD/AOD tracks", fDaughter->GetRef()->ClassName()));
return kFALSE;
// prepare some useful variables
Double_t tof, sigma, times[5];
Double_t &ref = times[(Int_t)fRefType];
- AliESDtrack *esdTrack = fDaughter->GetRefESDtrack();
- AliAODTrack *aodTrack = fDaughter->GetRefAODtrack();
+ AliESDtrack *esdTrack = fDaughter->Ref2ESDtrack();
+ AliAODTrack *aodTrack = fDaughter->Ref2AODtrack();
// cut check depends on the object type
if (esdTrack) {
// common evaluation variables
Double_t mom;
- AliESDtrack *esdTrack = fDaughter->GetRefESDtrack();
- AliAODTrack *aodTrack = fDaughter->GetRefAODtrack();
+ AliESDtrack *esdTrack = fDaughter->Ref2ESDtrack();
+ AliAODTrack *aodTrack = fDaughter->Ref2AODtrack();
// get inner momentum, needed for BB computation
if (esdTrack) {
//_________________________________________________________________________________________________
AliRsnCutPrimaryVertex::AliRsnCutPrimaryVertex
(const char *name, Double_t maxVz, Int_t nContributors, Bool_t acceptTPC) :
- AliRsnCut(name, AliRsnCut::kEvent, 0, nContributors - 1, 0.0, maxVz),
+ AliRsnCut(name, AliRsnCut::kEvent, 0, nContributors - 1, -maxVz, maxVz + 1E-6),
fAcceptTPC(acceptTPC),
fCheckPileUp(kFALSE)
{
// Since the range check uses the '>=' and '<=', the high edge
// must be decreased by 1 to get the right behaviour, since this is integer.
//
-
- fMinD = 0.0;
- fMaxD = maxVz + 1E-6;
}
//_________________________________________________________________________________________________
if (!TargetOK(object)) return kFALSE;
// retrieve ESD event
- AliESDEvent *esd = fEvent->GetRefESD();
- AliAODEvent *aod = fEvent->GetRefAOD();
+ AliESDEvent *esd = dynamic_cast<AliESDEvent*>(fEvent->GetRef());
+ AliAODEvent *aod = dynamic_cast<AliAODEvent*>(fEvent->GetRef());
if (esd) {
// pile-up check
} else
return kFALSE;
} else if (aod) {
- // pile-up check is not yet available for AODs
-
- // lines suggested by Andrea to reject TPC-only events
- if (!fAcceptTPC) {
- if (!aod->GetPrimaryVertexSPD()) return kFALSE;
- else if (aod->GetPrimaryVertexSPD()->GetNContributors() < 1) return kFALSE;
+ // in this case, as suggested by Andrea Dainese,
+ // we first check if the SPD primary vertex is there
+ // if it is not, then the only available is the TPC
+ // stand-alone primary vertex, which is rejected
+ AliAODVertex *aodv = aod->GetPrimaryVertexSPD();
+ if (!aodv) {
+ AliDebugClass(1, "Not found SPD vertex --> TPC only available, skipped");
+ return kFALSE;
+ }
+ // now check primary vertex
+ aodv = (AliAODVertex*)aod->GetPrimaryVertex();
+ if (CheckVertex(aodv)) {
+ AliDebugClass(1, "Vertex TRK is OK");
+ fCutValueD = aodv->GetZ();
+ fCutValueI = aodv->GetNContributors();
+ }
+ else {
+ aodv = aod->GetPrimaryVertexSPD();
+ if (CheckVertex(aodv)) {
+ AliDebugClass(1, "Vertex TRK is BAD, but vertex SPD is OK");
+ fCutValueD = aodv->GetZ();
+ fCutValueI = aodv->GetNContributors();
+ } else {
+ AliDebugClass(1, "Vertex TRK is BAD, and vertex SPD is BAD");
+ return kFALSE;
+ }
}
-
- AliAODVertex *prim = (AliAODVertex*)aod->GetPrimaryVertex();
- if (!prim) return kFALSE;
-
- fCutValueI = prim->GetNContributors();
- fCutValueD = prim->GetZ();
} else
return kFALSE;
#define ALIRSNCUTPRIMARYVERTEX_H
#include "AliRsnCut.h"
-#include "AliPID.h"
-#include "Riostream.h"
-#include "TMath.h"
+class AliVVertex;
-#include "AliLog.h"
-#include "AliESDEvent.h"
-#include "AliESDVertex.h"
-
-#include "AliRsnEvent.h"
-
-class AliRsnEvent;
-class AliRsnDaughter;
-class AliRsnPairParticle;
class AliRsnCutPrimaryVertex : public AliRsnCut {
public:
protected:
+ Bool_t CheckVertex(AliVVertex *vert);
+
Bool_t fAcceptTPC; // if kTRUE, the TPC primary vertexes are accepted
Bool_t fCheckPileUp; // check and reject pileupped events (pp)
ClassDef(AliRsnCutPrimaryVertex, 1)
};
+//__________________________________________________________________________________________________
+inline Bool_t AliRsnCutPrimaryVertex::CheckVertex(AliVVertex *vertex)
+{
+//
+// Checks if a candidate primary vertex is good,
+// which is true if it is not null and has at
+// least one contributor
+//
+
+ if (!vertex) return kFALSE;
+ if (vertex->GetNContributors() < 1) return kFALSE;
+
+ return kTRUE;
+}
+
#endif
//_________________________________________________________________________________________________
AliRsnCutTrackQuality::AliRsnCutTrackQuality(const char *name) :
- AliRsnCut(name, AliRsnCut::kDaughter, 0.0, 0.0),
+ AliRsnCut(name, AliRsnTarget::kDaughter, 0.0, 0.0),
fFlagsOn(0x0),
fFlagsOff(0x0),
fRejectKinkDaughters(kTRUE),
fITSminNClusters(0),
fITSmaxChi2(1E20),
fTPCminNClusters(0),
- fTPCmaxChi2(1E20)
+ fTPCmaxChi2(1E20),
+ fAODTestFilterBit(-1)
{
//
// Default constructor.
fITSminNClusters(copy.fITSminNClusters),
fITSmaxChi2(copy.fITSmaxChi2),
fTPCminNClusters(copy.fTPCminNClusters),
- fTPCmaxChi2(copy.fTPCmaxChi2)
+ fTPCmaxChi2(copy.fTPCmaxChi2),
+ fAODTestFilterBit(copy.fAODTestFilterBit)
{
//
// Copy constructor.
fITSmaxChi2 = copy.fITSmaxChi2;
fTPCminNClusters = copy.fTPCminNClusters;
fTPCmaxChi2 = copy.fTPCmaxChi2;
+ fAODTestFilterBit = copy.fAODTestFilterBit;
SetPtRange(copy.fPt[0], copy.fPt[1]);
SetEtaRange(copy.fEta[0], copy.fEta[1]);
fITSmaxChi2 = 1E20;
fTPCminNClusters = 0;
fTPCmaxChi2 = 1E20;
+ fAODTestFilterBit = -1;
SetPtRange(0.0, 1E20);
SetEtaRange(-1E20, 1E20);
// as a convention, if a the collection of 'on' flags is '0x0', it
// is assumed that no flags are required, and this check is skipped;
// for the collection of 'off' flags this is not needed
- AliVTrack *vtrack = fDaughter->GetRefVtrack();
+ AliVTrack *vtrack = fDaughter->Ref2Vtrack();
if (!vtrack) {
- AliDebug(AliLog::kDebug + 2, Form("This object is not either an ESD nor AOD track, it is an %s", fDaughter->GetRef()->ClassName()));
+ AliDebug(AliLog::kDebug + 2, "This object is not either an ESD nor AOD track");
return kFALSE;
}
ULong_t status = (ULong_t)vtrack->GetStatus();
ULong_t checkOn = status & fFlagsOn;
ULong_t checkOff = status & fFlagsOff;
if (fFlagsOn != 0x0 && checkOn != fFlagsOn) {
- AliDebug(AliLog::kDebug + 2, Form("Not all required flags are present: required %lx, track has %lx", fFlagsOn, status));
+ AliDebug(AliLog::kDebug + 2, Form("Failed flag check: required %s", Binary(fFlagsOn)));
+ AliDebug(AliLog::kDebug + 2, Form(" track has %s", Binary(status )));
return kFALSE;
}
if (checkOff != 0) {
- AliDebug(AliLog::kDebug + 2, Form("Some forbidden flags are present: required %lx, track has %lx", fFlagsOff, status));
+ AliDebug(AliLog::kDebug + 2, Form("Failed flag check: forbidden %s", Binary(fFlagsOff)));
+ AliDebug(AliLog::kDebug + 2, Form(" track has %s", Binary(status )));
return kFALSE;
}
+ AliDebug(AliLog::kDebug + 3, Form("Flag check OK: required %s", Binary(fFlagsOn)));
+ AliDebug(AliLog::kDebug + 3, Form(" forbidden %s", Binary(fFlagsOff)));
+ AliDebug(AliLog::kDebug + 3, Form(" track has %s", Binary(status )));
// retrieve real object type
- AliESDtrack *esdTrack = fDaughter->GetRefESDtrack();
- AliAODTrack *aodTrack = fDaughter->GetRefAODtrack();
+ AliESDtrack *esdTrack = fDaughter->Ref2ESDtrack();
+ AliAODTrack *aodTrack = fDaughter->Ref2AODtrack();
if (esdTrack) {
AliDebug(AliLog::kDebug + 2, "Checking an ESD track");
return CheckESD(esdTrack);
// an equivalend checker for AOD tracks
//
+ // if a test bit is used, check it and skip the following
+ if (fAODTestFilterBit >= 0) {
+ UInt_t bit = (UInt_t)fAODTestFilterBit;
+ AliDebugClass(2, Form("Required a test filter bit for AOD check: %u (result: %s)", bit, (track->TestFilterBit(bit) ? "accept" : "reject")));
+ if (!track->TestFilterBit(bit))
+ return kFALSE;
+ else {
+ if (track->Pt() < fPt[0] || track->Pt() > fPt[1]) return kFALSE;
+ if (track->Eta() < fEta[0] || track->Eta() > fEta[1]) return kFALSE;
+ return kTRUE;
+ }
+ }
+
// try to retrieve the reference AOD event
AliAODEvent *aodEvent = 0x0;
if (fEvent) aodEvent = fEvent->GetRefAOD();
void SetTPCmaxChi2(Double_t value) {fTPCmaxChi2 = value;}
void SetRejectKinkDaughters(Bool_t yn = kTRUE) {fRejectKinkDaughters = yn;}
+
+ void SetAODTestFilterBit(Int_t value) {fAODTestFilterBit = value;}
virtual Bool_t IsSelected(TObject *obj);
virtual void Print(const Option_t *option = "") const;
protected:
- Bool_t CheckESD(AliESDtrack *track);
- Bool_t CheckAOD(AliAODTrack *track);
+ Bool_t CheckESD(AliESDtrack *track);
+ Bool_t CheckAOD(AliAODTrack *track);
+ const char* Binary(UInt_t number);
ULong_t fFlagsOn; // status flags which must be ON (used AliESDtrack ones, connected with '|')
ULong_t fFlagsOff; // status flags which must be OFF (used AliESDtrack ones, connected with '|')
Int_t fTPCminNClusters; // minimum number of required clusters in TPC
Double_t fTPCmaxChi2; // maximum chi2 / number of clusters in TPC
+ Int_t fAODTestFilterBit; // test filter bit for AOD tracks
ClassDef(AliRsnCutTrackQuality, 1)
};
+//__________________________________________________________________________________________________
+inline const char * AliRsnCutTrackQuality::Binary(UInt_t number)
+{
+//
+// Convert an integer in binary
+//
+
+ static char b[15];
+ b[0] = '\0';
+
+ UInt_t z;
+ for (z = 512; z > 0; z >>= 1)
+ strcat(b, ((number & z) == z) ? "1" : "0");
+
+ return b;
+}
+
#endif
//_________________________________________________________________________________________________
AliRsnCutValue::AliRsnCutValue() :
AliRsnCut(),
- fUseMC(kFALSE),
fValue(0x0)
{
//
//_________________________________________________________________________________________________
AliRsnCutValue::AliRsnCutValue
-(const char *name, Double_t min, Double_t max, Bool_t useMC) :
+(const char *name, Double_t min, Double_t max) :
AliRsnCut(name, AliRsnTarget::kTargetTypes, min, max),
- fUseMC(useMC),
fValue(0x0)
{
//
//_________________________________________________________________________________________________
AliRsnCutValue::AliRsnCutValue(const AliRsnCutValue& copy) :
AliRsnCut(copy),
- fUseMC(copy.fUseMC),
fValue(copy.fValue)
{
//
//
AliRsnCut::operator=(copy);
- fUseMC = copy.fUseMC;
fValue = copy.fValue;
return (*this);
SetTargetType(fValue->GetTargetType());
// try to compute values
- Bool_t success = fValue->Eval(object, fUseMC);
+ Bool_t success = fValue->Eval(object);
// check success
if (!success) {
public:
AliRsnCutValue();
- AliRsnCutValue(const char *name, Double_t min, Double_t max, Bool_t isMC);
+ AliRsnCutValue(const char *name, Double_t min, Double_t max);
AliRsnCutValue(const AliRsnCutValue& copy);
AliRsnCutValue& operator=(const AliRsnCutValue& copy);
virtual ~AliRsnCutValue() { }
Double_t GetComputedValue() {if (fValue) return fValue->GetComputedValue(); return -1E20;}
AliRsnValue* GetValueObj() {return fValue;}
void SetValueObj(AliRsnValue *value) {fValue = value; SetTargetType(value->GetTargetType());}
- Bool_t IsUsingMC() {return fUseMC;}
- void UseMC(Bool_t yn = kTRUE) {fUseMC = yn;}
virtual Bool_t IsSelected(TObject *object);
virtual void Print(const Option_t *option = "") const;
protected:
- Bool_t fUseMC;
AliRsnValue *fValue;
ClassDef(AliRsnCutValue, 1)
-/**************************************************************************
- * 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. *
- **************************************************************************/
-
//
// This class works as generic interface to each candidate resonance daughter.
// Its main purpose is to provide a unique reference which includes all the
#include <TParticle.h>
#include <TDatabasePDG.h>
-#include "AliAODVertex.h"
#include "AliRsnDaughter.h"
ClassImp(AliRsnDaughter)
-//_____________________________________________________________________________
-AliRsnDaughter::AliRsnDaughter() :
- fOK(kFALSE),
- fLabel(-1),
- fMotherPDG(0),
- fRsnID(-1),
- fPrec(0.0, 0.0, 0.0, 0.0),
- fPsim(0.0, 0.0, 0.0, 0.0),
- fRef(0x0),
- fRefMC(0x0),
- fOwnerEvent(0x0)
-{
-//
-// Default constructor.
-// Initializes all data members to the same values
-// Which will be given by Reset() method.
-//
-}
-
//_____________________________________________________________________________
AliRsnDaughter::AliRsnDaughter(const AliRsnDaughter ©) :
TObject(copy),
fLabel = copy.fLabel;
fMotherPDG = copy.fMotherPDG;
fRsnID = copy.fRsnID;
- fPrec = copy.fPrec;
fPsim = copy.fPsim;
+ fPrec = copy.fPrec;
fRef = copy.fRef;
fRefMC = copy.fRefMC;
fOwnerEvent = copy.fOwnerEvent;
return (*this);
}
-//_____________________________________________________________________________
-void AliRsnDaughter::SetRef(AliVParticle *p)
-{
-//
-// Set the pointer to reference reconstructed VParticle
-// and copies its momentum in the 4-vector.
-// Mass is set to 0 (must be assigned by SetMass()).
-//
-
- fPrec.SetXYZT(0.0, 0.0, 0.0, 0.0);
- fRef = p;
-
- if (fRef) {
- fPrec.SetX(fRef->Px());
- fPrec.SetY(fRef->Py());
- fPrec.SetZ(fRef->Pz());
- }
-}
-
-//_____________________________________________________________________________
-void AliRsnDaughter::SetRefMC(AliVParticle *p)
-{
-//
-// Set the pointer to reference MonteCarlo VParticle
-// and copies its momentum in the 4-vector.
-// Mass is set to 0 (must be assigned by SetMass()).
-//
-
- fPsim.SetXYZT(0.0, 0.0, 0.0, 0.0);
- fRefMC = p;
-
- if (fRefMC) {
- fPsim.SetX(fRefMC->Px());
- fPsim.SetY(fRefMC->Py());
- fPsim.SetZ(fRefMC->Pz());
- }
-}
-
//_____________________________________________________________________________
void AliRsnDaughter::Reset()
{
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);
- SetRef(NULL);
- SetRefMC(NULL);
+ fRef = fRefMC = 0x0;
+ fOwnerEvent = 0x0;
}
//_____________________________________________________________________________
-Int_t AliRsnDaughter::GetPDG(Bool_t abs)
+Int_t AliRsnDaughter::GetPDG()
{
//
// Return the PDG code of the particle from MC ref (if any).
// If argument is kTRUE, returns its absolute value.
//
- Int_t pdg = 0;
- if (!fRefMC) return pdg;
-
- // ESD
- AliMCParticle *esd = GetRefMCESD();
- if (esd) pdg = esd->Particle()->GetPdgCode();
-
- // AOD
- AliAODMCParticle *aod = GetRefMCAOD();
- if (aod) pdg = aod->GetPdgCode();
-
- // abs value if required
- if (abs) pdg = TMath::Abs(pdg);
- return pdg;
+ 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;
+ }
}
//_____________________________________________________________________________
//
// ESD tracks
- AliESDtrack *esd = GetRefESDtrack();
+ AliESDtrack *esd = Ref2ESDtrack();
if (esd) return esd->GetID();
// AOD tracks
- AliAODTrack *aod = GetRefAODtrack();
+ AliAODTrack *aod = Ref2AODtrack();
if (aod) return aod->GetID();
// whatever else
}
//_____________________________________________________________________________
-Bool_t AliRsnDaughter::IsKinkDaughter()
+Int_t AliRsnDaughter::GetMother()
{
//
-// Checks if this track is a kink daughter.
-// this information is important for some cuts, in some cases
-// and it is retrieved differently from ESDs and AODs, so
-// this is done here in order to have a unique outcome.
+// Return index of the first mother of the MC reference, if any.
+// Otherwise, returns -1 (the same as for primary tracks)
//
- AliESDtrack *etrack = GetRefESDtrack();
- AliAODTrack *atrack = GetRefAODtrack();
-
- if (etrack) {
- return (etrack->GetKinkIndex(0) > 0);
- } else if (atrack) {
- AliAODVertex *vertex = atrack->GetProdVertex();
- if (vertex) if (vertex->GetType() == AliAODVertex::kKink) return kTRUE;
- }
-
- return kFALSE;
-}
-
-//______________________________________________________________________________
-AliRsnDaughter::ERefType AliRsnDaughter::RefType(ESpecies species)
-{
-//
-// Returns the expected object type for a candidate daughter
-// of the given species.
-//
+ if (!fRefMC) return -1;
- switch (species) {
- case kElectron:
- case kMuon:
- case kPion:
- case kKaon:
- case kProton:
- return kTrack;
- case kKaon0:
- case kLambda:
- return kV0;
- case kXi:
- case kOmega:
- return kCascade;
- default:
- return kNoType;
+ 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;
}
+
+
//______________________________________________________________________________
-void AliRsnDaughter::Print(Option_t *) const
+void AliRsnDaughter::Print(Option_t *opt) const
{
//
// Override of TObject::Print()
//
AliInfo("=== DAUGHTER INFO ======================================================================");
- //if (fRef) {
- // AliInfo(Form(" Ref : %x (%15s) with px,py,pz = %6.2f %6.2f %6.2f", (UInt_t)fRef , fRef ->ClassName(), fPrec.X(), fPrec.Y(), fPrec.Z()));
- //} else {
- // AliInfo(" Ref : NULL");
- //}
- //if (fRefMC) {
- // AliInfo(Form(" RefMC: %x (%15s) with px,py,pz = %6.2f %6.2f %6.2f", (UInt_t)fRefMC, fRefMC->ClassName(), fPsim.X(), fPsim.Y(), fPsim.Z()));
- //} else {
- // AliInfo(" RefMC: NULL");
- //}
+ 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("========================================================================================");
}
#ifndef ALIRSNDAUGHTER_H
#define ALIRSNDAUGHTER_H
-/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
- * See cxx source for full Copyright notice */
-
//
// Interface to single daughter candidate.
//
+#include <TMath.h>
#include <TLorentzVector.h>
#include "AliPID.h"
kUnknown
};
- AliRsnDaughter();
+ AliRsnDaughter() : fOK(kFALSE), fLabel(-1), fMotherPDG(0), fRsnID(-1),
+ fPrec(), fPsim(), fRef(0x0), fRefMC(0x0), fOwnerEvent(0x0) { }
AliRsnDaughter(const AliRsnDaughter ©);
AliRsnDaughter& operator= (const AliRsnDaughter& copy);
virtual ~AliRsnDaughter() { /*empty, since pointers must not be deleted*/ }
- // basic getters (for data members)
- Bool_t IsOK() const {return fOK;}
- Int_t GetLabel() const {return fLabel;}
- Int_t GetMotherPDG() const {return fMotherPDG;}
- Int_t GetRsnID() const {return fRsnID;}
- TLorentzVector& Prec() {return fPrec;}
- TLorentzVector& Psim() {return fPsim;}
- TLorentzVector& P(Bool_t mc) {return (mc ? fPsim : fPrec);}
- AliVParticle* GetRef() {return fRef;}
- AliVParticle* GetRefMC() {return fRefMC;}
- AliRsnEvent* GetOwnerEvent() {return fOwnerEvent;}
+ // basic getters
+ Bool_t IsOK() const {return fOK;}
+ Int_t GetLabel() const {return fLabel;}
+ Int_t GetMotherPDG() const {return fMotherPDG;}
+ Int_t GetRsnID() const {return fRsnID;}
+ AliVParticle* GetRef() {return fRef;}
+ AliVParticle* GetRefMC() {return fRefMC;}
+ AliRsnEvent* GetOwnerEvent() {return fOwnerEvent;}
+ TLorentzVector& P(Bool_t mc) {return (mc ? fPsim : fPrec);}
+ TLorentzVector& Prec() {return fPrec;}
+ TLorentzVector& Psim() {return fPsim;}
+ Int_t GetPDG();
+ Int_t GetPDGAbs() {return TMath::Abs(GetPDG());}
+ Int_t GetID();
+ Int_t GetMother();
// basic setters (for data members)
- void SetBad() {fOK = kFALSE;}
- void SetGood() {fOK = kTRUE;}
- void SetLabel(Int_t label) {fLabel = label;}
- void SetRsnID(Int_t id) {fRsnID = id;}
- void SetMotherPDG(Int_t value) {fMotherPDG = value;}
- void SetOwnerEvent(AliRsnEvent *e) {fOwnerEvent = e;}
- void SetRef(AliVParticle *p);
- void SetRefMC(AliVParticle *p);
- void SetMass(Double_t mass) {fPsim.SetVectM(fPsim.Vect(), mass); fPrec.SetVectM(fPrec.Vect(), mass);}
+ void Reset();
+ void SetOK(Bool_t ok) {fOK = ok;}
+ void SetBad() {fOK = kFALSE;}
+ void SetGood() {fOK = kTRUE;}
+ void SetLabel(Int_t label) {fLabel = label;}
+ void SetMotherPDG(Int_t value) {fMotherPDG = value;}
+ void SetRsnID(Int_t id) {fRsnID = id;}
+ void SetRef(AliVParticle *p) {fRef = p;}
+ void SetRefMC(AliVParticle *p) {fRefMC = p;}
+ void SetOwnerEvent(AliRsnEvent *e) {fOwnerEvent = e;}
- // utilities
- void Reset();
- Int_t GetPDG(Bool_t abs = kTRUE);
- Int_t GetID();
- Bool_t IsKinkDaughter();
- Bool_t IsPos() const {if (fRef) return (fRef->Charge() > 0); return kFALSE;}
- Bool_t IsNeg() const {if (fRef) return (fRef->Charge() < 0); return kFALSE;}
- Bool_t IsNeutral() const {if (fRef) return (!IsPos() && !IsNeg()); return kFALSE;}
- Bool_t IsSign(Char_t sign) const {if (sign == '+') return IsPos(); else if (sign == '-') return IsNeg(); else return IsNeutral();}
- Short_t ChargeS() const {if (IsPos()) return 1 ; else if (IsNeg()) return -1 ; else return 0 ;}
- Char_t ChargeC() const {if (IsPos()) return '+'; else if (IsNeg()) return '-'; else return '0';}
- void Print(Option_t *o="") const;
-
- // getters which automatically convert refs into allowed types
- AliVTrack* GetRefVtrack() {if (ClassMatchRef (AliVTrack ::Class())) return static_cast<AliVTrack*> (fRef) ; return 0x0;}
- AliESDtrack* GetRefESDtrack() {if (ClassMatchRef (AliESDtrack ::Class())) return static_cast<AliESDtrack*> (fRef) ; return 0x0;}
- AliESDv0* GetRefESDv0() {if (ClassMatchRef (AliESDv0 ::Class())) return static_cast<AliESDv0*> (fRef) ; return 0x0;}
- AliESDcascade* GetRefESDcascade() {if (ClassMatchRef (AliESDcascade ::Class())) return static_cast<AliESDcascade*> (fRef) ; return 0x0;}
- AliAODTrack* GetRefAODtrack() {if (ClassMatchRef (AliAODTrack ::Class())) return static_cast<AliAODTrack*> (fRef) ; return 0x0;}
- AliAODv0* GetRefAODv0() {if (ClassMatchRef (AliAODv0 ::Class())) return static_cast<AliAODv0*> (fRef) ; return 0x0;}
- AliAODcascade* GetRefAODcascade() {if (ClassMatchRef (AliAODcascade ::Class())) return static_cast<AliAODcascade*> (fRef) ; return 0x0;}
- AliMCParticle* GetRefMCtrack() {if (ClassMatchRef (AliMCParticle ::Class())) return static_cast<AliMCParticle*> (fRef) ; return 0x0;}
- AliMCParticle* GetRefMCESD() {if (ClassMatchRefMC(AliMCParticle ::Class())) return static_cast<AliMCParticle*> (fRefMC); return 0x0;}
- AliAODMCParticle* GetRefMCAOD() {if (ClassMatchRefMC(AliAODMCParticle::Class())) return static_cast<AliAODMCParticle*>(fRefMC); return 0x0;}
- Bool_t ClassMatchRef (TClass *ref) {if (fRef ) return (fRef ->InheritsFrom(ref)); return kFALSE;}
- Bool_t ClassMatchRefMC(TClass *ref) {if (fRefMC) return (fRefMC->InheritsFrom(ref)); return kFALSE;}
+ // additional functions
+ void FillP(Double_t mass);
+ void Print(Option_t *o = "") const;
+
+ // getters related to charge
+ Bool_t IsPos() const {if (fRef) return (fRef->Charge() > 0); return kFALSE;}
+ Bool_t IsNeg() const {if (fRef) return (fRef->Charge() < 0); return kFALSE;}
+ Bool_t IsCharged() const {if (fRef) return (IsPos() || IsNeg()); return kFALSE;}
+ Bool_t IsNeutral() const {if (fRef) return (!IsCharged()); return kFALSE;}
+ Short_t ChargeS() const {if (IsPos()) return 1 ; else if (IsNeg()) return -1 ; else return 0 ;}
+ Char_t ChargeC() const {if (IsPos()) return '+'; else if (IsNeg()) return '-'; else return '0';}
+
+ // getters which automatically convert refs into allowed types
+ static Bool_t Match(AliVParticle *p, TClass *ref) {if (p) return (p->InheritsFrom(ref)); return kFALSE;}
+ Bool_t MatchRef(TClass *ref) {return Match(fRef, ref);}
+ Bool_t MatchRefMC(TClass *ref) {return Match(fRefMC, ref);}
ERefType RefType();
Bool_t IsESD();
Bool_t IsAOD();
- Bool_t IsPureMC() {return (!IsESD() && !IsAOD());}
+
+ AliVTrack* Ref2Vtrack() {if (Match(fRef, AliVTrack ::Class())) return static_cast<AliVTrack*> (fRef); return 0x0;}
+ AliESDtrack* Ref2ESDtrack() {if (Match(fRef, AliESDtrack ::Class())) return static_cast<AliESDtrack*> (fRef); return 0x0;}
+ AliAODTrack* Ref2AODtrack() {if (Match(fRef, AliAODTrack ::Class())) return static_cast<AliAODTrack*> (fRef); return 0x0;}
+ AliMCParticle* Ref2MCparticle() {if (Match(fRef, AliMCParticle::Class())) return static_cast<AliMCParticle*> (fRef); return 0x0;}
+ AliAODMCParticle* Ref2AODMCparticle() {if (Match(fRef, AliMCParticle::Class())) return static_cast<AliAODMCParticle*>(fRef); return 0x0;}
+
+ AliESDv0* Ref2ESDv0() {if (Match(fRef, AliESDv0 ::Class())) return static_cast<AliESDv0*>(fRef); return 0x0;}
+ AliAODv0* Ref2AODv0() {if (Match(fRef, AliAODv0 ::Class())) return static_cast<AliAODv0*>(fRef); return 0x0;}
+
+ AliESDcascade* Ref2ESDcascade() {if (Match(fRef, AliESDcascade::Class())) return static_cast<AliESDcascade*>(fRef); return 0x0;}
+ AliAODcascade* Ref2AODcascade() {if (Match(fRef, AliAODcascade::Class())) return static_cast<AliAODcascade*>(fRef); return 0x0;}
+
+ AliMCParticle* RefMC2ESD() {if (Match(fRefMC, AliMCParticle ::Class())) return static_cast<AliMCParticle*> (fRef) ; return 0x0;}
+ AliAODMCParticle* RefMC2AOD() {if (Match(fRefMC, AliAODMCParticle::Class())) return static_cast<AliAODMCParticle*>(fRefMC); return 0x0;}
- // static utilities
+ // static functions related to internal ESpecies enum
static ERefType RefType(ESpecies species);
static Bool_t IsCharged(ESpecies species) {return (species <= kProton);}
static const char* SpeciesName(ESpecies species);
private:
Bool_t fOK; // internal utility flag which is kFALSE when this object should not be used
- Int_t fLabel; // GEANT label of corresponding MC particle
+ Int_t fLabel; // index of MC particle
Int_t fMotherPDG; // PDG code of mother (makes sense only if fRefMC is defined)
Int_t fRsnID; // internal ID for monitoring purposes
-
- TLorentzVector fPrec; // 4-vector filled with track info from default ref (if present)
- TLorentzVector fPsim; // 4-vector filled with track info from MC ref (if present)
+
+ TLorentzVector fPrec; // 4-momentum for rec
+ TLorentzVector fPsim; // 4-momentum for MC
AliVParticle *fRef; // reference to reconstructed object
AliVParticle *fRefMC; // reference to corresponding MC particle
AliRsnEvent *fOwnerEvent; // pointer to owner event
- ClassDef(AliRsnDaughter, 10)
+ ClassDef(AliRsnDaughter, 12)
};
+//__________________________________________________________________________________________________
inline AliRsnDaughter::ERefType AliRsnDaughter::RefType()
{
//
// of the object pointed by the fRef data member
//
- if (ClassMatchRef(AliESDtrack ::Class())) return kTrack;
- if (ClassMatchRef(AliESDv0 ::Class())) return kV0;
- if (ClassMatchRef(AliESDcascade::Class())) return kCascade;
- if (ClassMatchRef(AliAODTrack ::Class())) return kTrack;
- if (ClassMatchRef(AliAODv0 ::Class())) return kV0;
- if (ClassMatchRef(AliAODcascade::Class())) return kCascade;
- if (ClassMatchRef(AliMCParticle::Class())) return kTrack;
+ if (Match(fRef, AliESDtrack ::Class())) return kTrack;
+ if (Match(fRef, AliESDv0 ::Class())) return kV0;
+ if (Match(fRef, AliESDcascade::Class())) return kCascade;
+ if (Match(fRef, AliAODTrack ::Class())) return kTrack;
+ if (Match(fRef, AliAODv0 ::Class())) return kV0;
+ if (Match(fRef, AliAODcascade::Class())) return kCascade;
+ if (Match(fRef, AliMCParticle::Class())) return kTrack;
return kNoType;
}
+//__________________________________________________________________________________________________
inline Bool_t AliRsnDaughter::IsESD()
{
//
// Tells if the object pointed by fRef data member is ESD
+// NOTE: it is true even when fRef is the MC corresponding
+// object (= AliMCParticle)
//
- if (ClassMatchRef(AliESDtrack ::Class())) return kTRUE;
- if (ClassMatchRef(AliESDv0 ::Class())) return kTRUE;
- if (ClassMatchRef(AliESDcascade::Class())) return kTRUE;
+ if (Match(fRef, AliESDtrack ::Class())) return kTRUE;
+ if (Match(fRef, AliESDv0 ::Class())) return kTRUE;
+ if (Match(fRef, AliESDcascade::Class())) return kTRUE;
+ if (Match(fRef, AliMCParticle::Class())) return kTRUE;
return kFALSE;
}
+//__________________________________________________________________________________________________
inline Bool_t AliRsnDaughter::IsAOD()
{
//
// Tells if the object pointed by fRef data member is AOD
+// NOTE: it is true even when fRef is the MC corresponding
+// object (= AliAODMCParticle)
//
- if (ClassMatchRef(AliAODTrack ::Class())) return kTRUE;
- if (ClassMatchRef(AliAODv0 ::Class())) return kTRUE;
- if (ClassMatchRef(AliAODcascade::Class())) return kTRUE;
+ if (Match(fRef, AliAODTrack ::Class())) return kTRUE;
+ if (Match(fRef, AliAODv0 ::Class())) return kTRUE;
+ if (Match(fRef, AliAODcascade ::Class())) return kTRUE;
+ if (Match(fRef, AliAODMCParticle::Class())) return kTRUE;
return kFALSE;
}
+//__________________________________________________________________________________________________
+inline AliRsnDaughter::ERefType AliRsnDaughter::RefType(ESpecies species)
+{
+//
+// Returns the expected object type for a candidate daughter
+// of the given species.
+//
+
+ switch (species) {
+ case kElectron:
+ case kMuon:
+ case kPion:
+ case kKaon:
+ case kProton:
+ return kTrack;
+ case kKaon0:
+ case kLambda:
+ return kV0;
+ case kXi:
+ case kOmega:
+ return kCascade;
+ default:
+ return kNoType;
+ }
+}
+
+//__________________________________________________________________________________________________
+inline void AliRsnDaughter::FillP(Double_t mass)
+{
+//
+// Fills the 4-momentum data member using the values in the
+// AliVParticle pointer data members, choosing according to arguments
+//
+
+ if (fRefMC) fPsim.SetXYZM(fRefMC->Px(), fRefMC->Py(), fRefMC->Pz(), mass);
+ if (fRef) fPrec.SetXYZM(fRef ->Px(), fRef ->Py(), fRef ->Pz(), mass);
+}
#endif
-/**************************************************************************
- * 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. *
- **************************************************************************/
-
-////////////////////////////////////////////////////////////////////////////////
-//
-// This class is a simple set of definitions which are used to select among
-// all daughter candidates in term of the object type (track, V0, cascade),
-// charge and eventually PID.
-// The PID assigned to the definition is the one which is 'assigned' to the
-// candidate daughter for whatever implies a mass hypothesis. When MC is
-// available and one requires this, thie PID is also used to select only the
-// daughters which are of that species in MC.
-//
-// NOTE: charge is a single character. If one wants to select a well-defined
-// charge, he must use '+', '-' or '0', while any other character is
-// interpreted as 'no charge selection'.
+//
+// Definition for a single candidate daughter.
+// They can be chosen among the following possibilities:
+//
+// -- particle species, chosen in the enum AliRsnDaughter::ESpecies;
+// this option does two things:
+// -- when possible (needs MC) and required, allow to check is a daughter
+// is of the defined species (e.g.: for selecting true daughters of a resonance)
+// -- defines the mass to be assigned to this object, for any purpose
+// (e.g.: to compute its 4-momentum to be used for a resonance mass)
+//
+// -- track charge, which can be '+', '-', '0',
+// -- any other char leaves this undefined (use only in daughter monitor loops)
+// -- when doing resonance analysis, or when RSN Input handler needs to be used,
+// this must always be defined
+//
+// -- object type (track/V0/cascade)
+// -- could be needed to select tracks when particle species is not specified
+// -- works only in single daughter loops
//
// authors: A. Pulvirenti (alberto.pulvirenti@ct.infn.it)
// M. Vala (martin.vala@cern.ch)
//
-////////////////////////////////////////////////////////////////////////////////
#include "AliLog.h"
#include "AliRsnDaughterDef.h"
//_____________________________________________________________________________
AliRsnDaughterDef::AliRsnDaughterDef() :
- fOnlyTrue(kFALSE),
fPID(AliRsnDaughter::kUnknown),
fMass(0.0),
fCharge(0),
//_____________________________________________________________________________
AliRsnDaughterDef::AliRsnDaughterDef(AliRsnDaughter::ESpecies type, Char_t sign) :
- fOnlyTrue(kFALSE),
fPID(type),
fMass(AliRsnDaughter::SpeciesMass(type)),
fCharge(sign),
fRefType(AliRsnDaughter::RefType(type))
{
//
-// This version of constructor initializes the PID type
-// and the charge (optional, leave 2nd argument to default to include both),
-// and calls 'SetPID()' to assign the object type accordingly.
+// This version of constructor initializes the PID type (and then the mass)
+// and the charge (optional, leave 2nd argument to default to include both).
//
}
//_____________________________________________________________________________
AliRsnDaughterDef::AliRsnDaughterDef(EPARTYPE type, Char_t sign) :
- fOnlyTrue(kFALSE),
fPID(AliRsnDaughter::FromAliPID(type)),
fMass(AliRsnDaughter::SpeciesMass(AliRsnDaughter::FromAliPID(type))),
fCharge(sign),
fRefType(AliRsnDaughter::RefType(AliRsnDaughter::FromAliPID(type)))
{
//
-// This version of constructor initializes the PID type
-// and the charge (optional, leave 2nd argument to default to include both),
-// and calls 'SetPID()' to assign the object type accordingly.
+// This version of constructor initializes the PID type (and then the mass)
+// and the charge (optional, leave 2nd argument to default to include both).
//
}
//_____________________________________________________________________________
AliRsnDaughterDef::AliRsnDaughterDef(AliRsnDaughter::ERefType refType, Char_t sign) :
- fOnlyTrue(kFALSE),
fPID(AliRsnDaughter::kUnknown),
fMass(0.0),
fCharge(sign),
//_____________________________________________________________________________
AliRsnDaughterDef::AliRsnDaughterDef(const AliRsnDaughterDef ©) :
TObject(copy),
- fOnlyTrue(copy.fOnlyTrue),
fPID(copy.fPID),
fMass(copy.fMass),
fCharge(copy.fCharge),
// Assignment operator has standard behavior.
//
- fOnlyTrue = copy.fOnlyTrue;
fMass = copy.fMass;
fCharge = copy.fCharge;
fPID = copy.fPID;
return (*this);
}
-
-//_____________________________________________________________________________
-Bool_t AliRsnDaughterDef::MatchesDaughter(AliRsnDaughter *checked)
-{
-//
-// Checks if the argument matches the definitions, by combining the other
-// inline methods, and using the same philosophy.
-// The only exception is for the PID matching, which can be disabled
-// by second argument. In this case, a track is considered matched
-// if it is matched just in object type and charge.
-//
-
- Bool_t chargeMatch = MatchesCharge(checked);
- Bool_t objMatch = MatchesRefType(checked);
- Bool_t pidMatch = (fOnlyTrue ? MatchesPID(checked) : kTRUE);
-
- // return the AND of all
- return (chargeMatch && objMatch && pidMatch);
-}
#ifndef ALIRSNDAUGHTERDEF_H
#define ALIRSNDAUGHTERDEF_H
-/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
- * See cxx source for full Copyright notice */
-
-////////////////////////////////////////////////////////////////////////////////
//
-// Single daughter definitions.
+// Definition for a single candidate daughter.
+// They can be chosen among the following possibilities:
+//
+// -- particle species, chosen in the enum AliRsnDaughter::ESpecies;
+// this option does two things:
+// -- when possible (needs MC) and required, allow to check is a daughter
+// is of the defined species (e.g.: for selecting true daughters of a resonance)
+// -- defines the mass to be assigned to this object, for any purpose
+// (e.g.: to compute its 4-momentum to be used for a resonance mass)
//
-////////////////////////////////////////////////////////////////////////////////
+// -- track charge, which can be '+', '-', '0',
+// -- any other char leaves this undefined (use only in daughter monitor loops)
+// -- when doing resonance analysis, or when RSN Input handler needs to be used,
+// this must always be defined
+//
+// -- object type (track/V0/cascade)
+// -- could be needed to select tracks when particle species is not specified
+// -- works only in single daughter loops
+//
#include "AliRsnDaughter.h"
const AliRsnDaughterDef& operator= (const AliRsnDaughterDef ©);
virtual ~AliRsnDaughterDef() { }
- Bool_t IsOnlyTrue() const {return fOnlyTrue;}
AliRsnDaughter::ESpecies GetPID() const {return fPID;}
Double_t GetMass() const {return fMass;}
Char_t GetChargeC() const {return fCharge;}
virtual const char* GetName() const {return Form("%s%c", AliRsnDaughter::SpeciesName(fPID), fCharge);}
Bool_t IsChargeDefined() const {return (fCharge == '+' || fCharge == '-' || fCharge == '0');}
- void SetOnlyTrue(Bool_t yn = kTRUE) {fOnlyTrue = yn;}
void SetPID(AliRsnDaughter::ESpecies pid) {fPID = pid; fRefType = AliRsnDaughter::RefType(pid); fMass = AliRsnDaughter::SpeciesMass(pid);}
void SetCharge(Char_t charge) {fCharge = charge;}
void SetRefType(AliRsnDaughter::ERefType type) {fRefType = type;}
Bool_t MatchesPID(AliRsnDaughter *daughter);
Bool_t MatchesCharge(AliRsnDaughter *daughter);
Bool_t MatchesRefType(AliRsnDaughter *daughter);
- Bool_t MatchesDaughter(AliRsnDaughter *daughter);
- Bool_t MatchesPDG(Int_t pdgCode) {return (AliRsnDaughter::SpeciesPDG(fPID) == pdgCode);}
- Bool_t MatchesChargeS(Short_t charge) {return (GetChargeS() == charge);}
- Bool_t MatchesChargeC(Char_t charge) {return (GetChargeC() == charge);}
+ Bool_t MatchesPDG(Int_t pdgCode) {return (AliRsnDaughter::SpeciesPDG(fPID) == pdgCode);}
+ Bool_t MatchesChargeS(Short_t charge) {return (GetChargeS() == charge);}
+ Bool_t MatchesChargeC(Char_t charge) {return (GetChargeC() == charge);}
private:
- Bool_t fOnlyTrue; // fag to activate comparison of PID species
AliRsnDaughter::ESpecies fPID; // PID of particles
Double_t fMass; // mass of particles (subordinate to fPID)
Char_t fCharge; // charge of particles
inline Bool_t AliRsnDaughterDef::MatchesPID(AliRsnDaughter *daughter)
{
//
-// Checks if the daughter true PID (taken from MC) matches
-// that expected by this object.
-// Works only if an MC is present and the fPID data member
-// is set to something different from 'kUnknown'.
-// If above conditions are not satisfied, it returns always kTRUE.
+// Checks if the passed daughter true particle type
+// matches the species defined in fPID data member,
+// by comparing the corresponding PDG codes of both in absolute value.
+// Returns kTRUE when the two codes match, and kFALSE when:
+// -- PDG codes don't match
+// -- fPID is not set to a well-defined species (AliRsnDaughter::kUnknown)
+// -- passed daughter has not MC information
//
-
- if (fPID == AliRsnDaughter::kUnknown || daughter->GetRefMC() == 0x0)
- return kTRUE;
- else
- return (AliRsnDaughter::SpeciesPDG(fPID) == daughter->GetPDG());
+ if (fPID == AliRsnDaughter::kUnknown) {
+ AliError("This DaughterDef has undefined species: cannot check PDG matching with passed arg");
+ return kFALSE;
+ } else if (!daughter->GetRefMC()) {
+ AliError("The passed argument has NULL MC pointer: cannot check PDG matching with this DaughterDef");
+ return kFALSE;
+ }
+
+ return MatchesPDG(daughter->GetPDGAbs());
}
//__________________________________________________________________________________________________
inline Bool_t AliRsnDaughterDef::MatchesCharge(AliRsnDaughter *daughter)
{
//
-// Checks that the daughter charge matches that expected by this object.
-// Works only if the fCharge data member is set to '+', '-' or '0',
-// otherwise it accepts everything.
+// Checks if the passed daughter charge matches that defined in fCharge data member.
+// If fCharge is not initialized to '+', '-' or '0', that is interpreted as if the user
+// does not want to select in charge, and then the function returns always kTRUE.
//
switch (fCharge) {
default : return kTRUE;
}
}
-
+
//__________________________________________________________________________________________________
inline Bool_t AliRsnDaughterDef::MatchesRefType(AliRsnDaughter *daughter)
{
//
-// Checks that the daughter object type matches that expected by this object.
-// Works only if the fRefType data member is different from AliRsnDaughter::kNoType,
-// otherwise it accepts everything.
+// Checks that the daughter object type matches that defined in fRefType data member.
+// If fRefType is initialized to AliRsnDaughter::kNoType, that is interpreted as if the user
+// does not want to select in type and then the function returns always kTRUE.
//
AliRsnDaughter::ERefType type = daughter->RefType();
TClonesArray *cutsArray = 0x0, *entryArray = 0x0;
for (id = 0; id < nTot; id++) {
- ev->SetDaughterAbs(check, id);
- if (!check.IsOK()) continue;
+ ev->SetDaughter(check, id);
+ // some checks
+ if (!check.GetRef()) {
+ AliDebugClass(1, Form("[%s]: daughter has NULL ref", GetName()));
+ continue;
+ }
+ if (!check.IsOK()) {
+ AliDebugClass(1, Form("[%s]: daughter is BAD", GetName()));
+ continue;
+ }
// set pointers according to charge
- switch (check.ChargeS()) {
- case 1:
- cutsArray = &fCutSetsC;
- entryArray = &fEntryListsP;
- break;
- case -1:
- cutsArray = &fCutSetsC;
- entryArray = &fEntryListsM;
- break;
- default:
- cutsArray = &fCutSetsN;
- entryArray = &fEntryListsN;
- break;
+ if (check.ChargeS() > 0) {
+ cutsArray = &fCutSetsC;
+ entryArray = &fEntryListsP;
+ } else if (check.ChargeS() < 0) {
+ cutsArray = &fCutSetsC;
+ entryArray = &fEntryListsM;
+ } else {
+ cutsArray = &fCutSetsN;
+ entryArray = &fEntryListsN;
}
// check with all cuts in that charge
- nSel = cutsArray->GetEntriesFast();
+ nSel = cutsArray->GetEntries();
for (is = 0; is < nSel; is++) {
AliRsnCutSet *cuts = (AliRsnCutSet*)cutsArray->At(is);
if (cuts->IsSelected(&check)) {
TEntryList *el = (TEntryList*)entryArray->At(is);
el->Enter(id);
- }
+ }
}
}
#include <Riostream.h>
#include <TArrayF.h>
-#include "AliLog.h"
-#include "AliVEvent.h"
-#include "AliMCEvent.h"
-#include "AliStack.h"
#include "AliGenEventHeader.h"
-#include "AliESDtrackCuts.h"
-#include "AliESDUtils.h"
-#include "AliAODVertex.h"
-#include "AliMultiplicity.h"
-#include "AliRsnCutPID.h"
+
+#include "AliRsnCutSet.h"
#include "AliRsnEvent.h"
ClassImp(AliRsnEvent)
fRef(ref),
fRefMC(refMC),
fLeading(-1),
- fLocalID(-1),
fPID(0x0)
{
//
fRef(event.fRef),
fRefMC(event.fRefMC),
fLeading(event.fLeading),
- fLocalID(event.fLocalID),
fPID(event.fPID)
{
//
// Works in the same way as the copy constructor.
//
- (TObject)(*this) = (TObject)event;
+ TObject::operator=(event);
fRef = event.fRef;
fRefMC = event.fRefMC;
fLeading = event.fLeading;
- fLocalID = event.fLocalID;
fPID = event.fPID;
return (*this);
AliRsnEvent::~AliRsnEvent()
{
//
-// Destructor.
-// Dereferences global pointer, if needed.
+// Destructor (does nothing since there are not owned pointers)
//
-
- //if (gRsnCurrentEvent == this) gRsnCurrentEvent = 0;
- //if (gRsnMixedEvent == this) gRsnMixedEvent = 0;
}
//_____________________________________________________________________________
-Bool_t AliRsnEvent::SetDaughter(AliRsnDaughter &out, Int_t i, AliRsnDaughter::ERefType type)
+void AliRsnEvent::SetDaughter(AliRsnDaughter &out, Int_t index, Bool_t fromMC)
{
//
-// Using the second and third arguments, retrieves the i-th object in the
-// appropriate sample (tracks or V0s) and sets the first reference object
-// in order to point to that.
-// If a MonteCarlo information is provided, sets the useful informations from there,
-// and in case of a V0, sets the 'label' data member only when the two daughters
-// of the V0 point to the same mother.
-// Returns kFALSE whenever the operation fails (out of range, NULL references).
+// Assigns to the first argument the reference to the i-th track in the ref event.
+// What assignment method to be used will depend on the index and on the type of input.
+// If the last argument is kTRUE and an MC is referenced, then both fRef and fRefMC will
+// point to the MC particle (pure MC analysis)
//
- Bool_t ok = kFALSE;
-
+ // by default the daughter is reset
+ // and assigned the used index
out.Reset();
+ out.SetRsnID(index);
out.SetOwnerEvent(this);
-
- if (IsESD() && type == AliRsnDaughter::kTrack) ok = SetDaughterESDtrack (out, i);
- if (IsAOD() && type == AliRsnDaughter::kTrack) ok = SetDaughterAODtrack (out, i);
- if (IsESD() && type == AliRsnDaughter::kV0) ok = SetDaughterESDv0 (out, i);
- if (IsAOD() && type == AliRsnDaughter::kV0) ok = SetDaughterAODv0 (out, i);
- if (IsESD() && type == AliRsnDaughter::kCascade) ok = SetDaughterESDcascade(out, i);
- if (IsAOD() && type == AliRsnDaughter::kCascade) ok = SetDaughterAODcascade(out, i);
- return ok;
+ // check input type
+ if (!InputOK()) return;
+ Bool_t inputESD = IsESD();
+
+ // if it is pure MC, the index tells what particle
+ // to be read in the stack of MC particles, otherwise
+ // it is converted into a real collection index
+ if (fromMC) {
+ out.SetLabel(index);
+ Bool_t ok = (inputESD ? SetMCInfoESD(out) : SetMCInfoAOD(out));
+ if (ok) {
+ out.SetGood();
+ out.SetRef(out.GetRefMC());
+ }
+ } else {
+ Int_t trueIndex;
+ AliRsnDaughter::ERefType type;
+ if (!ConvertAbsoluteIndex(index, trueIndex, type)) {
+ AliError(Form("Failed to convert absolute index %d", index));
+ return;
+ }
+ switch (type) {
+ case AliRsnDaughter::kTrack:
+ if (inputESD) SetDaughterESDtrack(out, trueIndex); else SetDaughterAODtrack(out, trueIndex);
+ break;
+ case AliRsnDaughter::kV0:
+ if (inputESD) SetDaughterESDv0(out, trueIndex); else SetDaughterAODv0(out, trueIndex);
+ break;
+ case AliRsnDaughter::kCascade:
+ if (inputESD) SetDaughterESDcascade(out, trueIndex); else SetDaughterAODcascade(out, trueIndex);
+ break;
+ default:
+ AliError("Unrecognized daughter type");
+ return;
+ }
+ }
}
//_____________________________________________________________________________
-Bool_t AliRsnEvent::SetDaughterAbs(AliRsnDaughter &out, Int_t absIndex)
+AliRsnDaughter AliRsnEvent::GetDaughter(Int_t i, Bool_t fromMC)
{
//
-// Sets the first argument daughter using the absolute index, which
-// runs continuously from tracks, to V0s, to cascades.
-// In case the conversion to real index fails, the track is flagged as bad.
-// Additionally, sets the daughter internal 'fRsnID' member to this index.
+// Returns a daughter set using same criteria as SetDaughter
//
- Int_t index;
- AliRsnDaughter::ERefType type;
-
- out.SetRsnID(absIndex);
+ AliRsnDaughter d;
+ SetDaughter(d, i, fromMC);
+ return d;
+}
- if (ConvertAbsoluteIndex(absIndex, index, type)) {
- return SetDaughter(out, index, type);
- }
- else {
- out.Reset();
- return kFALSE;
+//_____________________________________________________________________________
+void AliRsnEvent::SetDaughterESDtrack(AliRsnDaughter &out, Int_t i)
+{
+//
+// Setup the first argument to the track identified by the index.
+// When available, adds the MC information and references.
+// ---
+// Version #1: ESD tracks
+//
+
+ AliESDEvent *esd = (AliESDEvent*)fRef;
+
+ if (i >= 0 && i < esd->GetNumberOfTracks()) {
+ AliESDtrack *track = esd->GetTrack(i);
+ if (track) {
+ out.SetRef(track);
+ out.SetGood();
+ // if MC is present, assign label and retrieve corresponding particle
+ if (fRefMC) {
+ out.SetLabel(TMath::Abs(track->GetLabel()));
+ if (!SetMCInfoESD(out)) {
+ AliWarning("Failed assignment of MC info");
+ }
+ }
+ } else {
+ AliWarning("Null track");
+ }
+ } else {
+ AliWarning(Form("Overflow: required index = %d, max = %d", i, esd->GetNumberOfTracks()));
}
}
//_____________________________________________________________________________
-Bool_t AliRsnEvent::SetDaughterMC(AliRsnDaughter &out, Int_t label)
+void AliRsnEvent::SetDaughterAODtrack(AliRsnDaughter &out, Int_t i)
{
//
-// Using the second argument, retrieves the i-th object in the
-// MC sample (if present) and assigns the track using only that,
-// so that it is considered both as main reference and MC reference.
-// (used for MC-only analysis).
+// Setup the first argument to the track identified by the index.
+// When available, adds the MC information and references.
+// ---
+// Version #2: AOD tracks
//
- if (!fRefMC) {
- out.SetBad();
- return kFALSE;
- }
+ AliAODEvent *aod = (AliAODEvent*)fRef;
- // try to convert into both types
- Int_t imum;
- AliMCEvent *esd = GetRefMCESD();
- AliAODEvent *aod = GetRefMCAOD();
-
- // ESD
- if (esd) {
- // if the MC track exists, assign it
- AliMCParticle *track = (AliMCParticle*)fRef->GetTrack(label);
- if (!track) {
- out.SetBad();
- return kFALSE;
- }
- out.SetRef(track);
- out.SetRefMC(track);
- out.SetLabel(label);
- out.SetGood();
-
- // search for its mother in stack
- imum = track->GetMother();
- if (imum >= 0 && imum < esd->Stack()->GetNtrack()) {
- TParticle *mum = esd->Stack()->Particle(imum);
- if (mum) out.SetMotherPDG(TMath::Abs(mum->GetPdgCode()));
+ if (i >= 0 && i < aod->GetNumberOfTracks()) {
+ AliAODTrack *track = aod->GetTrack(i);
+ if (track) {
+ out.SetRef(track);
+ out.SetGood();
+ // if MC is present, assign label and retrieve corresponding particle
+ if (fRefMC) {
+ out.SetLabel(TMath::Abs(track->GetLabel()));
+ if (!SetMCInfoAOD(out)) {
+ AliWarning("Failed assignment of MC info");
+ }
+ }
+ } else {
+ AliWarning("Null track");
}
+ } else {
+ AliWarning(Form("Overflow: required index = %d, max = %d", i, aod->GetNumberOfTracks()));
}
+}
+
+//_____________________________________________________________________________
+void AliRsnEvent::SetDaughterESDv0(AliRsnDaughter &out, Int_t i)
+{
+//
+// Setup the first argument to the track identified by the index.
+// When available, adds the MC information and references.
+// ---
+// Version #3: ESD v0
+//
- // AOD
- if (aod) {
- // checks that array of MC particles exists
- TClonesArray *mcArray = (TClonesArray*)aod->GetList()->FindObject(AliAODMCParticle::StdBranchName());
- if (!mcArray) {
- out.SetBad();
- return kFALSE;
+ if (i >= 0 && i < fRef->GetNumberOfV0s()) {
+ AliESDEvent *ev = GetRefESD();
+ AliESDv0 *v0 = ev->GetV0(i);
+ if (v0) {
+ out.SetRef(v0);
+ out.SetGood();
+ // if MC is present, retrieve the label of V0 from those of daughters
+ if (fRefMC) {
+ AliMCEvent *mc = (AliMCEvent*)fRefMC;
+ AliESDtrack *tp = ev->GetTrack(v0->GetPindex());
+ AliESDtrack *tn = ev->GetTrack(v0->GetNindex());
+ if (mc && tp && tn) {
+ Int_t lp = TMath::Abs(tp->GetLabel());
+ Int_t ln = TMath::Abs(tn->GetLabel());
+ TParticle *pp = mc->Stack()->Particle(lp);
+ TParticle *pn = mc->Stack()->Particle(ln);
+ if (pp && pn) {
+ // if their first mothers are the same, the V0 is true
+ // otherwise label remains '-1' --> fake V0
+ if (pp->GetFirstMother() == pn->GetFirstMother() && pp->GetFirstMother() >= 0) {
+ out.SetLabel(pp->GetFirstMother());
+ SetMCInfoESD(out);
+ }
+ }
+ }
+ }
}
+ }
+}
+
+//_____________________________________________________________________________
+void AliRsnEvent::SetDaughterAODv0(AliRsnDaughter &out, Int_t i)
+{
+//
+// Setup the first argument to the track identified by the index.
+// When available, adds the MC information and references.
+// ---
+// Version #4: AOD v0
+//
- // in this case one has to loop over the sample to find the good one
- TObjArrayIter next(mcArray);
- AliAODMCParticle *part = 0x0;
- while ((part = (AliAODMCParticle*)next())) {
- if (TMath::Abs(part->GetLabel()) == label) {
- // if the MC track exists, assign it
- out.SetRef(part);
- out.SetRefMC(part);
- out.SetLabel(label);
- out.SetGood();
-
- // search for the mother
- imum = part->GetMother();
- if (imum >= 0 && imum < mcArray->GetEntriesFast()) {
- AliAODMCParticle *mum = (AliAODMCParticle*)mcArray->At(imum);
- if (mum) out.SetMotherPDG(TMath::Abs(mum->GetPdgCode()));
+ if (i >= 0 && i < fRef->GetNumberOfV0s()) {
+ AliAODEvent *ev = (AliAODEvent*)fRef;
+ AliAODv0 *v0 = ev->GetV0(i);
+ if (v0) {
+ out.SetRef(v0);
+ out.SetGood();
+ if (fRefMC) {
+ AliAODEvent *mc = (AliAODEvent*)fRefMC;
+ TClonesArray *mcArray = (TClonesArray*)mc->GetList()->FindObject(AliAODMCParticle::StdBranchName());
+ AliAODTrack *tp = (AliAODTrack*)v0->GetDaughter(0);
+ AliAODTrack *tn = (AliAODTrack*)v0->GetDaughter(1);
+ if (mcArray && tp && tn) {
+ Int_t lp = TMath::Abs(tp->GetLabel());
+ Int_t ln = TMath::Abs(tn->GetLabel());
+ AliAODMCParticle *pp = (AliAODMCParticle*)mcArray->At(lp);
+ AliAODMCParticle *pn = (AliAODMCParticle*)mcArray->At(ln);
+ if (pp && pn) {
+ // if their first mothers are the same, the V0 is true
+ // otherwise label remains '-1' --> fake V0
+ if (pp->GetMother() == pn->GetMother() && pp->GetMother() >= 0) {
+ out.SetLabel(pp->GetMother());
+ SetMCInfoAOD(out);
+ }
+ }
}
- break;
}
}
- return kTRUE;
}
-
- out.SetOwnerEvent(this);
+}
- return kFALSE;
+//_____________________________________________________________________________
+void AliRsnEvent::SetDaughterESDcascade(AliRsnDaughter &out, Int_t i)
+{
+//
+// Setup the first argument to the track identified by the index.
+// When available, adds the MC information and references.
+// ---
+// Version #3: ESD cascade
+//
+
+ if (i >= 0 && i < fRef->GetNumberOfCascades()) {
+ AliESDEvent *ev = GetRefESD();
+ AliESDcascade *casc = ev->GetCascade(i);
+ if (casc) {
+ out.SetRef(casc);
+ out.SetGood();
+ if (fRefMC) {
+
+ }
+ }
+ }
}
//_____________________________________________________________________________
-AliRsnDaughter AliRsnEvent::GetDaughter(Int_t i, AliRsnDaughter::ERefType type)
+void AliRsnEvent::SetDaughterAODcascade(AliRsnDaughter &out, Int_t i)
{
//
-// Returns a daughter set using same criteria as SetDaughter
+// Setup the first argument to the track identified by the index.
+// When available, adds the MC information and references.
+// ---
+// Version #4: AOD cascade
//
- AliRsnDaughter d;
- SetDaughter(d, i, type);
- return d;
+ if (i >= 0 && i < fRef->GetNumberOfCascades()) {
+ AliAODEvent *ev = GetRefAOD();
+ AliAODv0 *casc = ev->GetCascade(i);
+ if (casc) {
+ out.SetRef(casc);
+ out.SetGood();
+ if (fRefMC) {
+
+ }
+ }
+ }
}
//_____________________________________________________________________________
-AliRsnDaughter AliRsnEvent::GetDaughterAbs(Int_t absIndex)
+Bool_t AliRsnEvent::SetMCInfoESD(AliRsnDaughter &out)
{
//
-// Returns a daughter set using same criteria as SetDaughter
+// Using the label assigned to the daughter, searches for the MC informations:
+// -- MC reference
+// -- mother
//
- AliRsnDaughter d;
- SetDaughterAbs(d, absIndex);
- return d;
+ // if label makes no sense --> failed
+ Int_t label = out.GetLabel();
+ if (label < 0 || !fRefMC) return kFALSE;
+
+ // get number of particles
+ Int_t nMC = fRefMC->GetNumberOfTracks();
+
+ // if label too large --> failed
+ if (label >= nMC) {
+ AliWarning(Form("Stack overflow: track label = %d -- stack maximum = %d", label, nMC));
+ return kFALSE;
+ }
+
+ // retrieve particle
+ AliMCEvent *mc = (AliMCEvent*)fRefMC;
+ AliMCParticle *mcPart = (AliMCParticle*)mc->GetTrack(label);
+
+ // if particle = NULL --> failed
+ if (!mcPart) {
+ AliWarning(Form("Stack discontinuity: label %d refers to a NULL object", label));
+ return kFALSE;
+ }
+ // otherwise --> success
+ out.SetRefMC(mcPart);
+
+ // if the particle is not primary, find the mother and get its PDG
+ Int_t imum = mcPart->Particle()->GetFirstMother();
+ if (imum >= 0 && imum < nMC) {
+ AliMCParticle *mcMother = (AliMCParticle*)mc->GetTrack(imum);
+ if (mcMother) {
+ out.SetMotherPDG(TMath::Abs(mcMother->Particle()->GetPdgCode()));
+ } else {
+ AliWarning(Form("Stack discontinuity: label mother %d refers to a NULL object", imum));
+ }
+ } else {
+ AliWarning(Form("Stack overflow: mother label = %d -- stack maximum = %d", imum, nMC));
+ }
+
+ return kTRUE;
}
//_____________________________________________________________________________
-AliRsnDaughter AliRsnEvent::GetDaughterMC(Int_t i)
+Bool_t AliRsnEvent::SetMCInfoAOD(AliRsnDaughter &out)
{
//
-// Returns a daughter set using same criteria as SetDaughterMC
+// Using the label assigned to the daughter, searches for the MC informations:
+// -- MC reference
+// -- mother
//
- AliRsnDaughter d;
- SetDaughterMC(d, i);
- return d;
+ // if label makes no sense --> failed
+ Int_t label = out.GetLabel();
+ if (label < 0 || !fRefMC) return kFALSE;
+
+ // retrieve particle
+ AliAODEvent *mc = (AliAODEvent*)fRefMC;
+ TClonesArray *mcArray = (TClonesArray*)mc->GetList()->FindObject(AliAODMCParticle::StdBranchName());
+
+ // get number of particles
+ Int_t nMC = mcArray->GetEntriesFast();
+
+ // if label too large --> failed
+ if (label >= nMC) {
+ AliWarning(Form("Stack overflow: track label = %d -- stack maximum = %d", label, nMC));
+ return kFALSE;
+ }
+
+ // if particle = NULL --> failed
+ AliAODMCParticle *mcPart = (AliAODMCParticle*)mcArray->At(label);
+ if (!mcPart) {
+ AliWarning(Form("Stack discontinuity: label %d refers to a NULL object", label));
+ return kFALSE;
+ }
+ // otherwise --> success
+ out.SetRefMC(mcPart);
+
+ // if the particle is not primary, find the mother and get its PDG
+ Int_t imum = mcPart->GetMother();
+ if (imum >= 0 && imum < nMC) {
+ AliAODMCParticle *mcMother = (AliAODMCParticle*)mcArray->At(imum);
+ if (mcMother) {
+ out.SetMotherPDG(TMath::Abs(mcMother->GetPdgCode()));
+ } else {
+ AliWarning(Form("Stack discontinuity: label mother %d refers to a NULL object", imum));
+ }
+ } else if (imum >= nMC) {
+ AliWarning(Form("Stack overflow: mother label = %d -- stack maximum = %d", imum, nMC));
+ }
+
+ return kTRUE;
}
//_____________________________________________________________________________
}
//_____________________________________________________________________________
-Int_t AliRsnEvent::GetMultiplicityFromESDCuts()
-{
-//
-// Returns event multiplicity as the number of
-// tracks passing the standard quality cuts.
-//
-
- if (!fRef) return -1;
-
- AliESDEvent *esd = GetRefESD();
- if (esd)
- return AliESDtrackCuts::GetReferenceMultiplicity(esd, kTRUE);
- else {
- AliWarning("Invoked multicplicity estimation from AliESDtrackCuts with null ESD");
- return -1;
- }
-}
-
-//_____________________________________________________________________________
-Float_t AliRsnEvent::GetMultiplicityFromSPD()
-{
-//
-// Returns event multiplicity computed from SPD.
-//
-
- if (!fRef) return -1.0;
-
- AliESDEvent *esd = GetRefESD();
- if (esd) {
- const AliMultiplicity *mult = esd->GetMultiplicity();
- Float_t nClusters[6] = {0.0,0.0,0.0,0.0,0.0,0.0};
- for(Int_t ilay = 0; ilay < 6; ilay++) nClusters[ilay] = (Float_t)mult->GetNumberOfITSClusters(ilay);
- return AliESDUtils::GetCorrSPD2(nClusters[1], GetVz());
- }
- else {
- AliWarning("Cannot compute SPD multiplicity without a well initialized ESD event");
- return -1.0;
- }
-}
-
-//_____________________________________________________________________________
-Int_t AliRsnEvent::SelectLeadingParticle
-(Double_t ptMin, AliRsnCutPID *cutPID)
+Int_t AliRsnEvent::SelectLeadingParticle(AliRsnCutSet *cuts)
{
//
// Searches the collection of all particles with given PID type and charge,
// otherwise it is done irrespectively of the charge.
//
+ // check input type
+ Bool_t inputESD = IsESD();
+ if (!inputESD && !IsAOD()) {
+ AliError("Need to process ESD or AOD input");
+ return -1;
+ }
+
+ Double_t ptMax = 0.0;
Int_t i, nTracks = fRef->GetNumberOfTracks();
+
fLeading = -1;
AliRsnDaughter leading;
- leading.SetBad();
for (i = 0; i < nTracks; i++) {
- AliRsnDaughter track = GetDaughter(i);
- if (cutPID) if (!cutPID->IsSelected(&track)) continue;
- const AliVParticle *ref = track.GetRef();
- if (ref->Pt() < ptMin) continue;
- //double pt = track.P().Perp();
- //Printf("track %d %g", i, pt);
- if (!leading.IsOK() || ref->Pt() > ptMin) {
- fLeading = i;
- //leading = track;
- ptMin = ref->Pt();
+ if (inputESD)
+ SetDaughterESDtrack(leading, i);
+ else
+ SetDaughterAODtrack(leading, i);
+ if (!leading.IsOK()) {
+ AliDebugClass(1, Form("Failed assignment of track %d", i));
+ continue;
}
- }
- return fLeading;
-}
-
-//_________________________________________________________________________________________________
-Double_t AliRsnEvent::GetAverageMomentum(Int_t &count, AliRsnCutPID *cutPID)
-{
-//
-// Loops on the list of tracks and computes average total momentum.
-//
-
- Int_t i, nTracks = fRef->GetNumberOfTracks();
- Double_t pmean = 0.0;
-
- for (i = 0, count = 0; i < nTracks; i++) {
- AliRsnDaughter track = GetDaughter(i);
- if (cutPID) if (!cutPID->IsSelected(&track)) continue;
- pmean += track.Prec().Mag();
- count++;
- }
-
- if (count > 0) pmean /= (Double_t)count;
- else pmean = 0.0;
-
- return pmean;
-}
-
-//_____________________________________________________________________________
-Bool_t AliRsnEvent::GetAngleDistr
-(Double_t &angleMean, Double_t &angleRMS, AliRsnDaughter *leading)
-{
-//
-// Takes the leading particle and computes the mean and RMS
-// of the distribution of directions of all other tracks
-// with respect to the direction of leading particle.
-//
-
- if (!leading) return kFALSE;
- if (!leading->IsOK()) return kFALSE;
-
- Int_t i, count, nTracks = fRef->GetNumberOfTracks();
- Double_t angle, angle2Mean = 0.0;
-
- angleMean = angle2Mean = 0.0;
-
- for (i = 0, count = 0; i < nTracks; i++) {
- AliRsnDaughter trk = GetDaughter(i);
- if (trk.GetID() == leading->GetID()) continue;
-
- angle = leading->Prec().Angle(trk.Prec().Vect());
-
- angleMean += angle;
- angle2Mean += angle * angle;
- count++;
- }
-
- if (!count) return kFALSE;
-
- angleMean /= (Double_t)count;
- angle2Mean /= (Double_t)count;
- angleRMS = TMath::Sqrt(angle2Mean - angleMean * angleMean);
-
- return kTRUE;
-}
-
-//_____________________________________________________________________________
-Bool_t AliRsnEvent::SetDaughterESDtrack(AliRsnDaughter &out, Int_t i)
-{
-//
-// Setup the first argument to the track identified by the index.
-// When available, adds the MC information and references.
-// ---
-// Version #1: ESD tracks
-//
-
- // check 1: index in good range
- if (i < 0 || i >= fRef->GetNumberOfTracks()) {
- out.SetBad();
- return kFALSE;
- }
-
- // check 2: not NULL object
- AliVTrack *track = (AliVTrack*)fRef->GetTrack(i);
- if (!track) {
- out.SetBad();
- return kFALSE;
- }
-
- // assign references of reconstructed track
- Int_t label = TMath::Abs(track->GetLabel());
- out.SetRef(track);
- out.SetLabel(label);
- out.SetGood();
-
- // assign MC info, if available
- return SetMCInfoESD(out);
-}
-
-//_____________________________________________________________________________
-Bool_t AliRsnEvent::SetDaughterAODtrack(AliRsnDaughter &out, Int_t i)
-{
-//
-// Setup the first argument to the track identified by the index.
-// When available, adds the MC information and references.
-// ---
-// Version #2: AOD tracks
-//
-
- // check 1: index in good range
- if (i < 0 || i >= fRef->GetNumberOfTracks()) {
- out.SetBad();
- return kFALSE;
- }
-
- // check 2: not NULL object
- AliVTrack *track = (AliVTrack*)fRef->GetTrack(i);
- if (!track) {
- out.SetBad();
- return kFALSE;
- }
-
- // assign references of reconstructed track
- Int_t label = TMath::Abs(track->GetLabel());
- out.SetRef(track);
- out.SetLabel(label);
- out.SetGood();
-
- // assign MC info, if available
- return SetMCInfoAOD(out);
-}
-
-//_____________________________________________________________________________
-Bool_t AliRsnEvent::SetDaughterESDv0(AliRsnDaughter &out, Int_t i)
-{
-//
-// Setup the first argument to the track identified by the index.
-// When available, adds the MC information and references.
-// ---
-// Version #3: ESD v0
-//
-
- // check 1: index in good range
- if (i > fRef->GetNumberOfV0s()) {
- out.SetBad();
- return 1;
- }
-
- // check 2: not NULL object
- AliESDEvent *ev = GetRefESD();
- AliESDv0 *v0 = ev->GetV0(i);
- if (!v0) {
- out.SetBad();
- return 2;
- }
-
- // assign references of reconstructed track
- out.SetRef(v0);
- out.SetGood();
- out.SetLabel(-1);
-
- // this time, assigning label is not trivial,
- // it is done only if MC is present and both
- // daughters come from a true particle
- AliMCEvent *mc = GetRefMCESD();
- AliESDtrack *tp = ev->GetTrack(v0->GetPindex());
- AliESDtrack *tn = ev->GetTrack(v0->GetNindex());
- if (mc && tp && tn) {
- Int_t lp = TMath::Abs(tp->GetLabel());
- Int_t ln = TMath::Abs(tn->GetLabel());
- TParticle *pp = mc->Stack()->Particle(lp);
- TParticle *pn = mc->Stack()->Particle(ln);
- // if their first mothers are the same, the V0 is true
- // otherwise no label can be assigned
- if (pp->GetFirstMother() == pn->GetFirstMother() && pp->GetFirstMother() >= 0) out.SetLabel(pp->GetFirstMother());
- }
-
- // assign MC info, if available
- return SetMCInfoESD(out);
-}
-
-//_____________________________________________________________________________
-Bool_t AliRsnEvent::SetDaughterAODv0(AliRsnDaughter &out, Int_t i)
-{
-//
-// Setup the first argument to the track identified by the index.
-// When available, adds the MC information and references.
-// ---
-// Version #4: AOD v0
-//
-
- // check 1: index in good range
- if (i > fRef->GetNumberOfV0s()) {
- out.SetBad();
- return kFALSE;
- }
-
- // check 2: not NULL object
- AliAODEvent *ev = GetRefAOD();
- AliAODv0 *v0 = ev->GetV0(i);
- if (!v0) {
- out.SetBad();
- return kFALSE;
- }
-
- TClonesArray *mcArray = (TClonesArray*)ev->GetList()->FindObject(AliAODMCParticle::StdBranchName());
- if (!mcArray) {
- out.SetBad();
- return kFALSE;
- }
-
- // assign references of reconstructed track
- out.SetRef(v0);
- out.SetGood();
- out.SetLabel(-1);
-
- // retrieve the owner vertex and its daughters
- AliAODTrack *tp = (AliAODTrack*)v0->GetDaughter(0);
- AliAODTrack *tn = (AliAODTrack*)v0->GetDaughter(1);
- if (mcArray && tp && tn) {
- Int_t lp = TMath::Abs(tp->GetLabel());
- Int_t ln = TMath::Abs(tn->GetLabel());
- // loop on array to find MC daughters
- AliAODMCParticle *pp = 0x0, *pn = 0x0;
- TObjArrayIter next(mcArray);
- AliAODMCParticle *part = 0x0;
- while ((part = (AliAODMCParticle*)next())) {
- if (TMath::Abs(part->GetLabel()) == lp) pp = part;
- if (TMath::Abs(part->GetLabel()) == ln) pn = part;
+ if (cuts && !cuts->IsSelected(&leading)) {
+ AliDebugClass(1, Form("Track %d didn't pass cuts", i));
+ continue;
}
- // assign a MC reference and a label only to true V0s
- if (pp && pn)
- if (pp->GetMother() == pn->GetMother() && pp->GetMother() >= 0) out.SetLabel(pp->GetMother());
- }
-
- // assign MC info, if available
- return SetMCInfoAOD(out);
-}
-
-//_____________________________________________________________________________
-Bool_t AliRsnEvent::SetDaughterESDcascade(AliRsnDaughter &out, Int_t i)
-{
-//
-// Setup the first argument to the track identified by the index.
-// When available, adds the MC information and references.
-// ---
-// Version #3: ESD cascade
-//
-
- // check 1: index in good range
- if (i > fRef->GetNumberOfCascades()) {
- out.SetBad();
- return 1;
- }
-
- // check 2: not NULL object
- AliESDEvent *ev = GetRefESD();
- AliESDcascade *casc = ev->GetCascade(i);
- if (!casc) {
- out.SetBad();
- return 2;
- }
-
- // assign references of reconstructed track
- out.SetRef(casc);
- out.SetGood();
- out.SetLabel(-1);
-
- return kTRUE;
-}
-
-//_____________________________________________________________________________
-Bool_t AliRsnEvent::SetDaughterAODcascade(AliRsnDaughter &out, Int_t i)
-{
-//
-// Setup the first argument to the track identified by the index.
-// When available, adds the MC information and references.
-// ---
-// Version #4: AOD cascade
-//
-
- // check 1: index in good range
- if (i > fRef->GetNumberOfCascades()) {
- out.SetBad();
- return kFALSE;
- }
-
- // check 2: not NULL object
- AliAODEvent *ev = GetRefAOD();
- AliAODv0 *casc = ev->GetCascade(i);
- if (!casc) {
- out.SetBad();
- return kFALSE;
- }
-
- // assign references of reconstructed track
- out.SetRef(casc);
- out.SetGood();
- out.SetLabel(-1);
-
- return kTRUE;
-}
-
-//_____________________________________________________________________________
-Bool_t AliRsnEvent::SetMCInfoESD(AliRsnDaughter &out)
-{
-//
-// Using the label assigned to the daughter, searches for the MC informations:
-// -- MC reference
-// -- mother
-//
-
- Int_t label = out.GetLabel();
-
- // if no MC reference is available, exit here (successfully)
- AliMCEvent *mc = GetRefMCESD();
- if (!mc) return kTRUE;
- Int_t nMC = mc->GetNumberOfTracks();
-
- // debug message for fakes
- if (label < 0) {
- AliDebug(AliLog::kDebug + 1, "Fake object (fake track or false V0)");
- return kFALSE;
- }
-
- // assign MC reference, being aware of eventual
- // overflows in the array (sometimes happened)
- if (label >= nMC) {
- AliWarning(Form("Stack overflow: track label = %d -- stack maximum = %d", label, nMC));
- return kFALSE;
- }
- AliMCParticle *mcPart = (AliMCParticle*)mc->GetTrack(label);
- if (!mcPart) {
- AliWarning(Form("Stack discontinuity: label %d refers to a NULL object", label));
- return kFALSE;
- }
- out.SetRefMC(mcPart);
-
- // if this is a primary track, exit here (successfully)
- Int_t imum = mcPart->Particle()->GetFirstMother();
- if (imum < 0) {
- out.SetMotherPDG(0);
- return kTRUE;
- }
-
- // if didn't stop there, search for the mother
- if (imum >= nMC) {
- AliWarning(Form("Stack overflow: track mother label = %d -- stack maximum = %d", label, nMC));
- return kFALSE;
- }
- AliMCParticle *mcMother = (AliMCParticle*)mc->GetTrack(imum);
- if (!mcMother) {
- AliWarning(Form("Stack discontinuity: label mother %d refers to a NULL object", imum));
- return kFALSE;
- }
- out.SetMotherPDG(TMath::Abs(mcMother->Particle()->GetPdgCode()));
-
- return kTRUE;
-}
-
-//_____________________________________________________________________________
-Bool_t AliRsnEvent::SetMCInfoAOD(AliRsnDaughter &out)
-{
-//
-// Using the label assigned to the daughter, searches for the MC informations:
-// -- MC reference
-// -- mother
-//
-
- Int_t label = out.GetLabel();
-
- // debug message for fakes
- if (label < 0) {
- AliDebug(AliLog::kDebug + 1, "Fake object (fake track or false V0)");
- return kFALSE;
- }
-
- // if no MC reference is available, exit here (successfully)
- AliAODEvent *mc = GetRefMCAOD();
- if (!mc) return kTRUE;
-
- // loop on particles using the track label as reference
- // and then assign also the mother type, if found
- TClonesArray *mcArray = (TClonesArray*)mc->GetList()->FindObject(AliAODMCParticle::StdBranchName());
- if (!mcArray) return kFALSE;
- TObjArrayIter next(mcArray);
- AliAODMCParticle *part = 0x0;
- while ((part = (AliAODMCParticle*)next())) {
- if (TMath::Abs(part->GetLabel()) == label) {
- out.SetRefMC(part);
- out.SetMotherPDG(0);
- Int_t imum = part->GetMother();
- if (imum >= 0 && imum <= mcArray->GetEntriesFast()) {
- AliAODMCParticle *mum = (AliAODMCParticle*)mcArray->At(imum);
- if (mum) out.SetMotherPDG(TMath::Abs(mum->GetPdgCode()));
- return kTRUE;
- } else {
- AliWarning(Form("Array overflow: track mother label = %d -- stack maximum = %d", imum, mcArray->GetEntriesFast()));
- return kFALSE;
- }
-
- // if a MC reference is found, there is no need to go on with the loop
- break;
+ // check if it has largest momentum
+ if (leading.GetRef()->Pt() > ptMax) {
+ ptMax = leading.GetRef()->Pt();
+ fLeading = i;
}
}
-
- return kTRUE;
+
+ return fLeading;
}
//
////////////////////////////////////////////////////////////////////////////////
+#include "AliLog.h"
+
#include "AliStack.h"
#include "AliVEvent.h"
#include "AliMCEvent.h"
#include "AliESDEvent.h"
#include "AliAODEvent.h"
-#include "AliVVertex.h"
+
#include "AliRsnDaughter.h"
-class AliRsnCutPID;
-class AliESDtrackCuts;
+class AliRsnCutSet;
class AliPIDResponse;
class AliRsnEvent : public TObject {
virtual ~AliRsnEvent();
// basic setters/getters
- void SetRef(AliVEvent *ref) {fRef = ref;}
- void SetRefMC(AliVEvent *refmc) {fRefMC = refmc;}
- void SetLeadingIndex(Int_t i) {fLeading = i;}
- void SetLocalID(Int_t i) {fLocalID = i;}
- void SetPIDResponse(AliPIDResponse *pid) {fPID = pid;}
- AliVEvent* GetRef() {return fRef;}
- AliVEvent* GetRefMC() {return fRefMC;}
- Int_t GetLeadingIndex() const {return fLeading;}
- Int_t GetLeadingParticleID() const {return fLeading;}
- Int_t GetLocalID() const {return fLocalID;}
- AliPIDResponse* GetPIDResponse() {return fPID;}
+ void SetRef(AliVEvent *ref) {fRef = ref;}
+ void SetRefMC(AliVEvent *refmc) {fRefMC = refmc;}
+ void SetPIDResponse(AliPIDResponse *pid) {fPID = pid;}
+ AliVEvent* GetRef() {return fRef;}
+ AliVEvent* GetRefMC() {return fRefMC;}
+ Int_t GetLeadingIndex() const {return fLeading;}
+ AliPIDResponse* GetPIDResponse() {return fPID;}
// getters which convert into allowed input types
- AliESDEvent* GetRefESD() {if (classMatchRef (AliESDEvent::Class())) return static_cast<AliESDEvent*>(fRef) ; return 0x0;}
- AliAODEvent* GetRefAOD() {if (classMatchRef (AliAODEvent::Class())) return static_cast<AliAODEvent*>(fRef) ; return 0x0;}
- AliMCEvent* GetRefMCESD() {if (classMatchRefMC(AliMCEvent ::Class())) return static_cast<AliMCEvent *>(fRefMC); return 0x0;}
- AliAODEvent* GetRefMCAOD() {if (classMatchRefMC(AliAODEvent::Class())) return static_cast<AliAODEvent*>(fRefMC); return 0x0;}
- Bool_t IsESD() {return (GetRefESD() != 0x0);}
- Bool_t IsAOD() {return (GetRefAOD() != 0x0);}
-
- // advanced getters
- Double_t GetVz() {if (fRef) return fRef->GetPrimaryVertex()->GetZ(); return 1E+10;}
- Int_t GetMultiplicityFromTracks() {if (fRef) return fRef->GetNumberOfTracks(); return -1;}
- Int_t GetMultiplicityFromMC() {if (fRefMC) return fRefMC->GetNumberOfTracks(); return -1;}
- Int_t GetMultiplicityFromESDCuts();
- Float_t GetMultiplicityFromSPD();
+ Bool_t Match(AliVEvent *ev, TClass *ref) {if (ev) return (ev->InheritsFrom(ref)); return kFALSE;}
+ Bool_t IsESD() {return (Match(fRef, AliESDEvent::Class()));}
+ Bool_t IsAOD() {return (Match(fRef, AliAODEvent::Class()));}
+ Bool_t InputOK();
+ AliESDEvent* GetRefESD() {if (IsESD()) return (AliESDEvent*)fRef; return 0x0;}
+ AliMCEvent* GetRefMCESD() {if (IsESD()) return (AliMCEvent *)fRefMC; return 0x0;}
+ AliAODEvent* GetRefAOD() {if (IsAOD()) return (AliAODEvent*)fRef; return 0x0;}
+ AliAODEvent* GetRefMCAOD() {if (IsAOD()) return (AliAODEvent*)fRefMC; return 0x0;}
// setters for a daughter
- Bool_t SetDaughterAbs(AliRsnDaughter &daughter, Int_t absoluteIndex);
- Bool_t SetDaughter(AliRsnDaughter &daughter, Int_t index, AliRsnDaughter::ERefType type = AliRsnDaughter::kTrack);
- Bool_t SetDaughterMC(AliRsnDaughter &daughter, Int_t index);
- AliRsnDaughter GetDaughterAbs(Int_t absoluteIndex);
- AliRsnDaughter GetDaughter(Int_t i, AliRsnDaughter::ERefType type = AliRsnDaughter::kTrack);
- AliRsnDaughter GetDaughterMC(Int_t i);
+ void SetDaughter (AliRsnDaughter &daughter, Int_t index, Bool_t fromMC = kFALSE);
+ AliRsnDaughter GetDaughter (Int_t index, Bool_t fromMC);
+ void SetDaughterESDtrack (AliRsnDaughter &target, Int_t index);
+ void SetDaughterESDv0 (AliRsnDaughter &target, Int_t index);
+ void SetDaughterESDcascade(AliRsnDaughter &target, Int_t index);
+ void SetDaughterESDMCtrack(AliRsnDaughter &target, Int_t index);
+ void SetDaughterAODtrack (AliRsnDaughter &target, Int_t index);
+ void SetDaughterAODv0 (AliRsnDaughter &target, Int_t index);
+ void SetDaughterAODcascade(AliRsnDaughter &target, Int_t index);
+ void SetDaughterAODMCtrack(AliRsnDaughter &target, Int_t index);
+ Bool_t SetMCInfoESD (AliRsnDaughter &target);
+ Bool_t SetMCInfoAOD (AliRsnDaughter &target);
+
+ // counters/converters of candidates
Int_t GetAbsoluteSum() {if (fRef) return (fRef->GetNumberOfTracks() + fRef->GetNumberOfV0s() + fRef->GetNumberOfCascades()); return 0;}
Bool_t ConvertAbsoluteIndex(Int_t index, Int_t &realIndex, AliRsnDaughter::ERefType &type);
Int_t ConvertRealIndex(Int_t index, AliRsnDaughter::ERefType type);
// leading particle stuff
- void SetLeadingParticle(AliRsnDaughter &leading) {if (fLeading >= 0) SetDaughter(leading, fLeading);}
- Int_t SelectLeadingParticle(Double_t ptMin = 0.0, AliRsnCutPID *cutPID = 0x0);
- Double_t GetAverageMomentum(Int_t &count, AliRsnCutPID *cutPID = 0x0);
- Bool_t GetAngleDistr(Double_t &angleMean, Double_t &angleRMS, AliRsnDaughter *reference);
+ void SetLeadingParticle(AliRsnDaughter &leading) {if (fLeading >= 0) SetDaughter(leading, fLeading, kFALSE);}
+ Int_t SelectLeadingParticle(AliRsnCutSet *cuts = 0x0);
private:
- Bool_t classMatchRef (TClass *ref) {if (fRef ) return (fRef ->InheritsFrom(ref)); return kFALSE;}
- Bool_t classMatchRefMC(TClass *ref) {if (fRefMC) return (fRefMC->InheritsFrom(ref)); return kFALSE;}
-
- Bool_t SetDaughterESDtrack(AliRsnDaughter &target, Int_t index);
- Bool_t SetDaughterAODtrack(AliRsnDaughter &target, Int_t index);
- Bool_t SetDaughterESDv0(AliRsnDaughter &target, Int_t index);
- Bool_t SetDaughterAODv0(AliRsnDaughter &target, Int_t index);
- Bool_t SetDaughterESDcascade(AliRsnDaughter &target, Int_t index);
- Bool_t SetDaughterAODcascade(AliRsnDaughter &target, Int_t index);
- Bool_t SetMCInfoESD(AliRsnDaughter &target);
- Bool_t SetMCInfoAOD(AliRsnDaughter &target);
-
- AliVEvent *fRef; // pointer to input event
- AliVEvent *fRefMC; // pointer to reference MC event (if any)
- Int_t fLeading; // index of leading track
- Int_t fLocalID; // identification number used locally
-
- AliPIDResponse *fPID; //! pointer to PID response
+ AliVEvent *fRef; // pointer to input event
+ AliVEvent *fRefMC; // pointer to reference MC event (if any)
+ Int_t fLeading; // index of leading track
+ AliPIDResponse *fPID; // pointer to PID response
ClassDef(AliRsnEvent, 5);
};
+inline Bool_t AliRsnEvent::InputOK()
+{
+//
+// Check that input is ESD or AOD
+//
+
+ if (IsESD()) {
+ AliDebugClass(1, "Input is ESD");
+ return kTRUE;
+ } else if (IsAOD()) {
+ AliDebugClass(1, "Input is AOD");
+ return kTRUE;
+ } else {
+ AliError("Need to process ESD or AOD input");
+ return kFALSE;
+ }
+}
+
#endif
AliError("Expression undefined.");
return kFALSE;
}
- if (fArg2 == 0) {
- AliError("Needed second parameter");
- return kFALSE;
- }
+ //if (fArg2 == 0) {
+ // AliError("Needed second parameter");
+ // return kFALSE;
+ //}
// AliDebug(AliLog::kDebug,Form("fOperator %d",fOperator));
+#include <Riostream.h>
#include "AliLog.h"
#include "AliRsnEvent.h"
AliMCEventHandler *mcH = multiIH->GetFirstMCEventHandler();
if (mcH) fRsnEvent->SetRefMC(mcH->MCEvent());
} else if (fRsnEvent->GetRefAOD()) {
- // TODO AOD MC
-// fRsnEvent->SetRefMC(mcH->MCEvent());
+ AliAODEvent *aod = fRsnEvent->GetRefAOD();
+ TClonesArray *listAOD = (TClonesArray*)(aod->GetList()->FindObject(AliAODMCParticle::StdBranchName()));
+ if (listAOD) fRsnEvent->SetRefMC(fRsnEvent->GetRefAOD());
}
if (fParentHandler->ParentHandler()) tmp = "MIX";
// applying pid cuts
//________________________________________________________________________________________
AliRsnListOutput::AliRsnListOutput(const char *name, AliRsnListOutput::EOut type) :
TNamed(name, ""),
+ fSkipFailed(kTRUE),
fType(type),
fSteps(0),
fValues(0),
//________________________________________________________________________________________
AliRsnListOutput::AliRsnListOutput(const AliRsnListOutput ©) :
TNamed(copy),
+ fSkipFailed(copy.fSkipFailed),
fType(copy.fType),
fSteps(copy.fSteps),
fValues(copy.fValues),
TNamed::operator=(copy);
+ fSkipFailed = copy.fSkipFailed;
fType = copy.fType;
fSteps = copy.fSteps;
fValues = copy.fValues;
globalOK = globalOK && val->Eval(target);
fArray[i] = (Double_t)val->GetComputedValue();
}
- if (!globalOK) return kFALSE;
+ if (!globalOK && fSkipFailed) return kFALSE;
// retrieve object
if (!fList || fIndex < 0) {
const AliRsnListOutput& operator=(const AliRsnListOutput ©);
virtual ~AliRsnListOutput();
- EOut GetType() {return fType;}
- Int_t GetSteps() {return fSteps;}
- TObjArray* GetValues() {return &fValues;}
- Int_t GetNValues() {return (fNValues = fValues.GetEntries());}
- AliRsnValue* GetValue(Int_t i) {return (AliRsnValue*)fValues[i];}
- void SetType(EOut type) {fType = type;}
- void SetSteps(Int_t n) {fSteps = n;}
+ EOut GetType() {return fType;}
+ Int_t GetSteps() {return fSteps;}
+ TObjArray* GetValues() {return &fValues;}
+ Int_t GetNValues() {return (fNValues = fValues.GetEntries());}
+ AliRsnValue* GetValue(Int_t i) {return (AliRsnValue*)fValues[i];}
+ Int_t GetIndex() {return fIndex;}
+ void SetType(EOut type) {fType = type;}
+ void SetSteps(Int_t n) {fSteps = n;}
+ void SetSkipFailed(Bool_t y) {fSkipFailed = y;}
void AddValue(AliRsnValue *value);
THnSparseF* CreateHistogramSparse(const char *name);
AliCFContainer* CreateCFContainer(const char *name);
+ Bool_t fSkipFailed; // tell to skip fills when one computation fails
EOut fType; // output format among allowed ones
Int_t fSteps; // number of steps (only for container)
TObjArray fValues; // container for all related values
//_____________________________________________________________________________
AliRsnLoopDaughter::AliRsnLoopDaughter(const char *name, Int_t listID, AliRsnDaughterDef *def) :
AliRsnLoop(name),
+ fOnlyTrue(kFALSE),
fListID(listID),
fDef(def),
fDaughter()
//_____________________________________________________________________________
AliRsnLoopDaughter::AliRsnLoopDaughter(const AliRsnLoopDaughter& copy) :
AliRsnLoop(copy),
+ fOnlyTrue(copy.fOnlyTrue),
fListID(copy.fListID),
fDef(copy.fDef),
fDaughter(copy.fDaughter)
//
AliRsnLoop::operator=(copy);
+ fOnlyTrue = copy.fOnlyTrue;
fListID = copy.fListID;
fDaughter = copy.fDaughter;
fDef = copy.fDef;
continue;
}
for (i = 0; i < list[il]->GetN(); i++) {
- evMain->SetDaughterAbs(fDaughter, (Int_t)list[il]->GetEntry(i));
+ evMain->SetDaughter(fDaughter, (Int_t)list[il]->GetEntry(i));
// check matching
- if (!fDef->MatchesDaughter(&fDaughter)) continue;
+ if (fOnlyTrue && !fDef->MatchesPID(&fDaughter)) continue;
+ if (!fDef->MatchesCharge(&fDaughter)) continue;
+ if (!fDef->MatchesRefType(&fDaughter)) continue;
// fill outputs
nadd++;
next.Reset();
AliRsnDaughterDef* GetDef() {return fDef;}
AliRsnDaughter* GetDaughter() {return &fDaughter;}
+ void SetOnlyTrue(Bool_t yn = kTRUE) {fOnlyTrue = yn;}
void SetListID(Int_t i) {fListID = i;}
void SetDef(AliRsnDaughterDef *def) {fDef = def;}
protected:
+ Bool_t fOnlyTrue; // for selecting only true particles
Int_t fListID; // index of entry list to use
AliRsnDaughterDef *fDef; // definition for selection
AliRsnDaughter fDaughter; //! daughter temporary member
// M. Vala (email: martin.vala@cern.ch)
//
+#include "Riostream.h"
+#include "AliLog.h"
#include "AliRsnLoopEff.h"
ClassImp(AliRsnLoopEff)
//_____________________________________________________________________________
-AliRsnLoopEff::AliRsnLoopEff(const char *name, Int_t nSteps) :
+AliRsnLoopEff::AliRsnLoopEff(const char *name, Int_t nSteps, Double_t maxDist) :
AliRsnLoop(name),
fAddSteps(nSteps),
- fSteps(0)
+ fSteps(0),
+ fOutput(0),
+ fMaxDistPV(maxDist)
{
//
// Default constructor
//
+
+ fVertex[0] = fVertex[1] = fVertex[2] = 0.0;
}
//_____________________________________________________________________________
AliRsnLoopEff::AliRsnLoopEff(const AliRsnLoopEff& copy) :
AliRsnLoop(copy),
fAddSteps(copy.fAddSteps),
- fSteps(copy.fSteps)
+ fSteps(copy.fSteps),
+ fOutput(copy.fOutput)
{
//
// Copy constructor
//
+
+ fVertex[0] = fVertex[1] = fVertex[2] = 0.0;
}
//_____________________________________________________________________________
fAddSteps = copy.fAddSteps;
fSteps = copy.fSteps;
+ fOutput = copy.fOutput;
return (*this);
}
//
fSteps.Delete();
+ delete fOutput;
}
//_____________________________________________________________________________
// Create the unique output object of this loop
//
- if (!fOutputs.IsEmpty()) {
- AliInfo("Clearing container of this efficiency loop.");
- fOutputs.Delete();
- }
-
- AliRsnListOutput out(Form("%s_out", GetName()), AliRsnListOutput::kCFContainer);
- out.SetSteps(NStepsAll());
-
- AddOutput(&out);
+ fOutput = new AliRsnListOutput(Form("%s_out", GetName()), AliRsnListOutput::kCFContainer);
}
//_____________________________________________________________________________
// Loops on all functions and eventual the ntuple, to initialize output objects.
//
- CreateOutput();
- return AliRsnLoop::Init(Form("%s_%s", prefix, GetName()), list);
+ if (!fOutputs.IsEmpty()) {
+ AliInfo("Clearing container of this efficiency loop.");
+ fOutputs.Delete();
+ }
+
+ Int_t nSteps = (Int_t)fSteps.GetEntries();
+ nSteps += fAddSteps;
+
+ fOutput->SetSteps(nSteps);
+ fOutput->SetSkipFailed(kFALSE);
+ AliRsnLoop::AddOutput(fOutput);
+
+ if (AliRsnLoop::Init(Form("%s_%s", prefix, GetName()), list)) {
+ fOutput = (AliRsnListOutput*)fOutputs[0];
+ return kTRUE;
+ } else {
+ fOutput = 0x0;
+ return kFALSE;
+ }
}
//_____________________________________________________________________________
return -1;
}
+
+//__________________________________________________________________________________________________
+Int_t AliRsnLoopEff::GetMatchedDaughter(Int_t label, AliRsnEvent *event)
+{
+//
+// Searches an object among all possible daughters which matches the corresponding label
+// and if it is found, assigns to the daughter and returns it
+//
+
+ if (!event) return -1;
+
+ AliRsnDaughter out;
+
+ Int_t i, imax = event->GetAbsoluteSum();
+ for (i = 0; i < imax; i++) {
+ event->SetDaughter(out, i);
+ if (out.IsOK() && out.GetLabel() == label) return i;
+ }
+
+ return -1;
+}
+
+//__________________________________________________________________________________________________
+Double_t AliRsnLoopEff::DistanceFromPV(Double_t x, Double_t y, Double_t z)
+{
+//
+// Compute distance from current primary vertex
+//
+
+ AliDebugClass(1, Form("Vertex = %.3f %.3f %.3f -- vprod = %.3f %.3f %.3f", fVertex[0], fVertex[1], fVertex[2], x, y, z));
+
+ x -= fVertex[0];
+ y -= fVertex[1];
+ z -= fVertex[2];
+
+ return TMath::Sqrt(x*x + y*y + z*z);
+}
+
+
#include "AliLog.h"
-#include "AliRsnEvent.h"
#include "AliRsnLoop.h"
+#include "AliRsnListOutput.h"
class AliRsnLoopEff : public AliRsnLoop {
public:
- AliRsnLoopEff(const char *name = "default", Int_t nSteps = 0);
+ AliRsnLoopEff(const char *name = "default", Int_t nSteps = 0, Double_t maxDistPV = 1E-2);
AliRsnLoopEff(const AliRsnLoopEff ©);
AliRsnLoopEff& operator=(const AliRsnLoopEff&);
~AliRsnLoopEff();
- AliRsnListOutput* GetOutput() {return (AliRsnListOutput*)fOutputs[0];}
+ AliRsnListOutput* GetOutput() {return fOutput;}
void CreateOutput();
-
- void AddStep(TObject *set);
- Int_t NStepsArray() {return (Int_t)fSteps.GetEntries();}
- Int_t NStepsAll() {return fAddSteps + NStepsArray();}
-
- virtual void AddOutput(TObject *) { AliWarning("In loops for efficiency it is not allowed to add outputs externally"); }
+ void AddStep(TObject *set);
+ void SetMaxDistanceFromPV(Double_t value) {fMaxDistPV = value;}
+ virtual void AddOutput(TObject *) {AliWarning("In loops for efficiency it is not allowed to add outputs externally");}
virtual Bool_t Init(const char *prefix, TList *list);
protected:
- Int_t FindTrack(Int_t label, AliVEvent *event);
+ Int_t FindTrack(Int_t label, AliVEvent *event);
+ Int_t GetMatchedDaughter(Int_t label, AliRsnEvent *event);
+ Double_t DistanceFromPV(Double_t x, Double_t y, Double_t z);
+ Bool_t CheckDistanceFromPV(Double_t x, Double_t y, Double_t z) {return (DistanceFromPV(x,y,z) <= fMaxDistPV);}
- Int_t fAddSteps; // number of additional steps
- TObjArray fSteps; // list of cuts for all steps with MC tracks
+ Int_t fAddSteps; // number of additional steps
+ TObjArray fSteps; // list of cuts for all steps with MC tracks
+ AliRsnListOutput *fOutput; // unique list output
+ Double_t fVertex[3]; //! primary vertex position
+ Double_t fMaxDistPV; // maximum allowed distance from primary vertex
private:
// author: Alberto Pulvirenti (alberto.pulvirenti@ct.infn.it)
//
+#include <Riostream.h>
+
#include "AliStack.h"
+#include "AliGenEventHeader.h"
+#include "AliAODMCHeader.h"
#include "AliRsnEvent.h"
#include "AliRsnCutManager.h"
//_____________________________________________________________________________
AliRsnLoopEffPair::AliRsnLoopEffPair(const char *name, AliRsnPairDef *def) :
- AliRsnLoopEff(name, 2),
+ AliRsnLoopEff(name, 1),
fDef(def),
fMother()
{
return (*this);
}
+//__________________________________________________________________________________________________
+Bool_t AliRsnLoopEffPair::AssignMotherAndDaughters(AliRsnEvent *rsnEvent, Int_t ipart)
+{
+//
+// Calls the appropriate assignment method
+//
+
+ // setup pointers
+ fMother.SetDaughter(0, &fDaughter[0]);
+ fMother.SetDaughter(1, &fDaughter[1]);
+ fMother.SetRefEvent(rsnEvent);
+ fDaughter[0].SetOwnerEvent(rsnEvent);
+ fDaughter[1].SetOwnerEvent(rsnEvent);
+
+ if (rsnEvent->IsESD())
+ return AssignMotherAndDaughtersESD(rsnEvent, ipart);
+ else if (rsnEvent->IsAOD())
+ return AssignMotherAndDaughtersAOD(rsnEvent, ipart);
+ else {
+ AliError("Unrecognized input event");
+ return kFALSE;
+ }
+}
+
+//__________________________________________________________________________________________________
+Bool_t AliRsnLoopEffPair::AssignMotherAndDaughtersESD(AliRsnEvent *rsnEvent, Int_t ipart)
+{
+//
+// Gets a particle in the MC event and try to assign it to the mother.
+// If it has two daughters, retrieve them and assign also them.
+// NOTE: assignment is done only for MC, since reconstructed match is assigned in the same way
+// for ESD and AOD, if available
+// ---
+// Implementation for ESD inputs
+//
+
+ AliMCEvent *mc = rsnEvent->GetRefMCESD();
+ AliStack *stack = mc->Stack();
+ AliMCParticle *mother = (AliMCParticle*)mc->GetTrack(ipart);
+ TParticle *motherP = mother->Particle();
+ Int_t ntracks = stack->GetNtrack();
+
+ // check PDG code and exit if it is wrong
+ if (TMath::Abs(motherP->GetPdgCode()) != fDef->GetMotherPDG()) return kFALSE;
+
+ // check number of daughters and exit if it is not 2
+ if (motherP->GetNDaughters() < 2) return kFALSE;
+
+ // check distance from primary vertex
+ TLorentzVector vprod;
+ motherP->ProductionVertex(vprod);
+ if (!CheckDistanceFromPV(vprod.X(), vprod.Y(), vprod.Z())) {
+ AliDebugClass(1, "Distant production vertex");
+ return kFALSE;
+ }
+
+ // get the daughters and check their PDG code and charge:
+ // if they match one of the pair daughter definitions,
+ // assign them as MC reference of the 'fDaughter' objects
+ fDaughter[0].Reset();
+ fDaughter[1].Reset();
+ Int_t index[2] = {motherP->GetFirstDaughter(), motherP->GetLastDaughter()};
+ Int_t i, pdg;
+ Short_t charge;
+ AliMCParticle *daughter = 0x0;
+ for (i = 0; i < 2; i++) {
+ // check index for stack
+ if (index[i] < 0 || index[i] > ntracks) {
+ AliError(Form("Index %d overflow: value = %d, max = %d", i, index[i], ntracks));
+ return kFALSE;
+ }
+ // get daughter and its PDG and charge
+ daughter = (AliMCParticle*)mc->GetTrack(index[i]);
+ pdg = TMath::Abs(daughter->Particle()->GetPdgCode());
+ charge = (Short_t)(daughter->Particle()->GetPDG()->Charge() / 3);
+ // check if it matches one definition
+ if (fDef->GetDef1().MatchesPDG(pdg) && fDef->GetDef1().MatchesChargeS(charge)) {
+ fDaughter[0].SetGood();
+ fDaughter[0].SetRefMC(daughter);
+ fDaughter[0].SetLabel(index[i]);
+ } else if (fDef->GetDef2().MatchesPDG(pdg) && fDef->GetDef2().MatchesChargeS(charge)) {
+ fDaughter[1].SetGood();
+ fDaughter[1].SetRefMC(daughter);
+ fDaughter[1].SetLabel(index[i]);
+ }
+ }
+
+ // return success if both daughters were assigned
+ if (fDaughter[0].IsOK() && fDaughter[1].IsOK()) {
+ return kTRUE;
+ } else {
+ fDaughter[0].Reset();
+ fDaughter[1].Reset();
+ return kFALSE;
+ }
+}
+
+//__________________________________________________________________________________________________
+Bool_t AliRsnLoopEffPair::AssignMotherAndDaughtersAOD(AliRsnEvent *rsnEvent, Int_t ipart)
+{
+ AliAODEvent *aod = rsnEvent->GetRefAOD();
+ TClonesArray *listAOD = (TClonesArray*)(aod->GetList()->FindObject(AliAODMCParticle::StdBranchName()));
+ AliAODMCParticle *mother = (AliAODMCParticle*)listAOD->At(ipart);
+ Int_t ntracks = listAOD->GetEntries();
+
+ // check PDG code and exit if it is wrong
+ if (TMath::Abs(mother->GetPdgCode()) != fDef->GetMotherPDG()) return kFALSE;
+
+ // check number of daughters and exit if it is not 2
+ if (mother->GetNDaughters() < 2) return kFALSE;
+
+ // check distance from primary vertex
+ Double_t vprod[3] = {(Double_t)mother->Xv(), (Double_t)mother->Yv(), (Double_t)mother->Zv()};
+ Double_t dv = DistanceFromPV(vprod[0], vprod[1], vprod[2]);
+ if (dv > fMaxDistPV) {
+ AliDebugClass(1, "Distant production vertex");
+ return kFALSE;
+ }
+
+ // get the daughters and check their PDG code and charge:
+ // if they match one of the pair daughter definitions,
+ // assign them as MC reference of the 'fDaughter' objects
+ fDaughter[0].Reset();
+ fDaughter[1].Reset();
+ Int_t index[2] = {(Int_t)mother->GetDaughter(0), (Int_t)mother->GetDaughter(1)};
+ Int_t i, pdg;
+ Short_t charge;
+ AliAODMCParticle *daughter = 0x0;
+ for (i = 0; i < 2; i++) {
+ // check index for stack
+ if (index[i] < 0 || index[i] > ntracks) {
+ AliError(Form("Index %d overflow: value = %d, max = %d", i, index[i], ntracks));
+ return kFALSE;
+ }
+ // get daughter and its PDG and charge
+ daughter = (AliAODMCParticle*)listAOD->At(index[i]);
+ pdg = TMath::Abs(daughter->GetPdgCode());
+ charge = (Short_t)(daughter->Charge() / 3);
+ // check if it matches one definition
+ if (fDef->GetDef1().MatchesPDG(pdg) && fDef->GetDef1().MatchesChargeS(charge)) {
+ fDaughter[0].SetGood();
+ fDaughter[0].SetRefMC(daughter);
+ fDaughter[0].SetLabel(index[i]);
+ } else if (fDef->GetDef2().MatchesPDG(pdg) && fDef->GetDef2().MatchesChargeS(charge)) {
+ fDaughter[1].SetGood();
+ fDaughter[1].SetRefMC(daughter);
+ fDaughter[1].SetLabel(index[i]);
+ }
+ }
+
+ // return success if both daughters were assigned
+ if (fDaughter[0].IsOK() && fDaughter[1].IsOK()) {
+ return kTRUE;
+ } else {
+ fDaughter[0].Reset();
+ fDaughter[1].Reset();
+ return kFALSE;
+ }
+}
+
//_____________________________________________________________________________
Int_t AliRsnLoopEffPair::DoLoop(AliRsnEvent *rsn, AliRsnDaughterSelector*, AliRsnEvent*, AliRsnDaughterSelector*)
{
// check event cuts
if (!OkEvent(rsn)) return 0;
+ // retrieve output
+ fOutput = (AliRsnListOutput*)fOutputs[0];
+
// check presence of MC reference
if (!rsn->GetRefMC()) {
AliError("Need a MC to compute efficiency");
return 0;
}
+ // check presence of event
+ if (!rsn->GetRef()) {
+ AliError("Need an event to compute efficiency");
+ return 0;
+ }
+
// check event type:
// must be ESD or AOD, and then use a bool to know in the rest
if (!rsn->IsESD() && !rsn->IsAOD()) {
return 0;
}
- // additional coherence checks
- AliVEvent *mcEvent = 0x0;
- AliStack *listESD = 0x0;
- TClonesArray *listAOD = 0x0;
- Int_t npart = 0;
+ // retrieve the MC primary vertex position
+ // and do some additional coherence checks
+ Int_t i, npart = 0;
if (rsn->IsESD()) {
- mcEvent = rsn->GetRefMCESD();
- listESD = ((AliMCEvent*)mcEvent)->Stack();
- if (!listESD) {
- AliError("Stack is not present");
- return 0;
- }
- npart = listESD->GetNprimary();
+ TArrayF mcVertex(3);
+ AliGenEventHeader *genEH = rsn->GetRefMCESD()->GenEventHeader();
+ genEH->PrimaryVertex(mcVertex);
+ for (i = 0; i < 3; i++) fVertex[i] = (Double_t)mcVertex[i];
+ npart = rsn->GetRefMCESD()->GetNumberOfTracks();
} else {
- mcEvent = rsn->GetRefMCAOD();
- listAOD = (TClonesArray*)((AliAODEvent*)mcEvent)->GetList()->FindObject(AliAODMCParticle::StdBranchName());
- if (!listAOD) {
- AliError("Stack is not present");
- return 0;
- }
- npart = listAOD->GetEntries();
+ for (i = 0; i < 3; i++) fVertex[i] = 0.0;
+ AliAODEvent *aod = rsn->GetRefMCAOD();
+ TClonesArray *listAOD = (TClonesArray*)(aod->GetList()->FindObject(AliAODMCParticle::StdBranchName()));
+ if (listAOD) npart = listAOD->GetEntries();
+ AliAODMCHeader *mcH = static_cast<AliAODMCHeader*>(aod->FindListObject(AliAODMCHeader::StdBranchName()));
+ if (mcH) mcH->GetVertex(fVertex);
}
// check number of particles
AliInfo("Empty event");
return 0;
}
-
- // by default, assign daughters to mother
- // in the correct order (ref. pairDef)
- fMother.SetDaughter(0, &fDaughter[0]);
- fMother.SetDaughter(1, &fDaughter[1]);
- fMother.SetRefEvent(rsn);
- fDaughter[0].SetOwnerEvent(rsn);
- fDaughter[1].SetOwnerEvent(rsn);
// utility variables
- Bool_t stop;
- Int_t ipart, pdg, ndaughters, dindex[2], id, label, charge, imatch, index, istep, count = 0, nsteps = NStepsArray();
- AliVParticle *mother = 0x0, *daughter = 0x0;
- AliMCParticle *motherESD = 0x0, *daughterESD = 0x0;
- AliAODMCParticle *motherAOD = 0x0, *daughterAOD = 0x0;
+ Int_t ipart, istep, count = 0, nsteps = fSteps.GetEntries();
+ Int_t ntracks = rsn->GetAbsoluteSum();
+ AliRsnDaughter check;
// loop over particles
for (ipart = 0; ipart < npart; ipart++) {
-
- // get next particle and take some quantities
- // in different way from ESD and AOD MC
- if (rsn->IsESD()) {
- mother = mcEvent->GetTrack(ipart);
- motherESD = static_cast<AliMCParticle*>(mother);
- pdg = TMath::Abs(motherESD->Particle()->GetPdgCode());
- ndaughters = motherESD->Particle()->GetNDaughters();
- } else {
- mother = (AliVParticle*)listAOD->At(ipart);
- motherAOD = static_cast<AliAODMCParticle*>(mother);
- pdg = TMath::Abs(motherAOD->GetPdgCode());
- ndaughters = motherAOD->GetNDaughters();
- }
-
- // skip particles with wrong PDG code,
- if (pdg != fDef->GetMotherPDG()) continue;
-
- // fill first step
- fMother.SumMC().SetXYZM(mother->Px(), mother->Py(), mother->Pz(), fDef->GetMotherMass());
- GetOutput()->Fill(&fMother, 0);
+ // check i-th particle
+ if (!AssignMotherAndDaughters(rsn, ipart)) continue;
+ // if assignment was successful, for first step, use MC info
+ fDaughter[0].SetRef(fDaughter[0].GetRefMC());
+ fDaughter[1].SetRef(fDaughter[1].GetRefMC());
+ fMother.SetRefEvent(rsn);
+ fMother.ComputeSum(fDef->GetDef1().GetMass(), fDef->GetDef2().GetMass(), fDef->GetMotherMass());
+ fOutput->Fill(&fMother, 0);
count++;
-
- // reject particles with more/less than 2 daughters
- if (ndaughters != 2) continue;
-
- // retrieve daughters
- // if one of them matches the definition for daughte #1 or #2 in pairDef,
- // assign it to the corresponding AliRsnDaughter member, and set it to 'good'
- // then, if both daughters are not 'good', skip the pair
- fDaughter[0].Reset();
- fDaughter[1].Reset();
- if (rsn->IsESD()) {
- dindex[0] = motherESD->Particle()->GetFirstDaughter();
- dindex[1] = motherESD->Particle()->GetLastDaughter();
- } else {
- dindex[0] = motherAOD->GetDaughter(0);
- dindex[1] = motherAOD->GetDaughter(1);
- }
-
- // try to assign a daughter to each fDaughter[] data member
- stop = kFALSE;
- for (id = 0; id < 2; id++) {
- // avoid overflows
- if (dindex[id] < 0 || dindex[id] > npart) {
- AliWarning(Form("Found a stack overflow in dindex[%d]: value = %d, max = %d", id, dindex[id], npart));
- stop = kTRUE;
- break;
- }
- // retrieve daughter and copy some info
- if (rsn->IsESD()) {
- daughter = mcEvent->GetTrack(dindex[id]);
- daughterESD = static_cast<AliMCParticle*>(daughter);
- pdg = TMath::Abs(daughterESD->Particle()->GetPdgCode());
- charge = (Short_t)(daughterESD->Particle()->GetPDG()->Charge() / 3);
- } else {
- daughter = (AliAODMCParticle*)listAOD->At(dindex[id]);
- daughterAOD = static_cast<AliAODMCParticle*>(daughter);
- pdg = TMath::Abs(daughterAOD->GetPdgCode());
- charge = (Short_t)daughterAOD->Charge();
- }
- label = TMath::Abs(daughter->GetLabel());
- // check if can be assigned
- imatch = -1;
- if ( fDef->GetDef1().MatchesPDG(pdg) && fDef->GetDef1().MatchesChargeS(charge) )
- imatch = 0;
- else if ( fDef->GetDef2().MatchesPDG(pdg) && fDef->GetDef2().MatchesChargeS(charge) )
- imatch = 1;
- if (imatch < 0 || imatch > 1) continue;
- // assign
- label = daughter->GetLabel();
- fDaughter[imatch].SetRefMC(daughter);
- fDaughter[imatch].SetGood();
- index = FindTrack(label, mcEvent);
- if (index > 0) {
- fDaughter[imatch].SetRef(rsn->GetRef()->GetTrack(index));
- }
- }
-
- // if both daughters were assigned, this means that the decay is correct
- // and then we fill second step
- if (fDaughter[0].IsOK() && fDaughter[1].IsOK()) {
- GetOutput()->Fill(&fMother, 1);
- for (istep = 0; istep < nsteps; istep++) {
- AliRsnCutManager *cuts = (AliRsnCutManager*)fSteps[istep];
- if (!cuts->IsSelected(&fMother)) break;
- GetOutput()->Fill(&fMother, 2 + istep);
+ // for each further step, try to find two tracks which pass the related cuts
+ for (istep = 0; istep < nsteps; istep++) {
+ AliRsnCutManager *cuts = (AliRsnCutManager*)fSteps[istep];
+ fDaughter[0].SetBad();
+ fDaughter[1].SetBad();
+ for (i = 0; i < ntracks; i++) {
+ rsn->SetDaughter(check, i);
+ if (!cuts->PassCommonDaughterCuts(&check)) continue;
+ if (TMath::Abs(check.GetLabel()) == fDaughter[0].GetLabel()) {
+ if (!cuts->PassDaughter1Cuts(&check)) continue;
+ fDaughter[0].SetRef(check.GetRef());
+ fDaughter[0].SetGood();
+ } else if (TMath::Abs(check.GetLabel()) == fDaughter[1].GetLabel()) {
+ if (!cuts->PassDaughter2Cuts(&check)) continue;
+ fDaughter[1].SetRef(check.GetRef());
+ fDaughter[1].SetGood();
+ }
+ if (fDaughter[0].IsOK() && fDaughter[1].IsOK()) {
+ fMother.ComputeSum(fDef->GetDef1().GetMass(), fDef->GetDef2().GetMass(), fDef->GetMotherMass());
+ if (cuts->PassMotherCuts(&fMother)) {
+ fOutput->Fill(&fMother, 1 + istep);
+ break;
+ }
+ }
}
}
}
#include "AliRsnDaughter.h"
#include "AliRsnLoopEff.h"
+class AliMCEvent;
+class AliAODEvent;
class AliRsnPairDef;
class AliRsnLoopEffPair : public AliRsnLoopEff {
public:
- AliRsnLoopEffPair(const char *name, AliRsnPairDef *def);
+ AliRsnLoopEffPair(const char *name = "default", AliRsnPairDef *def = 0x0);
AliRsnLoopEffPair(const AliRsnLoopEffPair& copy);
AliRsnLoopEffPair& operator=(const AliRsnLoopEffPair& copy);
virtual ~AliRsnLoopEffPair() {;}
AliRsnPairDef* GetDef() {return fDef;}
void SetDef(AliRsnPairDef *def) {fDef = def;}
virtual Int_t DoLoop(AliRsnEvent *main, AliRsnDaughterSelector *smain = 0, AliRsnEvent *mix = 0, AliRsnDaughterSelector *smix = 0);
+
+ Bool_t AssignMotherAndDaughters (AliRsnEvent *event, Int_t ipart);
+ Bool_t AssignMotherAndDaughtersESD(AliRsnEvent *event, Int_t ipart);
+ Bool_t AssignMotherAndDaughtersAOD(AliRsnEvent *event, Int_t ipart);
protected:
- AliRsnPairDef *fDef; // used pair definition
- AliRsnMother fMother; //! check object (mother)
- AliRsnDaughter fDaughter[2]; //! check object (daughter)
+ AliRsnPairDef *fDef; // used pair definition
+ AliRsnMother fMother; //! check object (mother)
+ AliRsnDaughter fDaughter[2]; //! check object (daughter)
ClassDef(AliRsnLoopEffPair, 1)
};
// M. Vala (email: martin.vala@cern.ch)
//
+#include <Riostream.h>
#include <TList.h>
#include <TEntryList.h>
AliRsnListOutput *out = 0x0;
for (i0 = 0; i0 < list0->GetN(); i0++) {
- evMain->SetDaughterAbs(fDaughter[0], (Int_t)list0->GetEntry(i0));
+ evMain->SetDaughter(fDaughter[0], (Int_t)list0->GetEntry(i0));
+ fDaughter[0].FillP(fPairDef->GetDef1().GetMass());
start = 0;
- if (!fDaughter[0].GetRef()) {
- AliDebugClass(3, Form("[%s]: daughte #1 has NULL ref", GetName()));
- continue;
- }
- if (!fDaughter[0].IsOK()) {
- AliDebugClass(3, Form("[%s]: daughte #1 is BAD", GetName()));
- continue;
- }
if (!fIsMixed && list0 == list1) start = i0 + 1;
for (i1 = start; i1 < list1->GetN(); i1++) {
- evMix->SetDaughterAbs(fDaughter[1], (Int_t)list1->GetEntry(i1));
- if (!fDaughter[1].GetRef()) {
- AliDebugClass(3, Form("[%s]: daughte #2 has NULL ref", GetName()));
- continue;
- }
- if (!fDaughter[1].IsOK()) {
- AliDebugClass(3, Form("[%s]: daughte #2 is BAD", GetName()));
- continue;
+ AliDebugClass(4, Form("Checking entries pair: %d (%d) with %d (%d)", (Int_t)i0, (Int_t)list0->GetEntry(i0), (Int_t)i1, (Int_t)list1->GetEntry(i1)));
+ evMix->SetDaughter(fDaughter[1], (Int_t)list1->GetEntry(i1));
+ fDaughter[1].FillP(fPairDef->GetDef2().GetMass());
+ fMother.Sum(0) = fDaughter[0].Prec() + fDaughter[1].Prec();
+ fMother.Sum(1) = fDaughter[0].Psim() + fDaughter[1].Psim();
+ fMother.Ref(0).SetXYZM(fMother.Sum(0).X(), fMother.Sum(0).Y(), fMother.Sum(0).Z(), fPairDef->GetMotherMass());
+ fMother.Ref(1).SetXYZM(fMother.Sum(1).X(), fMother.Sum(1).Y(), fMother.Sum(1).Z(), fPairDef->GetMotherMass());
+ // check cuts
+ if (fPairCuts) {
+ if (!fPairCuts->IsSelected(&fMother)) {
+ AliDebugClass(2, Form("[%s]: candidate mother didn't pass the cuts", GetName()));
+ continue;
+ }
}
// check mother
- if (!MotherOK()) {
- AliDebugClass(2, Form("[%s]: candidate mother didn't pass the cuts", GetName()));
- continue;
+ if (fOnlyTrue) {
+ if (!IsTrueMother()) {
+ AliDebugClass(2, Form("[%s]: candidate mother is not true", GetName()));
+ continue;
+ }
}
// fill outputs
next.Reset();
}
}
}
-
+
return npairs;
}
//_____________________________________________________________________________
-Bool_t AliRsnLoopPair::MotherOK()
+Bool_t AliRsnLoopPair::IsTrueMother()
{
//
-// Checks that first argument matches definitions for first daughter
-// and the same for second argument, where the order is defined by
-// the AliRsnPairDef data member.
-// If the matching is successful, the AliRsnMother data member is
-// initialized using the mass hypotheses defined here and the momenta
-// in the passed daughters.
-// The third argument is necessary to choose which one of the possible two
-// events owning the two daughter will be used as reference.
+// Checks to see if the mother comes from a true resonance.
+// It is triggered by the 'SetOnlyTrue()' function
//
+
+ // check #1:
+ // daughters have same mother with the right PDG code
+ Int_t commonPDG = fMother.CommonMother();
+ if (commonPDG != fPairDef->GetMotherPDG()) return kFALSE;
+ AliDebugClass(4, "Found a true mother");
- // check matching and exit if one of them fails
- // if true pair is required, this is taken into account:
- // if both true pairs and correct decay tree is required,
- // then we must be sure that also the true PID of daughters matches,
- // instead if correct decay tree is not required this additional check is not done
- fPairDef->GetDef1().SetOnlyTrue(fOnlyTrue && fCheckDecay);
- fPairDef->GetDef2().SetOnlyTrue(fOnlyTrue && fCheckDecay);
- if (!fPairDef->GetDef1().MatchesDaughter(&fDaughter[0])) return kFALSE;
- if (!fPairDef->GetDef2().MatchesDaughter(&fDaughter[1])) return kFALSE;
-
- // if matching is successful
- // compute 4-momenta of daughters and mother
- fMother.ComputeSum(fPairDef->GetDef1().GetMass(), fPairDef->GetDef2().GetMass());
-
- // if required a true pair, check this here and eventually return a fail message
- // this is done using the method AliRsnMother::CommonMother with 2 arguments
- // passed by reference, where the real GEANT label of the particle is stored
- // and one can check if these tracks are both really secondaries (ID >= 0)
- if (fOnlyTrue) {
- Int_t m0, m1, common;
- common = fMother.CommonMother(m0, m1);
- if (m0 < 0 || m1 < 0) return kFALSE;
- if (common != fPairDef->GetMotherPDG()) return kFALSE;
+ // check #2:
+ // checks if daughter have the right particle type
+ // (activated by fCheckDecay)
+ if (fCheckDecay) {
+ AliRsnDaughterDef &def1 = fPairDef->GetDef1();
+ AliRsnDaughterDef &def2 = fPairDef->GetDef2();
+ if (!def1.MatchesPID(&fDaughter[0])) return kFALSE;
+ if (!def2.MatchesPID(&fDaughter[1])) return kFALSE;
}
+ AliDebugClass(4, "Decay products match");
- // point to first event as reference
- // and checks the pair cuts,
- // (done first because it is more likely
- // that it is not passed and execution is faster)
- if (fPairCuts)
- return fPairCuts->IsSelected(&fMother);
- else
- return kTRUE;
+ return kTRUE;
}
void SetListID(Int_t i, Int_t val) {if (i==0||i==1) fListID[i] = val;}
// methods
- Bool_t MotherOK();
+ Bool_t IsTrueMother();
virtual void Print(Option_t *opt = "") const;
virtual Bool_t Init(const char *prefix, TList *list);
virtual Int_t DoLoop(AliRsnEvent *main, AliRsnDaughterSelector *smain, AliRsnEvent *mix = 0, AliRsnDaughterSelector *smix = 0);
ClassImp(AliRsnMother)
-//_____________________________________________________________________________
+//__________________________________________________________________________________________________
AliRsnMother::AliRsnMother(const AliRsnMother &obj) :
TObject(obj),
fRefEvent(obj.fRefEvent),
fSum(obj.fSum),
- fSumMC(obj.fSumMC)
+ fRef(obj.fRef)
{
//
// Copy constructor.
for (i = 0; i < 2; i++) fDaughter[i] = obj.fDaughter[i];
}
-//_____________________________________________________________________________
+//__________________________________________________________________________________________________
AliRsnMother& AliRsnMother::operator=(const AliRsnMother &obj)
{
//
// Does not duplicate pointers.
//
- Int_t i;
-
fSum = obj.fSum;
- fSumMC = obj.fSumMC;
-
- for (i = 0; i < 2; i++) fDaughter[i] = obj.fDaughter[i];
-
+ fRef = obj.fRef;
fRefEvent = obj.fRefEvent;
-
+ fDaughter[0] = obj.fDaughter[0];
+ fDaughter[1] = obj.fDaughter[1];
+
return (*this);
}
-//_____________________________________________________________________________
+//__________________________________________________________________________________________________
AliRsnMother::~AliRsnMother()
{
//
//
}
-//_____________________________________________________________________________
-Int_t AliRsnMother::CommonMother(Int_t &m0, Int_t &m1) const
-{
-//
-// If MC info is available, checks if the two tracks in the pair have the same mother.
-// If the mother label is the same, the function returns the PDG code of mother,
-// otherwise it returns 0.
-// The two arguments passed by reference contain the GEANT labels of the mother
-// of the two particles to which the two daughters point. This is for being able
-// to check if they are really coming from a resonance (indexes >= 0) or not.
-//
-
- // if MC info is not available, the check can't be done
- if (!fDaughter[0]->GetRefMC() || !fDaughter[1]->GetRefMC()) {
- AliDebug(AliLog::kDebug, "MC Info absent --> cannot check common mother");
- return 0;
- }
-
- // check that labels are the same
- m0 = -1;
- m1 = -2;
- if (fDaughter[0]->IsESD() && fDaughter[1]->IsESD()) {
- if (fDaughter[0]->GetRefMCESD() && fDaughter[1]->GetRefMCESD()) {
- m0 = fDaughter[0]->GetRefMCESD()->Particle()->GetFirstMother();
- m1 = fDaughter[1]->GetRefMCESD()->Particle()->GetFirstMother();
- }
- }
- if (fDaughter[0]->IsAOD() && fDaughter[1]->IsAOD()) {
- if (fDaughter[0]->GetRefMCAOD() && fDaughter[1]->GetRefMCAOD()) {
- m0 = fDaughter[0]->GetRefMCAOD()->GetMother();
- m1 = fDaughter[1]->GetRefMCAOD()->GetMother();
- }
- }
-
- // decide the answer depending on the two mother labels
- if (m0 != m1)
- return 0;
- else
- return TMath::Abs(fDaughter[0]->GetMotherPDG());
-}
-
-//_____________________________________________________________________________
-void AliRsnMother::ComputeSum(Double_t mass0, Double_t mass1)
-{
-//
-// Sets the masses for the 4-momenta of the daughters and then
-// sums them, taking into account that the space part is set to
-// each of them when the reference object is set (see AliRsnDaughter::SetRef)
-//
-
- fDaughter[0]->SetMass(mass0);
- fDaughter[1]->SetMass(mass1);
-
- fSum = fDaughter[0]->Prec() + fDaughter[1]->Prec();
- fSumMC = fDaughter[0]->Psim() + fDaughter[1]->Psim();
-}
-
-//_____________________________________________________________________________
-void AliRsnMother::ResetPair()
+//_______________________________________________________________________________________________________________________
+void AliRsnMother::Reset()
{
//
// Resets the mother, zeroing all data members.
Int_t i;
for (i = 0; i < 2; i++) fDaughter[i] = 0x0;
fRefEvent = 0x0;
-
- fSum .SetXYZM(0.0, 0.0, 0.0, 0.0);
- fSumMC.SetXYZM(0.0, 0.0, 0.0, 0.0);
+ fSum.SetXYZM(0.0, 0.0, 0.0, 0.0);
+ fRef.SetXYZM(0.0, 0.0, 0.0, 0.0);
}
-//_____________________________________________________________________________
-Double_t AliRsnMother::AngleTo(AliRsnDaughter *track, Bool_t mc)
+//__________________________________________________________________________________________________
+Int_t AliRsnMother::CommonMother() const
{
//
-// Compute the angle betwee this and the passed object
-// if second argument is kTRUE, use MC values.
+// If MC info is available, checks if the two tracks in the pair have the same mother.
+// If the mother label is the same, the function returns the PDG code of mother,
+// otherwise it returns 0.
+// The two arguments passed by reference contain the GEANT labels of the mother
+// of the two particles to which the two daughters point. This is for being able
+// to check if they are really coming from a resonance (indexes >= 0) or not.
//
- TLorentzVector &me = (mc ? fSumMC : fSum);
- TLorentzVector &he = track->P(mc);
+ Int_t m1 = fDaughter[0]->GetMother();
+ Int_t m2 = fDaughter[1]->GetMother();
+ Int_t out = 0;
+
+ // a true mother makes sense only if both mothers
+ // are not-negative and equal
+ if (m1 >= 0 && m2 >= 0 && m1 == m2) {
+ out = TMath::Abs(fDaughter[0]->GetMotherPDG());
+ AliDebugClass(1, Form("Mothers are: %d %d --> EQUAL (PDG = %d)", m1, m2, out));
+ }
- return me.Angle(he.Vect());
+ return out;
}
-//_____________________________________________________________________________
+//__________________________________________________________________________________________________
Double_t AliRsnMother::AngleToLeading(Bool_t &success)
{
//
Int_t id1 = fDaughter[0]->GetID();
Int_t id2 = fDaughter[1]->GetID();
- Int_t idL = fRefEvent->GetLeadingParticleID();
+ Int_t idL = fRefEvent->GetLeadingIndex();
if (id1 == idL || id2 == idL) {
success = kFALSE;
return -99.0;
}
- AliRsnDaughter leading = fRefEvent->GetDaughter(idL);
+ AliRsnDaughter leading = fRefEvent->GetDaughter(idL, kFALSE);
AliVParticle *ref = leading.GetRef();
Double_t angle = ref->Phi() - fSum.Phi();
return angle;
}
-//_____________________________________________________________________________
+//__________________________________________________________________________________________________
+void AliRsnMother::ComputeSum(Double_t mass0, Double_t mass1, Double_t motherMass)
+{
+//
+// Sets the masses for the 4-momenta of the daughters and then
+// sums them, taking into account that the space part is set to
+// each of them when the reference object is set (see AliRsnDaughter::SetRef)
+//
+
+ fDaughter[0]->FillP(mass0);
+ fDaughter[1]->FillP(mass1);
+
+ // sum
+ fSum = fDaughter[0]->Prec() + fDaughter[1]->Prec();
+ fSumMC = fDaughter[0]->Psim() + fDaughter[1]->Psim();
+
+ // reference
+ fRef.SetXYZM(fSum.X(), fSum.Y(), fSum.Z(), motherMass);
+ fRefMC.SetXYZM(fSumMC.X(), fSumMC.Y(), fSumMC.Z(), motherMass);
+}
+
+//__________________________________________________________________________________________________
Double_t AliRsnMother::CosThetaStar(Bool_t first, Bool_t useMC)
{
//
// [Contribution from Z. Feckova]
//
- TLorentzVector mother = (useMC ? fSumMC : fSum);
- TLorentzVector daughter0 = (first ? fDaughter[0]->P(useMC) : fDaughter[1]->P(useMC));
- TLorentzVector daughter1 = (first ? fDaughter[1]->P(useMC) : fDaughter[0]->P(useMC));
+ TLorentzVector &mother = Sum(useMC);
+ TLorentzVector &daughter0 = (first ? fDaughter[0]->P(useMC) : fDaughter[1]->P(useMC));
+ TLorentzVector &daughter1 = (first ? fDaughter[1]->P(useMC) : fDaughter[0]->P(useMC));
TVector3 momentumM(mother.Vect());
TVector3 normal(mother.Y() / momentumM.Mag(), -mother.X() / momentumM.Mag(), 0.0);
return cosThetaStar;
}
-//_____________________________________________________________________________
+//__________________________________________________________________________________________________
void AliRsnMother::PrintInfo(const Option_t * /*option*/) const
{
//
AliInfo("========= END PAIR INFO ===========");
}
-//_____________________________________________________________________________
+//__________________________________________________________________________________________________
Bool_t AliRsnMother::CheckPair(Bool_t checkMC) const
{
//
class AliRsnMother : public TObject {
public:
- AliRsnMother() : fRefEvent(0), fSum(), fSumMC() {fDaughter[0] = fDaughter[1] = 0;}
+ AliRsnMother() : fRefEvent(0), fSum(), fRef() {fDaughter[0] = fDaughter[1] = 0;}
AliRsnMother(const AliRsnMother &obj);
AliRsnMother& operator=(const AliRsnMother &obj);
virtual ~AliRsnMother();
// setters (4-vectors cannot be set)
+ void Reset();
void SetDaughter(Int_t i, AliRsnDaughter *d) {fDaughter[CkID(i)] = d;}
void SetRefEvent(AliRsnEvent *event) {fRefEvent = event;}
// getters
AliRsnEvent* GetRefEvent() {return fRefEvent;}
AliRsnDaughter* GetDaughter(const Int_t &i) {return fDaughter[CkID(i)];}
- TLorentzVector& Sum() {return fSum;}
- TLorentzVector& SumMC() {return fSumMC;}
+ TLorentzVector& Sum(Bool_t mc) {return (mc ? fSumMC : fSum);}
+ TLorentzVector& Ref(Bool_t mc) {return (mc ? fRefMC : fRef);}
+ Bool_t GetResolution(Double_t &value);
// checks
Bool_t IsLabelEqual() const {return TMath::Abs(fDaughter[0]->GetLabel()) == TMath::Abs(fDaughter[1]->GetLabel());}
Bool_t IsIndexEqual() const {return (fDaughter[0]->GetID() == fDaughter[1]->GetID());}
Bool_t IsOwnerEqual() const {return (fDaughter[0]->GetOwnerEvent() == fDaughter[1]->GetOwnerEvent());}
- Int_t CommonMother() const {Int_t d0, d1; return CommonMother(d0, d1);}
- Int_t CommonMother(Int_t &m0, Int_t &m1) const;
+ Int_t CommonMother() const;
- // useful computations/operations
- void ComputeSum(Double_t mass1, Double_t mass2);
- Double_t AngleTo(AliRsnDaughter *track, Bool_t mc = kFALSE);
+ // angles
+ Double_t AngleTo(AliRsnDaughter *track, Bool_t mc = kFALSE) {return track->P(mc).Angle(Sum(mc).Vect());}
Double_t AngleToLeading(Bool_t &success);
- Double_t CosThetaStar(Bool_t first = kTRUE, Bool_t useMC = kFALSE);
- void ResetPair();
+
+ // computations
+ void ComputeSum(Double_t mass1, Double_t mass2, Double_t motherMass);
+ Double_t CosThetaStar(Bool_t first = kTRUE, Bool_t useMC = kFALSE);
void PrintInfo(const Option_t *option = "ALL") const;
Bool_t CheckPair(Bool_t checkMC = kFALSE) const;
AliRsnDaughter *fDaughter[2]; // elements of the pair
AliRsnEvent *fRefEvent; // reference event
- TLorentzVector fSum; // sum computed from the two daughters
- TLorentzVector fSumMC; // sum computed from the two daughters
+ TLorentzVector fSum; // sum computed from the two daughters (rec)
+ TLorentzVector fSumMC; // sum computed from the two daughters (sim)
+ TLorentzVector fRef; // same to sum, but with fixed mass hypothesis (rec)
+ TLorentzVector fRefMC; // same to sum, but with fixed mass hypothesis (sim)
ClassDef(AliRsnMother, 1)
};
ClassImp(AliRsnValue)
//_____________________________________________________________________________
-AliRsnValue::AliRsnValue() :
- AliRsnTarget(),
- fComputedValue(0),
- fBinArray(0)
-{
-//
-// Default constructor without arguments.
-// Initialize data members to meaningless values.
-// This method is provided for ROOT streaming,
-// but should never be used directly by a user.
-//
-}
-
-//_____________________________________________________________________________
-AliRsnValue::AliRsnValue
-(const char *name, Int_t nbins, Double_t min, Double_t max) :
- AliRsnTarget(name),
- fComputedValue(0.0),
- fBinArray(0)
-{
-//
-// Main constructor (version 1).
-// This constructor defines in meaningful way all data members,
-// and defined a fixed binnings, subdividing the specified interval
-// into that many bins as specified in the integer argument.
-// ---
-// This method is also the entry point for all instances
-// of this class which don't need to do binning (e.g.: TNtuple inputs),
-// since arguments 3 to 5 have default values which don't create any
-// binning array, in order not to allocate memory when this is useless.
-//
-
- SetBins(nbins, min, max);
-}
-
-//_____________________________________________________________________________
-AliRsnValue::AliRsnValue
-(const char *name, Double_t min, Double_t max, Double_t step) :
- AliRsnTarget(name),
+AliRsnValue::AliRsnValue(const char *name, AliRsnTarget::ETargetType type) :
+ AliRsnTarget(name, type),
+ fUseMCInfo(kFALSE),
fComputedValue(0.0),
fBinArray(0)
{
//
-// Main constructor (version 2).
-// This constructor defines in meaningful way all data members
-// and creates enough equal bins of the specified size to cover
-// the required interval.
+// Constructor.
+// Initializes the binning to an empty array.
//
-
- SetBins(min, max, step);
-}
-
-//_____________________________________________________________________________
-AliRsnValue::AliRsnValue
-(const char *name, Int_t nbins, Double_t *array) :
- AliRsnTarget(name),
- fComputedValue(0.0),
- fBinArray(0)
-{
-//
-// Main constructor (version 3).
-// This constructor defines in meaningful way all data members
-// and creates a set of variable bins delimited by the passed array.
-//
-
- SetBins(nbins, array);
}
//_____________________________________________________________________________
AliRsnValue::AliRsnValue(const AliRsnValue& copy) :
AliRsnTarget(copy),
+ fUseMCInfo(copy.fUseMCInfo),
fComputedValue(copy.fComputedValue),
fBinArray(copy.fBinArray)
{
AliRsnTarget::operator=(copy);
+ fUseMCInfo = copy.fUseMCInfo;
fComputedValue = copy.fComputedValue;
fBinArray = copy.fBinArray;
}
//_____________________________________________________________________________
-Bool_t AliRsnValue::Eval(TObject *, Bool_t)
+Bool_t AliRsnValue::Eval(TObject *)
{
//
// Evaluation of the required value.
void AliRsnValue::Print(Option_t *option) const
{
//
-// Print informations about this object
+// Print informations about this object.
+// If one specifies option "BINS" all bin limits are also printed.
//
AliInfo("=== VALUE INFO =================================================");
class AliRsnValue : public AliRsnTarget {
public:
- AliRsnValue();
- AliRsnValue(const char *name, Int_t nbins = 0, Double_t min = 0.0, Double_t max = 0.0);
- AliRsnValue(const char *name, Double_t min, Double_t max, Double_t step);
- AliRsnValue(const char *name, Int_t nbins, Double_t *array);
+ AliRsnValue(const char *name = "", AliRsnTarget::ETargetType type = AliRsnTarget::kTargetTypes);
AliRsnValue(const AliRsnValue& copy);
AliRsnValue& operator=(const AliRsnValue& copy);
virtual ~AliRsnValue() { }
- TArrayD GetArray() const {return fBinArray;}
+ TArrayD& GetArray() {return fBinArray;}
const Double_t* GetArrayValues() const {return fBinArray.GetArray();}
Double_t GetComputedValue() const {return fComputedValue;}
+ void SetUseMCInfo(Bool_t yn = kTRUE) {fUseMCInfo = yn;}
void SetBins(Int_t n, Double_t min, Double_t max);
void SetBins(Int_t n, Double_t *array);
void SetBins(Double_t min, Double_t max, Double_t step);
- virtual Bool_t Eval(TObject *object, Bool_t useMC = kFALSE);
+ virtual Bool_t Eval(TObject *object);
virtual void Print(Option_t *option = "") const;
protected:
+ Bool_t fUseMCInfo; // flag to choose MC info when choice is possible
Double_t fComputedValue; // computed value
TArrayD fBinArray; // array of bins (when used for a histogram axis)
- ClassDef(AliRsnValue, 3) // AliRsnValue base class
+ ClassDef(AliRsnValue, 3) // AliRsnValue base class
};
#endif