1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
17 //---------------------------------------------------------------------------------
18 // Class AliMCEventHandler
19 // This class gives access to MC truth during the analysis.
20 // Monte Carlo truth is containe in the kinematics tree (produced particles) and
21 // the tree of reference hits.
23 // Origin: Andreas Morsch, CERN, andreas.morsch@cern.ch
24 //---------------------------------------------------------------------------------
28 #include "AliMCEventHandler.h"
29 #include "AliMCEvent.h"
30 #include "AliMCParticle.h"
32 #include "AliTrackReference.h"
33 #include "AliHeader.h"
38 #include <TTreeCache.h>
41 #include <TParticle.h>
43 #include <TClonesArray.h>
44 #include <TDirectoryFile.h>
46 ClassImp(AliMCEventHandler)
48 AliMCEventHandler::AliMCEventHandler() :
49 AliInputEventHandler(),
50 fMCEvent(new AliMCEvent()),
63 fPathName(new TString("./")),
69 fSubsidiaryHandlers(0),
70 fEventsInContainer(0),
71 fPreReadMode(kNoPreRead),
77 // Default constructor
79 // Be sure to add all particles to the PDG database
80 AliPDG::AddParticlesToPdgDataBase();
83 AliMCEventHandler::AliMCEventHandler(const char* name, const char* title) :
84 AliInputEventHandler(name, title),
85 fMCEvent(new AliMCEvent()),
98 fPathName(new TString("./")),
104 fSubsidiaryHandlers(0),
105 fEventsInContainer(0),
106 fPreReadMode(kNoPreRead),
114 // Be sure to add all particles to the PDG database
115 AliPDG::AddParticlesToPdgDataBase();
117 AliMCEventHandler::~AliMCEventHandler()
129 Bool_t AliMCEventHandler::Init(Option_t* opt)
133 if (!(strcmp(opt, "proof")) || !(strcmp(opt, "local"))) return kTRUE;
135 fFileE = TFile::Open(Form("%sgalice.root", fPathName->Data()));
137 AliError(Form("AliMCEventHandler:galice.root not found in directory %s ! \n", fPathName->Data()));
144 fFileE->GetObject("TE", fTreeE);
145 // Connect Tree E to the MCEvent
146 fMCEvent->ConnectTreeE(fTreeE);
147 fNEvent = fTreeE->GetEntries();
150 fFileK = TFile::Open(Form("%sKinematics%s.root", fPathName->Data(), fkExtension));
152 AliError(Form("AliMCEventHandler:Kinematics.root not found in directory %s ! \n", fPathName->Data()));
157 fEventsPerFile = fFileK->GetNkeys() - fFileK->GetNProcessIDs();
161 fFileTR = TFile::Open(Form("%sTrackRefs%s.root", fPathName->Data(), fkExtension));
163 AliError(Form("AliMCEventHandler:TrackRefs.root not found in directory %s ! \n", fPathName->Data()));
169 // Reset the event number
172 AliInfo(Form("Number of events in this directory %5d \n", fNEvent));
176 if (fSubsidiaryHandlers) {
177 TIter next(fSubsidiaryHandlers);
178 AliMCEventHandler *handler;
179 while((handler = (AliMCEventHandler*)next())) {
181 handler->SetNumberOfEventsInContainer(fNEvent);
188 Bool_t AliMCEventHandler::LoadEvent(Int_t iev)
190 // Load the event number iev
192 // Calculate the file number
193 if (!fInitOk) return kFALSE;
195 Int_t inew = iev / fEventsPerFile;
196 Bool_t firsttree = (fTreeK==0) ? kTRUE : kFALSE;
197 // Bool_t newtree = firsttree;
198 if (inew != fFileNumber) {
201 if (!OpenFile(fFileNumber)){
207 snprintf(folder, 20, "Event%d", iev);
209 fTreeE->GetEntry(iev);
211 fFileK->GetObject(folder, fDirK);
213 AliWarning(Form("AliMCEventHandler: Event #%5d - Cannot get kinematics\n", iev));
217 fDirK ->GetObject("TreeK", fTreeK);
219 AliError(Form("AliMCEventHandler: Event #%5d - Cannot get TreeK\n",iev));
222 // Connect TreeK to MCEvent
223 fMCEvent->ConnectTreeK(fTreeK);
226 // Check which format has been read
227 fFileTR->GetObject(folder, fDirTR);
229 AliError(Form("AliMCEventHandler: Event #%5d - Cannot get track references\n",iev));
233 fDirTR->GetObject("TreeTR", fTreeTR);
236 AliError(Form("AliMCEventHandler: Event #%5d - Cannot get TreeTR\n",iev));
239 // Connect TR to MCEvent
240 fMCEvent->ConnectTreeTR(fTreeTR);
242 // Now setup the caches if not yet done
244 fTreeK->SetCacheSize(fCacheSize);
245 fCacheTK = (TTreeCache*) fFileK->GetCacheRead(fTreeK);
246 TTreeCache::SetLearnEntries(1);
247 fTreeK->AddBranchToCache("*",kTRUE);
248 if (firsttree) Info("LoadEvent","Read cache enabled %lld bytes for TreeK",fCacheSize);
250 fTreeTR->SetCacheSize(fCacheSize);
251 fCacheTR = (TTreeCache*) fFileTR->GetCacheRead(fTreeTR);
252 TTreeCache::SetLearnEntries(1);
253 fTreeTR->AddBranchToCache("*",kTRUE);
254 if (firsttree) Info("LoadEvent","Read cache enabled %lld bytes for TreeTR",fCacheSize);
257 // We need to reuse the previous caches and every new event is a new tree
259 // fCacheTK->ResetCache();
260 // if (fFileK) fFileK->SetCacheRead(fCacheTK, fTreeK);
261 // fCacheTK->UpdateBranches(fTreeK);
264 // fCacheTR->ResetCache();
265 // if (fFileTR) fFileTR->SetCacheRead(fCacheTR, fTreeTR);
266 // fCacheTR->UpdateBranches(fTreeTR);
272 Bool_t AliMCEventHandler::OpenFile(Int_t i)
276 fkExtension = Form("%d", i);
281 if (fFileK && fCacheTK) fFileK->SetCacheRead(0, fTreeK);
283 fFileK = TFile::Open(Form("%sKinematics%s.root", fPathName->Data(), fkExtension));
285 AliError(Form("AliMCEventHandler:Kinematics%s.root not found in directory %s ! \n", fkExtension, fPathName->Data()));
291 if (fFileTR && fCacheTR) fFileTR->SetCacheRead(0, fTreeTR);
293 fFileTR = TFile::Open(Form("%sTrackRefs%s.root", fPathName->Data(), fkExtension));
295 AliWarning(Form("AliMCEventHandler:TrackRefs%s.root not found in directory %s ! \n", fkExtension, fPathName->Data()));
306 Bool_t AliMCEventHandler::BeginEvent(Long64_t entry)
309 fParticleSelected.Delete();
311 // Read the next event
313 if (fEventsInContainer != 0) {
314 entry = (Long64_t) ( entry * Float_t(fNEvent) / Float_t (fEventsInContainer));
325 if (entry >= fNEvent) {
326 AliWarning(Form("AliMCEventHandler: Event number out of range %5lld %5d\n", entry, fNEvent));
330 Bool_t result = LoadEvent(entry);
332 if (fSubsidiaryHandlers) {
333 TIter next(fSubsidiaryHandlers);
334 AliMCEventHandler *handler;
335 while((handler = (AliMCEventHandler*)next())) {
336 handler->BeginEvent(entry);
339 while((handler = (AliMCEventHandler*)next())) {
340 fMCEvent->AddSubsidiaryEvent(handler->MCEvent());
342 fMCEvent->InitEvent();
345 if (fPreReadMode == kLmPreRead) {
346 fMCEvent->PreReadAll();
353 void AliMCEventHandler::SelectParticle(Int_t i){
354 // taking the absolute values here, need to take care
355 // of negative daughter and mother
357 if (TMath::Abs(i) >= AliMCEvent::BgLabelOffset()) i = fMCEvent->BgLabelToIndex(TMath::Abs(i));
358 if(!IsParticleSelected(TMath::Abs(i)))fParticleSelected.Add(TMath::Abs(i),1);
361 Bool_t AliMCEventHandler::IsParticleSelected(Int_t i) {
362 // taking the absolute values here, need to take
363 // care with negative daughter and mother
365 return (fParticleSelected.GetValue(TMath::Abs(i))==1);
369 void AliMCEventHandler::CreateLabelMap(){
372 // this should be called once all selections where done
377 fParticleSelected.Delete();
381 VerifySelectedParticles();
384 for(int i = 0;i < fMCEvent->GetNumberOfTracks();++i){
385 if(IsParticleSelected(i)){
386 fLabelMap.Add(i,iNew);
392 Int_t AliMCEventHandler::GetNewLabel(Int_t i) {
393 // Gets the label from the new created Map
394 // Call CreatLabelMap before
395 // otherwise only 0 returned
396 return fLabelMap.GetValue(TMath::Abs(i));
399 void AliMCEventHandler::VerifySelectedParticles(){
402 // Make sure that each particle has at least it's predecessors
403 // selected so that we have the complete ancestry tree
404 // Private, should be only called by CreateLabelMap
407 fParticleSelected.Delete();
411 Int_t nprim = fMCEvent->GetNumberOfPrimaries();
413 for(int i = 0;i < fMCEvent->GetNumberOfTracks(); ++i){
415 SelectParticle(i);// take all primaries
419 if(!IsParticleSelected(i))continue;
421 AliMCParticle* mcpart = (AliMCParticle*) fMCEvent->GetTrack(i);
422 Int_t imo = mcpart->GetMother();
423 while((imo >= nprim)&&!IsParticleSelected(imo)){
424 // Mother not yet selected
426 mcpart = (AliMCParticle*) fMCEvent->GetTrack(imo);
427 imo = mcpart->GetMother();
429 // after last step we may have an unselected primary
432 if(!IsParticleSelected(imo))
435 }// loop over all tracks
438 Int_t AliMCEventHandler::GetParticleAndTR(Int_t i, TParticle*& particle, TClonesArray*& trefs)
444 return (fMCEvent->GetParticleAndTR(i, particle, trefs));
448 void AliMCEventHandler::DrawCheck(Int_t i, Int_t search)
450 // Retrieve entry i and draw momentum vector and hits
451 fMCEvent->DrawCheck(i, search);
454 Bool_t AliMCEventHandler::Notify(const char *path)
456 // Notify about directory change
457 // The directory is taken from the 'path' argument
459 TString fileName(path);
460 if(fileName.Contains("AliESDs.root")){
461 fileName.ReplaceAll("AliESDs.root", "");
463 else if(fileName.Contains("AliESDs_wSDD.root")){
464 fileName.ReplaceAll("AliESDs_wSDD.root", "");
466 else if(fileName.Contains("AliESDs_nob.root")){
467 fileName.ReplaceAll("AliESDs_nob.root", "");
469 else if(fileName.Contains("AliAOD.root")){
470 fileName.ReplaceAll("AliAOD.root", "");
472 else if(fileName.Contains("galice.root")){
473 // for running with galice and kinematics alone...
474 fileName.ReplaceAll("galice.root", "");
476 else if (fileName.BeginsWith("root:")) {
477 fileName.Append("?ZIP=");
480 *fPathName = fileName;
481 AliInfo(Form("Path: -%s-\n", fPathName->Data()));
486 // Handle subsidiary handlers
487 if (fSubsidiaryHandlers) {
488 TIter next(fSubsidiaryHandlers);
489 AliMCEventHandler *handler;
490 while((handler = (AliMCEventHandler*) next())) {
491 TString* spath = handler->GetInputPath();
492 if (spath->Contains("merged")) {
493 if (! fPathName->IsNull()) {
494 handler->Notify(Form("%s/../.", fPathName->Data()));
496 handler->Notify("../");
505 void AliMCEventHandler::ResetIO()
507 // Clear header and stack
509 if (fInitOk) fMCEvent->Clean();
512 delete fTreeE; fTreeE = 0;
515 if (fFileE) {delete fFileE; fFileE = 0;}
516 if (fFileK) {delete fFileK; fFileK = 0;}
517 if (fFileTR) {delete fFileTR; fFileTR = 0;}
521 if (fSubsidiaryHandlers) {
522 TIter next(fSubsidiaryHandlers);
523 AliMCEventHandler *handler;
524 while((handler = (AliMCEventHandler*)next())) {
532 Bool_t AliMCEventHandler::FinishEvent()
534 // Clean-up after each event
535 if (fFileK && fCacheTK) {
536 fTreeK->SetCacheSize(0);
538 fFileK->SetCacheRead(0, fTreeK);
540 if (fFileTR && fCacheTR) {
541 fTreeTR->SetCacheSize(0);
543 fFileTR->SetCacheRead(0, fTreeTR);
545 delete fDirTR; fDirTR = 0;
546 delete fDirK; fDirK = 0;
547 if (fInitOk) fMCEvent->FinishEvent();
549 if (fSubsidiaryHandlers) {
550 TIter next(fSubsidiaryHandlers);
551 AliMCEventHandler *handler;
552 while((handler = (AliMCEventHandler*)next())) {
553 handler->FinishEvent();
560 Bool_t AliMCEventHandler::Terminate()
566 Bool_t AliMCEventHandler::TerminateIO()
573 void AliMCEventHandler::SetInputPath(const char* fname)
575 // Set the input path name
577 fPathName = new TString(fname);
580 void AliMCEventHandler::AddSubsidiaryHandler(AliMCEventHandler* handler)
582 // Add a subsidiary handler. For example for background events
584 if (!fSubsidiaryHandlers) fSubsidiaryHandlers = new TList();
585 fSubsidiaryHandlers->Add(handler);