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 "AliTrackReference.h"
30 #include "AliHeader.h"
35 #include <TParticle.h>
36 #include <TClonesArray.h>
37 #include <TDirectoryFile.h>
43 ClassImp(AliMCEventHandler)
45 AliMCEventHandler::AliMCEventHandler() :
67 // Default constructor
70 AliMCEventHandler::AliMCEventHandler(const char* name, const char* title) :
71 AliVEventHandler(name, title),
81 fHeader(new AliHeader()),
82 fTrackReferences(new TClonesArray("AliTrackReference", 200)),
94 AliMCEventHandler::~AliMCEventHandler()
102 Bool_t AliMCEventHandler::InitIO(Option_t* /*opt*/)
106 fFileE = new TFile(Form("%sgalice.root", fPathName));
107 if (!fFileE) printf("AliMCEventHandler:galice.root not found in directory %s ! \n", fPathName);
109 fFileE->GetObject("TE", fTreeE);
110 fTreeE->SetBranchAddress("Header", &fHeader);
111 fNEvent = fTreeE->GetEntries();
114 fFileK = new TFile(Form("%sKinematics%s.root", fPathName, fExtension));
115 if (!fFileK) printf("AliMCEventHandler:Kinematics.root not found in directory %s ! \n", fPathName);
116 fEventsPerFile = fFileK->GetNkeys() - fFileK->GetNProcessIDs();
119 fFileTR = new TFile(Form("%sTrackRefs%s.root", fPathName, fExtension));
120 if (!fFileTR) printf("AliMCEventHandler:TrackRefs.root not found in directory %s ! \n", fPathName);
122 // Reset the event number
126 printf("AliMCEventHandler:Number of events in this directory %5d \n", fNEvent);
131 Bool_t AliMCEventHandler::GetEvent(Int_t iev)
133 // Load the event number iev
134 Int_t inew = iev/fEventsPerFile;
135 if (inew != fFileNumber) {
137 if (!OpenFile(fFileNumber)){
143 sprintf(folder, "Event%d", iev);
145 fTreeE->GetEntry(iev);
146 fStack = fHeader->Stack();
148 TDirectoryFile* dirK = 0;
149 fFileK->GetObject(folder, dirK);
151 printf("AliMCEventHandler: Event #%5d not found\n", iev);
154 dirK->GetObject("TreeK", fTreeK);
155 fStack->ConnectTree(fTreeK);
158 TDirectoryFile* dirTR = 0;
159 fFileTR->GetObject(folder, dirTR);
160 dirTR->GetObject("TreeTR", fTreeTR);
161 if (fTreeTR->GetBranch("AliRun")) {
162 // This is an old format with one branch per detector not in synch with TreeK
163 ReorderAndExpandTreeTR();
166 fTreeTR->SetBranchAddress("TrackReferences", &fTrackReferences);
170 fNparticles = fStack->GetNtrack();
171 fNprimaries = fStack->GetNprimary();
172 printf("AliMCEventHandler: Event#: %5d Number of particles %5d \n", fEvent, fNparticles);
178 Bool_t AliMCEventHandler::OpenFile(Int_t i)
183 fExtension = Form("%d", i);
190 fFileK = new TFile(Form("%sKinematics%s.root", fPathName, fExtension));
192 printf("AliMCEventHandler:Kinematics%s.root not found in directory %s ! \n", fExtension, fPathName);
197 fFileTR = new TFile(Form("%sTrackRefs%s.root", fPathName, fExtension));
199 printf("AliMCEventHandler:TrackRefs%s.root not found in directory %s ! \n", fExtension, fPathName);
206 Bool_t AliMCEventHandler::BeginEvent()
208 // Read the next event
210 if (fEvent >= fNEvent) {
211 printf("AliMCEventHandler: Event number out of range %5d\n", fEvent);
214 return GetEvent(fEvent);
217 Int_t AliMCEventHandler::GetParticleAndTR(Int_t i, TParticle*& particle, TClonesArray*& trefs)
220 if (i > -1 && i < fNparticles) {
221 fTreeTR->GetEntry(fStack->TreeKEntry(i));
223 printf("AliMCEventHandler::GetEntry: Index out of range");
225 particle = fStack->Particle(i);
226 trefs = fTrackReferences;
227 return trefs->GetEntries();
230 void AliMCEventHandler::DrawCheck(Int_t i, Bool_t search)
232 // Retrieve entry i and draw momentum vector and hits
233 if (i > -1 && i < fNparticles) {
234 fTreeTR->GetEntry(fStack->TreeKEntry(i));
236 printf("AliMCEventHandler::GetEntry: Index out of range");
239 Int_t nh = fTrackReferences->GetEntries();
243 while(nh == 0 && i < fNparticles - 1) {
245 fTreeTR->GetEntry(fStack->TreeKEntry(i));
246 nh = fTrackReferences->GetEntries();
248 printf("Found Hits at %5d\n", i);
250 TParticle* particle = fStack->Particle(i);
252 TH2F* h = new TH2F("", "", 100, -500, 500, 100, -500, 500);
253 Float_t x0 = particle->Vx();
254 Float_t y0 = particle->Vy();
256 Float_t x1 = particle->Vx() + particle->Px() * 50.;
257 Float_t y1 = particle->Vy() + particle->Py() * 50.;
259 TArrow* a = new TArrow(x0, y0, x1, y1, 0.01);
265 for (Int_t ih = 0; ih < nh; ih++) {
266 AliTrackReference* ref = (AliTrackReference*) fTrackReferences->At(ih);
267 TMarker* m = new TMarker(ref->X(), ref->Y(), 20);
269 m->SetMarkerSize(0.4);
274 Bool_t AliMCEventHandler::Notify(const char *path)
276 // Notify about directory change
277 // The directory is taken from the 'path' argument
280 printf("AliMCEventHandler::Notify() file: %s\n", path);
281 fPathName = Form("%s", path);
287 void AliMCEventHandler::ResetIO()
290 if (fFileE) delete fFileE;
291 if (fFileK) delete fFileK;
292 if (fFileTR) delete fFileTR;
296 Bool_t AliMCEventHandler::FinishEvent()
302 Bool_t AliMCEventHandler::Terminate()
308 Bool_t AliMCEventHandler::TerminateIO()
314 void AliMCEventHandler::ReorderAndExpandTreeTR()
317 // Reorder and expand the track reference tree in order to match the kinematics tree.
318 // Copy the information from different branches into one
321 if (fTmpTreeTR) delete fTmpTreeTR;
327 fTmpFileTR = new TFile("TrackRefsTmp.root", "recreate");
328 fTmpTreeTR = new TTree("TreeTR", "Track References");
329 if (!fTrackReferences) fTrackReferences = new TClonesArray("AliTrackReference", 100);
330 fTmpTreeTR->Branch("TrackReferences", "TClonesArray", &fTrackReferences, 4000);
332 TClonesArray* trefs[7];
333 for (Int_t i = 0; i < 7; i++) trefs[i] = 0;
335 // make branch for central track references
336 if (fTreeTR->GetBranch("AliRun")) fTreeTR->SetBranchAddress("AliRun", &trefs[0]);
337 if (fTreeTR->GetBranch("ITS")) fTreeTR->SetBranchAddress("ITS", &trefs[1]);
338 if (fTreeTR->GetBranch("TPC")) fTreeTR->SetBranchAddress("TPC", &trefs[2]);
339 if (fTreeTR->GetBranch("TRD")) fTreeTR->SetBranchAddress("TRD", &trefs[3]);
340 if (fTreeTR->GetBranch("TOF")) fTreeTR->SetBranchAddress("TOF", &trefs[4]);
341 if (fTreeTR->GetBranch("FRAME")) fTreeTR->SetBranchAddress("FRAME", &trefs[5]);
342 if (fTreeTR->GetBranch("MUON")) fTreeTR->SetBranchAddress("MUON", &trefs[6]);
345 Int_t np = fStack->GetNprimary();
346 Int_t nt = fTreeTR->GetEntries();
348 // Loop over tracks and find the secondaries with the help of the kine tree
353 for (Int_t ip = np - 1; ip > -1; ip--) {
354 TParticle *part = fStack->Particle(ip);
355 // printf("Particle %5d %5d %5d %5d %5d %5d \n",
356 // ip, part->GetPdgCode(), part->GetFirstMother(), part->GetFirstDaughter(),
357 // part->GetLastDaughter(), part->TestBit(kTransportBit));
359 // Determine range of secondaries produced by this primary during transport
360 Int_t dau1 = part->GetFirstDaughter();
361 if (dau1 < np) continue; // This particle has no secondaries produced during transport
364 Int_t inext = ip - 1;
367 part = fStack->Particle(inext);
368 dau2 = part->GetFirstDaughter();
369 if (dau2 == -1 || dau2 < np) {
375 dau2 = fStack->GetNtrack() - 1;
378 } // find upper bound
382 // printf("Check (1) %5d %5d %5d %5d %5d \n", ip, np, it, dau1, dau2);
384 // Loop over reference hits and find secondary label
385 // First the tricky part: find the entry in treeTR than contains the hits or
386 // make sure that no hits exist.
388 Bool_t hasHits = kFALSE;
389 Bool_t isOutside = kFALSE;
392 while (!hasHits && !isOutside && it < nt) {
393 fTreeTR->GetEntry(it++);
394 for (Int_t ib = 0; ib < 7; ib++) {
395 if (!trefs[ib]) continue;
396 Int_t nh = trefs[ib]->GetEntries();
397 for (Int_t ih = 0; ih < nh; ih++) {
398 AliTrackReference* tr = (AliTrackReference*) trefs[ib]->At(ih);
399 Int_t label = tr->Label();
400 if (label >= dau1 && label <= dau2) {
405 if (label > dau2 || label < ip) {
411 if (hasHits || isOutside) break;
416 // Write empty entries
417 for (Int_t id = dau1; (id <= dau2); id++) {
423 fTreeTR->GetEntry(itlast);
424 for (Int_t id = dau1; (id <= dau2) && (dau1 > -1); id++) {
425 for (Int_t ib = 0; ib < 7; ib++) {
426 if (!trefs[ib]) continue;
427 Int_t nh = trefs[ib]->GetEntries();
428 for (Int_t ih = 0; ih < nh; ih++) {
429 AliTrackReference* tr = (AliTrackReference*) trefs[ib]->At(ih);
430 Int_t label = tr->Label();
432 if (label == ip) continue;
433 if (label > dau2 || label < dau1)
434 printf("AliMCEventHandler::Track Reference Label out of range !: %5d %5d %5d %5d \n",
435 itlast, label, dau1, dau2);
438 tr->SetDetectorId(ib-1);
439 Int_t nref = fTrackReferences->GetEntriesFast();
440 TClonesArray &lref = *fTrackReferences;
441 new(lref[nref]) AliTrackReference(*tr);
446 fTrackReferences->Clear();
452 // Now loop again and write the primaries
455 for (Int_t ip = 0; ip < np; ip++) {
457 while (labmax < ip && it > -1) {
458 fTreeTR->GetEntry(it--);
459 for (Int_t ib = 0; ib < 7; ib++) {
460 if (!trefs[ib]) continue;
461 Int_t nh = trefs[ib]->GetEntries();
463 // Loop over reference hits and find primary labels
464 for (Int_t ih = 0; ih < nh; ih++) {
465 AliTrackReference* tr = (AliTrackReference*) trefs[ib]->At(ih);
466 Int_t label = tr->Label();
467 if (label < np && label > labmax) {
472 tr->SetDetectorId(ib-1);
473 Int_t nref = fTrackReferences->GetEntriesFast();
474 TClonesArray &lref = *fTrackReferences;
475 new(lref[nref]) AliTrackReference(*tr);
482 fTrackReferences->Clear();
486 if (ifills != fStack->GetNtrack())
487 printf("AliMCEventHandler:Number of entries in TreeTR (%5d) unequal to TreeK (%5d) \n",
488 ifills, fStack->GetNtrack());
489 fTreeTR = fTmpTreeTR;