ROOT logo
/**************************************************************************
 * Copyright(c) 1998-2007, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id$ */

//-------------------------------------------------------------------------
//     Class for Kinematic Events
//     Author: Andreas Morsch, CERN
//-------------------------------------------------------------------------
#include <TArrow.h>
#include <TMarker.h>
#include <TH2F.h>
#include <TTree.h>
#include <TFile.h>
#include <TParticle.h>
#include <TClonesArray.h>
#include <TList.h>
#include <TArrayF.h>

#include "AliLog.h"
#include "AliMCEvent.h"
#include "AliMCVertex.h"
#include "AliStack.h"
#include "AliTrackReference.h"
#include "AliHeader.h"
#include "AliGenEventHeader.h"
#include "AliGenHijingEventHeader.h"
#include "AliGenCocktailEventHeader.h"


Int_t AliMCEvent::fgkBgLabelOffset(10000000);


AliMCEvent::AliMCEvent():
    AliVEvent(),
    fStack(0),
    fMCParticles(0),
    fMCParticleMap(0),
    fHeader(new AliHeader()),
    fAODMCHeader(0),
    fTRBuffer(0),
    fTrackReferences(new TClonesArray("AliTrackReference", 1000)),
    fTreeTR(0),
    fTmpTreeTR(0),
    fTmpFileTR(0),
    fNprimaries(-1),
    fNparticles(-1),
    fSubsidiaryEvents(0),
    fPrimaryOffset(0),
    fSecondaryOffset(0),
    fExternal(0),
    fVertex(0),
    fNBG(-1)
{
    // Default constructor
}

AliMCEvent::AliMCEvent(const AliMCEvent& mcEvnt) :
    AliVEvent(mcEvnt),
    fStack(mcEvnt.fStack),
    fMCParticles(mcEvnt.fMCParticles),
    fMCParticleMap(mcEvnt.fMCParticleMap),
    fHeader(mcEvnt.fHeader),
    fAODMCHeader(mcEvnt.fAODMCHeader),
    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),
    fVertex(mcEvnt.fVertex),
    fNBG(mcEvnt.fNBG)
{ 
// Copy constructor
}


AliMCEvent& AliMCEvent::operator=(const AliMCEvent& mcEvnt)
{
    // assignment operator
    if (this!=&mcEvnt) { 
	AliVEvent::operator=(mcEvnt); 
    }
  
    return *this; 
}

void AliMCEvent::ConnectTreeE (TTree* tree)
{
    // Connect the event header tree
    tree->SetBranchAddress("Header", &fHeader);
}

void AliMCEvent::ConnectTreeK (TTree* tree)
{
    // 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();

    Int_t iev  = fHeader->GetEvent();
    Int_t ievr = fHeader->GetEventNrInRun();
    AliDebug(1, Form("AliMCEvent# %5d %5d: Number of particles: %5d (all) %5d (primaries)\n", 
		 iev, ievr, fNparticles, fNprimaries));
 
    // This is a cache for the TParticles converted to MCParticles on user request
    if (fMCParticleMap) {
	fMCParticleMap->Clear();
	fMCParticles->Delete();
	if (fNparticles>0) fMCParticleMap->Expand(fNparticles);
    }
    else
	fMCParticleMap = new TObjArray(fNparticles);
}

void AliMCEvent::ConnectTreeTR (TTree* tree)
{
    // Connect the track reference tree
    fTreeTR = tree;
    
    if (fTreeTR->GetBranch("AliRun")) {
	if (fTmpFileTR) {
	    fTmpFileTR->Close();
	    delete fTmpFileTR;
	}
	// This is an old format with one branch per detector not in synch with TreeK
	ReorderAndExpandTreeTR();
    } else {
	// New format 
	fTreeTR->SetBranchAddress("TrackReferences", &fTRBuffer);
    }
}

Int_t AliMCEvent::GetParticleAndTR(Int_t i, TParticle*& particle, TClonesArray*& trefs)
{
    // Retrieve entry i
    if (i < 0 || i >= fNparticles) {
	AliWarning(Form("AliMCEventHandler::GetEntry: Index out of range"));
	particle = 0;
	trefs    = 0;
	return (-1);
    }
    particle = fStack->Particle(i);
    if (fTreeTR) {
	fTreeTR->GetEntry(fStack->TreeKEntry(i));
	trefs    = fTRBuffer;
	return trefs->GetEntries();
    } else {
	trefs = 0;
	return -1;
    }
}


void AliMCEvent::Clean()
{
    // Clean-up before new trees are connected
    delete fStack; fStack = 0;

    // Clear TR
    if (fTRBuffer) {
	fTRBuffer->Delete();
	delete fTRBuffer;
	fTRBuffer = 0;
    }
}

#include <iostream>

void AliMCEvent::FinishEvent()
{
  // Clean-up after event
  //    
    if (fStack) fStack->Reset(0);
    fMCParticles->Delete();
    
    if (fMCParticleMap) 
      fMCParticleMap->Clear();
    if (fTRBuffer) {
      fTRBuffer->Delete();
    }
    //    fTrackReferences->Delete();
    fTrackReferences->Clear();
    fNparticles = -1;
    fNprimaries = -1;    
    fStack      =  0;
//    fSubsidiaryEvents->Clear();
    fSubsidiaryEvents = 0;
    fNBG = -1;
}



void AliMCEvent::DrawCheck(Int_t i, Int_t search)
{
    //
    // Simple event display for debugging
    if (!fTreeTR) {
	AliWarning("No Track Reference information available");
	return;
    } 
    
    if (i > -1 && i < fNparticles) {
	fTreeTR->GetEntry(fStack->TreeKEntry(i));
    } else {
	AliWarning("AliMCEvent::GetEntry: Index out of range");
    }
    
    Int_t nh = fTRBuffer->GetEntries();
    
    
    if (search) {
	while(nh <= search && i < fNparticles - 1) {
	    i++;
	    fTreeTR->GetEntry(fStack->TreeKEntry(i));
	    nh =  fTRBuffer->GetEntries();
	}
	printf("Found Hits at %5d\n", i);
    }
    TParticle* particle = fStack->Particle(i);
    
    TH2F*    h = new TH2F("", "", 100, -500, 500, 100, -500, 500);
    Float_t x0 = particle->Vx();
    Float_t y0 = particle->Vy();

    Float_t x1 = particle->Vx() + particle->Px() * 50.;
    Float_t y1 = particle->Vy() + particle->Py() * 50.;
    
    TArrow*  a = new TArrow(x0, y0, x1, y1, 0.01);
    h->Draw();
    a->SetLineColor(2);
    
    a->Draw();
    
    for (Int_t ih = 0; ih < nh; ih++) {
	AliTrackReference* ref = (AliTrackReference*) fTRBuffer->At(ih);
	TMarker* m = new TMarker(ref->X(), ref->Y(), 20);
	m->Draw();
	m->SetMarkerSize(0.4);
	
    }
}


void AliMCEvent::ReorderAndExpandTreeTR()
{
//
//  Reorder and expand the track reference tree in order to match the kinematics tree.
//  Copy the information from different branches into one
//
//  TreeTR

    fTmpFileTR = new TFile("TrackRefsTmp.root", "recreate");
    fTmpTreeTR = new TTree("TreeTR", "TrackReferences");
    if (!fTRBuffer)  fTRBuffer = new TClonesArray("AliTrackReference", 100);
    fTmpTreeTR->Branch("TrackReferences", "TClonesArray", &fTRBuffer, 64000, 0);
    

//
//  Activate the used branches only. Otherwisw we get a bad memory leak.
    if (fTreeTR) {
	fTreeTR->SetBranchStatus("*",        0);
	fTreeTR->SetBranchStatus("AliRun.*", 1);
	fTreeTR->SetBranchStatus("ITS.*",    1);
	fTreeTR->SetBranchStatus("TPC.*",    1);
	fTreeTR->SetBranchStatus("TRD.*",    1);
	fTreeTR->SetBranchStatus("TOF.*",    1);
	fTreeTR->SetBranchStatus("FRAME.*",  1);
	fTreeTR->SetBranchStatus("MUON.*",   1);
    }
    
//
//  Connect the active branches
    TClonesArray* trefs[7];
    for (Int_t i = 0; i < 7; i++) trefs[i] = 0;
    if (fTreeTR){
	// make branch for central track references
	if (fTreeTR->GetBranch("AliRun")) fTreeTR->SetBranchAddress("AliRun", &trefs[0]);
	if (fTreeTR->GetBranch("ITS"))    fTreeTR->SetBranchAddress("ITS",    &trefs[1]);
	if (fTreeTR->GetBranch("TPC"))    fTreeTR->SetBranchAddress("TPC",    &trefs[2]);
	if (fTreeTR->GetBranch("TRD"))    fTreeTR->SetBranchAddress("TRD",    &trefs[3]);
	if (fTreeTR->GetBranch("TOF"))    fTreeTR->SetBranchAddress("TOF",    &trefs[4]);
	if (fTreeTR->GetBranch("FRAME"))  fTreeTR->SetBranchAddress("FRAME",  &trefs[5]);
	if (fTreeTR->GetBranch("MUON"))   fTreeTR->SetBranchAddress("MUON",   &trefs[6]);
    }

    Int_t np = fStack->GetNprimary();
    Int_t nt = fTreeTR->GetEntries();
    
    //
    // Loop over tracks and find the secondaries with the help of the kine tree
    Int_t ifills = 0;
    Int_t it     = 0;
    Int_t itlast = 0;
    TParticle* part;

    for (Int_t ip = np - 1; ip > -1; ip--) {
	part = fStack->Particle(ip);
//	printf("Particle %5d %5d %5d %5d %5d %5d \n", 
//	       ip, part->GetPdgCode(), part->GetFirstMother(), part->GetFirstDaughter(), 
//	       part->GetLastDaughter(), part->TestBit(kTransportBit));

	// Determine range of secondaries produced by this primary during transport	
	Int_t dau1  = part->GetFirstDaughter();
	if (dau1 < np) continue;  // This particle has no secondaries produced during transport
	Int_t dau2  = -1;
	if (dau1 > -1) {
	    Int_t inext = ip - 1;
	    while (dau2 < 0) {
		if (inext >= 0) {
		    part = fStack->Particle(inext);
		    dau2 =  part->GetFirstDaughter();
		    if (dau2 == -1 || dau2 < np) {
			dau2 = -1;
		    } else {
			dau2--;
		    }
		} else {
		    dau2 = fStack->GetNtrack() - 1;
		}
		inext--;
	    } // find upper bound
	}  // dau2 < 0
	

//	printf("Check (1) %5d %5d %5d %5d %5d \n", ip, np, it, dau1, dau2);
//
// Loop over reference hits and find secondary label
// First the tricky part: find the entry in treeTR than contains the hits or
// make sure that no hits exist.
//
	Bool_t hasHits   = kFALSE;
	Bool_t isOutside = kFALSE;

	it = itlast;
	while (!hasHits && !isOutside && it < nt) {
	    fTreeTR->GetEntry(it++);
	    for (Int_t ib = 0; ib < 7; ib++) {
		if (!trefs[ib]) continue;
		Int_t nh = trefs[ib]->GetEntries();
		for (Int_t ih = 0; ih < nh; ih++) {
		    AliTrackReference* tr = (AliTrackReference*) trefs[ib]->At(ih);
		    Int_t label = tr->Label();
		    if (label >= dau1 && label <= dau2) {
			hasHits = kTRUE;
			itlast = it - 1;
			break;
		    }
		    if (label > dau2 || label < ip) {
			isOutside = kTRUE;
			itlast = it - 1;
			break;
		    }
		} // hits
		if (hasHits || isOutside) break;
	    } // branches
	} // entries

	if (!hasHits) {
	    // Write empty entries
	    for (Int_t id = dau1; (id <= dau2); id++) {
		fTmpTreeTR->Fill();
		ifills++;
	    } 
	} else {
	    // Collect all hits
	    fTreeTR->GetEntry(itlast);
	    for (Int_t id = dau1; (id <= dau2) && (dau1 > -1); id++) {
		for (Int_t ib = 0; ib < 7; ib++) {
		    if (!trefs[ib]) continue;
		    Int_t nh = trefs[ib]->GetEntries();
		    for (Int_t ih = 0; ih < nh; ih++) {
			AliTrackReference* tr = (AliTrackReference*) trefs[ib]->At(ih);
			Int_t label = tr->Label();
			// Skip primaries
			if (label == ip) continue;
			if (label > dau2 || label < dau1) 
			    printf("AliMCEventHandler::Track Reference Label out of range !: %5d %5d %5d %5d \n", 
				   itlast, label, dau1, dau2);
			if (label == id) {
			    // secondary found
			    tr->SetDetectorId(ib-1);
			    Int_t nref =  fTRBuffer->GetEntriesFast();
			    TClonesArray &lref = *fTRBuffer;
			    new(lref[nref]) AliTrackReference(*tr);
			}
		    } // hits
		} // branches
		fTmpTreeTR->Fill();
		fTRBuffer->Delete();
		ifills++;
	    } // daughters
	} // has hits
    } // tracks

    //
    // Now loop again and write the primaries
    //
    it = nt - 1;
    for (Int_t ip = 0; ip < np; ip++) {
	Int_t labmax = -1;
	while (labmax < ip && it > -1) {
	    fTreeTR->GetEntry(it--);
	    for (Int_t ib = 0; ib < 7; ib++) {
		if (!trefs[ib]) continue;
		Int_t nh = trefs[ib]->GetEntries();
		// 
		// Loop over reference hits and find primary labels
		for (Int_t ih = 0; ih < nh; ih++) {
		    AliTrackReference* tr = (AliTrackReference*)  trefs[ib]->At(ih);
		    Int_t label = tr->Label();
		    if (label < np && label > labmax) {
			labmax = label;
		    }
		    
		    if (label == ip) {
			tr->SetDetectorId(ib-1);
			Int_t nref = fTRBuffer->GetEntriesFast();
			TClonesArray &lref = *fTRBuffer;
			new(lref[nref]) AliTrackReference(*tr);
		    }
		} // hits
	    } // branches
	} // entries
	it++;
	fTmpTreeTR->Fill();
	fTRBuffer->Delete();
	ifills++;
    } // tracks
    // Check


    // Clean-up
    delete fTreeTR; fTreeTR = 0;
    
    for (Int_t ib = 0; ib < 7; ib++) {
	if (trefs[ib]) {
	    trefs[ib]->Clear();
	    delete trefs[ib];
	    trefs[ib] = 0;
	}
    }

    if (ifills != fStack->GetNtrack()) 
	printf("AliMCEvent:Number of entries in TreeTR (%5d) unequal to TreeK (%5d) \n", 
	       ifills, fStack->GetNtrack());

    fTmpTreeTR->Write();
    fTreeTR = fTmpTreeTR;
}

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;
    TObjArray     *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 If the MC Particle has been already cached
    if(!fMCParticleMap->At(i)) {
	// Get particle from the stack
	particle   = fStack->Particle(i);
	// Get track references from Tree TR
	if (fTreeTR) {
	    fTreeTR->GetEntry(fStack->TreeKEntry(i));
	    trefs     = fTRBuffer;
	    ntref     = trefs->GetEntriesFast();
	    rarray    = new TObjArray(ntref);
	    Int_t nen = fTrackReferences->GetEntriesFast();
	    for (Int_t j = 0; j < ntref; j++) {
		// Save the track references in a TClonesArray
		AliTrackReference* ref = dynamic_cast<AliTrackReference*>((*fTRBuffer)[j]);
		// Save the pointer in a TRefArray
		if (ref) {
		    new ((*fTrackReferences)[nen]) AliTrackReference(*ref);
		    rarray->AddAt((*fTrackReferences)[nen], j);
		    nen++;
		}
	    } // loop over track references for entry i
	} // if TreeTR available
	Int_t nentries = fMCParticles->GetEntriesFast();
	mcParticle = new ((*fMCParticles)[nentries]) AliMCParticle(particle, rarray, i);
	fMCParticleMap->AddAt(mcParticle, i);
	if (mcParticle) {
	    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));
    }

    //Printf("mcParticleGetMother %d",mcParticle->GetMother());
    return mcParticle;
}

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) 
{
    // 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);
}

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
    TIter next(fSubsidiaryEvents);
    next.Reset();
     if (oldidx < fNprimaries) {
	while((event = (AliMCEvent*)next())) {
	    if (oldidx < (event->GetPrimaryOffset() + event->GetNumberOfPrimaries())) break;
	}
	if (event) {
	    return (oldidx - event->GetPrimaryOffset());
	} else {
	    return (-1);
	}
    } else {
	while((event = (AliMCEvent*)next())) {
	    if (oldidx < (event->GetSecondaryOffset() + (event->GetNumberOfTracks() - event->GetNumberOfPrimaries()))) break;
	}
	if (event) {
	    return (oldidx - event->GetSecondaryOffset() + event->GetNumberOfPrimaries());
	} else {
	    return (-1);
	}
    }
}

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) const
{
//
// 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));
    }
}

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()
{
//
// Initialize the subsidiary event structure
    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());	    
	}
    }
}

void AliMCEvent::PreReadAll()                              
{
    // Preread the MC information
    Int_t i;
    // secondaries
    for (i = fStack->GetNprimary(); i < fStack->GetNtrack(); i++) 
    {
	GetTrack(i);
    }
    // primaries
    for (i = 0; i < fStack->GetNprimary(); i++) 
    {
	GetTrack(i);
    }
    AssignGeneratorIndex();
}

const AliVVertex * AliMCEvent::GetPrimaryVertex() const 
{
    // Create a MCVertex object from the MCHeader information
    TArrayF v;
    GenEventHeader()->PrimaryVertex(v) ;
    if (!fVertex) {
	fVertex = new AliMCVertex(v[0], v[1], v[2]);
    } else {
	((AliMCVertex*) fVertex)->SetPosition(v[0], v[1], v[2]);
    }
    return fVertex;
}

Bool_t AliMCEvent::IsFromBGEvent(Int_t index)
{
    // Checks if a particle is from the background events
    // Works for HIJING inside Cocktail
    if (fNBG == -1) {
	AliGenCocktailEventHeader* coHeader = 
	    dynamic_cast<AliGenCocktailEventHeader*> (GenEventHeader());
	if (!coHeader) return (0);
	TList* list = coHeader->GetHeaders();
	AliGenHijingEventHeader* hijingH = dynamic_cast<AliGenHijingEventHeader*>(list->FindObject("Hijing"));
	if (!hijingH) return (0);
	fNBG = hijingH->NProduced();
    }
    
    return (index < fNBG);
}


    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)
 AliMCEvent.cxx:1
 AliMCEvent.cxx:2
 AliMCEvent.cxx:3
 AliMCEvent.cxx:4
 AliMCEvent.cxx:5
 AliMCEvent.cxx:6
 AliMCEvent.cxx:7
 AliMCEvent.cxx:8
 AliMCEvent.cxx:9
 AliMCEvent.cxx:10
 AliMCEvent.cxx:11
 AliMCEvent.cxx:12
 AliMCEvent.cxx:13
 AliMCEvent.cxx:14
 AliMCEvent.cxx:15
 AliMCEvent.cxx:16
 AliMCEvent.cxx:17
 AliMCEvent.cxx:18
 AliMCEvent.cxx:19
 AliMCEvent.cxx:20
 AliMCEvent.cxx:21
 AliMCEvent.cxx:22
 AliMCEvent.cxx:23
 AliMCEvent.cxx:24
 AliMCEvent.cxx:25
 AliMCEvent.cxx:26
 AliMCEvent.cxx:27
 AliMCEvent.cxx:28
 AliMCEvent.cxx:29
 AliMCEvent.cxx:30
 AliMCEvent.cxx:31
 AliMCEvent.cxx:32
 AliMCEvent.cxx:33
 AliMCEvent.cxx:34
 AliMCEvent.cxx:35
 AliMCEvent.cxx:36
 AliMCEvent.cxx:37
 AliMCEvent.cxx:38
 AliMCEvent.cxx:39
 AliMCEvent.cxx:40
 AliMCEvent.cxx:41
 AliMCEvent.cxx:42
 AliMCEvent.cxx:43
 AliMCEvent.cxx:44
 AliMCEvent.cxx:45
 AliMCEvent.cxx:46
 AliMCEvent.cxx:47
 AliMCEvent.cxx:48
 AliMCEvent.cxx:49
 AliMCEvent.cxx:50
 AliMCEvent.cxx:51
 AliMCEvent.cxx:52
 AliMCEvent.cxx:53
 AliMCEvent.cxx:54
 AliMCEvent.cxx:55
 AliMCEvent.cxx:56
 AliMCEvent.cxx:57
 AliMCEvent.cxx:58
 AliMCEvent.cxx:59
 AliMCEvent.cxx:60
 AliMCEvent.cxx:61
 AliMCEvent.cxx:62
 AliMCEvent.cxx:63
 AliMCEvent.cxx:64
 AliMCEvent.cxx:65
 AliMCEvent.cxx:66
 AliMCEvent.cxx:67
 AliMCEvent.cxx:68
 AliMCEvent.cxx:69
 AliMCEvent.cxx:70
 AliMCEvent.cxx:71
 AliMCEvent.cxx:72
 AliMCEvent.cxx:73
 AliMCEvent.cxx:74
 AliMCEvent.cxx:75
 AliMCEvent.cxx:76
 AliMCEvent.cxx:77
 AliMCEvent.cxx:78
 AliMCEvent.cxx:79
 AliMCEvent.cxx:80
 AliMCEvent.cxx:81
 AliMCEvent.cxx:82
 AliMCEvent.cxx:83
 AliMCEvent.cxx:84
 AliMCEvent.cxx:85
 AliMCEvent.cxx:86
 AliMCEvent.cxx:87
 AliMCEvent.cxx:88
 AliMCEvent.cxx:89
 AliMCEvent.cxx:90
 AliMCEvent.cxx:91
 AliMCEvent.cxx:92
 AliMCEvent.cxx:93
 AliMCEvent.cxx:94
 AliMCEvent.cxx:95
 AliMCEvent.cxx:96
 AliMCEvent.cxx:97
 AliMCEvent.cxx:98
 AliMCEvent.cxx:99
 AliMCEvent.cxx:100
 AliMCEvent.cxx:101
 AliMCEvent.cxx:102
 AliMCEvent.cxx:103
 AliMCEvent.cxx:104
 AliMCEvent.cxx:105
 AliMCEvent.cxx:106
 AliMCEvent.cxx:107
 AliMCEvent.cxx:108
 AliMCEvent.cxx:109
 AliMCEvent.cxx:110
 AliMCEvent.cxx:111
 AliMCEvent.cxx:112
 AliMCEvent.cxx:113
 AliMCEvent.cxx:114
 AliMCEvent.cxx:115
 AliMCEvent.cxx:116
 AliMCEvent.cxx:117
 AliMCEvent.cxx:118
 AliMCEvent.cxx:119
 AliMCEvent.cxx:120
 AliMCEvent.cxx:121
 AliMCEvent.cxx:122
 AliMCEvent.cxx:123
 AliMCEvent.cxx:124
 AliMCEvent.cxx:125
 AliMCEvent.cxx:126
 AliMCEvent.cxx:127
 AliMCEvent.cxx:128
 AliMCEvent.cxx:129
 AliMCEvent.cxx:130
 AliMCEvent.cxx:131
 AliMCEvent.cxx:132
 AliMCEvent.cxx:133
 AliMCEvent.cxx:134
 AliMCEvent.cxx:135
 AliMCEvent.cxx:136
 AliMCEvent.cxx:137
 AliMCEvent.cxx:138
 AliMCEvent.cxx:139
 AliMCEvent.cxx:140
 AliMCEvent.cxx:141
 AliMCEvent.cxx:142
 AliMCEvent.cxx:143
 AliMCEvent.cxx:144
 AliMCEvent.cxx:145
 AliMCEvent.cxx:146
 AliMCEvent.cxx:147
 AliMCEvent.cxx:148
 AliMCEvent.cxx:149
 AliMCEvent.cxx:150
 AliMCEvent.cxx:151
 AliMCEvent.cxx:152
 AliMCEvent.cxx:153
 AliMCEvent.cxx:154
 AliMCEvent.cxx:155
 AliMCEvent.cxx:156
 AliMCEvent.cxx:157
 AliMCEvent.cxx:158
 AliMCEvent.cxx:159
 AliMCEvent.cxx:160
 AliMCEvent.cxx:161
 AliMCEvent.cxx:162
 AliMCEvent.cxx:163
 AliMCEvent.cxx:164
 AliMCEvent.cxx:165
 AliMCEvent.cxx:166
 AliMCEvent.cxx:167
 AliMCEvent.cxx:168
 AliMCEvent.cxx:169
 AliMCEvent.cxx:170
 AliMCEvent.cxx:171
 AliMCEvent.cxx:172
 AliMCEvent.cxx:173
 AliMCEvent.cxx:174
 AliMCEvent.cxx:175
 AliMCEvent.cxx:176
 AliMCEvent.cxx:177
 AliMCEvent.cxx:178
 AliMCEvent.cxx:179
 AliMCEvent.cxx:180
 AliMCEvent.cxx:181
 AliMCEvent.cxx:182
 AliMCEvent.cxx:183
 AliMCEvent.cxx:184
 AliMCEvent.cxx:185
 AliMCEvent.cxx:186
 AliMCEvent.cxx:187
 AliMCEvent.cxx:188
 AliMCEvent.cxx:189
 AliMCEvent.cxx:190
 AliMCEvent.cxx:191
 AliMCEvent.cxx:192
 AliMCEvent.cxx:193
 AliMCEvent.cxx:194
 AliMCEvent.cxx:195
 AliMCEvent.cxx:196
 AliMCEvent.cxx:197
 AliMCEvent.cxx:198
 AliMCEvent.cxx:199
 AliMCEvent.cxx:200
 AliMCEvent.cxx:201
 AliMCEvent.cxx:202
 AliMCEvent.cxx:203
 AliMCEvent.cxx:204
 AliMCEvent.cxx:205
 AliMCEvent.cxx:206
 AliMCEvent.cxx:207
 AliMCEvent.cxx:208
 AliMCEvent.cxx:209
 AliMCEvent.cxx:210
 AliMCEvent.cxx:211
 AliMCEvent.cxx:212
 AliMCEvent.cxx:213
 AliMCEvent.cxx:214
 AliMCEvent.cxx:215
 AliMCEvent.cxx:216
 AliMCEvent.cxx:217
 AliMCEvent.cxx:218
 AliMCEvent.cxx:219
 AliMCEvent.cxx:220
 AliMCEvent.cxx:221
 AliMCEvent.cxx:222
 AliMCEvent.cxx:223
 AliMCEvent.cxx:224
 AliMCEvent.cxx:225
 AliMCEvent.cxx:226
 AliMCEvent.cxx:227
 AliMCEvent.cxx:228
 AliMCEvent.cxx:229
 AliMCEvent.cxx:230
 AliMCEvent.cxx:231
 AliMCEvent.cxx:232
 AliMCEvent.cxx:233
 AliMCEvent.cxx:234
 AliMCEvent.cxx:235
 AliMCEvent.cxx:236
 AliMCEvent.cxx:237
 AliMCEvent.cxx:238
 AliMCEvent.cxx:239
 AliMCEvent.cxx:240
 AliMCEvent.cxx:241
 AliMCEvent.cxx:242
 AliMCEvent.cxx:243
 AliMCEvent.cxx:244
 AliMCEvent.cxx:245
 AliMCEvent.cxx:246
 AliMCEvent.cxx:247
 AliMCEvent.cxx:248
 AliMCEvent.cxx:249
 AliMCEvent.cxx:250
 AliMCEvent.cxx:251
 AliMCEvent.cxx:252
 AliMCEvent.cxx:253
 AliMCEvent.cxx:254
 AliMCEvent.cxx:255
 AliMCEvent.cxx:256
 AliMCEvent.cxx:257
 AliMCEvent.cxx:258
 AliMCEvent.cxx:259
 AliMCEvent.cxx:260
 AliMCEvent.cxx:261
 AliMCEvent.cxx:262
 AliMCEvent.cxx:263
 AliMCEvent.cxx:264
 AliMCEvent.cxx:265
 AliMCEvent.cxx:266
 AliMCEvent.cxx:267
 AliMCEvent.cxx:268
 AliMCEvent.cxx:269
 AliMCEvent.cxx:270
 AliMCEvent.cxx:271
 AliMCEvent.cxx:272
 AliMCEvent.cxx:273
 AliMCEvent.cxx:274
 AliMCEvent.cxx:275
 AliMCEvent.cxx:276
 AliMCEvent.cxx:277
 AliMCEvent.cxx:278
 AliMCEvent.cxx:279
 AliMCEvent.cxx:280
 AliMCEvent.cxx:281
 AliMCEvent.cxx:282
 AliMCEvent.cxx:283
 AliMCEvent.cxx:284
 AliMCEvent.cxx:285
 AliMCEvent.cxx:286
 AliMCEvent.cxx:287
 AliMCEvent.cxx:288
 AliMCEvent.cxx:289
 AliMCEvent.cxx:290
 AliMCEvent.cxx:291
 AliMCEvent.cxx:292
 AliMCEvent.cxx:293
 AliMCEvent.cxx:294
 AliMCEvent.cxx:295
 AliMCEvent.cxx:296
 AliMCEvent.cxx:297
 AliMCEvent.cxx:298
 AliMCEvent.cxx:299
 AliMCEvent.cxx:300
 AliMCEvent.cxx:301
 AliMCEvent.cxx:302
 AliMCEvent.cxx:303
 AliMCEvent.cxx:304
 AliMCEvent.cxx:305
 AliMCEvent.cxx:306
 AliMCEvent.cxx:307
 AliMCEvent.cxx:308
 AliMCEvent.cxx:309
 AliMCEvent.cxx:310
 AliMCEvent.cxx:311
 AliMCEvent.cxx:312
 AliMCEvent.cxx:313
 AliMCEvent.cxx:314
 AliMCEvent.cxx:315
 AliMCEvent.cxx:316
 AliMCEvent.cxx:317
 AliMCEvent.cxx:318
 AliMCEvent.cxx:319
 AliMCEvent.cxx:320
 AliMCEvent.cxx:321
 AliMCEvent.cxx:322
 AliMCEvent.cxx:323
 AliMCEvent.cxx:324
 AliMCEvent.cxx:325
 AliMCEvent.cxx:326
 AliMCEvent.cxx:327
 AliMCEvent.cxx:328
 AliMCEvent.cxx:329
 AliMCEvent.cxx:330
 AliMCEvent.cxx:331
 AliMCEvent.cxx:332
 AliMCEvent.cxx:333
 AliMCEvent.cxx:334
 AliMCEvent.cxx:335
 AliMCEvent.cxx:336
 AliMCEvent.cxx:337
 AliMCEvent.cxx:338
 AliMCEvent.cxx:339
 AliMCEvent.cxx:340
 AliMCEvent.cxx:341
 AliMCEvent.cxx:342
 AliMCEvent.cxx:343
 AliMCEvent.cxx:344
 AliMCEvent.cxx:345
 AliMCEvent.cxx:346
 AliMCEvent.cxx:347
 AliMCEvent.cxx:348
 AliMCEvent.cxx:349
 AliMCEvent.cxx:350
 AliMCEvent.cxx:351
 AliMCEvent.cxx:352
 AliMCEvent.cxx:353
 AliMCEvent.cxx:354
 AliMCEvent.cxx:355
 AliMCEvent.cxx:356
 AliMCEvent.cxx:357
 AliMCEvent.cxx:358
 AliMCEvent.cxx:359
 AliMCEvent.cxx:360
 AliMCEvent.cxx:361
 AliMCEvent.cxx:362
 AliMCEvent.cxx:363
 AliMCEvent.cxx:364
 AliMCEvent.cxx:365
 AliMCEvent.cxx:366
 AliMCEvent.cxx:367
 AliMCEvent.cxx:368
 AliMCEvent.cxx:369
 AliMCEvent.cxx:370
 AliMCEvent.cxx:371
 AliMCEvent.cxx:372
 AliMCEvent.cxx:373
 AliMCEvent.cxx:374
 AliMCEvent.cxx:375
 AliMCEvent.cxx:376
 AliMCEvent.cxx:377
 AliMCEvent.cxx:378
 AliMCEvent.cxx:379
 AliMCEvent.cxx:380
 AliMCEvent.cxx:381
 AliMCEvent.cxx:382
 AliMCEvent.cxx:383
 AliMCEvent.cxx:384
 AliMCEvent.cxx:385
 AliMCEvent.cxx:386
 AliMCEvent.cxx:387
 AliMCEvent.cxx:388
 AliMCEvent.cxx:389
 AliMCEvent.cxx:390
 AliMCEvent.cxx:391
 AliMCEvent.cxx:392
 AliMCEvent.cxx:393
 AliMCEvent.cxx:394
 AliMCEvent.cxx:395
 AliMCEvent.cxx:396
 AliMCEvent.cxx:397
 AliMCEvent.cxx:398
 AliMCEvent.cxx:399
 AliMCEvent.cxx:400
 AliMCEvent.cxx:401
 AliMCEvent.cxx:402
 AliMCEvent.cxx:403
 AliMCEvent.cxx:404
 AliMCEvent.cxx:405
 AliMCEvent.cxx:406
 AliMCEvent.cxx:407
 AliMCEvent.cxx:408
 AliMCEvent.cxx:409
 AliMCEvent.cxx:410
 AliMCEvent.cxx:411
 AliMCEvent.cxx:412
 AliMCEvent.cxx:413
 AliMCEvent.cxx:414
 AliMCEvent.cxx:415
 AliMCEvent.cxx:416
 AliMCEvent.cxx:417
 AliMCEvent.cxx:418
 AliMCEvent.cxx:419
 AliMCEvent.cxx:420
 AliMCEvent.cxx:421
 AliMCEvent.cxx:422
 AliMCEvent.cxx:423
 AliMCEvent.cxx:424
 AliMCEvent.cxx:425
 AliMCEvent.cxx:426
 AliMCEvent.cxx:427
 AliMCEvent.cxx:428
 AliMCEvent.cxx:429
 AliMCEvent.cxx:430
 AliMCEvent.cxx:431
 AliMCEvent.cxx:432
 AliMCEvent.cxx:433
 AliMCEvent.cxx:434
 AliMCEvent.cxx:435
 AliMCEvent.cxx:436
 AliMCEvent.cxx:437
 AliMCEvent.cxx:438
 AliMCEvent.cxx:439
 AliMCEvent.cxx:440
 AliMCEvent.cxx:441
 AliMCEvent.cxx:442
 AliMCEvent.cxx:443
 AliMCEvent.cxx:444
 AliMCEvent.cxx:445
 AliMCEvent.cxx:446
 AliMCEvent.cxx:447
 AliMCEvent.cxx:448
 AliMCEvent.cxx:449
 AliMCEvent.cxx:450
 AliMCEvent.cxx:451
 AliMCEvent.cxx:452
 AliMCEvent.cxx:453
 AliMCEvent.cxx:454
 AliMCEvent.cxx:455
 AliMCEvent.cxx:456
 AliMCEvent.cxx:457
 AliMCEvent.cxx:458
 AliMCEvent.cxx:459
 AliMCEvent.cxx:460
 AliMCEvent.cxx:461
 AliMCEvent.cxx:462
 AliMCEvent.cxx:463
 AliMCEvent.cxx:464
 AliMCEvent.cxx:465
 AliMCEvent.cxx:466
 AliMCEvent.cxx:467
 AliMCEvent.cxx:468
 AliMCEvent.cxx:469
 AliMCEvent.cxx:470
 AliMCEvent.cxx:471
 AliMCEvent.cxx:472
 AliMCEvent.cxx:473
 AliMCEvent.cxx:474
 AliMCEvent.cxx:475
 AliMCEvent.cxx:476
 AliMCEvent.cxx:477
 AliMCEvent.cxx:478
 AliMCEvent.cxx:479
 AliMCEvent.cxx:480
 AliMCEvent.cxx:481
 AliMCEvent.cxx:482
 AliMCEvent.cxx:483
 AliMCEvent.cxx:484
 AliMCEvent.cxx:485
 AliMCEvent.cxx:486
 AliMCEvent.cxx:487
 AliMCEvent.cxx:488
 AliMCEvent.cxx:489
 AliMCEvent.cxx:490
 AliMCEvent.cxx:491
 AliMCEvent.cxx:492
 AliMCEvent.cxx:493
 AliMCEvent.cxx:494
 AliMCEvent.cxx:495
 AliMCEvent.cxx:496
 AliMCEvent.cxx:497
 AliMCEvent.cxx:498
 AliMCEvent.cxx:499
 AliMCEvent.cxx:500
 AliMCEvent.cxx:501
 AliMCEvent.cxx:502
 AliMCEvent.cxx:503
 AliMCEvent.cxx:504
 AliMCEvent.cxx:505
 AliMCEvent.cxx:506
 AliMCEvent.cxx:507
 AliMCEvent.cxx:508
 AliMCEvent.cxx:509
 AliMCEvent.cxx:510
 AliMCEvent.cxx:511
 AliMCEvent.cxx:512
 AliMCEvent.cxx:513
 AliMCEvent.cxx:514
 AliMCEvent.cxx:515
 AliMCEvent.cxx:516
 AliMCEvent.cxx:517
 AliMCEvent.cxx:518
 AliMCEvent.cxx:519
 AliMCEvent.cxx:520
 AliMCEvent.cxx:521
 AliMCEvent.cxx:522
 AliMCEvent.cxx:523
 AliMCEvent.cxx:524
 AliMCEvent.cxx:525
 AliMCEvent.cxx:526
 AliMCEvent.cxx:527
 AliMCEvent.cxx:528
 AliMCEvent.cxx:529
 AliMCEvent.cxx:530
 AliMCEvent.cxx:531
 AliMCEvent.cxx:532
 AliMCEvent.cxx:533
 AliMCEvent.cxx:534
 AliMCEvent.cxx:535
 AliMCEvent.cxx:536
 AliMCEvent.cxx:537
 AliMCEvent.cxx:538
 AliMCEvent.cxx:539
 AliMCEvent.cxx:540
 AliMCEvent.cxx:541
 AliMCEvent.cxx:542
 AliMCEvent.cxx:543
 AliMCEvent.cxx:544
 AliMCEvent.cxx:545
 AliMCEvent.cxx:546
 AliMCEvent.cxx:547
 AliMCEvent.cxx:548
 AliMCEvent.cxx:549
 AliMCEvent.cxx:550
 AliMCEvent.cxx:551
 AliMCEvent.cxx:552
 AliMCEvent.cxx:553
 AliMCEvent.cxx:554
 AliMCEvent.cxx:555
 AliMCEvent.cxx:556
 AliMCEvent.cxx:557
 AliMCEvent.cxx:558
 AliMCEvent.cxx:559
 AliMCEvent.cxx:560
 AliMCEvent.cxx:561
 AliMCEvent.cxx:562
 AliMCEvent.cxx:563
 AliMCEvent.cxx:564
 AliMCEvent.cxx:565
 AliMCEvent.cxx:566
 AliMCEvent.cxx:567
 AliMCEvent.cxx:568
 AliMCEvent.cxx:569
 AliMCEvent.cxx:570
 AliMCEvent.cxx:571
 AliMCEvent.cxx:572
 AliMCEvent.cxx:573
 AliMCEvent.cxx:574
 AliMCEvent.cxx:575
 AliMCEvent.cxx:576
 AliMCEvent.cxx:577
 AliMCEvent.cxx:578
 AliMCEvent.cxx:579
 AliMCEvent.cxx:580
 AliMCEvent.cxx:581
 AliMCEvent.cxx:582
 AliMCEvent.cxx:583
 AliMCEvent.cxx:584
 AliMCEvent.cxx:585
 AliMCEvent.cxx:586
 AliMCEvent.cxx:587
 AliMCEvent.cxx:588
 AliMCEvent.cxx:589
 AliMCEvent.cxx:590
 AliMCEvent.cxx:591
 AliMCEvent.cxx:592
 AliMCEvent.cxx:593
 AliMCEvent.cxx:594
 AliMCEvent.cxx:595
 AliMCEvent.cxx:596
 AliMCEvent.cxx:597
 AliMCEvent.cxx:598
 AliMCEvent.cxx:599
 AliMCEvent.cxx:600
 AliMCEvent.cxx:601
 AliMCEvent.cxx:602
 AliMCEvent.cxx:603
 AliMCEvent.cxx:604
 AliMCEvent.cxx:605
 AliMCEvent.cxx:606
 AliMCEvent.cxx:607
 AliMCEvent.cxx:608
 AliMCEvent.cxx:609
 AliMCEvent.cxx:610
 AliMCEvent.cxx:611
 AliMCEvent.cxx:612
 AliMCEvent.cxx:613
 AliMCEvent.cxx:614
 AliMCEvent.cxx:615
 AliMCEvent.cxx:616
 AliMCEvent.cxx:617
 AliMCEvent.cxx:618
 AliMCEvent.cxx:619
 AliMCEvent.cxx:620
 AliMCEvent.cxx:621
 AliMCEvent.cxx:622
 AliMCEvent.cxx:623
 AliMCEvent.cxx:624
 AliMCEvent.cxx:625
 AliMCEvent.cxx:626
 AliMCEvent.cxx:627
 AliMCEvent.cxx:628
 AliMCEvent.cxx:629
 AliMCEvent.cxx:630
 AliMCEvent.cxx:631
 AliMCEvent.cxx:632
 AliMCEvent.cxx:633
 AliMCEvent.cxx:634
 AliMCEvent.cxx:635
 AliMCEvent.cxx:636
 AliMCEvent.cxx:637
 AliMCEvent.cxx:638
 AliMCEvent.cxx:639
 AliMCEvent.cxx:640
 AliMCEvent.cxx:641
 AliMCEvent.cxx:642
 AliMCEvent.cxx:643
 AliMCEvent.cxx:644
 AliMCEvent.cxx:645
 AliMCEvent.cxx:646
 AliMCEvent.cxx:647
 AliMCEvent.cxx:648
 AliMCEvent.cxx:649
 AliMCEvent.cxx:650
 AliMCEvent.cxx:651
 AliMCEvent.cxx:652
 AliMCEvent.cxx:653
 AliMCEvent.cxx:654
 AliMCEvent.cxx:655
 AliMCEvent.cxx:656
 AliMCEvent.cxx:657
 AliMCEvent.cxx:658
 AliMCEvent.cxx:659
 AliMCEvent.cxx:660
 AliMCEvent.cxx:661
 AliMCEvent.cxx:662
 AliMCEvent.cxx:663
 AliMCEvent.cxx:664
 AliMCEvent.cxx:665
 AliMCEvent.cxx:666
 AliMCEvent.cxx:667
 AliMCEvent.cxx:668
 AliMCEvent.cxx:669
 AliMCEvent.cxx:670
 AliMCEvent.cxx:671
 AliMCEvent.cxx:672
 AliMCEvent.cxx:673
 AliMCEvent.cxx:674
 AliMCEvent.cxx:675
 AliMCEvent.cxx:676
 AliMCEvent.cxx:677
 AliMCEvent.cxx:678
 AliMCEvent.cxx:679
 AliMCEvent.cxx:680
 AliMCEvent.cxx:681
 AliMCEvent.cxx:682
 AliMCEvent.cxx:683
 AliMCEvent.cxx:684
 AliMCEvent.cxx:685
 AliMCEvent.cxx:686
 AliMCEvent.cxx:687
 AliMCEvent.cxx:688
 AliMCEvent.cxx:689
 AliMCEvent.cxx:690
 AliMCEvent.cxx:691
 AliMCEvent.cxx:692
 AliMCEvent.cxx:693
 AliMCEvent.cxx:694
 AliMCEvent.cxx:695
 AliMCEvent.cxx:696
 AliMCEvent.cxx:697
 AliMCEvent.cxx:698
 AliMCEvent.cxx:699
 AliMCEvent.cxx:700
 AliMCEvent.cxx:701
 AliMCEvent.cxx:702
 AliMCEvent.cxx:703
 AliMCEvent.cxx:704
 AliMCEvent.cxx:705
 AliMCEvent.cxx:706
 AliMCEvent.cxx:707
 AliMCEvent.cxx:708
 AliMCEvent.cxx:709
 AliMCEvent.cxx:710
 AliMCEvent.cxx:711
 AliMCEvent.cxx:712
 AliMCEvent.cxx:713
 AliMCEvent.cxx:714
 AliMCEvent.cxx:715
 AliMCEvent.cxx:716
 AliMCEvent.cxx:717
 AliMCEvent.cxx:718
 AliMCEvent.cxx:719
 AliMCEvent.cxx:720
 AliMCEvent.cxx:721
 AliMCEvent.cxx:722
 AliMCEvent.cxx:723
 AliMCEvent.cxx:724
 AliMCEvent.cxx:725
 AliMCEvent.cxx:726
 AliMCEvent.cxx:727
 AliMCEvent.cxx:728
 AliMCEvent.cxx:729
 AliMCEvent.cxx:730
 AliMCEvent.cxx:731
 AliMCEvent.cxx:732
 AliMCEvent.cxx:733
 AliMCEvent.cxx:734
 AliMCEvent.cxx:735
 AliMCEvent.cxx:736
 AliMCEvent.cxx:737
 AliMCEvent.cxx:738
 AliMCEvent.cxx:739
 AliMCEvent.cxx:740
 AliMCEvent.cxx:741
 AliMCEvent.cxx:742
 AliMCEvent.cxx:743
 AliMCEvent.cxx:744
 AliMCEvent.cxx:745
 AliMCEvent.cxx:746
 AliMCEvent.cxx:747
 AliMCEvent.cxx:748
 AliMCEvent.cxx:749
 AliMCEvent.cxx:750
 AliMCEvent.cxx:751
 AliMCEvent.cxx:752
 AliMCEvent.cxx:753
 AliMCEvent.cxx:754
 AliMCEvent.cxx:755
 AliMCEvent.cxx:756
 AliMCEvent.cxx:757
 AliMCEvent.cxx:758
 AliMCEvent.cxx:759
 AliMCEvent.cxx:760
 AliMCEvent.cxx:761
 AliMCEvent.cxx:762
 AliMCEvent.cxx:763
 AliMCEvent.cxx:764
 AliMCEvent.cxx:765
 AliMCEvent.cxx:766
 AliMCEvent.cxx:767
 AliMCEvent.cxx:768
 AliMCEvent.cxx:769
 AliMCEvent.cxx:770
 AliMCEvent.cxx:771
 AliMCEvent.cxx:772
 AliMCEvent.cxx:773
 AliMCEvent.cxx:774
 AliMCEvent.cxx:775
 AliMCEvent.cxx:776
 AliMCEvent.cxx:777
 AliMCEvent.cxx:778
 AliMCEvent.cxx:779
 AliMCEvent.cxx:780
 AliMCEvent.cxx:781
 AliMCEvent.cxx:782
 AliMCEvent.cxx:783
 AliMCEvent.cxx:784
 AliMCEvent.cxx:785
 AliMCEvent.cxx:786
 AliMCEvent.cxx:787
 AliMCEvent.cxx:788
 AliMCEvent.cxx:789
 AliMCEvent.cxx:790
 AliMCEvent.cxx:791
 AliMCEvent.cxx:792
 AliMCEvent.cxx:793
 AliMCEvent.cxx:794
 AliMCEvent.cxx:795
 AliMCEvent.cxx:796
 AliMCEvent.cxx:797
 AliMCEvent.cxx:798
 AliMCEvent.cxx:799
 AliMCEvent.cxx:800
 AliMCEvent.cxx:801
 AliMCEvent.cxx:802
 AliMCEvent.cxx:803
 AliMCEvent.cxx:804
 AliMCEvent.cxx:805
 AliMCEvent.cxx:806
 AliMCEvent.cxx:807
 AliMCEvent.cxx:808
 AliMCEvent.cxx:809
 AliMCEvent.cxx:810
 AliMCEvent.cxx:811
 AliMCEvent.cxx:812
 AliMCEvent.cxx:813
 AliMCEvent.cxx:814
 AliMCEvent.cxx:815
 AliMCEvent.cxx:816
 AliMCEvent.cxx:817
 AliMCEvent.cxx:818
 AliMCEvent.cxx:819
 AliMCEvent.cxx:820
 AliMCEvent.cxx:821
 AliMCEvent.cxx:822
 AliMCEvent.cxx:823
 AliMCEvent.cxx:824
 AliMCEvent.cxx:825
 AliMCEvent.cxx:826
 AliMCEvent.cxx:827
 AliMCEvent.cxx:828
 AliMCEvent.cxx:829
 AliMCEvent.cxx:830
 AliMCEvent.cxx:831
 AliMCEvent.cxx:832
 AliMCEvent.cxx:833
 AliMCEvent.cxx:834
 AliMCEvent.cxx:835
 AliMCEvent.cxx:836
 AliMCEvent.cxx:837
 AliMCEvent.cxx:838
 AliMCEvent.cxx:839
 AliMCEvent.cxx:840
 AliMCEvent.cxx:841
 AliMCEvent.cxx:842
 AliMCEvent.cxx:843
 AliMCEvent.cxx:844
 AliMCEvent.cxx:845
 AliMCEvent.cxx:846
 AliMCEvent.cxx:847
 AliMCEvent.cxx:848
 AliMCEvent.cxx:849
 AliMCEvent.cxx:850
 AliMCEvent.cxx:851
 AliMCEvent.cxx:852
 AliMCEvent.cxx:853
 AliMCEvent.cxx:854
 AliMCEvent.cxx:855
 AliMCEvent.cxx:856
 AliMCEvent.cxx:857
 AliMCEvent.cxx:858
 AliMCEvent.cxx:859
 AliMCEvent.cxx:860
 AliMCEvent.cxx:861
 AliMCEvent.cxx:862
 AliMCEvent.cxx:863
 AliMCEvent.cxx:864
 AliMCEvent.cxx:865
 AliMCEvent.cxx:866
 AliMCEvent.cxx:867
 AliMCEvent.cxx:868
 AliMCEvent.cxx:869
 AliMCEvent.cxx:870
 AliMCEvent.cxx:871
 AliMCEvent.cxx:872
 AliMCEvent.cxx:873
 AliMCEvent.cxx:874
 AliMCEvent.cxx:875
 AliMCEvent.cxx:876
 AliMCEvent.cxx:877
 AliMCEvent.cxx:878
 AliMCEvent.cxx:879
 AliMCEvent.cxx:880
 AliMCEvent.cxx:881
 AliMCEvent.cxx:882
 AliMCEvent.cxx:883
 AliMCEvent.cxx:884
 AliMCEvent.cxx:885
 AliMCEvent.cxx:886
 AliMCEvent.cxx:887
 AliMCEvent.cxx:888
 AliMCEvent.cxx:889
 AliMCEvent.cxx:890
 AliMCEvent.cxx:891
 AliMCEvent.cxx:892
 AliMCEvent.cxx:893
 AliMCEvent.cxx:894
 AliMCEvent.cxx:895
 AliMCEvent.cxx:896
 AliMCEvent.cxx:897
 AliMCEvent.cxx:898
 AliMCEvent.cxx:899
 AliMCEvent.cxx:900
 AliMCEvent.cxx:901
 AliMCEvent.cxx:902
 AliMCEvent.cxx:903
 AliMCEvent.cxx:904
 AliMCEvent.cxx:905
 AliMCEvent.cxx:906
 AliMCEvent.cxx:907
 AliMCEvent.cxx:908
 AliMCEvent.cxx:909
 AliMCEvent.cxx:910
 AliMCEvent.cxx:911
 AliMCEvent.cxx:912
 AliMCEvent.cxx:913
 AliMCEvent.cxx:914
 AliMCEvent.cxx:915
 AliMCEvent.cxx:916
 AliMCEvent.cxx:917
 AliMCEvent.cxx:918
 AliMCEvent.cxx:919
 AliMCEvent.cxx:920
 AliMCEvent.cxx:921
 AliMCEvent.cxx:922
 AliMCEvent.cxx:923
 AliMCEvent.cxx:924
 AliMCEvent.cxx:925
 AliMCEvent.cxx:926
 AliMCEvent.cxx:927
 AliMCEvent.cxx:928
 AliMCEvent.cxx:929
 AliMCEvent.cxx:930
 AliMCEvent.cxx:931
 AliMCEvent.cxx:932
 AliMCEvent.cxx:933
 AliMCEvent.cxx:934
 AliMCEvent.cxx:935
 AliMCEvent.cxx:936
 AliMCEvent.cxx:937
 AliMCEvent.cxx:938
 AliMCEvent.cxx:939
 AliMCEvent.cxx:940
 AliMCEvent.cxx:941
 AliMCEvent.cxx:942
 AliMCEvent.cxx:943
 AliMCEvent.cxx:944
 AliMCEvent.cxx:945
 AliMCEvent.cxx:946
 AliMCEvent.cxx:947
 AliMCEvent.cxx:948
 AliMCEvent.cxx:949
 AliMCEvent.cxx:950
 AliMCEvent.cxx:951
 AliMCEvent.cxx:952
 AliMCEvent.cxx:953
 AliMCEvent.cxx:954
 AliMCEvent.cxx:955
 AliMCEvent.cxx:956
 AliMCEvent.cxx:957
 AliMCEvent.cxx:958
 AliMCEvent.cxx:959
 AliMCEvent.cxx:960
 AliMCEvent.cxx:961
 AliMCEvent.cxx:962
 AliMCEvent.cxx:963
 AliMCEvent.cxx:964
 AliMCEvent.cxx:965
 AliMCEvent.cxx:966
 AliMCEvent.cxx:967
 AliMCEvent.cxx:968
 AliMCEvent.cxx:969
 AliMCEvent.cxx:970
 AliMCEvent.cxx:971
 AliMCEvent.cxx:972
 AliMCEvent.cxx:973
 AliMCEvent.cxx:974
 AliMCEvent.cxx:975
 AliMCEvent.cxx:976
 AliMCEvent.cxx:977
 AliMCEvent.cxx:978
 AliMCEvent.cxx:979
 AliMCEvent.cxx:980
 AliMCEvent.cxx:981
 AliMCEvent.cxx:982
 AliMCEvent.cxx:983
 AliMCEvent.cxx:984
 AliMCEvent.cxx:985
 AliMCEvent.cxx:986
 AliMCEvent.cxx:987
 AliMCEvent.cxx:988
 AliMCEvent.cxx:989
 AliMCEvent.cxx:990
 AliMCEvent.cxx:991
 AliMCEvent.cxx:992
 AliMCEvent.cxx:993
 AliMCEvent.cxx:994
 AliMCEvent.cxx:995
 AliMCEvent.cxx:996
 AliMCEvent.cxx:997
 AliMCEvent.cxx:998