X-Git-Url: http://git.uio.no/git/?a=blobdiff_plain;f=STEER%2FAliESDEvent.cxx;h=a3082187bbb061d73e5e1af7f1e362ea7167754f;hb=fb3430ac68b6928f9e0d35e74bf71f65785c98a5;hp=ac57bd4734b2040737235a962187971eefa99103;hpb=7f68891d8a42e64b1197c3e0deb8348a6bcd6ac0;p=u%2Fmrichter%2FAliRoot.git diff --git a/STEER/AliESDEvent.cxx b/STEER/AliESDEvent.cxx index ac57bd4734b..a3082187bbb 100644 --- a/STEER/AliESDEvent.cxx +++ b/STEER/AliESDEvent.cxx @@ -17,19 +17,30 @@ //----------------------------------------------------------------- // Implementation of the AliESDEvent class -// This is the class to deal with during the phisical analysis of data. +// This is the class to deal with during the physics analysis of data. // It also ensures the backward compatibility with the old ESD format. +/* + AliESDEvent *ev= new AliESDEvent(); + ev->ReadFromTree(esdTree); + ... + for (Int_t i=0; iGetEntry(i); + if(ev->GetAliESDOld())ev->CopyFromOldESD(); +*/ +// The AliESDInputHandler does this automatically for you // // Origin: Christian Klein-Boesing, CERN, Christian.Klein-Boesing@cern.ch //----------------------------------------------------------------- #include "TList.h" +#include "TRefArray.h" #include +#include +#include #include "AliESDEvent.h" #include "AliESDfriend.h" #include "AliESDVZERO.h" -#include "AliESDHLTtrack.h" #include "AliESDFMD.h" #include "AliESD.h" #include "AliESDMuonTrack.h" @@ -40,17 +51,22 @@ #include "AliESDPmdTrack.h" #include "AliESDTrdTrack.h" #include "AliESDVertex.h" +#include "AliVertexerTracks.h" #include "AliESDcascade.h" #include "AliESDkink.h" #include "AliESDtrack.h" #include "AliESDHLTtrack.h" #include "AliESDCaloCluster.h" +#include "AliESDCaloCells.h" #include "AliESDv0.h" #include "AliESDFMD.h" #include "AliESDVZERO.h" #include "AliMultiplicity.h" #include "AliRawDataErrorLog.h" - +#include "AliLog.h" +#include "AliESDACORDE.h" +#include "AliESDHLTDecision.h" +#include "AliCentrality.h" ClassImp(AliESDEvent) @@ -58,26 +74,34 @@ 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"}; + const char* AliESDEvent::fgkESDListName[kESDListN] = {"AliESDRun", + "AliESDHeader", + "AliESDZDC", + "AliESDFMD", + "AliESDVZERO", + "AliESDTZERO", + "TPCVertex", + "SPDVertex", + "PrimaryVertex", + "AliMultiplicity", + "PHOSTrigger", + "EMCALTrigger", + "SPDPileupVertices", + "TrkPileupVertices", + "Tracks", + "MuonTracks", + "PmdTracks", + "TrdTracks", + "V0s", + "Cascades", + "Kinks", + "CaloClusters", + "EMCALCells", + "PHOSCells", + "AliRawDataErrorLogs", + "AliESDACORDE", + "AliTOFHeader"}; + //______________________________________________________________________________ AliESDEvent::AliESDEvent(): AliVEvent(), @@ -88,11 +112,15 @@ AliESDEvent::AliESDEvent(): fESDFMD(0), fESDVZERO(0), fESDTZERO(0), + fTPCVertex(0), fSPDVertex(0), fPrimaryVertex(0), fSPDMult(0), fPHOSTrigger(0), fEMCALTrigger(0), + fESDACORDE(0), + fSPDPileupVertices(0), + fTrkPileupVertices(0), fTracks(0), fMuonTracks(0), fPmdTracks(0), @@ -101,13 +129,14 @@ AliESDEvent::AliESDEvent(): fCascades(0), fKinks(0), fCaloClusters(0), + fEMCALCells(0), fPHOSCells(0), fErrorLogs(0), fESDOld(0), + fESDFriendOld(0), fConnected(kFALSE), - fEMCALClusters(0), - fFirstEMCALCluster(-1), - fPHOSClusters(0), - fFirstPHOSCluster(-1) + fUseOwnList(kFALSE), + fTOFHeader(0), + fCentrality(0) { } //______________________________________________________________________________ @@ -120,11 +149,15 @@ AliESDEvent::AliESDEvent(const AliESDEvent& esd): fESDFMD(new AliESDFMD(*esd.fESDFMD)), fESDVZERO(new AliESDVZERO(*esd.fESDVZERO)), fESDTZERO(new AliESDTZERO(*esd.fESDTZERO)), + fTPCVertex(new AliESDVertex(*esd.fTPCVertex)), fSPDVertex(new AliESDVertex(*esd.fSPDVertex)), fPrimaryVertex(new AliESDVertex(*esd.fPrimaryVertex)), fSPDMult(new AliMultiplicity(*esd.fSPDMult)), fPHOSTrigger(new AliESDCaloTrigger(*esd.fPHOSTrigger)), fEMCALTrigger(new AliESDCaloTrigger(*esd.fEMCALTrigger)), + fESDACORDE(new AliESDACORDE(*esd.fESDACORDE)), + fSPDPileupVertices(new TClonesArray(*esd.fSPDPileupVertices)), + fTrkPileupVertices(new TClonesArray(*esd.fTrkPileupVertices)), fTracks(new TClonesArray(*esd.fTracks)), fMuonTracks(new TClonesArray(*esd.fMuonTracks)), fPmdTracks(new TClonesArray(*esd.fPmdTracks)), @@ -133,14 +166,15 @@ AliESDEvent::AliESDEvent(const AliESDEvent& esd): fCascades(new TClonesArray(*esd.fCascades)), fKinks(new TClonesArray(*esd.fKinks)), fCaloClusters(new TClonesArray(*esd.fCaloClusters)), + fEMCALCells(new AliESDCaloCells(*esd.fEMCALCells)), + fPHOSCells(new AliESDCaloCells(*esd.fPHOSCells)), fErrorLogs(new TClonesArray(*esd.fErrorLogs)), - fESDOld(new AliESD(*esd.fESDOld)), + fESDOld(esd.fESDOld ? new AliESD(*esd.fESDOld) : 0), + fESDFriendOld(esd.fESDFriendOld ? new AliESDfriend(*esd.fESDFriendOld) : 0), fConnected(esd.fConnected), - fEMCALClusters(esd.fEMCALClusters), - fFirstEMCALCluster(esd.fFirstEMCALCluster), - fPHOSClusters(esd.fPHOSClusters), - fFirstPHOSCluster(esd.fFirstPHOSCluster) - + fUseOwnList(esd.fUseOwnList), + fTOFHeader(new AliTOFHeader(*esd.fTOFHeader)), + fCentrality(new AliCentrality(*esd.fCentrality)) { // CKB init in the constructor list and only add here ... AddObject(fESDRun); @@ -149,11 +183,14 @@ AliESDEvent::AliESDEvent(const AliESDEvent& esd): AddObject(fESDFMD); AddObject(fESDVZERO); AddObject(fESDTZERO); + AddObject(fTPCVertex); AddObject(fSPDVertex); AddObject(fPrimaryVertex); AddObject(fSPDMult); AddObject(fPHOSTrigger); AddObject(fEMCALTrigger); + AddObject(fSPDPileupVertices); + AddObject(fTrkPileupVertices); AddObject(fTracks); AddObject(fMuonTracks); AddObject(fPmdTracks); @@ -162,7 +199,11 @@ AliESDEvent::AliESDEvent(const AliESDEvent& esd): AddObject(fCascades); AddObject(fKinks); AddObject(fCaloClusters); + AddObject(fEMCALCells); + AddObject(fPHOSCells); AddObject(fErrorLogs); + AddObject(fESDACORDE); + AddObject(fTOFHeader); GetStdContent(); @@ -176,62 +217,91 @@ AliESDEvent & AliESDEvent::operator=(const AliESDEvent& source) { if(&source == this) return *this; AliVEvent::operator=(source); - fESDRun = new AliESDRun(*source.fESDRun); - fHeader = new AliESDHeader(*source.fHeader); - fESDZDC = new AliESDZDC(*source.fESDZDC); - fESDFMD = new AliESDFMD(*source.fESDFMD); - fESDVZERO = new AliESDVZERO(*source.fESDVZERO); - fESDTZERO = new AliESDTZERO(*source.fESDTZERO); - fSPDVertex = new AliESDVertex(*source.fSPDVertex); - fPrimaryVertex = new AliESDVertex(*source.fPrimaryVertex); - fSPDMult = new AliMultiplicity(*source.fSPDMult); - fPHOSTrigger = new AliESDCaloTrigger(*source.fPHOSTrigger); - fEMCALTrigger = new AliESDCaloTrigger(*source.fEMCALTrigger); - fTracks = new TClonesArray(*source.fTracks); - fMuonTracks = new TClonesArray(*source.fMuonTracks); - fPmdTracks = new TClonesArray(*source.fPmdTracks); - fTrdTracks = new TClonesArray(*source.fTrdTracks); - fV0s = new TClonesArray(*source.fV0s); - fCascades = new TClonesArray(*source.fCascades); - fKinks = new TClonesArray(*source.fKinks); - fCaloClusters = new TClonesArray(*source.fCaloClusters); - fErrorLogs = new TClonesArray(*source.fErrorLogs); - fESDOld = new AliESD(*source.fESDOld); - // CKB this way?? or - // or AddObject( fESDZDC = new AliESDZDC(*source.fESDZDC)); - - fESDObjects = new TList(); - AddObject(fESDRun); - AddObject(fHeader); - AddObject(fESDZDC); - AddObject(fESDFMD); - AddObject(fESDVZERO); - AddObject(fESDTZERO); - AddObject(fSPDVertex); - AddObject(fPrimaryVertex); - AddObject(fSPDMult); - AddObject(fPHOSTrigger); - AddObject(fEMCALTrigger); - AddObject(fTracks); - AddObject(fMuonTracks); - AddObject(fPmdTracks); - AddObject(fTrdTracks); - AddObject(fV0s); - AddObject(fCascades); - AddObject(fKinks); - AddObject(fCaloClusters); - AddObject(fErrorLogs); + // This assumes that the list is already created + // and that the virtual void Copy(Tobject&) function + // is correctly implemented in the derived class + // otherwise only TObject::Copy() will be used - fConnected = source.fConnected; - fEMCALClusters = source.fEMCALClusters; - fFirstEMCALCluster = source.fFirstEMCALCluster; - fPHOSClusters = source.fPHOSClusters; - fFirstPHOSCluster = source.fFirstPHOSCluster; + if((fESDObjects->GetSize()==0)&&(source.fESDObjects->GetSize()>=kESDListN)){ + // We cover the case that we do not yet have the + // standard content but the source has it + CreateStdContent(); + } - return *this; + TIter next(source.GetList()); + TObject *its = 0; + TString name; + while ((its = next())) { + name.Form("%s", its->GetName()); + TObject *mine = fESDObjects->FindObject(name.Data()); + if(!mine){ + TClass* pClass=TClass::GetClass(its->ClassName()); + if (!pClass) { + AliWarning(Form("Can not find class description for entry %s (%s)\n", + its->ClassName(), name.Data())); + continue; + } + mine=(TObject*)pClass->New(); + if(!mine){ + // not in this: can be added to list + AliWarning(Form("%s:%d Could not find %s for copying \n", + (char*)__FILE__,__LINE__,name.Data())); + continue; + } + if(mine->InheritsFrom("TNamed")){ + ((TNamed*)mine)->SetName(name); + } + else if(mine->InheritsFrom("TCollection")){ + if(mine->InheritsFrom("TClonesArray")) { + TClonesArray* tcits = dynamic_cast(its); + if (tcits) + dynamic_cast(mine)->SetClass(tcits->GetClass()); + } + dynamic_cast(mine)->SetName(name); + } + AliDebug(1, Form("adding object %s of type %s", mine->GetName(), mine->ClassName())); + AddObject(mine); + } + + if(!its->InheritsFrom("TCollection")){ + // simple objects + its->Copy(*mine); + } + else if(its->InheritsFrom("TClonesArray")){ + // Create or expand the tclonesarray pointers + // so we can directly copy to the object + TClonesArray *its_tca = (TClonesArray*)its; + TClonesArray *mine_tca = (TClonesArray*)mine; + + // this leaves the capacity of the TClonesArray the same + // except for a factor of 2 increase when size > capacity + // does not release any memory occupied by the tca + mine_tca->ExpandCreate(its_tca->GetEntriesFast()); + for(int i = 0;i < its_tca->GetEntriesFast();++i){ + // copy + TObject *mine_tca_obj = mine_tca->At(i); + TObject *its_tca_obj = its_tca->At(i); + // no need to delete first + // pointers within the class should be handled by Copy()... + // Can there be Empty slots? + its_tca_obj->Copy(*mine_tca_obj); + } + } + else{ + AliWarning(Form("%s:%d cannot copy TCollection \n", + (char*)__FILE__,__LINE__)); + } + } + + fCentrality = source.fCentrality; + + fConnected = source.fConnected; + fUseOwnList = source.fUseOwnList; + + return *this; } @@ -250,20 +320,80 @@ AliESDEvent::~AliESDEvent() delete fESDObjects; fESDObjects = 0; } - + if (fCentrality) delete fCentrality; } +void AliESDEvent::Copy(TObject &obj) const { + + // interface to TOBject::Copy + // Copies the content of this into obj! + // bascially obj = *this + + if(this==&obj)return; + AliESDEvent *robj = dynamic_cast(&obj); + if(!robj)return; // not an AliESEvent + *robj = *this; + return; +} + //______________________________________________________________________________ void AliESDEvent::Reset() { - + // Handle the cases + // Std content + Non std content + // Reset the standard contents ResetStdContent(); + // reset for the old data without AliESDEvent... if(fESDOld)fESDOld->Reset(); - // call reset for user supplied data? + if(fESDFriendOld){ + fESDFriendOld->~AliESDfriend(); + new (fESDFriendOld) AliESDfriend(); + } + // + + if(fESDObjects->GetSize()>kESDListN){ + // we have non std content + // this also covers esdfriends + for(int i = kESDListN;i < fESDObjects->GetSize();++i){ + TObject *pObject = fESDObjects->At(i); + // TClonesArrays + if(pObject->InheritsFrom(TClonesArray::Class())){ + ((TClonesArray*)pObject)->Delete(); + } + else if(!pObject->InheritsFrom(TCollection::Class())){ + TClass *pClass = TClass::GetClass(pObject->ClassName()); + if (pClass && pClass->GetListOfMethods()->FindObject("Clear")) { + AliDebug(1, Form("Clear for object %s class %s", pObject->GetName(), pObject->ClassName())); + pObject->Clear(); + } + else { + AliDebug(1, Form("ResetWithPlacementNew for object %s class %s", pObject->GetName(), pObject->ClassName())); + ResetWithPlacementNew(pObject); + } + } + else{ + AliWarning(Form("No reset for %s \n", + pObject->ClassName())); + } + } + } + +} + +Bool_t AliESDEvent::ResetWithPlacementNew(TObject *pObject){ + Long_t dtoronly = TObject::GetDtorOnly(); + TClass *pClass = TClass::GetClass(pObject->ClassName()); + TObject::SetDtorOnly(pObject); + delete pObject; + // Recreate with placement new + pClass->New(pObject); + // Restore the state. + TObject::SetDtorOnly((void*)dtoronly); + return kTRUE; } void AliESDEvent::ResetStdContent() @@ -272,43 +402,62 @@ void AliESDEvent::ResetStdContent() if(fESDRun) fESDRun->Reset(); if(fHeader) fHeader->Reset(); if(fESDZDC) fESDZDC->Reset(); - if(fESDFMD) fESDFMD->Clear(); // why clear.... need consistend names - // if(fESDVZERO) fESDVZERO->; // NOT IMPLEMENTED - // if(fESDVZERO) new (fESDVZERO) AliESDVZERO(); + if(fESDFMD) { + fESDFMD->Clear(); + } + if(fESDVZERO){ + // reset by callin d'to /c'tor keep the pointer + fESDVZERO->~AliESDVZERO(); + new (fESDVZERO) AliESDVZERO(); + } + if(fESDACORDE){ + fESDACORDE->~AliESDACORDE(); + new (fESDACORDE) AliESDACORDE(); + } if(fESDTZERO) fESDTZERO->Reset(); // CKB no clear/reset implemented + if(fTPCVertex){ + fTPCVertex->~AliESDVertex(); + new (fTPCVertex) AliESDVertex(); + fTPCVertex->SetName(fgkESDListName[kTPCVertex]); + } if(fSPDVertex){ fSPDVertex->~AliESDVertex(); new (fSPDVertex) AliESDVertex(); - fSPDVertex->SetName(fESDListName[kSPDVertex]); + fSPDVertex->SetName(fgkESDListName[kSPDVertex]); } if(fPrimaryVertex){ fPrimaryVertex->~AliESDVertex(); new (fPrimaryVertex) AliESDVertex(); - fPrimaryVertex->SetName(fESDListName[kPrimaryVertex]); + fPrimaryVertex->SetName(fgkESDListName[kPrimaryVertex]); } if(fSPDMult){ fSPDMult->~AliMultiplicity(); new (fSPDMult) AliMultiplicity(); } - if(fPHOSTrigger)fPHOSTrigger->Reset(); - if(fEMCALTrigger)fEMCALTrigger->Reset(); + if(fTOFHeader){ + fTOFHeader->~AliTOFHeader(); + new (fTOFHeader) AliTOFHeader(); + //fTOFHeader->SetName(fgkESDListName[kTOFHeader]); + } + if(fPHOSTrigger)fPHOSTrigger->DeAllocate(); + if(fEMCALTrigger)fEMCALTrigger->DeAllocate(); + if(fSPDPileupVertices)fSPDPileupVertices->Delete(); + if(fTrkPileupVertices)fTrkPileupVertices->Delete(); 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(fMuonTracks)fMuonTracks->Delete(); + if(fPmdTracks)fPmdTracks->Delete(); + if(fTrdTracks)fTrdTracks->Delete(); + if(fV0s)fV0s->Delete(); + if(fCascades)fCascades->Delete(); + if(fKinks)fKinks->Delete(); if(fCaloClusters)fCaloClusters->Delete(); + if(fPHOSCells)fPHOSCells->DeleteContainer(); + if(fEMCALCells)fEMCALCells->DeleteContainer(); if(fErrorLogs) fErrorLogs->Delete(); - // don't reset fconnected fConnected ; + // don't reset fconnected fConnected and the list - fEMCALClusters=0; - fFirstEMCALCluster=-1; - fPHOSClusters=0; - fFirstPHOSCluster=-1; } @@ -337,14 +486,20 @@ void AliESDEvent::Print(Option_t *) const GetRunNumber(), GetTriggerMask(), GetMagneticField() ); - printf("Vertex: (%.4f +- %.4f, %.4f +- %.4f, %.4f +- %.4f) cm\n", + if (fPrimaryVertex) + printf("Vertex: (%.4f +- %.4f, %.4f +- %.4f, %.4f +- %.4f) cm\n", fPrimaryVertex->GetXv(), fPrimaryVertex->GetXRes(), fPrimaryVertex->GetYv(), fPrimaryVertex->GetYRes(), fPrimaryVertex->GetZv(), fPrimaryVertex->GetZRes()); - printf("Mean vertex in RUN: X=%.4f Y=%.4f cm\n", - GetDiamondX(),GetDiamondY()); + printf("Mean vertex in RUN: X=%.4f Y=%.4f Z=%.4f cm\n", + GetDiamondX(),GetDiamondY(),GetDiamondZ()); + if(fSPDMult) printf("SPD Multiplicity. Number of tracklets %d \n", fSPDMult->GetNumberOfTracklets()); + printf("Number of pileup primary vertices reconstructed with SPD %d\n", + GetNumberOfPileupVerticesSPD()); + printf("Number of pileup primary vertices reconstructed using the tracks %d\n", + GetNumberOfPileupVerticesTracks()); printf("Number of tracks: \n"); printf(" charged %d\n", GetNumberOfTracks()); printf(" muon %d\n", GetNumberOfMuonTracks()); @@ -353,16 +508,21 @@ void AliESDEvent::Print(Option_t *) const printf(" v0 %d\n", GetNumberOfV0s()); printf(" cascades %d\n", GetNumberOfCascades()); printf(" kinks %d\n", GetNumberOfKinks()); + if(fPHOSCells)printf(" PHOSCells %d\n", fPHOSCells->GetNumberOfCells()); + else printf(" PHOSCells not in the Event\n"); + if(fEMCALCells)printf(" EMCALCells %d\n", fEMCALCells->GetNumberOfCells()); + else printf(" EMCALCells not in the Event\n"); printf(" CaloClusters %d\n", GetNumberOfCaloClusters()); - printf(" phos %d\n", GetNumberOfPHOSClusters()); - printf(" emcal %d\n", GetNumberOfEMCALClusters()); printf(" FMD %s\n", (fESDFMD ? "yes" : "no")); printf(" VZERO %s\n", (fESDVZERO ? "yes" : "no")); + TObject* pHLTDecision=GetHLTTriggerDecision(); + printf("HLT trigger decision: %s\n", pHLTDecision?pHLTDecision->GetOption():"not available"); + if (pHLTDecision) pHLTDecision->Print("compact"); return; } -void AliESDEvent::SetESDfriend(const AliESDfriend *ev) { +void AliESDEvent::SetESDfriend(const AliESDfriend *ev) const { // // Attaches the complementary info to the ESD // @@ -380,7 +540,83 @@ void AliESDEvent::SetESDfriend(const AliESDfriend *ev) { } } -Bool_t AliESDEvent::RemoveTrack(Int_t rm) { +Bool_t AliESDEvent::RemoveKink(Int_t rm) const { + // --------------------------------------------------------- + // Remove a kink candidate and references to it from ESD, + // if this candidate does not come from a reconstructed decay + // Not yet implemented... + // --------------------------------------------------------- + Int_t last=GetNumberOfKinks()-1; + if ((rm<0)||(rm>last)) return kFALSE; + + return kTRUE; +} + +Bool_t AliESDEvent::RemoveV0(Int_t rm) const { + // --------------------------------------------------------- + // Remove a V0 candidate and references to it from ESD, + // if this candidate does not come from a reconstructed decay + // --------------------------------------------------------- + Int_t last=GetNumberOfV0s()-1; + if ((rm<0)||(rm>last)) return kFALSE; + + AliESDv0 *v0=GetV0(rm); + Int_t idxP=v0->GetPindex(), idxN=v0->GetNindex(); + + v0=GetV0(last); + Int_t lastIdxP=v0->GetPindex(), lastIdxN=v0->GetNindex(); + + Int_t used=0; + + // Check if this V0 comes from a reconstructed decay + Int_t ncs=GetNumberOfCascades(); + for (Int_t n=0; nGetPindex(); + Int_t csIdxN=cs->GetNindex(); + + if (idxP==csIdxP) + if (idxN==csIdxN) return kFALSE; + + if (csIdxP==lastIdxP) + if (csIdxN==lastIdxN) used++; + } + + //Replace the removed V0 with the last V0 + TClonesArray &a=*fV0s; + delete a.RemoveAt(rm); + + if (rm==last) return kTRUE; + + //v0 is pointing to the last V0 candidate... + new (a[rm]) AliESDv0(*v0); + delete a.RemoveAt(last); + + if (!used) return kTRUE; + + + // Remap the indices of the daughters of reconstructed decays + for (Int_t n=0; nGetPindex(); + Int_t csIdxN=cs->GetNindex(); + + if (csIdxP==lastIdxP) + if (csIdxN==lastIdxN) { + cs->AliESDv0::SetIndex(1,idxP); + cs->AliESDv0::SetIndex(0,idxN); + used--; + if (!used) return kTRUE; + } + } + + return kTRUE; +} + +Bool_t AliESDEvent::RemoveTrack(Int_t rm) const { // --------------------------------------------------------- // Remove a track and references to it from ESD, // if this track does not come from a reconstructed decay @@ -390,6 +626,26 @@ Bool_t AliESDEvent::RemoveTrack(Int_t rm) { Int_t used=0; + // Check if this track comes from the reconstructed primary vertices + if (fTPCVertex && fTPCVertex->GetStatus()) { + UShort_t *primIdx=fTPCVertex->GetIndices(); + Int_t n=fTPCVertex->GetNIndices(); + while (n--) { + Int_t idx=Int_t(primIdx[n]); + if (rm==idx) return kFALSE; + if (idx==last) used++; + } + } + if (fPrimaryVertex && fPrimaryVertex->GetStatus()) { + UShort_t *primIdx=fPrimaryVertex->GetIndices(); + Int_t n=fPrimaryVertex->GetNIndices(); + while (n--) { + Int_t idx=Int_t(primIdx[n]); + if (rm==idx) return kFALSE; + if (idx==last) used++; + } + } + // Check if this track comes from a reconstructed decay Int_t nv0=GetNumberOfV0s(); for (Int_t n=0; nGetIndex(); if (rm==idx) return kFALSE; if (idx==last) used++; + + AliESDv0 *v0=cs; + 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 nkn=GetNumberOfKinks(); @@ -426,6 +691,20 @@ Bool_t AliESDEvent::RemoveTrack(Int_t rm) { if (idx==last) used++; } + // Check if this track is associated with a CaloCluster + Int_t ncl=GetNumberOfCaloClusters(); + for (Int_t n=0; nGetTracksMatched(); + Int_t s=arr->GetSize(); + while (s--) { + Int_t idx=arr->At(s); + if (rm==idx) return kFALSE; + if (idx==last) used++; + } + } + + //Replace the removed track with the last track TClonesArray &a=*fTracks; @@ -438,9 +717,36 @@ Bool_t AliESDEvent::RemoveTrack(Int_t rm) { new (a[rm]) AliESDtrack(*t); delete a.RemoveAt(last); + if (!used) return kTRUE; + // Remap the indices of the tracks used for the primary vertex reconstruction + if (fTPCVertex && fTPCVertex->GetStatus()) { + UShort_t *primIdx=fTPCVertex->GetIndices(); + Int_t n=fTPCVertex->GetNIndices(); + while (n--) { + Int_t idx=Int_t(primIdx[n]); + if (idx==last) { + primIdx[n]=Short_t(rm); + used--; + if (!used) return kTRUE; + } + } + } + if (fPrimaryVertex && fPrimaryVertex->GetStatus()) { + UShort_t *primIdx=fPrimaryVertex->GetIndices(); + Int_t n=fPrimaryVertex->GetNIndices(); + while (n--) { + Int_t idx=Int_t(primIdx[n]); + if (idx==last) { + primIdx[n]=Short_t(rm); + used--; + if (!used) return kTRUE; + } + } + } + // Remap the indices of the daughters of reconstructed decays for (Int_t n=0; nGetIndex(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; nGetTracksMatched(); + Int_t s=arr->GetSize(); + while (s--) { + Int_t idx=arr->At(s); + if (idx==last) { + arr->AddAt(rm,s); + used--; + if (!used) return kTRUE; + } + } + } + return kTRUE; } @@ -487,19 +819,52 @@ 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 + // 1) Cleaning the V0 candidates + // --------------------------- + // If the cosine of the V0 pointing angle "csp" and + // the DCA between the daughter tracks "dca" does not satisfy + // the conditions + // + // csp > cleanPars[1] + dca/cleanPars[0]*(1.- cleanPars[1]) + // + // an attempt to remove this V0 candidate from ESD is made. + // + // The V0 candidate gets removed if it does not belong to any + // recosntructed cascade decay + // + // 12.11.2007, optimal values: cleanPars[0]=0.5, cleanPars[1]=0.999 + // + // 2) Cleaning the tracks + // ---------------------- + // If track's transverse parameter is larger than cleanPars[2] // OR - // track's longitudinal parameter is larger than fZmax - // an attempt to remove this track from ESD is made. + // track's longitudinal parameter is larger than cleanPars[3] + // an attempt to remove this track from ESD is made. // - // The track gets removed if it does not come - // from a reconstructed decay + // The track gets removed if it does not come + // from a reconstructed decay // + Bool_t rc=kFALSE; + + Float_t dcaMax=cleanPars[0]; + Float_t cspMin=cleanPars[1]; + + Int_t nV0s=GetNumberOfV0s(); + for (Int_t i=nV0s-1; i>=0; i--) { + AliESDv0 *v0=GetV0(i); + + Float_t dca=v0->GetDcaV0Daughters(); + Float_t csp=v0->GetV0CosineOfPointingAngle(); + Float_t cspcut=cspMin + dca/dcaMax*(1.-cspMin); + if (csp > cspcut) continue; + if (RemoveV0(i)) rc=kTRUE; + } - Float_t dmax=cleanPars[0], zmax=cleanPars[1]; - const AliESDVertex *vertex=GetVertex(); - Bool_t vtxOK=vertex->GetStatus(), rc=kFALSE; + Float_t dmax=cleanPars[2], zmax=cleanPars[3]; + + const AliESDVertex *vertex=GetPrimaryVertexSPD(); + Bool_t vtxOK=vertex->GetStatus(); Int_t nTracks=GetNumberOfTracks(); for (Int_t i=nTracks-1; i>=0; i--) { @@ -513,7 +878,28 @@ Bool_t AliESDEvent::Clean(Float_t *cleanPars) { return rc; } -Int_t AliESDEvent::AddTrack(const AliESDtrack *t) { +Char_t AliESDEvent::AddPileupVertexSPD(const AliESDVertex *vtx) +{ + // Add a pileup primary vertex reconstructed with SPD + TClonesArray &ftr = *fSPDPileupVertices; + Char_t n=Char_t(ftr.GetEntriesFast()); + AliESDVertex *vertex = new(ftr[n]) AliESDVertex(*vtx); + vertex->SetID(n); + return n; +} + +Char_t AliESDEvent::AddPileupVertexTracks(const AliESDVertex *vtx) +{ + // Add a pileup primary vertex reconstructed with SPD + TClonesArray &ftr = *fTrkPileupVertices; + Char_t n=Char_t(ftr.GetEntriesFast()); + AliESDVertex *vertex = new(ftr[n]) AliESDVertex(*vtx); + vertex->SetID(n); + return n; +} + +Int_t AliESDEvent::AddTrack(const AliESDtrack *t) +{ // Add track TClonesArray &ftr = *fTracks; AliESDtrack * track = new(ftr[fTracks->GetEntriesFast()])AliESDtrack(*t); @@ -521,17 +907,20 @@ Int_t AliESDEvent::AddTrack(const AliESDtrack *t) { return track->GetID(); } - void AliESDEvent::AddMuonTrack(const AliESDMuonTrack *t) { + void AliESDEvent::AddMuonTrack(const AliESDMuonTrack *t) +{ TClonesArray &fmu = *fMuonTracks; new(fmu[fMuonTracks->GetEntriesFast()]) AliESDMuonTrack(*t); } -void AliESDEvent::AddPmdTrack(const AliESDPmdTrack *t) { +void AliESDEvent::AddPmdTrack(const AliESDPmdTrack *t) +{ TClonesArray &fpmd = *fPmdTracks; new(fpmd[fPmdTracks->GetEntriesFast()]) AliESDPmdTrack(*t); } -void AliESDEvent::AddTrdTrack(const AliESDTrdTrack *t) { +void AliESDEvent::AddTrdTrack(const AliESDTrdTrack *t) +{ TClonesArray &ftrd = *fTrdTracks; new(ftrd[fTrdTracks->GetEntriesFast()]) AliESDTrdTrack(*t); } @@ -539,7 +928,8 @@ void AliESDEvent::AddTrdTrack(const AliESDTrdTrack *t) { -Int_t AliESDEvent::AddKink(const AliESDkink *c) { +Int_t AliESDEvent::AddKink(const AliESDkink *c) +{ // Add kink TClonesArray &fk = *fKinks; AliESDkink * kink = new(fk[fKinks->GetEntriesFast()]) AliESDkink(*c); @@ -548,13 +938,15 @@ Int_t AliESDEvent::AddKink(const AliESDkink *c) { } -void AliESDEvent::AddCascade(const AliESDcascade *c) { +void AliESDEvent::AddCascade(const AliESDcascade *c) +{ TClonesArray &fc = *fCascades; new(fc[fCascades->GetEntriesFast()]) AliESDcascade(*c); } -Int_t AliESDEvent::AddCaloCluster(const AliESDCaloCluster *c) { +Int_t AliESDEvent::AddCaloCluster(const AliESDCaloCluster *c) +{ // Add calocluster TClonesArray &fc = *fCaloClusters; AliESDCaloCluster *clus = new(fc[fCaloClusters->GetEntriesFast()]) AliESDCaloCluster(*c); @@ -563,47 +955,123 @@ Int_t AliESDEvent::AddCaloCluster(const AliESDCaloCluster *c) { } - void AliESDEvent::AddRawDataErrorLog(const AliRawDataErrorLog *log) { - TClonesArray &errlogs = *fErrorLogs; - new(errlogs[errlogs.GetEntriesFast()]) AliRawDataErrorLog(*log); +void AliESDEvent::AddRawDataErrorLog(const AliRawDataErrorLog *log) const { + TClonesArray &errlogs = *fErrorLogs; + new(errlogs[errlogs.GetEntriesFast()]) AliRawDataErrorLog(*log); +} + +void AliESDEvent::SetZDCData(AliESDZDC * obj) +{ + // use already allocated space + if(fESDZDC) + *fESDZDC = *obj; +} + +void AliESDEvent::SetPrimaryVertexTPC(const AliESDVertex *vertex) +{ + // Set the TPC vertex + // use already allocated space + if(fTPCVertex){ + *fTPCVertex = *vertex; + fTPCVertex->SetName(fgkESDListName[kTPCVertex]); } +} -void AliESDEvent::SetVertex(const AliESDVertex *vertex) { +void AliESDEvent::SetPrimaryVertexSPD(const AliESDVertex *vertex) +{ + // Set the SPD vertex // use already allocated space if(fSPDVertex){ *fSPDVertex = *vertex; - fSPDVertex->SetName(fESDListName[kSPDVertex]); + fSPDVertex->SetName(fgkESDListName[kSPDVertex]); } } -void AliESDEvent::SetPrimaryVertex(const AliESDVertex *vertex) { +void AliESDEvent::SetPrimaryVertexTracks(const AliESDVertex *vertex) +{ + // Set the primary vertex reconstructed using he ESD tracks. + // use already allocated space if(fPrimaryVertex){ *fPrimaryVertex = *vertex; - fPrimaryVertex->SetName(fESDListName[kPrimaryVertex]); + fPrimaryVertex->SetName(fgkESDListName[kPrimaryVertex]); + } +} + +const AliESDVertex * AliESDEvent::GetPrimaryVertex() const +{ + // + // Get the "best" available reconstructed primary vertex. + // + if(fPrimaryVertex){ + if (fPrimaryVertex->GetStatus()) return fPrimaryVertex; } + if(fSPDVertex){ + if (fSPDVertex->GetStatus()) return fSPDVertex; + } + if(fTPCVertex) return fTPCVertex; + + AliWarning("No primary vertex available. Returning the \"default\"..."); + return fSPDVertex; } -void AliESDEvent::SetMultiplicity(const AliMultiplicity *mul) { +AliESDVertex * AliESDEvent::PrimaryVertexTracksUnconstrained() const +{ + // + // Removes diamond constraint from fPrimaryVertex (reconstructed with tracks) + // Returns a AliESDVertex which has to be deleted by the user + // + if(!fPrimaryVertex) { + AliWarning("No primary vertex from tracks available."); + return 0; + } + if(!fPrimaryVertex->GetStatus()) { + AliWarning("No primary vertex from tracks available."); + return 0; + } + + AliVertexerTracks vertexer(GetMagneticField()); + Float_t diamondxyz[3]={(Float_t)GetDiamondX(),(Float_t)GetDiamondY(),0.}; + Float_t diamondcovxy[3]; GetDiamondCovXY(diamondcovxy); + Float_t diamondcov[6]={diamondcovxy[0],diamondcovxy[1],diamondcovxy[2],0.,0.,7.}; + AliESDVertex *vertex = + (AliESDVertex*)vertexer.RemoveConstraintFromVertex(fPrimaryVertex,diamondxyz,diamondcov); + + return vertex; +} + +void AliESDEvent::SetMultiplicity(const AliMultiplicity *mul) +{ + // Set the SPD Multiplicity if(fSPDMult){ *fSPDMult = *mul; } } -void AliESDEvent::SetFMDData(AliESDFMD * obj) { +void AliESDEvent::SetFMDData(AliESDFMD * obj) +{ // use already allocated space if(fESDFMD){ *fESDFMD = *obj; } } -void AliESDEvent::SetVZEROData(AliESDVZERO * obj){ +void AliESDEvent::SetVZEROData(AliESDVZERO * obj) +{ // use already allocated space if(fESDVZERO) - new(fESDVZERO) AliESDVZERO(*obj); + *fESDVZERO = *obj; +} + +void AliESDEvent::SetACORDEData(AliESDACORDE * obj) +{ + if(fESDACORDE) + *fESDACORDE = *obj; } -void AliESDEvent::GetESDfriend(AliESDfriend *ev) const { + +void AliESDEvent::GetESDfriend(AliESDfriend *ev) const +{ // // Extracts the complementary info from the ESD // @@ -619,8 +1087,10 @@ void AliESDEvent::GetESDfriend(AliESDfriend *ev) const { t->ReleaseESDfriendTrack();// Not to have two copies of "friendTrack" } -} + AliESDfriend *fr = (AliESDfriend*)(const_cast(this)->FindListObject("AliESDfriend")); + if (fr) ev->SetVZEROfriend(fr->GetVZEROfriend()); +} void AliESDEvent::AddObject(TObject* obj) { @@ -637,48 +1107,60 @@ void AliESDEvent::GetStdContent() // set pointers for standard content // 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]); - + fESDRun = (AliESDRun*)fESDObjects->FindObject(fgkESDListName[kESDRun]); + fHeader = (AliESDHeader*)fESDObjects->FindObject(fgkESDListName[kHeader]); + fESDZDC = (AliESDZDC*)fESDObjects->FindObject(fgkESDListName[kESDZDC]); + fESDFMD = (AliESDFMD*)fESDObjects->FindObject(fgkESDListName[kESDFMD]); + fESDVZERO = (AliESDVZERO*)fESDObjects->FindObject(fgkESDListName[kESDVZERO]); + fESDTZERO = (AliESDTZERO*)fESDObjects->FindObject(fgkESDListName[kESDTZERO]); + fTPCVertex = (AliESDVertex*)fESDObjects->FindObject(fgkESDListName[kTPCVertex]); + fSPDVertex = (AliESDVertex*)fESDObjects->FindObject(fgkESDListName[kSPDVertex]); + fPrimaryVertex = (AliESDVertex*)fESDObjects->FindObject(fgkESDListName[kPrimaryVertex]); + fSPDMult = (AliMultiplicity*)fESDObjects->FindObject(fgkESDListName[kSPDMult]); + fPHOSTrigger = (AliESDCaloTrigger*)fESDObjects->FindObject(fgkESDListName[kPHOSTrigger]); + fEMCALTrigger = (AliESDCaloTrigger*)fESDObjects->FindObject(fgkESDListName[kEMCALTrigger]); + fSPDPileupVertices = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kSPDPileupVertices]); + fTrkPileupVertices = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kTrkPileupVertices]); + fTracks = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kTracks]); + fMuonTracks = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kMuonTracks]); + fPmdTracks = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kPmdTracks]); + fTrdTracks = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kTrdTracks]); + fV0s = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kV0s]); + fCascades = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kCascades]); + fKinks = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kKinks]); + fCaloClusters = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kCaloClusters]); + fEMCALCells = (AliESDCaloCells*)fESDObjects->FindObject(fgkESDListName[kEMCALCells]); + fPHOSCells = (AliESDCaloCells*)fESDObjects->FindObject(fgkESDListName[kPHOSCells]); + fErrorLogs = (TClonesArray*)fESDObjects->FindObject(fgkESDListName[kErrorLogs]); + fESDACORDE = (AliESDACORDE*)fESDObjects->FindObject(fgkESDListName[kESDACORDE]); + fTOFHeader = (AliTOFHeader*)fESDObjects->FindObject(fgkESDListName[kTOFHeader]); } void AliESDEvent::SetStdNames(){ // Set the names of the standard contents // - if(fESDObjects->GetEntries()==kESDListN){ - for(int i = 0;i < fESDObjects->GetEntries();i++){ + if(fESDObjects->GetEntries()>=kESDListN){ + for(int i = 0;i < fESDObjects->GetEntries() && iAt(i); if(fObj->InheritsFrom("TNamed")){ - ((TNamed*)fObj)->SetName(fESDListName[i]); + ((TNamed*)fObj)->SetName(fgkESDListName[i]); } else if(fObj->InheritsFrom("TClonesArray")){ - ((TClonesArray*)fObj)->SetName(fESDListName[i]); + ((TClonesArray*)fObj)->SetName(fgkESDListName[i]); } } } else{ - printf("%s:%d SetStdNames() Wrong number of Std Entries \n",(char*)__FILE__,__LINE__); + AliWarning("Std Entries missing"); } } + +void AliESDEvent::CreateStdContent(Bool_t bUseThisList){ + fUseOwnList = bUseThisList; + CreateStdContent(); +} + void AliESDEvent::CreateStdContent() { // create the standard AOD content and set pointers @@ -692,9 +1174,12 @@ void AliESDEvent::CreateStdContent() AddObject(new AliESDTZERO()); AddObject(new AliESDVertex()); AddObject(new AliESDVertex()); + AddObject(new AliESDVertex()); AddObject(new AliMultiplicity()); AddObject(new AliESDCaloTrigger()); AddObject(new AliESDCaloTrigger()); + AddObject(new TClonesArray("AliESDVertex",0)); + AddObject(new TClonesArray("AliESDVertex",0)); AddObject(new TClonesArray("AliESDtrack",0)); AddObject(new TClonesArray("AliESDMuonTrack",0)); AddObject(new TClonesArray("AliESDPmdTrack",0)); @@ -703,7 +1188,11 @@ void AliESDEvent::CreateStdContent() AddObject(new TClonesArray("AliESDcascade",0)); AddObject(new TClonesArray("AliESDkink",0)); AddObject(new TClonesArray("AliESDCaloCluster",0)); + AddObject(new AliESDCaloCells()); + AddObject(new AliESDCaloCells()); AddObject(new TClonesArray("AliRawDataErrorLog",0)); + AddObject(new AliESDACORDE()); + AddObject(new AliTOFHeader()); // check the order of the indices against enum... @@ -713,48 +1202,174 @@ void AliESDEvent::CreateStdContent() GetStdContent(); } -TObject* AliESDEvent::FindListObject(const char *name){ - if(fESDObjects)return fESDObjects->FindObject(name); +TObject* AliESDEvent::FindListObject(const char *name) const { +// +// Find object with name "name" in the list of branches +// + if(fESDObjects){ + return fESDObjects->FindObject(name); + } return 0; } -void AliESDEvent::ReadFromTree(TTree *tree){ +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); + AliDebug(1,Form("IsPHOS cluster %d Size: %d \n",i,clusters->GetEntriesFast())); + } + } + } + return clusters->GetEntriesFast(); +} + +Int_t AliESDEvent::GetEMCALClusters(TRefArray *clusters) const +{ + // fills the provided TRefArray with all found emcal clusters + + clusters->Clear(); + + AliESDCaloCluster *cl = 0; + for (Int_t i = 0; i < GetNumberOfCaloClusters(); i++) { + + if ( (cl = GetCaloCluster(i)) ) { + if (cl->IsEMCAL()){ + clusters->Add(cl); + AliDebug(1,Form("IsEMCAL cluster %d Size: %d \n",i,clusters->GetEntriesFast())); + } + } + } + return clusters->GetEntriesFast(); +} + +void AliESDEvent::WriteToTree(TTree* tree) const { + // Book the branches as in TTree::Branch(TCollection*) + // but add a "." at the end of top level branches which are + // not a TClonesArray + + + TString branchname; + TIter next(fESDObjects); + const Int_t kSplitlevel = 99; // default value in TTree::Branch() + const Int_t kBufsize = 32000; // default value in TTree::Branch() + TObject *obj = 0; + + while ((obj = next())) { + branchname.Form("%s", obj->GetName()); + if(branchname.CompareTo("AliESDfriend")==0)branchname = "ESDfriend."; + if ((kSplitlevel > 1) && !obj->InheritsFrom(TClonesArray::Class())) { + if(!branchname.EndsWith("."))branchname += "."; + } + if (!tree->FindBranch(branchname)) { + // For the custom streamer to be called splitlevel + // has to be negative, only needed for HLT + Int_t splitLevel = (TString(obj->ClassName()) == "AliHLTGlobalTriggerDecision") ? -1 : kSplitlevel - 1; + tree->Bronch(branchname, obj->ClassName(), fESDObjects->GetObjectRef(obj),kBufsize, splitLevel); + } + } +} + +void AliESDEvent::ReadFromTree(TTree *tree, Option_t* opt){ +// +// Connect the ESDEvent to a tree +// + if(!tree){ + AliWarning("AliESDEvent::ReadFromTree() Zero Pointer to Tree \n"); + return; + } // load the TTree - tree->LoadTree(0); + if(!tree->GetTree())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 (!address) { - printf("%s %d AliESDEvent::ReadFromTree() Reading old Tree \n",(char*)__FILE__,__LINE__); - tree->SetBranchAddress("ESD",&fESDOld); - } else { - printf("%s %d AliESDEvent::ReadFromTree() Reading old Tree \n",(char*)__FILE__,__LINE__); - printf("%s %d Branch already connected. Using existing branch address. \n",(char*)__FILE__,__LINE__); - fESDOld = (AliESD*) (*address); + if(tree->GetBranch("ESD")) { + char ** address = (char **)(tree->GetBranch("ESD")->GetAddress()); + // do we have the friend branch + TBranch * esdFB = tree->GetBranch("ESDfriend."); + char ** addressF = 0; + if(esdFB)addressF = (char **)(esdFB->GetAddress()); + if (!address) { + AliInfo("AliESDEvent::ReadFromTree() Reading old Tree"); + tree->SetBranchAddress("ESD", &fESDOld); + if(esdFB){ + tree->SetBranchAddress("ESDfriend.",&fESDFriendOld); } + } else { + AliInfo("AliESDEvent::ReadFromTree() Reading old Tree"); + AliInfo("Branch already connected. Using existing branch address."); + fESDOld = (AliESD*) (*address); + // addressF can still be 0, since branch needs to switched on + if(addressF)fESDFriendOld = (AliESDfriend*) (*addressF); + } + + // have already connected the old ESD structure... ? + // reuse also the pointer of the AlliESDEvent + // otherwise create new ones + TList* connectedList = (TList*) (tree->GetUserInfo()->FindObject("ESDObjectsConnectedToTree")); + + if(connectedList){ + // If connected use the connected list of objects + if(fESDObjects!= connectedList){ + // protect when called twice + fESDObjects->Delete(); + fESDObjects = connectedList; + } + GetStdContent(); + + // The pointer to the friend changes when called twice via InitIO + // since AliESDEvent is deleted + TObject* oldf = FindListObject("AliESDfriend"); + TObject* newf = 0; + if(addressF){ + newf = (TObject*)*addressF; + } + if(newf!=0&&oldf!=newf){ + // remove the old reference + // Should we also delete it? Or is this handled in TTree I/O + // since it is created by the first SetBranchAddress + fESDObjects->Remove(oldf); + // add the new one + fESDObjects->Add(newf); + } - CreateStdContent(); // create for copy - // when reading back we are not owner of the list - // must not delete it - fESDObjects->SetOwner(kFALSE); + fConnected = true; return; + } + // else... + CreateStdContent(); // create for copy + // if we have the esdfriend add it, so we always can access it via the userinfo + if(fESDFriendOld)AddObject(fESDFriendOld); + // we are not owner of the list objects + // must not delete it + fESDObjects->SetOwner(kTRUE); + fESDObjects->SetName("ESDObjectsConnectedToTree"); + tree->GetUserInfo()->Add(fESDObjects); + fConnected = true; + return; } + - fESDOld = 0; - - + delete fESDOld; + fESDOld = 0; // Try to find AliESDEvent AliESDEvent *esdEvent = 0; esdEvent = (AliESDEvent*)tree->GetTree()->GetUserInfo()->FindObject("AliESDEvent"); - //esdEvent = (AliESDEvent*)tree->GetUserInfo()->FindObject("AliESDEvent"); - if(esdEvent){ // Check if already connected to tree + esdEvent->Reset(); TList* connectedList = (TList*) (tree->GetUserInfo()->FindObject("ESDObjectsConnectedToTree")); - if (connectedList) { + + + if (connectedList && (strcmp(opt, "reconnect"))) { // If connected use the connected list if objects fESDObjects->Delete(); fESDObjects = connectedList; @@ -762,46 +1377,70 @@ void AliESDEvent::ReadFromTree(TTree *tree){ fConnected = true; return; } + // Connect to tree - if(fESDObjects->GetEntries()!=0){ - // this should not happen here put a warning? - } // prevent a memory leak when reading back the TList - delete fESDObjects; - fESDObjects = 0; - // create a new TList from the UserInfo TList... - // copy constructor does not work... - fESDObjects = (TList*)(esdEvent->GetList()->Clone()); - fESDObjects->SetOwner(kFALSE); + // if (!(strcmp(opt, "reconnect"))) fESDObjects->Delete(); + + if(!fUseOwnList){ + // create a new TList from the UserInfo TList... + // copy constructor does not work... + fESDObjects = (TList*)(esdEvent->GetList()->Clone()); + fESDObjects->SetOwner(kTRUE); + } + else if ( fESDObjects->GetEntries()==0){ + // at least create the std content if we want to read to our list + CreateStdContent(); + } + + // in principle + // we only need new things in the list if we do no already have it.. + // TODO just add new entries + if(fESDObjects->GetEntries()GetEntries(),kESDListN); + AliWarning(Form("AliESDEvent::ReadFromTree() TList contains less than the standard contents %d < %d \n", + fESDObjects->GetEntries(),kESDListN)); } // set the branch addresses TIter next(fESDObjects); TNamed *el; while((el=(TNamed*)next())){ TString bname(el->GetName()); - if(bname.CompareTo("AliESDfriend")==0) { // AliESDfriend does not have a name ... - tree->SetBranchAddress("ESDfriend.",fESDObjects->GetObjectRef(el)); + TBranch *br = tree->GetBranch("ESDfriend."); + if (br) tree->SetBranchAddress("ESDfriend.",fESDObjects->GetObjectRef(el)); } else{ - tree->SetBranchAddress(bname.Data(),fESDObjects->GetObjectRef(el)); + // check if branch exists under this Name + TBranch *br = tree->GetBranch(bname.Data()); + if(br){ + tree->SetBranchAddress(bname.Data(),fESDObjects->GetObjectRef(el)); + } + else{ + br = tree->GetBranch(Form("%s.",bname.Data())); + if(br){ + tree->SetBranchAddress(Form("%s.",bname.Data()),fESDObjects->GetObjectRef(el)); + } + else{ + AliWarning(Form("AliESDEvent::ReadFromTree() No Branch found with Name %s or %s.",bname.Data(),bname.Data())); + } + + } } } GetStdContent(); // when reading back we are not owner of the list // must not delete it - fESDObjects->SetOwner(kFALSE); + fESDObjects->SetOwner(kTRUE); fESDObjects->SetName("ESDObjectsConnectedToTree"); // we are not owner of the list objects // must not delete it tree->GetUserInfo()->Add(fESDObjects); + tree->GetUserInfo()->SetOwner(kFALSE); fConnected = true; - }// no esdEvent + }// no esdEvent --> else { // we can't get the list from the user data, create standard content // and set it by hand (no ESDfriend at the moment @@ -810,16 +1449,22 @@ void AliESDEvent::ReadFromTree(TTree *tree){ TNamed *el; while((el=(TNamed*)next())){ TString bname(el->GetName()); - tree->SetBranchAddress(bname.Data(),fESDObjects->GetObjectRef(el)); + TBranch *br = tree->GetBranch(bname.Data()); + if(br){ + tree->SetBranchAddress(bname.Data(),fESDObjects->GetObjectRef(el)); + } + else{ + br = tree->GetBranch(Form("%s.",bname.Data())); + if(br){ + tree->SetBranchAddress(Form("%s.",bname.Data()),fESDObjects->GetObjectRef(el)); + } + } } GetStdContent(); // when reading back we are not owner of the list // must not delete it - fESDObjects->SetOwner(kFALSE); + fESDObjects->SetOwner(kTRUE); } - - - } @@ -827,13 +1472,12 @@ void AliESDEvent::CopyFromOldESD() { // Method which copies over everthing from the old esd structure to the // new - if(fESDOld){ ResetStdContent(); // Run SetRunNumber(fESDOld->GetRunNumber()); SetPeriodNumber(fESDOld->GetPeriodNumber()); - SetMagneticField(fESDRun->GetMagneticField()); + SetMagneticField(fESDOld->GetMagneticField()); // leave out diamond ... // SetDiamond(const AliESDVertex *vertex) { fESDRun->SetDiamond(vertex);} @@ -850,11 +1494,18 @@ void AliESDEvent::CopyFromOldESD() // ZDC SetZDC(fESDOld->GetZDCN1Energy(), - fESDOld->GetZDCP1Energy(), - fESDOld->GetZDCEMEnergy(), - fESDOld->GetZDCN2Energy(), - fESDOld->GetZDCP2Energy(), - fESDOld->GetZDCParticipants()); + fESDOld->GetZDCP1Energy(), + fESDOld->GetZDCEMEnergy(), + 0, + fESDOld->GetZDCN2Energy(), + fESDOld->GetZDCP2Energy(), + fESDOld->GetZDCParticipants(), + 0, + 0, + 0, + 0, + 0, + 0); // FMD @@ -869,12 +1520,12 @@ void AliESDEvent::CopyFromOldESD() // VZERO if (fESDOld->GetVZEROData()) SetVZEROData(fESDOld->GetVZEROData()); - if(fESDOld->GetVertex())SetVertex(fESDOld->GetVertex()); + if(fESDOld->GetVertex())SetPrimaryVertexSPD(fESDOld->GetVertex()); - if(fESDOld->GetPrimaryVertex())SetPrimaryVertex(fESDOld->GetPrimaryVertex()); + if(fESDOld->GetPrimaryVertex())SetPrimaryVertexTracks(fESDOld->GetPrimaryVertex()); if(fESDOld->GetMultiplicity())SetMultiplicity(fESDOld->GetMultiplicity()); - + for(int i = 0;iGetNumberOfTracks();i++){ AddTrack(fESDOld->GetTrack(i)); } @@ -907,8 +1558,195 @@ void AliESDEvent::CopyFromOldESD() for(int i = 0;iGetNumberOfCaloClusters();i++){ AddCaloCluster(fESDOld->GetCaloCluster(i)); } + }// if fesdold } +Bool_t AliESDEvent::IsEventSelected(const char *trigExpr) const +{ + // Check if the event satisfies the trigger + // selection expression trigExpr. + // trigExpr can be any logical expression + // of the trigger classes defined in AliESDRun + // In case of wrong syntax return kTRUE. + + TString expr(trigExpr); + if (expr.IsNull()) return kTRUE; + + ULong64_t mask = GetTriggerMask(); + for(Int_t itrig = 0; itrig < AliESDRun::kNTriggerClasses; itrig++) { + if (mask & (1ull << itrig)) { + expr.ReplaceAll(GetESDRun()->GetTriggerClass(itrig),"1"); + } + else { + expr.ReplaceAll(GetESDRun()->GetTriggerClass(itrig),"0"); + } + } + + Int_t error; + if ((gROOT->ProcessLineFast(expr.Data(),&error) == 0) && + (error == TInterpreter::kNoError)) { + return kFALSE; + } + + return kTRUE; + +} + +TObject* AliESDEvent::GetHLTTriggerDecision() const +{ + // get the HLT trigger decission object + + // cast away const'nes because the FindListObject method + // is not const + AliESDEvent* pNonConst=const_cast(this); + return pNonConst->FindListObject("HLTGlobalTrigger"); +} + +TString AliESDEvent::GetHLTTriggerDescription() const +{ + // get the HLT trigger decission description + TString description; + TObject* pDecision=GetHLTTriggerDecision(); + if (pDecision) { + description=pDecision->GetTitle(); + } + + return description; +} + +Bool_t AliESDEvent::IsHLTTriggerFired(const char* name) const +{ + // get the HLT trigger decission description + TObject* pDecision=GetHLTTriggerDecision(); + if (!pDecision) return kFALSE; + + Option_t* option=pDecision->GetOption(); + if (option==NULL || *option!='1') return kFALSE; + + if (name) { + TString description=GetHLTTriggerDescription(); + Int_t index=description.Index(name); + if (index<0) return kFALSE; + index+=strlen(name); + if (index>=description.Length()) return kFALSE; + if (description[index]!=0 && description[index]!=' ') return kFALSE; + } + return kTRUE; +} + +//______________________________________________________________________________ +Bool_t AliESDEvent::IsPileupFromSPD(Int_t minContributors, + Double_t minZdist, + Double_t nSigmaZdist, + Double_t nSigmaDiamXY, + Double_t nSigmaDiamZ) const{ + // + // This function checks if there was a pile up + // reconstructed with SPD + // + Int_t nc1=fSPDVertex->GetNContributors(); + if(nc1<1) return kFALSE; + Int_t nPileVert=GetNumberOfPileupVerticesSPD(); + if(nPileVert==0) return kFALSE; + + for(Int_t i=0; iGetNContributors(); + if(nc2>=minContributors){ + Double_t z1=fSPDVertex->GetZ(); + Double_t z2=pv->GetZ(); + Double_t distZ=TMath::Abs(z2-z1); + Double_t distZdiam=TMath::Abs(z2-GetDiamondZ()); + Double_t cutZdiam=nSigmaDiamZ*TMath::Sqrt(GetSigma2DiamondZ()); + if(GetSigma2DiamondZ()<0.0001)cutZdiam=99999.; //protection for missing z diamond information + if(distZ>minZdist && distZdiamGetX(); + Double_t y2=pv->GetY(); + Double_t distXdiam=TMath::Abs(x2-GetDiamondX()); + Double_t distYdiam=TMath::Abs(y2-GetDiamondY()); + Double_t cov1[6],cov2[6]; + fSPDVertex->GetCovarianceMatrix(cov1); + pv->GetCovarianceMatrix(cov2); + Double_t errxDist=TMath::Sqrt(cov2[0]+GetSigma2DiamondX()); + Double_t erryDist=TMath::Sqrt(cov2[2]+GetSigma2DiamondY()); + Double_t errzDist=TMath::Sqrt(cov1[5]+cov2[5]); + Double_t cutXdiam=nSigmaDiamXY*errxDist; + if(GetSigma2DiamondX()<0.0001)cutXdiam=99999.; //protection for missing diamond information + Double_t cutYdiam=nSigmaDiamXY*erryDist; + if(GetSigma2DiamondY()<0.0001)cutYdiam=99999.; //protection for missing diamond information + if( (distXdiamnSigmaZdist*errzDist) ){ + return kTRUE; + } + } + } + } + return kFALSE; +} + +//______________________________________________________________________________ +void AliESDEvent::EstimateMultiplicity(Int_t &tracklets, Int_t &trITSTPC, Int_t &trITSSApure, Double_t eta, Bool_t useDCAFlag,Bool_t useV0Flag) const +{ + // + // calculates 3 estimators for the multiplicity in the -eta:eta range + // tracklets : using SPD tracklets only + // trITSTPC : using TPC/ITS + complementary ITS SA tracks + tracklets from clusters not used by tracks + // trITSSApure : using ITS standalone tracks + tracklets from clusters not used by tracks + // if useDCAFlag is true: account for the ESDtrack flag marking the tracks with large DCA + // if useV0Flag is true: account for the ESDtrack flag marking conversion and K0's V0s + tracklets = trITSSApure = trITSTPC = 0; + int ntr = fSPDMult ? fSPDMult->GetNumberOfTracklets() : 0; + // + // count tracklets + for (int itr=ntr;itr--;) { + if (TMath::Abs(fSPDMult->GetEta(itr))>eta) continue; + tracklets++; + if (fSPDMult->FreeClustersTracklet(itr,0)) trITSTPC++; // not used in ITS/TPC or ITS_SA track + if (fSPDMult->FreeClustersTracklet(itr,1)) trITSSApure++; // not used in ITS_SA_Pure track + } + // + // count real tracks + ntr = GetNumberOfTracks(); + for (int itr=ntr;itr--;) { + AliESDtrack *t = GetTrack(itr); + if (TMath::Abs(t->Eta())>eta) continue; + if (!t->IsOn(AliESDtrack::kITSin)) continue; + if (useDCAFlag && t->IsOn(AliESDtrack::kMultSec)) continue; + if (useV0Flag && t->IsOn(AliESDtrack::kMultInV0)) continue; + if (t->IsOn(AliESDtrack::kITSpureSA)) trITSSApure++; + else trITSTPC++; + } + // +} +Bool_t AliESDEvent::IsPileupFromSPDInMultBins() const { + Int_t nTracklets=GetMultiplicity()->GetNumberOfTracklets(); + if(nTracklets<20) return IsPileupFromSPD(3,0.8); + else if(nTracklets<50) return IsPileupFromSPD(4,0.8); + else return IsPileupFromSPD(5,0.8); +} +void AliESDEvent::SetTOFHeader(const AliTOFHeader *header) +{ + // + // Set the TOF event_time + // + + if (fTOFHeader) { + *fTOFHeader=*header; + //fTOFHeader->SetName(fgkESDListName[kTOFHeader]); + } + else { + // for analysis of reconstructed events + // when this information is not avaliable + fTOFHeader = new AliTOFHeader(*header); + //AddObject(fTOFHeader); + } + +} + +AliCentrality* AliESDEvent::GetCentrality() +{ + if (!fCentrality) fCentrality = new AliCentrality(); + return fCentrality; +}