]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - STEER/AliMCEvent.cxx
MCEvent::GetTrack gives back *VParticle.
[u/mrichter/AliRoot.git] / STEER / AliMCEvent.cxx
index d652f276b533743b3b3ddf0f993531b42dc2967b..e7b687aec4a1e4d7f65c6175f3d6f8f394c555bf 100644 (file)
@@ -27,6 +27,7 @@
 #include <TParticle.h>
 #include <TClonesArray.h>
 #include <TRefArray.h>
+#include <TList.h>
 
 #include "AliLog.h"
 #include "AliMCEvent.h"
 #include "AliGenEventHeader.h"
 
 
+Int_t AliMCEvent::fgkBgLabelOffset(10000000);
+
+
 AliMCEvent::AliMCEvent():
     AliVEvent(),
     fStack(0),
-    fMCParticles(new TClonesArray("AliMCParticle",1000)),
+    fMCParticles(0),
     fMCParticleMap(0),
-    fHeader(0),
+    fHeader(new AliHeader()),
     fTRBuffer(0),
     fTrackReferences(new TClonesArray("AliTrackReference", 1000)),
     fTreeTR(0),
     fTmpTreeTR(0),
     fTmpFileTR(0),
     fNprimaries(-1),
-    fNparticles(-1)
+    fNparticles(-1),
+    fSubsidiaryEvents(0),
+    fPrimaryOffset(0),
+    fSecondaryOffset(0),
+    fExternal(0)
 {
     // Default constructor
 }
 
 AliMCEvent::AliMCEvent(const AliMCEvent& mcEvnt) :
     AliVEvent(mcEvnt),
-    fStack(0),
-    fMCParticles(0),
-    fMCParticleMap(0),
-    fHeader(0),
-    fTRBuffer(0),
-    fTrackReferences(0),
-    fTreeTR(0),
-    fTmpTreeTR(0),
-    fTmpFileTR(0),
-    fNprimaries(-1),
-    fNparticles(-1) 
+    fStack(mcEvnt.fStack),
+    fMCParticles(mcEvnt.fMCParticles),
+    fMCParticleMap(mcEvnt.fMCParticleMap),
+    fHeader(mcEvnt.fHeader),
+    fTRBuffer(mcEvnt.fTRBuffer),
+    fTrackReferences(mcEvnt.fTrackReferences),
+    fTreeTR(mcEvnt.fTreeTR),
+    fTmpTreeTR(mcEvnt.fTmpTreeTR),
+    fTmpFileTR(mcEvnt.fTmpFileTR),
+    fNprimaries(mcEvnt.fNprimaries),
+    fNparticles(mcEvnt.fNparticles),
+    fSubsidiaryEvents(0),
+    fPrimaryOffset(0),
+    fSecondaryOffset(0),
+    fExternal(0)
 { 
 // Copy constructor
 }
@@ -90,6 +102,8 @@ void AliMCEvent::ConnectTreeE (TTree* tree)
 void AliMCEvent::ConnectTreeK (TTree* tree)
 {
     // Connect the kinematics tree to the stack
+    if (!fMCParticles) fMCParticles = new TClonesArray("AliMCParticle",1000);
+    //
     fStack = fHeader->Stack();
     fStack->ConnectTree(tree);
     //
@@ -106,10 +120,11 @@ void AliMCEvent::ConnectTreeK (TTree* tree)
     // This is a cache for the TParticles converted to MCParticles on user request
     if (fMCParticleMap) {
        fMCParticleMap->Clear();
-       if (fNparticles>0) fMCParticleMap->Expand(fNparticles);}
+       fMCParticles->Delete();
+       if (fNparticles>0) fMCParticleMap->Expand(fNparticles);
+    }
     else
        fMCParticleMap = new TRefArray(fNparticles);
-
 }
 
 void AliMCEvent::ConnectTreeTR (TTree* tree)
@@ -154,17 +169,16 @@ Int_t AliMCEvent::GetParticleAndTR(Int_t i, TParticle*& particle, TClonesArray*&
 void AliMCEvent::Clean()
 {
     // Clean-up before new trees are connected
-    
-    if (fHeader) {
-       delete fHeader;
-       fHeader = 0;
-    }
-    
-    delete fStack;
+//    if (fHeader) {
+//     delete fHeader;
+//     fHeader = 0;
+//    }
+
+    delete fStack; fStack = 0;
 
     // Clear TR
     if (fTRBuffer) {
-       fTRBuffer->Clear();
+       fTRBuffer->Delete();
        delete fTRBuffer;
        fTRBuffer = 0;
     }
@@ -173,10 +187,18 @@ void AliMCEvent::Clean()
 void AliMCEvent::FinishEvent()
 {
   // Clean-up after event
-  fStack->Reset(0);
-  fMCParticles->Delete();
-  fMCParticleMap->Delete();
-  fTrackReferences->Clear();
+  //    
+    fStack->Reset(0);
+    fMCParticles->Delete();
+    fMCParticleMap->Clear();
+    if (fTRBuffer)
+      fTRBuffer->Delete();
+    fTrackReferences->Delete();
+    fNparticles = -1;
+    fNprimaries = -1;    
+    fStack      =  0;
+//    fSubsidiaryEvents->Clear();
+    fSubsidiaryEvents = 0;
 }
 
 
@@ -374,7 +396,7 @@ void AliMCEvent::ReorderAndExpandTreeTR()
                    } // hits
                } // branches
                fTmpTreeTR->Fill();
-               fTRBuffer->Clear();
+               fTRBuffer->Delete();
                ifills++;
            } // daughters
        } // has hits
@@ -411,7 +433,7 @@ void AliMCEvent::ReorderAndExpandTreeTR()
        } // entries
        it++;
        fTmpTreeTR->Fill();
-       fTRBuffer->Clear();
+       fTRBuffer->Delete();
        ifills++;
     } // tracks
     // Check
@@ -436,24 +458,52 @@ void AliMCEvent::ReorderAndExpandTreeTR()
     fTreeTR = fTmpTreeTR;
 }
 
-AliMCParticle* AliMCEvent::GetTrack(Int_t i) const
+AliVParticle* AliMCEvent::GetTrack(Int_t i) const
 {
     // Get MC Particle i
+    //
+
+    if (fExternal) {
+       return ((AliVParticle*) (fMCParticles->At(i)));
+    }
+    
+    //
+    // Check first if this explicitely accesses the subsidiary event
+    
+    if (i >= BgLabelOffset()) {
+       if (fSubsidiaryEvents) {
+           AliMCEvent* bgEvent = (AliMCEvent*) (fSubsidiaryEvents->At(1));
+           return (bgEvent->GetTrack(i - BgLabelOffset()));
+       } else {
+           return 0;
+       }
+    }
+    
+    //
     AliMCParticle *mcParticle = 0;
     TParticle     *particle   = 0;
     TClonesArray  *trefs      = 0;
     Int_t          ntref      = 0;
     TRefArray     *rarray     = 0;
+
+
+
     // Out of range check
     if (i < 0 || i >= fNparticles) {
        AliWarning(Form("AliMCEvent::GetEntry: Index out of range"));
        mcParticle = 0;
        return (mcParticle);
     }
+
     
+    if (fSubsidiaryEvents) {
+       AliMCEvent*   mc;
+       Int_t idx = FindIndexAndEvent(i, mc);
+       return (mc->GetTrack(idx));
+    } 
 
     //
-    // First check of the MC Particle has been already cached
+    // First check If the MC Particle has been already cached
     if(!fMCParticleMap->At(i)) {
        // Get particle from the stack
        particle   = fStack->Particle(i);
@@ -477,12 +527,138 @@ AliMCParticle* AliMCEvent::GetTrack(Int_t i) const
        new ((*fMCParticles)[nentries]) AliMCParticle(particle, rarray, i);
        mcParticle = dynamic_cast<AliMCParticle*>((*fMCParticles)[nentries]);
        fMCParticleMap->AddAt(mcParticle, i);
+
+       TParticle* part = mcParticle->Particle();
+       Int_t imo  = part->GetFirstMother();
+       Int_t id1  = part->GetFirstDaughter();
+       Int_t id2  = part->GetLastDaughter();
+       if (fPrimaryOffset > 0 || fSecondaryOffset > 0) {
+           // Remapping of the mother and daughter indices
+           if (imo < fNprimaries) {
+               mcParticle->SetMother(imo + fPrimaryOffset);
+           } else {
+               mcParticle->SetMother(imo + fSecondaryOffset - fNprimaries);
+           }
+
+           if (id1 < fNprimaries) {
+               mcParticle->SetFirstDaughter(id1 + fPrimaryOffset);
+               mcParticle->SetLastDaughter (id2 + fPrimaryOffset);
+           } else {
+               mcParticle->SetFirstDaughter(id1 + fSecondaryOffset - fNprimaries);
+               mcParticle->SetLastDaughter (id2 + fSecondaryOffset - fNprimaries);
+           }
+
+           
+           if (i > fNprimaries) {
+               mcParticle->SetLabel(i + fPrimaryOffset);
+           } else {
+               mcParticle->SetLabel(i + fSecondaryOffset - fNprimaries);
+           }
+           
+           
+       } else {
+           mcParticle->SetFirstDaughter(id1);
+           mcParticle->SetLastDaughter (id2);
+           mcParticle->SetMother       (imo);
+       }
+
     } else {
        mcParticle = dynamic_cast<AliMCParticle*>(fMCParticleMap->At(i));
     }
+    
+    
     return mcParticle;
 }
 
- AliGenEventHeader* AliMCEvent::GenEventHeader() {return (fHeader->GenEventHeader());}
+    AliGenEventHeader* AliMCEvent::GenEventHeader() {return (fHeader->GenEventHeader());}
+
+
+void AliMCEvent::AddSubsidiaryEvent(AliMCEvent* event) 
+{
+    // Add a subsidiary event to the list; for example merged background event.
+    if (!fSubsidiaryEvents) {
+       TList* events = new TList();
+       events->Add(new AliMCEvent(*this));
+       fSubsidiaryEvents = events;
+    }
+    
+    fSubsidiaryEvents->Add(event);
+}
+
+Int_t AliMCEvent::FindIndexAndEvent(Int_t oldidx, AliMCEvent*& event) const
+{
+    // Find the index and event in case of composed events like signal + background
+    TIter next(fSubsidiaryEvents);
+    next.Reset();
+     if (oldidx < fNprimaries) {
+       while((event = (AliMCEvent*)next())) {
+           if (oldidx < (event->GetPrimaryOffset() + event->GetNumberOfPrimaries())) break;
+       }
+       return (oldidx - event->GetPrimaryOffset());
+    } else {
+       while((event = (AliMCEvent*)next())) {
+           if (oldidx < (event->GetSecondaryOffset() + (event->GetNumberOfTracks() - event->GetNumberOfPrimaries()))) break;
+       }
+       return (oldidx - event->GetSecondaryOffset() + event->GetNumberOfPrimaries());
+    }
+}
+
+Int_t AliMCEvent::BgLabelToIndex(Int_t label)
+{
+    // Convert a background label to an absolute index
+    if (fSubsidiaryEvents) {
+       AliMCEvent* bgEvent = (AliMCEvent*) (fSubsidiaryEvents->At(1));
+       label -= BgLabelOffset();
+       if (label < bgEvent->GetNumberOfPrimaries()) {
+           label += bgEvent->GetPrimaryOffset();
+       } else {
+           label += (bgEvent->GetSecondaryOffset() - fNprimaries);
+       }
+    }
+    return (label);
+}
+
+
+Bool_t AliMCEvent::IsPhysicalPrimary(Int_t i) 
+{
+//
+// Delegate to subevent if necesarry 
+
+    
+    if (!fSubsidiaryEvents) {
+       return fStack->IsPhysicalPrimary(i);
+    } else {
+       AliMCEvent* evt = 0;
+       Int_t idx = FindIndexAndEvent(i, evt);
+       return (evt->IsPhysicalPrimary(idx));
+    }
+}
+
+void AliMCEvent::InitEvent()
+{
+    if (fSubsidiaryEvents) {
+       TIter next(fSubsidiaryEvents);
+       AliMCEvent* evt;
+       fNprimaries = 0;
+       fNparticles = 0;
+       
+       while((evt = (AliMCEvent*)next())) {
+           fNprimaries += evt->GetNumberOfPrimaries(); 
+           fNparticles += evt->GetNumberOfTracks();    
+       }
+       
+       Int_t ioffp = 0;
+       Int_t ioffs = fNprimaries;
+       next.Reset();
+       
+       while((evt = (AliMCEvent*)next())) {
+           evt->SetPrimaryOffset(ioffp);
+           evt->SetSecondaryOffset(ioffs);
+           ioffp += evt->GetNumberOfPrimaries();
+           ioffs += (evt->GetNumberOfTracks() - evt->GetNumberOfPrimaries());      
+       }
+    }
+}
+
 
 ClassImp(AliMCEvent)