]> git.uio.no Git - u/mrichter/AliRoot.git/blame - STEER/STEERBase/AliMCEventHandler.cxx
Patch allowing to run analysis on a chain with file names different than AliESDs...
[u/mrichter/AliRoot.git] / STEER / STEERBase / AliMCEventHandler.cxx
CommitLineData
93836e1b 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved *
5fe09262 3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
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 **************************************************************************/
15
16/* $Id$ */
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.
22//
23// Origin: Andreas Morsch, CERN, andreas.morsch@cern.ch
24//---------------------------------------------------------------------------------
25
26
27
28#include "AliMCEventHandler.h"
415d9f5c 29#include "AliMCEvent.h"
93836e1b 30#include "AliMCParticle.h"
82418625 31#include "AliPDG.h"
5fe09262 32#include "AliTrackReference.h"
33#include "AliHeader.h"
34#include "AliStack.h"
2c36081e 35#include "AliLog.h"
5fe09262 36
37#include <TTree.h>
fdbaa4ce 38#include <TSystem.h>
43072535 39#include <TTreeCache.h>
5fe09262 40#include <TFile.h>
93836e1b 41#include <TList.h>
5fe09262 42#include <TParticle.h>
0a05cd41 43#include <TString.h>
5fe09262 44#include <TClonesArray.h>
45#include <TDirectoryFile.h>
5fe09262 46
47ClassImp(AliMCEventHandler)
48
49AliMCEventHandler::AliMCEventHandler() :
e473e8b0 50 AliInputEventHandler(),
415d9f5c 51 fMCEvent(new AliMCEvent()),
5fe09262 52 fFileE(0),
53 fFileK(0),
54 fFileTR(0),
5fe09262 55 fTreeE(0),
56 fTreeK(0),
57 fTreeTR(0),
5efedd31 58 fDirK(0),
59 fDirTR(0),
da97a08a 60 fParticleSelected(0),
61 fLabelMap(0),
5fe09262 62 fNEvent(-1),
63 fEvent(-1),
0a05cd41 64 fPathName(new TString("./")),
89afaa5a 65 fkExtension(""),
9aea8469 66 fFileNumber(0),
969c7896 67 fEventsPerFile(0),
c8b7b5d3 68 fReadTR(kTRUE),
93836e1b 69 fInitOk(kFALSE),
70 fSubsidiaryHandlers(0),
35152e4b 71 fEventsInContainer(0),
43072535 72 fPreReadMode(kNoPreRead),
73 fCacheSize(0),
74 fCacheTK(0),
75 fCacheTR(0)
5fe09262 76{
82418625 77 //
78 // Default constructor
79 //
80 // Be sure to add all particles to the PDG database
81 AliPDG::AddParticlesToPdgDataBase();
5fe09262 82}
83
84AliMCEventHandler::AliMCEventHandler(const char* name, const char* title) :
e473e8b0 85 AliInputEventHandler(name, title),
415d9f5c 86 fMCEvent(new AliMCEvent()),
5fe09262 87 fFileE(0),
88 fFileK(0),
89 fFileTR(0),
5fe09262 90 fTreeE(0),
91 fTreeK(0),
92 fTreeTR(0),
5efedd31 93 fDirK(0),
94 fDirTR(0),
da97a08a 95 fParticleSelected(0),
96 fLabelMap(0),
5fe09262 97 fNEvent(-1),
98 fEvent(-1),
0a05cd41 99 fPathName(new TString("./")),
89afaa5a 100 fkExtension(""),
9aea8469 101 fFileNumber(0),
0cd61c1d 102 fEventsPerFile(0),
c8b7b5d3 103 fReadTR(kTRUE),
93836e1b 104 fInitOk(kFALSE),
105 fSubsidiaryHandlers(0),
35152e4b 106 fEventsInContainer(0),
43072535 107 fPreReadMode(kNoPreRead),
108 fCacheSize(0),
109 fCacheTK(0),
110 fCacheTR(0)
5fe09262 111{
82418625 112 //
113 // Constructor
114 //
115 // Be sure to add all particles to the PDG database
116 AliPDG::AddParticlesToPdgDataBase();
5fe09262 117}
118AliMCEventHandler::~AliMCEventHandler()
119{
120 // Destructor
3f61d763 121 delete fPathName;
415d9f5c 122 delete fMCEvent;
5fe09262 123 delete fFileE;
124 delete fFileK;
125 delete fFileTR;
43072535 126 delete fCacheTK;
127 delete fCacheTR;
5fe09262 128}
129
300d5701 130Bool_t AliMCEventHandler::Init(Option_t* opt)
5fe09262 131{
132 // Initialize input
133 //
6073f8c9 134 if (!(strcmp(opt, "proof")) || !(strcmp(opt, "local"))) return kTRUE;
135 //
0a05cd41 136 fFileE = TFile::Open(Form("%sgalice.root", fPathName->Data()));
c8b7b5d3 137 if (!fFileE) {
138 AliError(Form("AliMCEventHandler:galice.root not found in directory %s ! \n", fPathName->Data()));
139 fInitOk = kFALSE;
140 return kFALSE;
141 }
142
415d9f5c 143 //
144 // Tree E
5fe09262 145 fFileE->GetObject("TE", fTreeE);
415d9f5c 146 // Connect Tree E to the MCEvent
147 fMCEvent->ConnectTreeE(fTreeE);
5fe09262 148 fNEvent = fTreeE->GetEntries();
149 //
150 // Tree K
89afaa5a 151 fFileK = TFile::Open(Form("%sKinematics%s.root", fPathName->Data(), fkExtension));
c8b7b5d3 152 if (!fFileK) {
65b25288 153 AliError(Form("AliMCEventHandler:Kinematics.root not found in directory %s ! \n", fPathName->Data()));
c8b7b5d3 154 fInitOk = kFALSE;
b72029a3 155 return kTRUE;
c8b7b5d3 156 }
157
9aea8469 158 fEventsPerFile = fFileK->GetNkeys() - fFileK->GetNProcessIDs();
5fe09262 159 //
160 // Tree TR
969c7896 161 if (fReadTR) {
89afaa5a 162 fFileTR = TFile::Open(Form("%sTrackRefs%s.root", fPathName->Data(), fkExtension));
c8b7b5d3 163 if (!fFileTR) {
164 AliError(Form("AliMCEventHandler:TrackRefs.root not found in directory %s ! \n", fPathName->Data()));
165 fInitOk = kFALSE;
b72029a3 166 return kTRUE;
c8b7b5d3 167 }
969c7896 168 }
5fe09262 169 //
170 // Reset the event number
2c36081e 171 fEvent = -1;
172 fFileNumber = 0;
b544c64d 173 AliInfo(Form("Number of events in this directory %5d \n", fNEvent));
c8b7b5d3 174 fInitOk = kTRUE;
93836e1b 175
176
177 if (fSubsidiaryHandlers) {
178 TIter next(fSubsidiaryHandlers);
179 AliMCEventHandler *handler;
180 while((handler = (AliMCEventHandler*)next())) {
181 handler->Init(opt);
182 handler->SetNumberOfEventsInContainer(fNEvent);
183 }
184 }
185
5fe09262 186 return kTRUE;
5fe09262 187}
188
e473e8b0 189Bool_t AliMCEventHandler::LoadEvent(Int_t iev)
9aea8469 190{
191 // Load the event number iev
2c36081e 192 //
193 // Calculate the file number
68793909 194 if (!fInitOk) return kFALSE;
c8b7b5d3 195
68793909 196 Int_t inew = iev / fEventsPerFile;
43072535 197 Bool_t firsttree = (fTreeK==0) ? kTRUE : kFALSE;
66fc3944 198// Bool_t newtree = firsttree;
68793909 199 if (inew != fFileNumber) {
66fc3944 200// newtree = kTRUE;
68793909 201 fFileNumber = inew;
202 if (!OpenFile(fFileNumber)){
203 return kFALSE;
9aea8469 204 }
68793909 205 }
206 // Folder name
207 char folder[20];
76880c9a 208 snprintf(folder, 20, "Event%d", iev);
68793909 209 // TreeE
210 fTreeE->GetEntry(iev);
211 // Tree K
212 fFileK->GetObject(folder, fDirK);
213 if (!fDirK) {
214 AliWarning(Form("AliMCEventHandler: Event #%5d - Cannot get kinematics\n", iev));
215 return kFALSE;
216 }
b72029a3 217
68793909 218 fDirK ->GetObject("TreeK", fTreeK);
219 if (!fTreeK) {
220 AliError(Form("AliMCEventHandler: Event #%5d - Cannot get TreeK\n",iev));
221 return kFALSE;
222 }
223 // Connect TreeK to MCEvent
224 fMCEvent->ConnectTreeK(fTreeK);
225 //Tree TR
226 if (fFileTR) {
227 // Check which format has been read
228 fFileTR->GetObject(folder, fDirTR);
229 if (!fDirTR) {
230 AliError(Form("AliMCEventHandler: Event #%5d - Cannot get track references\n",iev));
231 return kFALSE;
232 }
233
234 fDirTR->GetObject("TreeTR", fTreeTR);
5fe09262 235 //
68793909 236 if (!fTreeTR) {
237 AliError(Form("AliMCEventHandler: Event #%5d - Cannot get TreeTR\n",iev));
238 return kFALSE;
239 }
240 // Connect TR to MCEvent
241 fMCEvent->ConnectTreeTR(fTreeTR);
242 }
43072535 243 // Now setup the caches if not yet done
244 if (fCacheSize) {
66fc3944 245 fTreeK->SetCacheSize(fCacheSize);
246 fCacheTK = (TTreeCache*) fFileK->GetCacheRead(fTreeK);
247 TTreeCache::SetLearnEntries(1);
248 fTreeK->AddBranchToCache("*",kTRUE);
249 if (firsttree) Info("LoadEvent","Read cache enabled %lld bytes for TreeK",fCacheSize);
250 if (fTreeTR) {
251 fTreeTR->SetCacheSize(fCacheSize);
252 fCacheTR = (TTreeCache*) fFileTR->GetCacheRead(fTreeTR);
43072535 253 TTreeCache::SetLearnEntries(1);
66fc3944 254 fTreeTR->AddBranchToCache("*",kTRUE);
255 if (firsttree) Info("LoadEvent","Read cache enabled %lld bytes for TreeTR",fCacheSize);
256 }
257// } else {
43072535 258 // We need to reuse the previous caches and every new event is a new tree
66fc3944 259// if (fCacheTK) {
260// fCacheTK->ResetCache();
261// if (fFileK) fFileK->SetCacheRead(fCacheTK, fTreeK);
262// fCacheTK->UpdateBranches(fTreeK);
263// }
264// if (fCacheTR) {
265// fCacheTR->ResetCache();
266// if (fFileTR) fFileTR->SetCacheRead(fCacheTR, fTreeTR);
267// fCacheTR->UpdateBranches(fTreeTR);
268// }
43072535 269 }
68793909 270 return kTRUE;
9aea8469 271}
272
273Bool_t AliMCEventHandler::OpenFile(Int_t i)
274{
275 // Open file i
9aea8469 276 if (i > 0) {
89afaa5a 277 fkExtension = Form("%d", i);
9aea8469 278 } else {
89afaa5a 279 fkExtension = "";
9aea8469 280 }
281
43072535 282 if (fFileK && fCacheTK) fFileK->SetCacheRead(0, fTreeK);
9aea8469 283 delete fFileK;
89afaa5a 284 fFileK = TFile::Open(Form("%sKinematics%s.root", fPathName->Data(), fkExtension));
9aea8469 285 if (!fFileK) {
89afaa5a 286 AliError(Form("AliMCEventHandler:Kinematics%s.root not found in directory %s ! \n", fkExtension, fPathName->Data()));
c8b7b5d3 287 fInitOk = kFALSE;
288 return kFALSE;
9aea8469 289 }
290
c8b7b5d3 291 if (fReadTR) {
43072535 292 if (fFileTR && fCacheTR) fFileTR->SetCacheRead(0, fTreeTR);
293 delete fFileTR;
294 fFileTR = TFile::Open(Form("%sTrackRefs%s.root", fPathName->Data(), fkExtension));
295 if (!fFileTR) {
296 AliWarning(Form("AliMCEventHandler:TrackRefs%s.root not found in directory %s ! \n", fkExtension, fPathName->Data()));
297 fInitOk = kFALSE;
298 return kFALSE;
299 }
9aea8469 300 }
301
c8b7b5d3 302 fInitOk = kTRUE;
93836e1b 303
c8b7b5d3 304 return kTRUE;
9aea8469 305}
306
ed97dc98 307Bool_t AliMCEventHandler::BeginEvent(Long64_t entry)
9aea8469 308{
aa7e002c 309 // Begin event
da97a08a 310 fParticleSelected.Delete();
311 fLabelMap.Delete();
9aea8469 312 // Read the next event
93836e1b 313
314 if (fEventsInContainer != 0) {
11e4d716 315 entry = (Long64_t) ( entry * Float_t(fNEvent) / Float_t (fEventsInContainer));
93836e1b 316 }
317
318
ed97dc98 319 if (entry == -1) {
320 fEvent++;
321 entry = fEvent;
322 } else {
323 fEvent = entry;
324 }
325
326 if (entry >= fNEvent) {
73bbf779 327 AliWarning(Form("AliMCEventHandler: Event number out of range %5lld %5d\n", entry, fNEvent));
9aea8469 328 return kFALSE;
329 }
93836e1b 330
e473e8b0 331 Bool_t result = LoadEvent(entry);
93836e1b 332
333 if (fSubsidiaryHandlers) {
334 TIter next(fSubsidiaryHandlers);
335 AliMCEventHandler *handler;
336 while((handler = (AliMCEventHandler*)next())) {
337 handler->BeginEvent(entry);
338 }
339 next.Reset();
340 while((handler = (AliMCEventHandler*)next())) {
341 fMCEvent->AddSubsidiaryEvent(handler->MCEvent());
342 }
343 fMCEvent->InitEvent();
344 }
35152e4b 345
346 if (fPreReadMode == kLmPreRead) {
347 fMCEvent->PreReadAll();
348 }
349
93836e1b 350 return result;
351
5fe09262 352}
353
da97a08a 354void AliMCEventHandler::SelectParticle(Int_t i){
355 // taking the absolute values here, need to take care
356 // of negative daughter and mother
357 // IDs when setting!
93836e1b 358 if (TMath::Abs(i) >= AliMCEvent::BgLabelOffset()) i = fMCEvent->BgLabelToIndex(TMath::Abs(i));
359 if(!IsParticleSelected(TMath::Abs(i)))fParticleSelected.Add(TMath::Abs(i),1);
da97a08a 360}
361
362Bool_t AliMCEventHandler::IsParticleSelected(Int_t i) {
363 // taking the absolute values here, need to take
364 // care with negative daughter and mother
365 // IDs when setting!
366 return (fParticleSelected.GetValue(TMath::Abs(i))==1);
367}
368
369
370void AliMCEventHandler::CreateLabelMap(){
371
372 //
373 // this should be called once all selections where done
374 //
375
376 fLabelMap.Delete();
377 if(!fMCEvent){
378 fParticleSelected.Delete();
379 return;
380 }
381
382 VerifySelectedParticles();
da97a08a 383
384 Int_t iNew = 0;
93836e1b 385 for(int i = 0;i < fMCEvent->GetNumberOfTracks();++i){
da97a08a 386 if(IsParticleSelected(i)){
387 fLabelMap.Add(i,iNew);
388 iNew++;
389 }
390 }
391}
392
393Int_t AliMCEventHandler::GetNewLabel(Int_t i) {
93836e1b 394 // Gets the label from the new created Map
da97a08a 395 // Call CreatLabelMap before
396 // otherwise only 0 returned
397 return fLabelMap.GetValue(TMath::Abs(i));
398}
399
400void AliMCEventHandler::VerifySelectedParticles(){
401
402 //
403 // Make sure that each particle has at least it's predecessors
404 // selected so that we have the complete ancestry tree
405 // Private, should be only called by CreateLabelMap
406
407 if(!fMCEvent){
93836e1b 408 fParticleSelected.Delete();
409 return;
da97a08a 410 }
da97a08a 411
93836e1b 412 Int_t nprim = fMCEvent->GetNumberOfPrimaries();
413
414 for(int i = 0;i < fMCEvent->GetNumberOfTracks(); ++i){
415 if(i < nprim){
416 SelectParticle(i);// take all primaries
417 continue;
418 }
419
420 if(!IsParticleSelected(i))continue;
421
63a1afff 422 AliMCParticle* mcpart = (AliMCParticle*) fMCEvent->GetTrack(i);
93836e1b 423 Int_t imo = mcpart->GetMother();
424 while((imo >= nprim)&&!IsParticleSelected(imo)){
425 // Mother not yet selected
426 SelectParticle(imo);
0f0c06de 427 mcpart = (AliMCParticle*) fMCEvent->GetTrack(imo);
93836e1b 428 imo = mcpart->GetMother();
429 }
430 // after last step we may have an unselected primary
da97a08a 431 // mother
432 if(imo>=0){
433 if(!IsParticleSelected(imo))
434 SelectParticle(imo);
435 }
436 }// loop over all tracks
437}
438
5fe09262 439Int_t AliMCEventHandler::GetParticleAndTR(Int_t i, TParticle*& particle, TClonesArray*& trefs)
440{
441 // Retrieve entry i
c8b7b5d3 442 if (!fInitOk) {
443 return 0;
444 } else {
445 return (fMCEvent->GetParticleAndTR(i, particle, trefs));
446 }
5fe09262 447}
448
2d8f26f6 449void AliMCEventHandler::DrawCheck(Int_t i, Int_t search)
5fe09262 450{
451 // Retrieve entry i and draw momentum vector and hits
415d9f5c 452 fMCEvent->DrawCheck(i, search);
5fe09262 453}
454
890126ab 455Bool_t AliMCEventHandler::Notify(const char *path)
5fe09262 456{
53faeca4 457 // Notify about directory change
458 // The directory is taken from the 'path' argument
459 // Reconnect trees
460 TString fileName(path);
fdbaa4ce 461 TString dirname = gSystem->DirName(fileName);
462 TString basename = gSystem->BaseName(fileName);
463 Int_t index = basename.Index("#");
464 basename = basename(0, index+1);
465 fileName = dirname;
466 fileName += "/";
467 fileName += basename;
468 if (fileName.BeginsWith("root:")) {
39734d21 469 fileName.Append("?ZIP=");
470 }
93836e1b 471
53faeca4 472 *fPathName = fileName;
93836e1b 473 AliInfo(Form("Path: -%s-\n", fPathName->Data()));
53faeca4 474
f6065654 475 ResetIO();
476 InitIO("");
477
93836e1b 478// Handle subsidiary handlers
479 if (fSubsidiaryHandlers) {
480 TIter next(fSubsidiaryHandlers);
481 AliMCEventHandler *handler;
482 while((handler = (AliMCEventHandler*) next())) {
483 TString* spath = handler->GetInputPath();
484 if (spath->Contains("merged")) {
485 if (! fPathName->IsNull()) {
486 handler->Notify(Form("%s/../.", fPathName->Data()));
487 } else {
488 handler->Notify("../");
489 }
490 }
491 }
492 }
493
5fe09262 494 return kTRUE;
495}
36e82a52 496
5fe09262 497void AliMCEventHandler::ResetIO()
498{
5efedd31 499// Clear header and stack
b72029a3 500
aff49450 501 if (fInitOk) fMCEvent->Clean();
5efedd31 502
36e82a52 503// Delete Tree E
415d9f5c 504 delete fTreeE; fTreeE = 0;
b72029a3 505
5efedd31 506// Reset files
89f249fc 507 if (fFileE) {delete fFileE; fFileE = 0;}
508 if (fFileK) {delete fFileK; fFileK = 0;}
509 if (fFileTR) {delete fFileTR; fFileTR = 0;}
89afaa5a 510 fkExtension="";
c8b7b5d3 511 fInitOk = kFALSE;
93836e1b 512
513 if (fSubsidiaryHandlers) {
514 TIter next(fSubsidiaryHandlers);
515 AliMCEventHandler *handler;
516 while((handler = (AliMCEventHandler*)next())) {
517 handler->ResetIO();
518 }
519 }
520
5fe09262 521}
522
523
524Bool_t AliMCEventHandler::FinishEvent()
525{
5efedd31 526 // Clean-up after each event
66fc3944 527 if (fFileK && fCacheTK) {
528 fTreeK->SetCacheSize(0);
529 fCacheTK = 0;
530 fFileK->SetCacheRead(0, fTreeK);
531 }
532 if (fFileTR && fCacheTR) {
533 fTreeTR->SetCacheSize(0);
534 fCacheTR = 0;
535 fFileTR->SetCacheRead(0, fTreeTR);
536 }
43072535 537 delete fDirTR; fDirTR = 0;
538 delete fDirK; fDirK = 0;
aff49450 539 if (fInitOk) fMCEvent->FinishEvent();
93836e1b 540
541 if (fSubsidiaryHandlers) {
542 TIter next(fSubsidiaryHandlers);
543 AliMCEventHandler *handler;
544 while((handler = (AliMCEventHandler*)next())) {
545 handler->FinishEvent();
546 }
547 }
548
5fe09262 549 return kTRUE;
550}
551
552Bool_t AliMCEventHandler::Terminate()
553{
554 // Dummy
555 return kTRUE;
556}
557
558Bool_t AliMCEventHandler::TerminateIO()
559{
560 // Dummy
561 return kTRUE;
562}
563
0a05cd41 564
0931e76a 565void AliMCEventHandler::SetInputPath(const char* fname)
0a05cd41 566{
567 // Set the input path name
568 delete fPathName;
569 fPathName = new TString(fname);
570}
93836e1b 571
572void AliMCEventHandler::AddSubsidiaryHandler(AliMCEventHandler* handler)
573{
574 // Add a subsidiary handler. For example for background events
575
576 if (!fSubsidiaryHandlers) fSubsidiaryHandlers = new TList();
577 fSubsidiaryHandlers->Add(handler);
578}