]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - STEER/STEERBase/AliMCEvent.cxx
Ignore streamer of raw header v3_14.
[u/mrichter/AliRoot.git] / STEER / STEERBase / AliMCEvent.cxx
index 20794f6537e33eeb37750f9e4329498c1f4c3ab8..3d4bddba882cbcd92087ecc4aaab407e7b703589 100644 (file)
@@ -49,6 +49,7 @@ AliMCEvent::AliMCEvent():
     fMCParticles(0),
     fMCParticleMap(0),
     fHeader(new AliHeader()),
+    fAODMCHeader(0),
     fTRBuffer(0),
     fTrackReferences(new TClonesArray("AliTrackReference", 1000)),
     fTreeTR(0),
@@ -72,6 +73,7 @@ AliMCEvent::AliMCEvent(const AliMCEvent& mcEvnt) :
     fMCParticles(mcEvnt.fMCParticles),
     fMCParticleMap(mcEvnt.fMCParticleMap),
     fHeader(mcEvnt.fHeader),
+    fAODMCHeader(mcEvnt.fAODMCHeader),
     fTRBuffer(mcEvnt.fTRBuffer),
     fTrackReferences(mcEvnt.fTrackReferences),
     fTreeTR(mcEvnt.fTreeTR),
@@ -108,14 +110,34 @@ void AliMCEvent::ConnectTreeE (TTree* tree)
 
 void AliMCEvent::ConnectTreeK (TTree* tree)
 {
-    // Connect the kinematics tree to the stack
-    if (!fMCParticles) fMCParticles = new TClonesArray("AliMCParticle",1000);
-    //
+    // Connect Kinematics tree
     fStack = fHeader->Stack();
     fStack->ConnectTree(tree);
     //
     // Load the event
     fStack->GetEvent();
+    
+    UpdateEventInformation();
+}
+
+void AliMCEvent::ConnectHeaderAndStack(AliHeader* header)
+{
+  // fill MC event information from stack and header
+  
+  fHeader = header;
+  fStack = fHeader->Stack();
+
+  UpdateEventInformation();
+}
+void AliMCEvent::UpdateEventInformation()
+{
+    // bookkeeping for next event
+  
+    // Connect the kinematics tree to the stack
+    if (!fMCParticles) fMCParticles = new TClonesArray("AliMCParticle",1000);
+
+    // Initialize members
     fNparticles = fStack->GetNtrack();
     fNprimaries = fStack->GetNprimary();
 
@@ -496,7 +518,7 @@ AliVParticle* AliMCEvent::GetTrack(Int_t i) const
     TParticle     *particle   = 0;
     TClonesArray  *trefs      = 0;
     Int_t          ntref      = 0;
-    TRefArray     *rarray     = 0;
+    TObjArray     *rarray     = 0;
 
 
 
@@ -524,7 +546,7 @@ AliVParticle* AliMCEvent::GetTrack(Int_t i) const
            fTreeTR->GetEntry(fStack->TreeKEntry(i));
            trefs     = fTRBuffer;
            ntref     = trefs->GetEntriesFast();
-           rarray    = new TRefArray(ntref);
+           rarray    = new TObjArray(ntref);
            Int_t nen = fTrackReferences->GetEntriesFast();
            for (Int_t j = 0; j < ntref; j++) {
                // Save the track references in a TClonesArray
@@ -576,10 +598,25 @@ AliVParticle* AliMCEvent::GetTrack(Int_t i) const
     } else {
        mcParticle = dynamic_cast<AliMCParticle*>(fMCParticleMap->At(i));
     }
+
+    //Printf("mcParticleGetMother %d",mcParticle->GetMother());
     return mcParticle;
 }
 
-AliGenEventHeader* AliMCEvent::GenEventHeader() const {return (fHeader->GenEventHeader());}
+AliGenEventHeader* AliMCEvent::GenEventHeader() const 
+{
+  if (!fExternal) {
+    // ESD
+    return (fHeader->GenEventHeader());
+  } else {
+    // AOD
+    if (fAODMCHeader) {
+      TList * lh = fAODMCHeader->GetCocktailHeaders();
+      if (lh) {return ((AliGenEventHeader*) lh->At(0));}
+    }
+  }
+  return 0;
+}
 
 
 void AliMCEvent::AddSubsidiaryEvent(AliMCEvent* event) 
@@ -594,6 +631,39 @@ void AliMCEvent::AddSubsidiaryEvent(AliMCEvent* event)
     fSubsidiaryEvents->Add(event);
 }
 
+AliGenEventHeader *AliMCEvent::FindHeader(Int_t ipart) {
+  //
+  // Get Header belonging to this track; 
+  // only works for primaries (i.e. particles coming from the Generator)
+  // Also sorts out the case of Cocktail event (get header of subevent in cocktail generetor header)  
+  //
+
+  AliMCEvent *event = this;
+
+  if (fSubsidiaryEvents) {
+    // Get pointer to subevent if needed
+    ipart = FindIndexAndEvent(ipart,event); 
+  }
+
+  AliGenEventHeader* header = event->GenEventHeader();
+  if (ipart >= header->NProduced()) {
+    AliWarning(Form("Not a primary -- returning 0 (idx %d, nPrimary %d)",ipart,header->NProduced()));
+    return 0;
+  }
+  AliGenCocktailEventHeader *coHeader = dynamic_cast<AliGenCocktailEventHeader*>(header);
+  if (coHeader) { // Cocktail event
+    TList* headerList = coHeader->GetHeaders();
+    TIter headIt(headerList);
+    Int_t nproduced = 0;
+    do { // Go trhough all headers and look for the correct one
+      header = (AliGenEventHeader*) headIt();
+      if (header) nproduced += header->NProduced();
+    } while (header && ipart >= nproduced);
+  }
+
+  return header;
+}
+
 Int_t AliMCEvent::FindIndexAndEvent(Int_t oldidx, AliMCEvent*& event) const
 {
     // Find the index and event in case of composed events like signal + background
@@ -636,7 +706,7 @@ Int_t AliMCEvent::BgLabelToIndex(Int_t label)
 }
 
 
-Bool_t AliMCEvent::IsPhysicalPrimary(Int_t i) 
+Bool_t AliMCEvent::IsPhysicalPrimary(Int_t i) const
 {
 //
 // Delegate to subevent if necesarry 
@@ -651,6 +721,33 @@ Bool_t AliMCEvent::IsPhysicalPrimary(Int_t i)
     }
 }
 
+Bool_t AliMCEvent::IsSecondaryFromWeakDecay(Int_t i)
+{
+//
+// Delegate to subevent if necesarry 
+    if (!fSubsidiaryEvents) {
+       return fStack->IsSecondaryFromWeakDecay(i);
+    } else {
+       AliMCEvent* evt = 0;
+       Int_t idx = FindIndexAndEvent(i, evt);
+       return (evt->IsSecondaryFromWeakDecay(idx));
+    }
+}
+
+Bool_t AliMCEvent::IsSecondaryFromMaterial(Int_t i)
+{
+//
+// Delegate to subevent if necesarry 
+    if (!fSubsidiaryEvents) {
+       return fStack->IsSecondaryFromMaterial(i);
+    } else {
+       AliMCEvent* evt = 0;
+       Int_t idx = FindIndexAndEvent(i, evt);
+       return (evt->IsSecondaryFromMaterial(idx));
+    }
+}
+
+
 void AliMCEvent::InitEvent()
 {
 //
@@ -693,6 +790,7 @@ void AliMCEvent::PreReadAll()
     {
        GetTrack(i);
     }
+    AssignGeneratorIndex();
 }
 
 const AliVVertex * AliMCEvent::GetPrimaryVertex() const 
@@ -726,4 +824,175 @@ Bool_t AliMCEvent::IsFromBGEvent(Int_t index)
 }
 
 
+    TList* AliMCEvent::GetCocktailList()
+    {
+      //gives the CocktailHeaders when reading ESDs/AODs (corresponding to fExteral=kFALSE/kTRUE)
+      //the AODMC header (and the aodmc array) is passed as an instance to MCEvent by the AliAODInputHandler
+      if(fExternal==kFALSE) { 
+       AliGenCocktailEventHeader* coHeader =dynamic_cast<AliGenCocktailEventHeader*> (GenEventHeader());
+       if(!coHeader) {
+         return 0;
+       } else {
+         return (coHeader->GetHeaders());
+       }
+      } else {
+       if(!fAODMCHeader) { 
+         return 0;
+       } else {
+         return (fAODMCHeader->GetCocktailHeaders());
+       }
+      }
+    }
+
+
+TString AliMCEvent::GetGenerator(Int_t index)
+{
+  Int_t nsumpart=fNprimaries;
+  TList* lh = GetCocktailList();
+  if(!lh){ TString noheader="nococktailheader";
+    return noheader;}
+  Int_t nh=lh->GetEntries();
+  for (Int_t i = nh-1; i >= 0; i--){
+    AliGenEventHeader* gh=(AliGenEventHeader*)lh->At(i);
+    TString genname=gh->GetName();
+    Int_t npart=gh->NProduced();
+    if (i == 0) npart = nsumpart;
+    if(index < nsumpart && index >= (nsumpart-npart)) return genname;
+    nsumpart-=npart;
+  }
+  TString empty="";
+  return empty;
+}
+
+void AliMCEvent::AssignGeneratorIndex() {
+  //
+  // Assign the generator index to each particle
+  //
+  TList* list = GetCocktailList();
+  if (fNprimaries <= 0) {
+    AliWarning(Form("AliMCEvent::AssignGeneratorIndex: no primaries %10d\n", fNprimaries));
+    return;
+}
+  if (!list) {
+    return;
+  } else {
+    Int_t nh = list->GetEntries();
+    Int_t nsumpart = fNprimaries;
+    for(Int_t i = nh-1; i >= 0; i--){
+      AliGenEventHeader* gh = (AliGenEventHeader*)list->At(i);
+      Int_t npart = gh->NProduced();
+      if (i==0) {
+       if (npart != nsumpart) {
+         //      printf("Header inconsistent ! %5d %5d \n", npart, nsumpart);
+       }
+       npart = nsumpart;
+      }
+      //
+      // Loop over primary particles for generator i
+      for (Int_t j = nsumpart-1; j >= nsumpart-npart; j--) {
+       AliVParticle* part = GetTrack(j);
+       if (!part) {
+         AliWarning(Form("AliMCEvent::AssignGeneratorIndex: 0-pointer to particle j %8d npart %8d nsumpart %8d Nprimaries %8d\n", 
+                         j, npart, nsumpart, fNprimaries));
+         break;
+       }
+       part->SetGeneratorIndex(i);
+       Int_t dmin = part->GetFirstDaughter();
+       Int_t dmax = part->GetLastDaughter();
+       if (dmin == -1) continue;
+       AssignGeneratorIndex(i, dmin, dmax);
+      } 
+      nsumpart -= npart;
+    }
+  }
+}
+void AliMCEvent::AssignGeneratorIndex(Int_t index, Int_t dmin, Int_t dmax) {
+  for (Int_t k = dmin; k <= dmax; k++) {
+    AliVParticle* dpart = GetTrack(k);
+    dpart->SetGeneratorIndex(index);
+    Int_t d1 = dpart->GetFirstDaughter();
+    Int_t d2 = dpart->GetLastDaughter();
+    if (d1 > -1) {
+      AssignGeneratorIndex(index, d1, d2);
+    }
+  }
+}
+
+   Bool_t  AliMCEvent::GetCocktailGenerator(Int_t index,TString &nameGen){
+     //method that gives the generator for a given particle with label index (or that of the corresponding primary)
+     AliVParticle* mcpart0 = (AliVParticle*) (GetTrack(index));
+     if(!mcpart0){
+       printf("AliMCEvent-BREAK: No valid AliMCParticle at label %i\n",index);
+       return 0;
+     }
+     /*
+     Int_t ig = mcpart0->GetGeneratorIndex();
+     if (ig != -1) {
+       nameGen = ((AliGenEventHeader*)GetCocktailList()->At(ig))->GetName();
+       return 1;
+     }
+     */
+    nameGen=GetGenerator(index);
+    if(nameGen.Contains("nococktailheader") )return 0;
+    Int_t lab=index;
+
+    while(nameGen.IsWhitespace()){
+      
+      
+    AliVParticle* mcpart = (AliVParticle*) (GetTrack(lab));
+     if(!mcpart){
+      printf("AliMCEvent-BREAK: No valid AliMCParticle at label %i\n",lab);
+      break;}
+     Int_t mother=0;
+     mother = mcpart->GetMother();
+   
+    if(mother<0){
+      printf("AliMCEvent - BREAK: Reached primary particle without valid mother\n");
+      break;
+    }
+      AliVParticle* mcmom = (AliVParticle*) (GetTrack(mother));
+      if(!mcmom){
+      printf("AliMCEvent-BREAK: No valid AliMCParticle mother at label %i\n",mother);
+       break;
+      }
+      lab=mother;
+   
+    nameGen=GetGenerator(mother);
+   }
+   
+   return 1;
+}
+
+void  AliMCEvent::SetParticleArray(TClonesArray* mcParticles) 
+  {
+    fMCParticles = mcParticles; 
+    fNparticles = fMCParticles->GetEntries(); 
+    fExternal = kTRUE; 
+    fNprimaries = 0;
+    struct Local {
+      static Int_t binaryfirst(TClonesArray* a, Int_t low, Int_t high)
+      {
+       Int_t mid  = low + (high - low)/2;
+       if (low > a->GetEntries()-1) return (a->GetEntries()-1);
+       if (!((AliVParticle*) a->At(mid))->IsPrimary()) {
+         if (mid > 1 && !((AliVParticle*) a->At(mid-1))->IsPrimary()) {
+           return binaryfirst(a, low, mid-1);
+         } else {
+           return mid;
+         } 
+       } else {
+         return binaryfirst(a, mid+1, high);
+       }
+      }
+    };
+    fNprimaries = Local::binaryfirst(mcParticles, 0, mcParticles->GetEntries()-1);
+    AssignGeneratorIndex();
+  }
+
+AliVEvent::EDataLayoutType AliMCEvent::GetDataLayoutType() const
+{
+  return AliVEvent::kMC;
+}
+
 ClassImp(AliMCEvent)