1 /**************************************************************************
2 * Copyright(c) 1998-2007, 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 **************************************************************************/
18 //-------------------------------------------------------------------------
19 // Class for Kinematic Events
20 // Author: Andreas Morsch, CERN
21 //-------------------------------------------------------------------------
27 #include <TParticle.h>
28 #include <TClonesArray.h>
29 #include <TObjArray.h>
32 #include "AliMCEvent.h"
34 #include "AliTrackReference.h"
35 #include "AliHeader.h"
36 #include "AliGenEventHeader.h"
39 AliMCEvent::AliMCEvent():
42 fMCParticles(new TClonesArray("AliMCParticle",1000)),
52 // Default constructor
55 AliMCEvent::AliMCEvent(const AliMCEvent& mcEvnt) :
72 AliMCEvent& AliMCEvent::operator=(const AliMCEvent& mcEvnt)
74 // assignment operator
76 AliVEvent::operator=(mcEvnt);
82 void AliMCEvent::ConnectTreeE (TTree* tree)
84 // Connect the event header tree
85 tree->SetBranchAddress("Header", &fHeader);
88 void AliMCEvent::ConnectTreeK (TTree* tree)
90 // Connect the kinematics tree to the stack
91 fStack = fHeader->Stack();
92 fStack->ConnectTree(tree);
96 fNparticles = fStack->GetNtrack();
97 fNprimaries = fStack->GetNprimary();
98 AliInfo(Form("AliMCEvent: Number of particles: %5d (all) %5d (primaries)\n",
99 fNparticles, fNprimaries));
101 // This is a cache for the TParticles converted to MCParticles on user request
102 if (fMCParticleMap) {
103 fMCParticleMap->Clear();
104 if (fNparticles>0) fMCParticleMap->Expand(fNparticles);}
106 fMCParticleMap = new TObjArray(fNparticles);
107 fMCParticles->Clear();
110 void AliMCEvent::ConnectTreeTR (TTree* tree)
112 // Connect the track reference tree
115 if (fTreeTR->GetBranch("AliRun")) {
120 // This is an old format with one branch per detector not in synch with TreeK
121 ReorderAndExpandTreeTR();
124 fTreeTR->SetBranchAddress("TrackReferences", &fTrackReferences);
128 Int_t AliMCEvent::GetParticleAndTR(Int_t i, TParticle*& particle, TClonesArray*& trefs)
131 if (i < 0 || i >= fNparticles) {
132 AliWarning(Form("AliMCEventHandler::GetEntry: Index out of range"));
137 particle = fStack->Particle(i);
139 fTreeTR->GetEntry(fStack->TreeKEntry(i));
140 trefs = fTrackReferences;
141 return trefs->GetEntries();
149 void AliMCEvent::Clean()
151 // Clean-up before new trees are connected
161 if (fTrackReferences) {
162 fTrackReferences->Clear();
163 delete fTrackReferences;
164 fTrackReferences = 0;
168 void AliMCEvent::FinishEvent()
170 // Clean-up after event
175 void AliMCEvent::DrawCheck(Int_t i, Int_t search)
178 // Simple event display for debugging
180 AliWarning("No Track Reference information available");
184 if (i > -1 && i < fNparticles) {
185 fTreeTR->GetEntry(fStack->TreeKEntry(i));
187 AliWarning("AliMCEvent::GetEntry: Index out of range");
190 Int_t nh = fTrackReferences->GetEntries();
194 while(nh <= search && i < fNparticles - 1) {
196 fTreeTR->GetEntry(fStack->TreeKEntry(i));
197 nh = fTrackReferences->GetEntries();
199 printf("Found Hits at %5d\n", i);
201 TParticle* particle = fStack->Particle(i);
203 TH2F* h = new TH2F("", "", 100, -500, 500, 100, -500, 500);
204 Float_t x0 = particle->Vx();
205 Float_t y0 = particle->Vy();
207 Float_t x1 = particle->Vx() + particle->Px() * 50.;
208 Float_t y1 = particle->Vy() + particle->Py() * 50.;
210 TArrow* a = new TArrow(x0, y0, x1, y1, 0.01);
216 for (Int_t ih = 0; ih < nh; ih++) {
217 AliTrackReference* ref = (AliTrackReference*) fTrackReferences->At(ih);
218 TMarker* m = new TMarker(ref->X(), ref->Y(), 20);
220 m->SetMarkerSize(0.4);
226 void AliMCEvent::ReorderAndExpandTreeTR()
229 // Reorder and expand the track reference tree in order to match the kinematics tree.
230 // Copy the information from different branches into one
234 fTmpFileTR = new TFile("TrackRefsTmp.root", "recreate");
235 fTmpTreeTR = new TTree("TreeTR", "TrackReferences");
236 if (!fTrackReferences) fTrackReferences = new TClonesArray("AliTrackReference", 100);
237 fTmpTreeTR->Branch("TrackReferences", "TClonesArray", &fTrackReferences, 32000, 0);
241 // Activate the used branches only. Otherwisw we get a bad memory leak.
242 fTreeTR->SetBranchStatus("*", 0);
243 fTreeTR->SetBranchStatus("AliRun.*", 1);
244 fTreeTR->SetBranchStatus("ITS.*", 1);
245 fTreeTR->SetBranchStatus("TPC.*", 1);
246 fTreeTR->SetBranchStatus("TRD.*", 1);
247 fTreeTR->SetBranchStatus("TOF.*", 1);
248 fTreeTR->SetBranchStatus("FRAME.*", 1);
249 fTreeTR->SetBranchStatus("MUON.*", 1);
251 // Connect the active branches
252 TClonesArray* trefs[7];
253 for (Int_t i = 0; i < 7; i++) trefs[i] = 0;
255 // make branch for central track references
256 if (fTreeTR->GetBranch("AliRun")) fTreeTR->SetBranchAddress("AliRun", &trefs[0]);
257 if (fTreeTR->GetBranch("ITS")) fTreeTR->SetBranchAddress("ITS", &trefs[1]);
258 if (fTreeTR->GetBranch("TPC")) fTreeTR->SetBranchAddress("TPC", &trefs[2]);
259 if (fTreeTR->GetBranch("TRD")) fTreeTR->SetBranchAddress("TRD", &trefs[3]);
260 if (fTreeTR->GetBranch("TOF")) fTreeTR->SetBranchAddress("TOF", &trefs[4]);
261 if (fTreeTR->GetBranch("FRAME")) fTreeTR->SetBranchAddress("FRAME", &trefs[5]);
262 if (fTreeTR->GetBranch("MUON")) fTreeTR->SetBranchAddress("MUON", &trefs[6]);
265 Int_t np = fStack->GetNprimary();
266 Int_t nt = fTreeTR->GetEntries();
269 // Loop over tracks and find the secondaries with the help of the kine tree
275 for (Int_t ip = np - 1; ip > -1; ip--) {
276 part = fStack->Particle(ip);
277 // printf("Particle %5d %5d %5d %5d %5d %5d \n",
278 // ip, part->GetPdgCode(), part->GetFirstMother(), part->GetFirstDaughter(),
279 // part->GetLastDaughter(), part->TestBit(kTransportBit));
281 // Determine range of secondaries produced by this primary during transport
282 Int_t dau1 = part->GetFirstDaughter();
283 if (dau1 < np) continue; // This particle has no secondaries produced during transport
286 Int_t inext = ip - 1;
289 part = fStack->Particle(inext);
290 dau2 = part->GetFirstDaughter();
291 if (dau2 == -1 || dau2 < np) {
297 dau2 = fStack->GetNtrack() - 1;
300 } // find upper bound
304 // printf("Check (1) %5d %5d %5d %5d %5d \n", ip, np, it, dau1, dau2);
306 // Loop over reference hits and find secondary label
307 // First the tricky part: find the entry in treeTR than contains the hits or
308 // make sure that no hits exist.
310 Bool_t hasHits = kFALSE;
311 Bool_t isOutside = kFALSE;
314 while (!hasHits && !isOutside && it < nt) {
315 fTreeTR->GetEntry(it++);
316 for (Int_t ib = 0; ib < 7; ib++) {
317 if (!trefs[ib]) continue;
318 Int_t nh = trefs[ib]->GetEntries();
319 for (Int_t ih = 0; ih < nh; ih++) {
320 AliTrackReference* tr = (AliTrackReference*) trefs[ib]->At(ih);
321 Int_t label = tr->Label();
322 if (label >= dau1 && label <= dau2) {
327 if (label > dau2 || label < ip) {
333 if (hasHits || isOutside) break;
338 // Write empty entries
339 for (Int_t id = dau1; (id <= dau2); id++) {
345 fTreeTR->GetEntry(itlast);
346 for (Int_t id = dau1; (id <= dau2) && (dau1 > -1); id++) {
347 for (Int_t ib = 0; ib < 7; ib++) {
348 if (!trefs[ib]) continue;
349 Int_t nh = trefs[ib]->GetEntries();
350 for (Int_t ih = 0; ih < nh; ih++) {
351 AliTrackReference* tr = (AliTrackReference*) trefs[ib]->At(ih);
352 Int_t label = tr->Label();
354 if (label == ip) continue;
355 if (label > dau2 || label < dau1)
356 printf("AliMCEventHandler::Track Reference Label out of range !: %5d %5d %5d %5d \n",
357 itlast, label, dau1, dau2);
360 tr->SetDetectorId(ib-1);
361 Int_t nref = fTrackReferences->GetEntriesFast();
362 TClonesArray &lref = *fTrackReferences;
363 new(lref[nref]) AliTrackReference(*tr);
368 fTrackReferences->Clear();
375 // Now loop again and write the primaries
378 for (Int_t ip = 0; ip < np; ip++) {
380 while (labmax < ip && it > -1) {
381 fTreeTR->GetEntry(it--);
382 for (Int_t ib = 0; ib < 7; ib++) {
383 if (!trefs[ib]) continue;
384 Int_t nh = trefs[ib]->GetEntries();
386 // Loop over reference hits and find primary labels
387 for (Int_t ih = 0; ih < nh; ih++) {
388 AliTrackReference* tr = (AliTrackReference*) trefs[ib]->At(ih);
389 Int_t label = tr->Label();
390 if (label < np && label > labmax) {
395 tr->SetDetectorId(ib-1);
396 Int_t nref = fTrackReferences->GetEntriesFast();
397 TClonesArray &lref = *fTrackReferences;
398 new(lref[nref]) AliTrackReference(*tr);
405 fTrackReferences->Clear();
412 delete fTreeTR; fTreeTR = 0;
414 for (Int_t ib = 0; ib < 7; ib++) {
422 if (ifills != fStack->GetNtrack())
423 printf("AliMCEvent:Number of entries in TreeTR (%5d) unequal to TreeK (%5d) \n",
424 ifills, fStack->GetNtrack());
427 fTreeTR = fTmpTreeTR;
430 AliMCParticle* AliMCEvent::GetTrack(Int_t i) const
433 AliMCParticle *mcParticle;
436 // Out of range check
437 if (i < 0 || i >= fNparticles) {
438 AliWarning(Form("AliMCEvent::GetEntry: Index out of range"));
444 particle = fStack->Particle(i);
446 // First check of the MC Particle has been already cached
447 if(!fMCParticleMap->At(i)) {
448 Int_t nentries = fMCParticles->GetEntriesFast();
449 new ((*fMCParticles)[nentries]) AliMCParticle(particle);
450 mcParticle = dynamic_cast<AliMCParticle*>((*fMCParticles)[nentries]);
451 fMCParticleMap->AddAt(mcParticle, i);
453 mcParticle = dynamic_cast<AliMCParticle*>(fMCParticleMap->At(i));
459 AliGenEventHeader* AliMCEvent::GenEventHeader() {return (fHeader->GenEventHeader());}