/* $Id$ */
//-----------------------------------------------------------------
-// Implementation of the ESD class
-// This is the class to deal with during the phisical analysis of data
-// This class is generated directly by the reconstruction methods
-// Origin: Iouri Belikov, CERN, Jouri.Belikov@cern.ch
+// Implementation of the AliESDEvent class
+// This is the class to deal with during the phisical analysis of data.
+// It also ensures the backward compatibility with the old ESD format.
+//
+// Origin: Christian Klein-Boesing, CERN, Christian.Klein-Boesing@cern.ch
//-----------------------------------------------------------------
#include "TList.h"
+#include "TRefArray.h"
#include <TNamed.h>
#include "AliESDEvent.h"
#include "AliESDHLTtrack.h"
#include "AliESDFMD.h"
#include "AliESD.h"
+#include "AliESDMuonTrack.h"
+#include "AliESDPmdTrack.h"
+#include "AliESDTrdTrack.h"
+#include "AliESDVertex.h"
+#include "AliESDcascade.h"
+#include "AliESDPmdTrack.h"
+#include "AliESDTrdTrack.h"
+#include "AliESDVertex.h"
+#include "AliESDcascade.h"
+#include "AliESDkink.h"
+#include "AliESDtrack.h"
+#include "AliESDHLTtrack.h"
+#include "AliESDCaloCluster.h"
+#include "AliESDv0.h"
+#include "AliESDFMD.h"
+#include "AliESDVZERO.h"
+#include "AliMultiplicity.h"
+#include "AliRawDataErrorLog.h"
ClassImp(AliESDEvent)
+
+
+// here we define the names, some classes are no TNamed, therefore the classnames
+// are the Names
+ const char* AliESDEvent::fESDListName[kESDListN] = {"AliESDRun",
+ "AliESDHeader",
+ "AliESDZDC",
+ "AliESDFMD",
+ "AliESDVZERO",
+ "AliESDTZERO",
+ "SPDVertex",
+ "PrimaryVertex",
+ "AliMultiplicity",
+ "PHOSTrigger",
+ "EMCALTrigger",
+ "Tracks",
+ "MuonTracks",
+ "PmdTracks",
+ "TrdTracks",
+ "V0s",
+ "Cascades",
+ "Kinks",
+ "CaloClusters",
+ "AliRawDataErrorLogs"};
//______________________________________________________________________________
AliESDEvent::AliESDEvent():
+ AliVEvent(),
fESDObjects(new TList()),
fESDRun(0),
fHeader(0),
fCaloClusters(0),
fErrorLogs(0),
fESDOld(0),
+ fConnected(kFALSE),
fEMCALClusters(0),
fFirstEMCALCluster(-1),
fPHOSClusters(0),
}
//______________________________________________________________________________
AliESDEvent::AliESDEvent(const AliESDEvent& esd):
- TObject(esd),
+ AliVEvent(esd),
fESDObjects(new TList()),
fESDRun(new AliESDRun(*esd.fESDRun)),
fHeader(new AliESDHeader(*esd.fHeader)),
fCaloClusters(new TClonesArray(*esd.fCaloClusters)),
fErrorLogs(new TClonesArray(*esd.fErrorLogs)),
fESDOld(new AliESD(*esd.fESDOld)),
+ fConnected(esd.fConnected),
fEMCALClusters(esd.fEMCALClusters),
fFirstEMCALCluster(esd.fFirstEMCALCluster),
fPHOSClusters(esd.fPHOSClusters),
// Assignment operator
if(&source == this) return *this;
- TObject::operator=(source);
+ AliVEvent::operator=(source);
fESDRun = new AliESDRun(*source.fESDRun);
fHeader = new AliESDHeader(*source.fHeader);
AddObject(fCaloClusters);
AddObject(fErrorLogs);
-
+ fConnected = source.fConnected;
fEMCALClusters = source.fEMCALClusters;
fFirstEMCALCluster = source.fFirstEMCALCluster;
fPHOSClusters = source.fPHOSClusters;
//
// everthing on the list gets deleted automatically
- delete fESDObjects;
- fESDObjects = 0;
+
+
+ if(fESDObjects&&!fConnected)
+ {
+ delete fESDObjects;
+ fESDObjects = 0;
+ }
+
+
}
//______________________________________________________________________________
if(fESDTZERO) fESDTZERO->Reset();
// CKB no clear/reset implemented
if(fSPDVertex){
+ fSPDVertex->~AliESDVertex();
new (fSPDVertex) AliESDVertex();
- fSPDVertex->SetName("SPDVertex");
+ fSPDVertex->SetName(fESDListName[kSPDVertex]);
}
if(fPrimaryVertex){
+ fPrimaryVertex->~AliESDVertex();
new (fPrimaryVertex) AliESDVertex();
- fPrimaryVertex->SetName("PrimaryVertex");
+ fPrimaryVertex->SetName(fESDListName[kPrimaryVertex]);
+ }
+ if(fSPDMult){
+ fSPDMult->~AliMultiplicity();
+ new (fSPDMult) AliMultiplicity();
}
- if(fSPDMult)new (fSPDMult) AliMultiplicity();
if(fPHOSTrigger)fPHOSTrigger->Reset();
if(fEMCALTrigger)fEMCALTrigger->Reset();
- if(fTracks)fTracks->Clear();
+ if(fTracks)fTracks->Delete();
if(fMuonTracks)fMuonTracks->Clear();
if(fPmdTracks)fPmdTracks->Clear();
if(fTrdTracks)fTrdTracks->Clear();
if(fV0s)fV0s->Clear();
if(fCascades)fCascades->Clear();
if(fKinks)fKinks->Clear();
- if(fCaloClusters)fCaloClusters->Clear();
- if(fErrorLogs) fErrorLogs->Clear();
+ if(fCaloClusters)fCaloClusters->Delete();
+ if(fErrorLogs) fErrorLogs->Delete();
+
+ // don't reset fconnected fConnected ;
fEMCALClusters=0;
fFirstEMCALCluster=-1;
printf(" emcal %d\n", GetNumberOfEMCALClusters());
printf(" FMD %s\n", (fESDFMD ? "yes" : "no"));
printf(" VZERO %s\n", (fESDVZERO ? "yes" : "no"));
+
+ return;
}
void AliESDEvent::SetESDfriend(const AliESDfriend *ev) {
// to be sure that we set the tracks also
// in case of old esds
- if(fESDOld)CopyFromOldESD();
+ // if(fESDOld)CopyFromOldESD();
Int_t ntrk=ev->GetNumberOfTracks();
}
}
+Bool_t AliESDEvent::RemoveTrack(Int_t rm) {
+ // ---------------------------------------------------------
+ // Remove a track and references to it from ESD,
+ // if this track does not come from a reconstructed decay
+ // ---------------------------------------------------------
+ Int_t last=GetNumberOfTracks()-1;
+ if ((rm<0)||(rm>last)) return kFALSE;
+
+ Int_t used=0;
+
+ // Check if this track comes from a reconstructed decay
+ Int_t nv0=GetNumberOfV0s();
+ for (Int_t n=0; n<nv0; n++) {
+ AliESDv0 *v0=GetV0(n);
+
+ Int_t idx=v0->GetNindex();
+ if (rm==idx) return kFALSE;
+ if (idx==last) used++;
+
+ idx=v0->GetPindex();
+ if (rm==idx) return kFALSE;
+ if (idx==last) used++;
+ }
+
+ Int_t ncs=GetNumberOfCascades();
+ for (Int_t n=0; n<ncs; n++) {
+ AliESDcascade *cs=GetCascade(n);
+
+ Int_t idx=cs->GetIndex();
+ if (rm==idx) return kFALSE;
+ if (idx==last) used++;
+ }
+
+ Int_t nkn=GetNumberOfKinks();
+ for (Int_t n=0; n<nkn; n++) {
+ AliESDkink *kn=GetKink(n);
+
+ Int_t idx=kn->GetIndex(0);
+ if (rm==idx) return kFALSE;
+ if (idx==last) used++;
+
+ idx=kn->GetIndex(1);
+ if (rm==idx) return kFALSE;
+ if (idx==last) used++;
+ }
+
+
+ //Replace the removed track with the last track
+ TClonesArray &a=*fTracks;
+ delete a.RemoveAt(rm);
+
+ if (rm==last) return kTRUE;
+
+ AliESDtrack *t=GetTrack(last);
+ t->SetID(rm);
+ new (a[rm]) AliESDtrack(*t);
+ delete a.RemoveAt(last);
+
+ if (!used) return kTRUE;
+
+
+ // Remap the indices of the daughters of reconstructed decays
+ for (Int_t n=0; n<nv0; n++) {
+ AliESDv0 *v0=GetV0(n);
+ if (v0->GetIndex(0)==last) {
+ v0->SetIndex(0,rm);
+ used--;
+ if (!used) return kTRUE;
+ }
+ if (v0->GetIndex(1)==last) {
+ v0->SetIndex(1,rm);
+ used--;
+ if (!used) return kTRUE;
+ }
+ }
+
+ for (Int_t n=0; n<ncs; n++) {
+ AliESDcascade *cs=GetCascade(n);
+ if (cs->GetIndex()==last) {
+ cs->SetIndex(rm);
+ used--;
+ if (!used) return kTRUE;
+ }
+ }
+
+ for (Int_t n=0; n<nkn; n++) {
+ AliESDkink *kn=GetKink(n);
+ if (kn->GetIndex(0)==last) {
+ kn->SetIndex(rm,0);
+ used--;
+ if (!used) return kTRUE;
+ }
+ if (kn->GetIndex(1)==last) {
+ kn->SetIndex(rm,1);
+ used--;
+ if (!used) return kTRUE;
+ }
+ }
+
+ return kTRUE;
+}
+
+
+Bool_t AliESDEvent::Clean(Float_t *cleanPars) {
+ //
+ // Remove the data which are not needed for the physics analysis.
+ //
+ // If track's transverse parameter is larger than fDmax
+ // OR
+ // track's longitudinal parameter is larger than fZmax
+ // an attempt to remove this track from ESD is made.
+ //
+ // The track gets removed if it does not come
+ // from a reconstructed decay
+ //
+
+ Float_t dmax=cleanPars[0], zmax=cleanPars[1];
+
+ const AliESDVertex *vertex=GetVertex();
+ Bool_t vtxOK=vertex->GetStatus(), rc=kFALSE;
+
+ Int_t nTracks=GetNumberOfTracks();
+ for (Int_t i=nTracks-1; i>=0; i--) {
+ AliESDtrack *track=GetTrack(i);
+ Float_t xy,z; track->GetImpactParameters(xy,z);
+ if ((TMath::Abs(xy) > dmax) || (vtxOK && (TMath::Abs(z) > zmax))) {
+ if (RemoveTrack(i)) rc=kTRUE;
+ }
+ }
+
+ return rc;
+}
+
Int_t AliESDEvent::AddTrack(const AliESDtrack *t) {
// Add track
TClonesArray &ftr = *fTracks;
return track->GetID();
}
+ void AliESDEvent::AddMuonTrack(const AliESDMuonTrack *t) {
+ TClonesArray &fmu = *fMuonTracks;
+ new(fmu[fMuonTracks->GetEntriesFast()]) AliESDMuonTrack(*t);
+}
+
+void AliESDEvent::AddPmdTrack(const AliESDPmdTrack *t) {
+ TClonesArray &fpmd = *fPmdTracks;
+ new(fpmd[fPmdTracks->GetEntriesFast()]) AliESDPmdTrack(*t);
+}
+
+void AliESDEvent::AddTrdTrack(const AliESDTrdTrack *t) {
+ TClonesArray &ftrd = *fTrdTracks;
+ new(ftrd[fTrdTracks->GetEntriesFast()]) AliESDTrdTrack(*t);
+}
+
+
+
+
Int_t AliESDEvent::AddKink(const AliESDkink *c) {
// Add kink
TClonesArray &fk = *fKinks;
return fKinks->GetEntriesFast()-1;
}
+
+void AliESDEvent::AddCascade(const AliESDcascade *c) {
+ TClonesArray &fc = *fCascades;
+ new(fc[fCascades->GetEntriesFast()]) AliESDcascade(*c);
+}
+
+
Int_t AliESDEvent::AddCaloCluster(const AliESDCaloCluster *c) {
// Add calocluster
TClonesArray &fc = *fCaloClusters;
}
+ void AliESDEvent::AddRawDataErrorLog(const AliRawDataErrorLog *log) {
+ TClonesArray &errlogs = *fErrorLogs;
+ new(errlogs[errlogs.GetEntriesFast()]) AliRawDataErrorLog(*log);
+ }
+
+void AliESDEvent::SetVertex(const AliESDVertex *vertex) {
+ // use already allocated space
+ if(fSPDVertex){
+ *fSPDVertex = *vertex;
+ fSPDVertex->SetName(fESDListName[kSPDVertex]);
+ }
+}
+
+void AliESDEvent::SetPrimaryVertex(const AliESDVertex *vertex) {
+ if(fPrimaryVertex){
+ *fPrimaryVertex = *vertex;
+ fPrimaryVertex->SetName(fESDListName[kPrimaryVertex]);
+ }
+}
+
+void AliESDEvent::SetMultiplicity(const AliMultiplicity *mul) {
+ if(fSPDMult){
+ *fSPDMult = *mul;
+ }
+}
+
+
void AliESDEvent::SetFMDData(AliESDFMD * obj) {
// use already allocated space
if(fESDFMD){
- new(fESDFMD) AliESDFMD(*obj);
+ *fESDFMD = *obj;
}
}
Int_t ntrk=GetNumberOfTracks();
for (Int_t i=0; i<ntrk; i++) {
- const AliESDtrack *t=GetTrack(i);
+ AliESDtrack *t=GetTrack(i);
const AliESDfriendTrack *f=t->GetFriendTrack();
ev->AddTrack(f);
+
+ t->ReleaseESDfriendTrack();// Not to have two copies of "friendTrack"
+
}
}
void AliESDEvent::GetStdContent()
{
// set pointers for standard content
- // eventually get by name?
- fESDRun = (AliESDRun*)fESDObjects->At(kESDRun);
- fHeader = (AliESDHeader*)fESDObjects->At(kHeader);
- fESDZDC = (AliESDZDC*)fESDObjects->At(kESDZDC);
- fESDFMD = (AliESDFMD*)fESDObjects->At(kESDFMD);
- fESDVZERO = (AliESDVZERO*)fESDObjects->At(kESDVZERO);
- fESDTZERO = (AliESDTZERO*)fESDObjects->At(kESDTZERO);
- fSPDVertex = (AliESDVertex*)fESDObjects->At(kSPDVertex);
- fPrimaryVertex = (AliESDVertex*)fESDObjects->At(kPrimaryVertex);
- fSPDMult = (AliMultiplicity*)fESDObjects->At(kSPDMult);
- fPHOSTrigger = (AliESDCaloTrigger*)fESDObjects->At(kPHOSTrigger);
- fEMCALTrigger = (AliESDCaloTrigger*)fESDObjects->At(kEMCALTrigger);
- fTracks = (TClonesArray*)fESDObjects->At(kTracks);
- fMuonTracks = (TClonesArray*)fESDObjects->At(kMuonTracks);
- fPmdTracks = (TClonesArray*)fESDObjects->At(kPmdTracks);
- fTrdTracks = (TClonesArray*)fESDObjects->At(kTrdTracks);
- fV0s = (TClonesArray*)fESDObjects->At(kV0s);
- fCascades = (TClonesArray*)fESDObjects->At(kCascades);
- fKinks = (TClonesArray*)fESDObjects->At(kKinks);
- fCaloClusters = (TClonesArray*)fESDObjects->At(kCaloClusters);
- fErrorLogs = (TClonesArray*)fESDObjects->At(kErrorLogs);
+ // get by name much safer and not a big overhead since not called very often
+
+ fESDRun = (AliESDRun*)fESDObjects->FindObject(fESDListName[kESDRun]);
+ fHeader = (AliESDHeader*)fESDObjects->FindObject(fESDListName[kHeader]);
+ fESDZDC = (AliESDZDC*)fESDObjects->FindObject(fESDListName[kESDZDC]);
+ fESDFMD = (AliESDFMD*)fESDObjects->FindObject(fESDListName[kESDFMD]);
+ fESDVZERO = (AliESDVZERO*)fESDObjects->FindObject(fESDListName[kESDVZERO]);
+ fESDTZERO = (AliESDTZERO*)fESDObjects->FindObject(fESDListName[kESDTZERO]);
+ fSPDVertex = (AliESDVertex*)fESDObjects->FindObject(fESDListName[kSPDVertex]);
+ fPrimaryVertex = (AliESDVertex*)fESDObjects->FindObject(fESDListName[kPrimaryVertex]);
+ fSPDMult = (AliMultiplicity*)fESDObjects->FindObject(fESDListName[kSPDMult]);
+ fPHOSTrigger = (AliESDCaloTrigger*)fESDObjects->FindObject(fESDListName[kPHOSTrigger]);
+ fEMCALTrigger = (AliESDCaloTrigger*)fESDObjects->FindObject(fESDListName[kEMCALTrigger]);
+ fTracks = (TClonesArray*)fESDObjects->FindObject(fESDListName[kTracks]);
+ fMuonTracks = (TClonesArray*)fESDObjects->FindObject(fESDListName[kMuonTracks]);
+ fPmdTracks = (TClonesArray*)fESDObjects->FindObject(fESDListName[kPmdTracks]);
+ fTrdTracks = (TClonesArray*)fESDObjects->FindObject(fESDListName[kTrdTracks]);
+ fV0s = (TClonesArray*)fESDObjects->FindObject(fESDListName[kV0s]);
+ fCascades = (TClonesArray*)fESDObjects->FindObject(fESDListName[kCascades]);
+ fKinks = (TClonesArray*)fESDObjects->FindObject(fESDListName[kKinks]);
+ fCaloClusters = (TClonesArray*)fESDObjects->FindObject(fESDListName[kCaloClusters]);
+ fErrorLogs = (TClonesArray*)fESDObjects->FindObject(fESDListName[kErrorLogs]);
}
void AliESDEvent::SetStdNames(){
// Set the names of the standard contents
- fSPDVertex->SetName("SPDVertex");
- fPrimaryVertex->SetName("PrimaryVertex");
- fPHOSTrigger->SetName("PHOSTrigger");
- fEMCALTrigger->SetName("EMCALTrigger");
- fTracks->SetName("Tracks");
- fMuonTracks->SetName("MuonTracks");
- fPmdTracks->SetName("PmdTracks");
- fTrdTracks->SetName("TrdTracks");
- fV0s->SetName("V0s");
- fCascades->SetName("Cascades");
- fKinks->SetName("Kinks");
- fCaloClusters->SetName("CaloClusters");
-
+ //
+ if(fESDObjects->GetEntries()==kESDListN){
+ for(int i = 0;i < fESDObjects->GetEntries();i++){
+ TObject *fObj = fESDObjects->At(i);
+ if(fObj->InheritsFrom("TNamed")){
+ ((TNamed*)fObj)->SetName(fESDListName[i]);
+ }
+ else if(fObj->InheritsFrom("TClonesArray")){
+ ((TClonesArray*)fObj)->SetName(fESDListName[i]);
+ }
+ }
+ }
+ else{
+ printf("%s:%d SetStdNames() Wrong number of Std Entries \n",(char*)__FILE__,__LINE__);
+ }
}
void AliESDEvent::CreateStdContent()
// check the order of the indices against enum...
- // read back pointers
- GetStdContent();
// set names
SetStdNames();
-
+ // read back pointers
+ GetStdContent();
}
TObject* AliESDEvent::FindListObject(const char *name){
return 0;
}
+Int_t AliESDEvent::GetPHOSClusters(TRefArray *clusters) const
+{
+ // fills the provided TRefArray with all found phos clusters
+
+ clusters->Clear();
+
+ AliESDCaloCluster *cl = 0;
+ for (Int_t i = 0; i < GetNumberOfCaloClusters(); i++) {
+
+ if ( cl = GetCaloCluster(i)) {
+ if (cl->IsPHOS()){
+ clusters->Add(cl);
+ printf("IsPHOS %d Size: %d \n",i,clusters->GetEntriesFast());
+ }
+ }
+ }
+ return clusters->GetEntriesFast();
+}
+
+Int_t AliESDEvent::GetEMCALClusters(TRefArray *clusters) const
+{
+ // fills the provided TRefArray with all found phos clusters
+
+ clusters->Clear();
+
+ AliESDCaloCluster *cl = 0;
+ for (Int_t i = 0; i < GetNumberOfCaloClusters(); i++) {
+
+ if ( cl = GetCaloCluster(i)) {
+ if (cl->IsEMCAL()){
+ clusters->Add(cl);
+ printf("IsEMCAL %d Size: %d \n",i,clusters->GetEntriesFast());
+ }
+ }
+ }
+ return clusters->GetEntriesFast();
+}
+
+
void AliESDEvent::ReadFromTree(TTree *tree){
-
-
+
+ // load the TTree
+ tree->LoadTree(0);
+
// if we find the "ESD" branch on the tree we do have the old structure
if(tree->GetBranch("ESD")){
char ** address = (char **)(tree->GetBranch("ESD")->GetAddress());
if(esdEvent){
// Check if already connected to tree
-// TList* connectedList = (TList*) (tree->GetTree()->GetUserInfo()->FindObject("ESDObjectsConnectedToTree"));
- TList* connectedList = (TList*) (tree->GetUserInfo()->FindObject("ESDObjectsConnectedToTree"));
- if (connectedList) {
- // If connected use the connected list if objects
- fESDObjects->Delete();
- fESDObjects = connectedList;
- GetStdContent();
- return;
- }
- // Connect to tree
+ TList* connectedList = (TList*) (tree->GetUserInfo()->FindObject("ESDObjectsConnectedToTree"));
+ if (connectedList) {
+ // If connected use the connected list if objects
+ fESDObjects->Delete();
+ fESDObjects = connectedList;
+ GetStdContent();
+ fConnected = true;
+ return;
+ }
+ // Connect to tree
if(fESDObjects->GetEntries()!=0){
// this should not happen here put a warning?
}
// create a new TList from the UserInfo TList...
// copy constructor does not work...
fESDObjects = (TList*)(esdEvent->GetList()->Clone());
+ fESDObjects->SetOwner(kFALSE);
if(fESDObjects->GetEntries()<kESDListN){
printf("%s %d AliESDEvent::ReadFromTree() TList contains less than the standard contents %d < %d \n",
(char*)__FILE__,__LINE__,fESDObjects->GetEntries(),kESDListN);
// when reading back we are not owner of the list
// must not delete it
fESDObjects->SetOwner(kFALSE);
- // Add list to user info
fESDObjects->SetName("ESDObjectsConnectedToTree");
+ // we are not owner of the list objects
+ // must not delete it
tree->GetUserInfo()->Add(fESDObjects);
+ fConnected = true;
}// no esdEvent
else {
// we can't get the list from the user data, create standard content
// FMD
- SetFMDData(fESDOld->GetFMDData());
+ if(fESDOld->GetFMDData())SetFMDData(fESDOld->GetFMDData());
// T0
// leave amps out
// VZERO
- SetVZEROData(fESDOld->GetVZEROData());
+ if (fESDOld->GetVZEROData()) SetVZEROData(fESDOld->GetVZEROData());
- SetVertex(fESDOld->GetVertex());
+ if(fESDOld->GetVertex())SetVertex(fESDOld->GetVertex());
- SetPrimaryVertex(fESDOld->GetPrimaryVertex());
+ if(fESDOld->GetPrimaryVertex())SetPrimaryVertex(fESDOld->GetPrimaryVertex());
- SetMultiplicity(fESDOld->GetMultiplicity());
+ if(fESDOld->GetMultiplicity())SetMultiplicity(fESDOld->GetMultiplicity());
for(int i = 0;i<fESDOld->GetNumberOfTracks();i++){
AddTrack(fESDOld->GetTrack(i));