#include "AliAODVertex.h"
#include "AliAODTrack.h"
ClassImp(AliAODVertex)
AliAODVertex::AliAODVertex() :
AliVVertex(),
fChi2perNDF(-999.),
fID(-1),
fBCID(AliVTrack::kTOFBCNA),
fType(kUndef),
fNprong(0),
fIprong(0),
fNContributors(0),
fCovMatrix(NULL),
fParent(),
fDaughters(),
fProngs(NULL)
{
fPosition[0] = fPosition[1] = fPosition[2] = -999.;
}
AliAODVertex::AliAODVertex(const Double_t position[3],
const Double_t covMatrix[6],
Double_t chi2perNDF,
TObject *parent,
Short_t id,
Char_t vtype,
Int_t nprong) :
AliVVertex(),
fChi2perNDF(chi2perNDF),
fID(id),
fBCID(AliVTrack::kTOFBCNA),
fType(vtype),
fNprong(nprong),
fIprong(0),
fNContributors(0),
fCovMatrix(NULL),
fParent(parent),
fDaughters(),
fProngs(0)
{
SetPosition(position);
if (covMatrix) SetCovMatrix(covMatrix);
MakeProngs();
}
AliAODVertex::AliAODVertex(const Float_t position[3],
const Float_t covMatrix[6],
Double_t chi2perNDF,
TObject *parent,
Short_t id,
Char_t vtype,
Int_t nprong) :
AliVVertex(),
fChi2perNDF(chi2perNDF),
fID(id),
fBCID(AliVTrack::kTOFBCNA),
fType(vtype),
fNprong(nprong),
fIprong(0),
fNContributors(0),
fCovMatrix(NULL),
fParent(parent),
fDaughters(),
fProngs(0)
{
SetPosition(position);
if (covMatrix) SetCovMatrix(covMatrix);
MakeProngs();
}
AliAODVertex::AliAODVertex(const Double_t position[3],
Double_t chi2perNDF,
Char_t vtype,
Int_t nprong) :
AliVVertex(),
fChi2perNDF(chi2perNDF),
fID(-1),
fBCID(AliVTrack::kTOFBCNA),
fType(vtype),
fNprong(nprong),
fIprong(0),
fNContributors(0),
fCovMatrix(NULL),
fParent(),
fDaughters(),
fProngs(0)
{
SetPosition(position);
MakeProngs();
}
AliAODVertex::AliAODVertex(const Float_t position[3],
Double_t chi2perNDF,
Char_t vtype, Int_t nprong) :
AliVVertex(),
fChi2perNDF(chi2perNDF),
fID(-1),
fBCID(AliVTrack::kTOFBCNA),
fType(vtype),
fNprong(nprong),
fIprong(0),
fNContributors(0),
fCovMatrix(NULL),
fParent(),
fDaughters(),
fProngs(0)
{
SetPosition(position);
MakeProngs();
}
AliAODVertex::~AliAODVertex()
{
delete fCovMatrix;
if (fNprong > 0) delete[] fProngs;
}
AliAODVertex::AliAODVertex(const AliAODVertex& vtx) :
AliVVertex(vtx),
fChi2perNDF(vtx.fChi2perNDF),
fID(vtx.fID),
fBCID(vtx.fBCID),
fType(vtx.fType),
fNprong(vtx.fNprong),
fIprong(vtx.fIprong),
fNContributors(vtx.fNContributors),
fCovMatrix(NULL),
fParent(vtx.fParent),
fDaughters(vtx.fDaughters),
fProngs(0)
{
for (int i = 0; i < 3; i++)
fPosition[i] = vtx.fPosition[i];
if (vtx.fCovMatrix) fCovMatrix=new AliAODRedCov<3>(*vtx.fCovMatrix);
MakeProngs();
for (int i = 0; i < fNprong; i++) {
fProngs[i] = vtx.fProngs[i];
}
}
AliAODVertex* AliAODVertex::CloneWithoutRefs() const
{
Double_t cov[6] = { 0.0 };
if (fCovMatrix) fCovMatrix->GetCovMatrix(cov);
AliAODVertex* v = new AliAODVertex(fPosition,
cov,
fChi2perNDF,
0x0,
fID,
fType,
0);
v->SetName(GetName());
v->SetNContributors(fNContributors);
return v;
}
AliAODVertex& AliAODVertex::operator=(const AliAODVertex& vtx)
{
if (this != &vtx) {
AliVVertex::operator=(vtx);
for (int i = 0; i < 3; i++)
fPosition[i] = vtx.fPosition[i];
fChi2perNDF = vtx.fChi2perNDF;
fID = vtx.fID;
fType = vtx.fType;
fBCID = vtx.fBCID;
delete fCovMatrix;
fCovMatrix = NULL;
if (vtx.fCovMatrix) fCovMatrix = new AliAODRedCov<3>(*vtx.fCovMatrix);
fNContributors = vtx.fNContributors;
fParent = vtx.fParent;
fDaughters = vtx.fDaughters;
fNprong = vtx.fNprong;
fIprong = vtx.fIprong;
MakeProngs();
for (int i = 0; i < fNprong; i++) {
fProngs[i] = vtx.fProngs[i];
}
}
return *this;
}
void AliAODVertex::AddDaughter(TObject *daughter)
{
if (!fProngs) {
if (fDaughters.GetEntries()==0) {
TRefArray* arr = &fDaughters;
new(arr)TRefArray(TProcessID::GetProcessWithUID(daughter));
}
fDaughters.Add(daughter);
} else {
if (fIprong < fNprong) {
fProngs[fIprong++] = daughter;
} else {
AliWarning("Number of daughters out of range !\n");
}
}
return;
}
template <class T> void AliAODVertex::GetSigmaXYZ(T sigma[3]) const
{
if(fCovMatrix) {
sigma[0]=fCovMatrix[3];
sigma[1]=fCovMatrix[4];
sigma[2]=fCovMatrix[5];
} else
sigma[0]=sigma[1]=sigma[2]=-999.;
}
Int_t AliAODVertex::GetNContributors() const
{
Int_t cont = 0;
TString vtitle = GetTitle();
if (!vtitle.Contains("VertexerTracks") || vtitle.Contains("TracksNoConstraint") || fType==kPileupTracks
) {
cont = fNContributors;
} else {
for (Int_t iDaug = 0; iDaug < GetNDaughters(); iDaug++) {
AliAODTrack* aodT = dynamic_cast<AliAODTrack*>(fDaughters.At(iDaug));
if (!aodT) continue;
if (aodT->GetUsedForPrimVtxFit()) cont++;
}
if(vtitle.Contains("VertexerTracksWithConstraint"))cont++;
}
return cont;
}
Bool_t AliAODVertex::HasDaughter(TObject *daughter) const
{
if (!fProngs) {
TRefArrayIter iter(&fDaughters);
while (TObject *daugh = iter.Next()) {
if (daugh == daughter) return kTRUE;
}
return kFALSE;
} else {
Bool_t has = kFALSE;
for (int i = 0; i < fNprong; i++) {
if (fProngs[i].GetObject() == daughter) has = kTRUE;
}
return has;
}
}
Double_t AliAODVertex::RotatedCovMatrixXX(Double_t phi, Double_t theta) const
{
if (!fCovMatrix) {
return -999.;
}
Double_t covMatrix[6];
GetCovMatrix(covMatrix);
Double_t cp = TMath::Cos(phi);
Double_t sp = TMath::Sin(phi);
Double_t ct = TMath::Cos(theta);
Double_t st = TMath::Sin(theta);
return
covMatrix[0]*cp*cp*ct*ct
+covMatrix[1]*2.*cp*sp*ct*ct
+covMatrix[3]*2.*cp*ct*st
+covMatrix[2]*sp*sp*ct*ct
+covMatrix[4]*2.*sp*ct*st
+covMatrix[5]*st*st;
}
Double_t AliAODVertex::RotatedCovMatrixXY(Double_t phi, Double_t theta) const
{
if (!fCovMatrix) {
return -999.;
}
Double_t covMatrix[6];
GetCovMatrix(covMatrix);
Double_t cp = TMath::Cos(phi);
Double_t sp = TMath::Sin(phi);
Double_t ct = TMath::Cos(theta);
Double_t st = TMath::Sin(theta);
return
-covMatrix[0]*cp*sp*ct
+covMatrix[1]*ct*(cp*cp-sp*sp)
-covMatrix[3]*sp*st
+covMatrix[2]*cp*sp*ct
+covMatrix[4]*cp*st;
}
Double_t AliAODVertex::RotatedCovMatrixXZ(Double_t phi, Double_t theta) const
{
if (!fCovMatrix) {
return -999.;
}
Double_t covMatrix[6];
GetCovMatrix(covMatrix);
Double_t cp = TMath::Cos(phi);
Double_t sp = TMath::Sin(phi);
Double_t ct = TMath::Cos(theta);
Double_t st = TMath::Sin(theta);
return
-covMatrix[0]*cp*cp*ct*st
-covMatrix[1]*2.*cp*sp*ct*st
+covMatrix[3]*cp*(ct*ct-st*st)
-covMatrix[2]*sp*sp*ct*st
+covMatrix[4]*sp*(ct*ct-st*st)
+covMatrix[5]*ct*st;
}
Double_t AliAODVertex::RotatedCovMatrixYY(Double_t phi) const
{
if (!fCovMatrix) {
return -999.;
}
Double_t covMatrix[6];
GetCovMatrix(covMatrix);
Double_t cp = TMath::Cos(phi);
Double_t sp = TMath::Sin(phi);
return
covMatrix[0]*sp*sp
-covMatrix[1]*2.*cp*sp
+covMatrix[2]*cp*cp;
}
Double_t AliAODVertex::RotatedCovMatrixYZ(Double_t phi, Double_t theta) const
{
if (!fCovMatrix) {
return -999.;
}
Double_t covMatrix[6];
GetCovMatrix(covMatrix);
Double_t cp = TMath::Cos(phi);
Double_t sp = TMath::Sin(phi);
Double_t ct = TMath::Cos(theta);
Double_t st = TMath::Sin(theta);
return
covMatrix[0]*cp*sp*st
+covMatrix[1]*st*(sp*sp-cp*cp)
-covMatrix[3]*sp*ct
-covMatrix[2]*cp*sp*st
+covMatrix[4]*cp*ct;
}
Double_t AliAODVertex::RotatedCovMatrixZZ(Double_t phi, Double_t theta) const
{
if (!fCovMatrix) {
return -999.;
}
Double_t covMatrix[6];
GetCovMatrix(covMatrix);
Double_t cp = TMath::Cos(phi);
Double_t sp = TMath::Sin(phi);
Double_t ct = TMath::Cos(theta);
Double_t st = TMath::Sin(theta);
return
covMatrix[0]*cp*cp*st*st
+covMatrix[1]*2.*cp*sp*st*st
-covMatrix[3]*2.*cp*ct*st
+covMatrix[2]*sp*sp*st*st
-covMatrix[4]*2.*sp*sp*ct*st
+covMatrix[5]*ct*ct;
}
Double_t AliAODVertex::Distance2ToVertex(const AliAODVertex *vtx) const
{
Double_t dx = GetX()-vtx->GetX();
Double_t dy = GetY()-vtx->GetY();
Double_t dz = GetZ()-vtx->GetZ();
return dx*dx+dy*dy+dz*dz;
}
Double_t AliAODVertex::DistanceXY2ToVertex(const AliAODVertex *vtx) const
{
Double_t dx = GetX()-vtx->GetX();
Double_t dy = GetY()-vtx->GetY();
return dx*dx+dy*dy;
}
Double_t AliAODVertex::Error2DistanceToVertex(AliAODVertex *vtx) const
{
Double_t phi,theta;
PhiAndThetaToVertex(vtx,phi,theta);
Double_t error2 = RotatedCovMatrixXX(phi,theta);
Double_t error2vtx = vtx->RotatedCovMatrixXX(phi,theta);
return error2+error2vtx;
}
Double_t AliAODVertex::Error2DistanceXYToVertex(AliAODVertex *vtx) const
{
Double_t phi,theta;
PhiAndThetaToVertex(vtx,phi,theta);
Double_t error2 = RotatedCovMatrixXX(phi);
Double_t error2vtx = vtx->RotatedCovMatrixXX(phi);
return error2+error2vtx;
}
template <class T, class P>
void AliAODVertex::PhiAndThetaToVertex(AliAODVertex *vtx, P &phi, T &theta) const
{
phi = TMath::Pi()+TMath::ATan2(-vtx->GetY()+GetY(),-vtx->GetX()+GetX());
Double_t vtxxphi = vtx->GetX()*TMath::Cos(phi)+vtx->GetY()*TMath::Sin(phi);
Double_t xphi = GetX()*TMath::Cos(phi)+GetY()*TMath::Sin(phi);
theta = TMath::ATan2(vtx->GetZ()-GetZ(),vtxxphi-xphi);
}
void AliAODVertex::PrintIndices() const
{
TRefArrayIter iter(&fDaughters);
while (TObject *daugh = iter.Next()) {
printf("Particle %p originates from this vertex.\n", static_cast<void*>(daugh));
}
}
const char* AliAODVertex::AsString() const
{
TString tmp(Form("%10s pos(%7.2f,%7.2f,%7.2f)",GetTypeName((AODVtx_t)GetType()),GetX(),GetY(),GetZ()));
if (GetType()==kPrimary || GetType()==kMainSPD || GetType()==kPileupSPD )
{
tmp += Form(" ncontrib %d chi2/ndf %4.1f",GetNContributors(),GetChi2perNDF());
}
if ( !fParent.GetObject() )
{
tmp += " no parent";
}
if ( fDaughters.GetEntriesFast() > 0 )
{
if ( fDaughters.GetEntriesFast() == 1 )
{
tmp += " origin of 1 particle";
}
else
{
tmp += Form(" origin of %2d particles",fDaughters.GetEntriesFast());
}
}
return tmp.Data();
}
const char* AliAODVertex::GetTypeName(AODVtx_t type)
{
switch (type)
{
case kPrimary:
return "primary";
break;
case kKink:
return "kink";
break;
case kV0:
return "v0";
break;
case kCascade:
return "cascade";
break;
case kMainSPD:
return "mainSPD";
break;
case kPileupSPD:
return "pileupSPD";
break;
case kPileupTracks:
return "pileupTRK";
break;
case kMainTPC:
return "mainTPC";
break;
default:
return "unknown";
break;
};
}
void AliAODVertex::Print(Option_t* ) const
{
printf("Vertex position:\n");
printf(" x = %f\n", fPosition[0]);
printf(" y = %f\n", fPosition[1]);
printf(" z = %f\n", fPosition[2]);
printf(" parent particle: %p\n", static_cast<void*>(fParent.GetObject()));
printf(" origin of %d particles\n", fDaughters.GetEntriesFast());
printf(" vertex type %d\n", fType);
printf(" Chi^2/NDF = %f\n", fChi2perNDF);
}