#include <Riostream.h>
#include <TArrayF.h>
#include "AliGenEventHeader.h"
#include "AliRsnCutSet.h"
#include "AliRsnEvent.h"
ClassImp(AliRsnEvent)
AliRsnEvent::AliRsnEvent(AliVEvent *ref, AliVEvent *refMC) :
fRef(ref),
fRefMC(refMC),
fLeading(-1),
fPID(0x0),
fAODList(0x0)
{
}
AliRsnEvent::AliRsnEvent(const AliRsnEvent &event) :
TObject(event),
fRef(event.fRef),
fRefMC(event.fRefMC),
fLeading(event.fLeading),
fPID(event.fPID),
fAODList(event.fAODList)
{
}
AliRsnEvent &AliRsnEvent::operator= (const AliRsnEvent &event)
{
TObject::operator=(event);
if (this == &event)
return *this;
fRef = event.fRef;
fRefMC = event.fRefMC;
fLeading = event.fLeading;
fPID = event.fPID;
fAODList = event.fAODList;
return (*this);
}
AliRsnEvent::~AliRsnEvent()
{
}
void AliRsnEvent::SetDaughter(AliRsnDaughter &out, Int_t index, Bool_t fromMC)
{
out.Reset();
out.SetRsnID(index);
out.SetOwnerEvent(this);
if (!InputOK()) return;
Bool_t inputESD = IsESD();
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;
}
}
}
AliRsnDaughter AliRsnEvent::GetDaughter(Int_t i, Bool_t fromMC)
{
AliRsnDaughter d;
SetDaughter(d, i, fromMC);
return d;
}
void AliRsnEvent::SetDaughterESDtrack(AliRsnDaughter &out, Int_t i)
{
AliESDEvent *esd = (AliESDEvent *)fRef;
if (i >= 0 && i < esd->GetNumberOfTracks()) {
AliESDtrack *track = esd->GetTrack(i);
if (track) {
out.SetRef(track);
out.SetGood();
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()));
}
}
void AliRsnEvent::SetDaughterAODtrack(AliRsnDaughter &out, Int_t i)
{
AliAODEvent *aod = (AliAODEvent *)fRef;
if (i >= 0 && i < aod->GetNumberOfTracks()) {
AliAODTrack *track = dynamic_cast<AliAODTrack*>(aod->GetTrack(i));
if(!track) AliFatal("Not a standard AOD");
if (track) {
out.SetRef(track);
out.SetGood();
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)
{
if (i >= 0 && i < fRef->GetNumberOfV0s()) {
AliESDEvent *ev = GetRefESD();
AliESDv0 *v0 = ev->GetV0(i);
if (v0) {
out.SetRef(v0);
out.SetGood();
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 (pp->GetFirstMother() == pn->GetFirstMother() && pp->GetFirstMother() >= 0) {
out.SetLabel(pp->GetFirstMother());
TParticle *mom = mc->Stack()->Particle(pn->GetFirstMother());
if(mom->GetPdgCode() == 310) {
out.SetLabel(mom->GetFirstMother());
}
SetMCInfoESD(out);
}
}
}
}
}
}
}
void AliRsnEvent::SetDaughterAODv0(AliRsnDaughter &out, Int_t i)
{
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 (pp->GetMother() == pn->GetMother() && pp->GetMother() >= 0) {
out.SetLabel(pp->GetMother());
SetMCInfoAOD(out);
}
}
}
}
}
}
}
void AliRsnEvent::SetDaughterESDcascade(AliRsnDaughter &out, Int_t i)
{
if (i >= 0 && i < fRef->GetNumberOfCascades()) {
AliESDEvent *ev = GetRefESD();
AliESDcascade *casc = ev->GetCascade(i);
if (casc) {
out.SetRef(casc);
out.SetGood();
if (fRefMC) {
}
}
}
}
void AliRsnEvent::SetDaughterAODcascade(AliRsnDaughter &out, Int_t i)
{
if (i >= 0 && i < fRef->GetNumberOfCascades()) {
AliAODEvent *ev = GetRefAOD();
AliAODv0 *casc = ev->GetCascade(i);
if (casc) {
out.SetRef(casc);
out.SetGood();
if (fRefMC) {
}
}
}
}
Bool_t AliRsnEvent::SetMCInfoESD(AliRsnDaughter &out)
{
Int_t label = out.GetLabel();
if (label < 0 || !fRefMC) return kFALSE;
Int_t nMC = fRefMC->GetNumberOfTracks();
if (label >= nMC) {
AliDebug(4, Form("Stack overflow: track label = %d -- stack maximum = %d", label, nMC));
return kFALSE;
}
AliMCEvent *mc = (AliMCEvent *)fRefMC;
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);
Int_t imum = mcPart->Particle()->GetFirstMother();
if (imum >= 0 && imum < nMC) {
AliMCParticle *mcMother = (AliMCParticle *)mc->GetTrack(imum);
if (mcMother) {
out.SetMotherPDG(mcMother->Particle()->GetPdgCode());
} else {
AliWarning(Form("Stack discontinuity: label mother %d refers to a NULL object", imum));
}
} else {
AliDebug(4, Form("Stack overflow: mother label = %d -- stack maximum = %d", imum, nMC));
}
return kTRUE;
}
Bool_t AliRsnEvent::SetMCInfoAOD(AliRsnDaughter &out)
{
Int_t label = out.GetLabel();
if (label < 0 || !fRefMC) return kFALSE;
AliAODEvent *mc = (AliAODEvent *)fRefMC;
TClonesArray *mcArray = (TClonesArray *)mc->GetList()->FindObject(AliAODMCParticle::StdBranchName());
Int_t nMC = mcArray->GetEntriesFast();
if (label >= nMC) {
AliDebug(4, Form("Stack overflow: track label = %d -- stack maximum = %d", label, nMC));
return kFALSE;
}
AliAODMCParticle *mcPart = (AliAODMCParticle *)mcArray->At(label);
if (!mcPart) {
AliWarning(Form("Stack discontinuity: label %d refers to a NULL object", label));
return kFALSE;
}
out.SetRefMC(mcPart);
Int_t imum = mcPart->GetMother();
if (imum >= 0 && imum < nMC) {
AliAODMCParticle *mcMother = (AliAODMCParticle *)mcArray->At(imum);
if (mcMother) {
out.SetMotherPDG(mcMother->GetPdgCode());
} else {
AliWarning(Form("Stack discontinuity: label mother %d refers to a NULL object", imum));
}
} else if (imum >= nMC) {
AliDebug(4, Form("Stack overflow: mother label = %d -- stack maximum = %d", imum, nMC));
}
return kTRUE;
}
Bool_t AliRsnEvent::ConvertAbsoluteIndex(Int_t index, Int_t &realIndex, AliRsnDaughter::ERefType &type)
{
Int_t nTracks = fRef->GetNumberOfTracks();
Int_t nV0s = fRef->GetNumberOfV0s();
Int_t nCascades = fRef->GetNumberOfCascades();
if (index < nTracks) {
realIndex = index;
type = AliRsnDaughter::kTrack;
return kTRUE;
} else if (index >= nTracks && index < nTracks + nV0s) {
realIndex = index - nTracks;
type = AliRsnDaughter::kV0;
return kTRUE;
} else if (index >= nTracks + nV0s && index < nTracks + nV0s + nCascades) {
realIndex = index - nTracks - nV0s;
type = AliRsnDaughter::kCascade;
return kTRUE;
}
realIndex = -1;
type = AliRsnDaughter::kNoType;
return kFALSE;
}
Int_t AliRsnEvent::ConvertRealIndex(Int_t index, AliRsnDaughter::ERefType type)
{
Int_t nTracks = fRef->GetNumberOfTracks();
Int_t nV0s = fRef->GetNumberOfV0s();
Int_t nCascades = fRef->GetNumberOfCascades();
switch (type) {
case AliRsnDaughter::kTrack:
if (index >= 0 && index < nTracks)
return index;
else
return -1;
case AliRsnDaughter::kV0:
if (index >= 0 && index < nV0s)
return nTracks + index;
else
return -1;
case AliRsnDaughter::kCascade:
if (index >= 0 && index < nCascades)
return nTracks + nV0s + index;
else
return -1;
default:
return -1;
}
}
Int_t AliRsnEvent::SelectLeadingParticle(AliRsnCutSet *cuts)
{
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;
for (i = 0; i < nTracks; i++) {
if (inputESD)
SetDaughterESDtrack(leading, i);
else
SetDaughterAODtrack(leading, i);
if (!leading.IsOK()) {
AliDebugClass(1, Form("Failed assignment of track %d", i));
continue;
}
if (cuts && !cuts->IsSelected(&leading)) {
AliDebugClass(1, Form("Track %d didn't pass cuts", i));
continue;
}
if (leading.GetRef()->Pt() > ptMax) {
ptMax = leading.GetRef()->Pt();
fLeading = i;
}
}
return fLeading;
}