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"
39 #include <TTreeCache.h>
42 #include <TParticle.h>
44 #include <TClonesArray.h>
45 #include <TDirectoryFile.h>
47 ClassImp(AliMCEventHandler)
49 AliMCEventHandler::AliMCEventHandler() :
50 AliInputEventHandler(),
64 fPathName(new TString("./")),
70 fSubsidiaryHandlers(0),
71 fEventsInContainer(0),
72 fPreReadMode(kLmPreRead), // was kNoPreRead
78 // Default constructor
80 // Be sure to add all particles to the PDG database
81 AliPDG::AddParticlesToPdgDataBase();
84 AliMCEventHandler::AliMCEventHandler(const char* name, const char* title) :
85 AliInputEventHandler(name, title),
99 fPathName(new TString("./")),
105 fSubsidiaryHandlers(0),
106 fEventsInContainer(0),
107 fPreReadMode(kLmPreRead), // was kNoPreRead
115 // Be sure to add all particles to the PDG database
116 AliPDG::AddParticlesToPdgDataBase();
118 AliMCEventHandler::~AliMCEventHandler()
130 Bool_t AliMCEventHandler::Init(Option_t* opt)
134 if (!(strcmp(opt, "proof")) || !(strcmp(opt, "local"))) return kTRUE;
136 fFileE = TFile::Open(Form("%sgalice.root", fPathName->Data()));
138 AliError(Form("AliMCEventHandler:galice.root not found in directory %s ! \n", fPathName->Data()));
145 fFileE->GetObject("TE", fTreeE);
146 // Connect Tree E to the MCEvent
147 if (!fMCEvent) fMCEvent = new AliMCEvent();
148 fMCEvent->ConnectTreeE(fTreeE);
149 fNEvent = fTreeE->GetEntries();
152 fFileK = TFile::Open(Form("%sKinematics%s.root", fPathName->Data(), fkExtension));
154 AliError(Form("AliMCEventHandler:Kinematics.root not found in directory %s ! \n", fPathName->Data()));
159 fEventsPerFile = fFileK->GetNkeys() - fFileK->GetNProcessIDs();
163 fFileTR = TFile::Open(Form("%sTrackRefs%s.root", fPathName->Data(), fkExtension));
165 AliError(Form("AliMCEventHandler:TrackRefs.root not found in directory %s ! \n", fPathName->Data()));
171 // Reset the event number
174 AliInfo(Form("Number of events in this directory %5d \n", fNEvent));
178 if (fSubsidiaryHandlers) {
179 TIter next(fSubsidiaryHandlers);
180 AliMCEventHandler *handler;
181 while((handler = (AliMCEventHandler*)next())) {
183 handler->SetNumberOfEventsInContainer(fNEvent);
190 Bool_t AliMCEventHandler::LoadEvent(Int_t iev)
192 // Load the event number iev
194 // Calculate the file number
195 if (!fInitOk) return kFALSE;
197 Int_t inew = iev / fEventsPerFile;
198 Bool_t firsttree = (fTreeK==0) ? kTRUE : kFALSE;
199 // Bool_t newtree = firsttree;
200 if (inew != fFileNumber) {
203 if (!OpenFile(fFileNumber)){
209 snprintf(folder, 20, "Event%d", iev);
211 fTreeE->GetEntry(iev);
213 fFileK->GetObject(folder, fDirK);
215 AliWarning(Form("AliMCEventHandler: Event #%5d - Cannot get kinematics\n", iev));
219 fDirK ->GetObject("TreeK", fTreeK);
221 AliError(Form("AliMCEventHandler: Event #%5d - Cannot get TreeK\n",iev));
224 // Connect TreeK to MCEvent
225 fMCEvent->ConnectTreeK(fTreeK);
228 // Check which format has been read
229 fFileTR->GetObject(folder, fDirTR);
231 AliError(Form("AliMCEventHandler: Event #%5d - Cannot get track references\n",iev));
235 fDirTR->GetObject("TreeTR", fTreeTR);
238 AliError(Form("AliMCEventHandler: Event #%5d - Cannot get TreeTR\n",iev));
241 // Connect TR to MCEvent
242 fMCEvent->ConnectTreeTR(fTreeTR);
244 // Now setup the caches if not yet done
246 fTreeK->SetCacheSize(fCacheSize);
247 fCacheTK = (TTreeCache*) fFileK->GetCacheRead(fTreeK);
248 TTreeCache::SetLearnEntries(1);
249 fTreeK->AddBranchToCache("*",kTRUE);
250 if (firsttree) Info("LoadEvent","Read cache enabled %lld bytes for TreeK",fCacheSize);
252 fTreeTR->SetCacheSize(fCacheSize);
253 fCacheTR = (TTreeCache*) fFileTR->GetCacheRead(fTreeTR);
254 TTreeCache::SetLearnEntries(1);
255 fTreeTR->AddBranchToCache("*",kTRUE);
256 if (firsttree) Info("LoadEvent","Read cache enabled %lld bytes for TreeTR",fCacheSize);
259 // We need to reuse the previous caches and every new event is a new tree
261 // fCacheTK->ResetCache();
262 // if (fFileK) fFileK->SetCacheRead(fCacheTK, fTreeK);
263 // fCacheTK->UpdateBranches(fTreeK);
266 // fCacheTR->ResetCache();
267 // if (fFileTR) fFileTR->SetCacheRead(fCacheTR, fTreeTR);
268 // fCacheTR->UpdateBranches(fTreeTR);
274 Bool_t AliMCEventHandler::OpenFile(Int_t i)
279 fkExtension = Form("%d", i);
284 if (fFileK && fCacheTK) fFileK->SetCacheRead(0, fTreeK);
286 fFileK = TFile::Open(Form("%sKinematics%s.root", fPathName->Data(), fkExtension));
288 AliError(Form("AliMCEventHandler:Kinematics%s.root not found in directory %s ! \n", fkExtension, fPathName->Data()));
289 delete fMCEvent; fMCEvent=0;
295 if (fFileTR && fCacheTR) fFileTR->SetCacheRead(0, fTreeTR);
297 fFileTR = TFile::Open(Form("%sTrackRefs%s.root", fPathName->Data(), fkExtension));
299 AliError(Form("AliMCEventHandler:TrackRefs%s.root not found in directory %s ! \n", fkExtension, fPathName->Data()));
306 Bool_t AliMCEventHandler::BeginEvent(Long64_t entry)
309 if (!fInitOk) return kFALSE;
310 fParticleSelected.Delete();
312 // Read the next event
314 if (fEventsInContainer != 0) {
315 entry = (Long64_t) ( entry * Float_t(fNEvent) / Float_t (fEventsInContainer));
326 if (entry >= fNEvent) {
327 AliWarning(Form("AliMCEventHandler: Event number out of range %5lld %5d\n", entry, fNEvent));
331 Bool_t result = LoadEvent(entry);
333 if (fSubsidiaryHandlers) {
334 TIter next(fSubsidiaryHandlers);
335 AliMCEventHandler *handler;
336 while((handler = (AliMCEventHandler*)next())) {
337 handler->BeginEvent(entry);
340 while((handler = (AliMCEventHandler*)next())) {
341 if (!handler->MCEvent()) continue;
342 fMCEvent->AddSubsidiaryEvent(handler->MCEvent());
344 fMCEvent->InitEvent();
347 if (fPreReadMode == kLmPreRead) {
348 fMCEvent->PreReadAll();
355 void AliMCEventHandler::SelectParticle(Int_t i){
356 // taking the absolute values here, need to take care
357 // of negative daughter and mother
359 if (!fInitOk) return;
360 if (TMath::Abs(i) >= AliMCEvent::BgLabelOffset()) i = fMCEvent->BgLabelToIndex(TMath::Abs(i));
361 if(!IsParticleSelected(TMath::Abs(i)))fParticleSelected.Add(TMath::Abs(i),1);
364 Bool_t AliMCEventHandler::IsParticleSelected(Int_t i) {
365 // taking the absolute values here, need to take
366 // care with negative daughter and mother
368 return (fParticleSelected.GetValue(TMath::Abs(i))==1);
372 void AliMCEventHandler::CreateLabelMap(){
375 // this should be called once all selections where done
380 fParticleSelected.Delete();
384 VerifySelectedParticles();
387 for(int i = 0;i < fMCEvent->GetNumberOfTracks();++i){
388 if(IsParticleSelected(i)){
389 fLabelMap.Add(i,iNew);
395 Int_t AliMCEventHandler::GetNewLabel(Int_t i) {
396 // Gets the label from the new created Map
397 // Call CreatLabelMap before
398 // otherwise only 0 returned
399 return fLabelMap.GetValue(TMath::Abs(i));
402 void AliMCEventHandler::VerifySelectedParticles(){
405 // Make sure that each particle has at least it's predecessors
406 // selected so that we have the complete ancestry tree
407 // Private, should be only called by CreateLabelMap
410 fParticleSelected.Delete();
414 Int_t nprim = fMCEvent->GetNumberOfPrimaries();
416 for(int i = 0;i < fMCEvent->GetNumberOfTracks(); ++i){
418 SelectParticle(i);// take all primaries
422 if(!IsParticleSelected(i))continue;
424 AliMCParticle* mcpart = (AliMCParticle*) fMCEvent->GetTrack(i);
425 Int_t imo = mcpart->GetMother();
426 while((imo >= nprim)&&!IsParticleSelected(imo)){
427 // Mother not yet selected
429 mcpart = (AliMCParticle*) fMCEvent->GetTrack(imo);
430 imo = mcpart->GetMother();
432 // after last step we may have an unselected primary
435 if(!IsParticleSelected(imo))
438 }// loop over all tracks
441 Int_t AliMCEventHandler::GetParticleAndTR(Int_t i, TParticle*& particle, TClonesArray*& trefs)
447 return (fMCEvent->GetParticleAndTR(i, particle, trefs));
451 void AliMCEventHandler::DrawCheck(Int_t i, Int_t search)
453 // Retrieve entry i and draw momentum vector and hits
454 fMCEvent->DrawCheck(i, search);
457 Bool_t AliMCEventHandler::Notify(const char *path)
459 // Notify about directory change
460 // The directory is taken from the 'path' argument
462 TString fileName(path);
463 TString dirname = gSystem->DirName(fileName);
464 TString basename = gSystem->BaseName(fileName);
465 Int_t index = basename.Index("#");
466 basename = basename(0, index+1);
469 fileName += basename;
471 if (fileName.BeginsWith("root:")) {
472 fileName.Append("?ZIP=");
475 *fPathName = fileName;
476 AliInfo(Form("Path: -%s-\n", fPathName->Data()));
481 // Handle subsidiary handlers
482 if (fSubsidiaryHandlers) {
483 TIter next(fSubsidiaryHandlers);
484 AliMCEventHandler *handler;
485 while((handler = (AliMCEventHandler*) next())) {
486 TString* spath = handler->GetInputPath();
487 if (spath->Contains("merged")) {
488 if (! fPathName->IsNull()) {
489 handler->Notify(Form("%s/../.", fPathName->Data()));
491 handler->Notify("../");
500 void AliMCEventHandler::ResetIO()
502 // Clear header and stack
504 if (fInitOk) fMCEvent->Clean();
507 delete fTreeE; fTreeE = 0;
510 if (fFileE) {delete fFileE; fFileE = 0;}
511 if (fFileK) {delete fFileK; fFileK = 0;}
512 if (fFileTR) {delete fFileTR; fFileTR = 0;}
516 if (fSubsidiaryHandlers) {
517 TIter next(fSubsidiaryHandlers);
518 AliMCEventHandler *handler;
519 while((handler = (AliMCEventHandler*)next())) {
527 Bool_t AliMCEventHandler::FinishEvent()
529 // Clean-up after each event
530 if (fFileK && fCacheTK) {
531 fTreeK->SetCacheSize(0);
533 fFileK->SetCacheRead(0, fTreeK);
535 if (fFileTR && fCacheTR) {
536 fTreeTR->SetCacheSize(0);
538 fFileTR->SetCacheRead(0, fTreeTR);
540 delete fDirTR; fDirTR = 0;
541 delete fDirK; fDirK = 0;
542 if (fInitOk) fMCEvent->FinishEvent();
544 if (fSubsidiaryHandlers) {
545 TIter next(fSubsidiaryHandlers);
546 AliMCEventHandler *handler;
547 while((handler = (AliMCEventHandler*)next())) {
548 handler->FinishEvent();
555 Bool_t AliMCEventHandler::Terminate()
561 Bool_t AliMCEventHandler::TerminateIO()
568 void AliMCEventHandler::SetInputPath(const char* fname)
570 // Set the input path name
572 fPathName = new TString(fname);
575 void AliMCEventHandler::AddSubsidiaryHandler(AliMCEventHandler* handler)
577 // Add a subsidiary handler. For example for background events
579 if (!fSubsidiaryHandlers) fSubsidiaryHandlers = new TList();
580 fSubsidiaryHandlers->Add(handler);