AliRoot Core  3dc7879 (3dc7879)
AliMCEvent.cxx
Go to the documentation of this file.
1 /**************************************************************************
2  * Copyright(c) 1998-2007, ALICE Experiment at CERN, All rights reserved. *
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 //-------------------------------------------------------------------------
19 // Class for Kinematic Events
20 // Author: Andreas Morsch, CERN
21 //-------------------------------------------------------------------------
22 #include <TArrow.h>
23 #include <TMarker.h>
24 #include <TH2F.h>
25 #include <TTree.h>
26 #include <TFile.h>
27 #include <TParticle.h>
28 #include <TClonesArray.h>
29 #include <TList.h>
30 #include <TArrayF.h>
31 
32 #include "AliLog.h"
33 #include "AliMCEvent.h"
34 #include "AliMCVertex.h"
35 #include "AliStack.h"
36 #include "AliTrackReference.h"
37 #include "AliHeader.h"
38 #include "AliGenEventHeader.h"
41 #include "AliFastContainerAccess.h"
42 #include "AliMiscConstants.h"
43 
44 
45 Int_t AliMCEvent::fgkBgLabelOffset(10000000);
46 
47 
49  AliVEvent(),
50  fStack(0),
51  fMCParticles(0),
52  fMCParticleMap(0),
53  fHeader(new AliHeader()),
54  fAODMCHeader(0),
55  fTRBuffer(0),
56  fTrackReferences(new TClonesArray("AliTrackReference", 1000)),
57  fTreeTR(0),
58  fTmpTreeTR(0),
59  fTmpFileTR(0),
60  fNprimaries(-1),
61  fNparticles(-1),
62  fSubsidiaryEvents(0),
63  fPrimaryOffset(0),
64  fSecondaryOffset(0),
65  fExternal(0),
66  fTopEvent(0),
67  fVertex(0),
68  fNBG(-1)
69 {
70  // Default constructor
71  fTopEvent = this;
72 }
73 
75  AliVEvent(mcEvnt),
76  fStack(mcEvnt.fStack),
77  fMCParticles(mcEvnt.fMCParticles),
79  fHeader(mcEvnt.fHeader),
80  fAODMCHeader(mcEvnt.fAODMCHeader),
81  fTRBuffer(mcEvnt.fTRBuffer),
83  fTreeTR(mcEvnt.fTreeTR),
84  fTmpTreeTR(mcEvnt.fTmpTreeTR),
85  fTmpFileTR(mcEvnt.fTmpFileTR),
86  fNprimaries(mcEvnt.fNprimaries),
87  fNparticles(mcEvnt.fNparticles),
89  fPrimaryOffset(0),
91  fExternal(0),
92  fTopEvent(mcEvnt.fTopEvent),
93  fVertex(mcEvnt.fVertex),
94  fNBG(mcEvnt.fNBG)
95 {
96 // Copy constructor
97 }
98 
99 
101 {
102  // assignment operator
103  if (this!=&mcEvnt) {
104  AliVEvent::operator=(mcEvnt);
105  }
106 
107  return *this;
108 }
109 
111 {
113 }
114 
116 {
117  // Connect the event header tree
118  tree->SetBranchAddress("Header", &fHeader);
119 }
120 
122 {
123  // Connect Kinematics tree
124  fStack = fHeader->Stack();
125  fStack->ConnectTree(tree);
126  //
127  // Load the event
128  fStack->GetEvent();
129 
131 }
132 
134 {
135  // fill MC event information from stack and header
136 
137  fHeader = header;
138  fStack = fHeader->Stack();
139 
141 }
142 
144 {
145  // bookkeeping for next event
146 
147  // Connect the kinematics tree to the stack
148  if (!fMCParticles) fMCParticles = new TClonesArray("AliMCParticle",1000);
149 
150  // Initialize members
153 
154  Int_t iev = fHeader->GetEvent();
155  Int_t ievr = fHeader->GetEventNrInRun();
156  AliDebug(1, Form("AliMCEvent# %5d %5d: Number of particles: %5d (all) %5d (primaries)\n",
157  iev, ievr, fNparticles, fNprimaries));
158 
159  // This is a cache for the TParticles converted to MCParticles on user request
160  if (fMCParticleMap) {
161  fMCParticleMap->Clear();
162  fMCParticles->Delete();
163  if (fNparticles>0) fMCParticleMap->Expand(fNparticles);
164  }
165  else
167 }
168 
170 {
171  // Connect the track reference tree
172  fTreeTR = tree;
173  if (!fTreeTR) return; // just disconnect
174 
175  if (fTreeTR->GetBranch("AliRun")) {
176  if (fTmpFileTR) {
177  fTmpFileTR->Close();
178  delete fTmpFileTR;
179  }
180  // This is an old format with one branch per detector not in synch with TreeK
182  } else {
183  // New format
184  fTreeTR->SetBranchAddress("TrackReferences", &fTRBuffer);
185  }
186 }
187 
188 Int_t AliMCEvent::GetParticleAndTR(Int_t i, TParticle*& particle, TClonesArray*& trefs)
189 {
190  // Retrieve entry i
191  if (i >= BgLabelOffset()) {
192  if (fSubsidiaryEvents) {
193  AliMCEvent* bgEvent=0;
194  i = FindIndexAndEvent(i, bgEvent);
195  return bgEvent->GetParticleAndTR(i,particle,trefs);
196  } else {
197  particle = 0;
198  trefs = 0;
199  return -1;
200  }
201  }
202  //
203  if (i < 0 || i >= fNparticles) {
204  AliWarning(Form("AliMCEventHandler::GetEntry: Index out of range"));
205  particle = 0;
206  trefs = 0;
207  return (-1);
208  }
209 
210  if (fSubsidiaryEvents) {
211  AliMCEvent* mc;
212  Int_t idx = FindIndexAndEvent(i, mc);
213  return mc->GetParticleAndTR(idx,particle,trefs);
214  }
215  //
216  particle = fStack->Particle(i,kTRUE);
217  if (fTreeTR) {
218  fTreeTR->GetEntry(fStack->TreeKEntry(i,kTRUE));
219  trefs = fTRBuffer;
220  return trefs->GetEntries();
221  } else {
222  trefs = 0;
223  return -1;
224  }
225 
226 
227 }
228 
229 
231 {
232  // Clean-up before new trees are connected
233  delete fStack; fStack = 0;
234 
235  // Clear TR
236  if (fTRBuffer) {
237  fTRBuffer->Delete();
238  delete fTRBuffer;
239  fTRBuffer = 0;
240  }
241 }
242 
243 #include <iostream>
244 
246 {
247  // Clean-up after event
248  //
249  if (fStack) fStack->Reset(0);
250  fMCParticles->Delete();
251 
252  if (fMCParticleMap)
253  fMCParticleMap->Clear();
254  if (fTRBuffer) {
255  fTRBuffer->Delete();
256  }
257  // fTrackReferences->Delete();
258  fTrackReferences->Clear();
259  fNparticles = -1;
260  fNprimaries = -1;
261  fStack = 0;
262  delete fSubsidiaryEvents;
263  fSubsidiaryEvents = 0;
264  fNBG = -1;
265 }
266 
267 
268 
269 void AliMCEvent::DrawCheck(Int_t i, Int_t search)
270 {
271  //
272  // Simple event display for debugging
273  if (!fTreeTR) {
274  AliWarning("No Track Reference information available");
275  return;
276  }
277 
278  if (i > -1 && i < fNparticles) {
279  fTreeTR->GetEntry(fStack->TreeKEntry(i));
280  } else {
281  AliWarning("AliMCEvent::GetEntry: Index out of range");
282  }
283 
284  Int_t nh = fTRBuffer->GetEntries();
285 
286 
287  if (search) {
288  while(nh <= search && i < fNparticles - 1) {
289  i++;
290  fTreeTR->GetEntry(fStack->TreeKEntry(i));
291  nh = fTRBuffer->GetEntries();
292  }
293  printf("Found Hits at %5d\n", i);
294  }
295  TParticle* particle = fStack->Particle(i,kTRUE);
296  if (!particle) return;
297  TH2F* h = new TH2F("", "", 100, -500, 500, 100, -500, 500);
298  Float_t x0 = particle->Vx();
299  Float_t y0 = particle->Vy();
300 
301  Float_t x1 = particle->Vx() + particle->Px() * 50.;
302  Float_t y1 = particle->Vy() + particle->Py() * 50.;
303 
304  TArrow* a = new TArrow(x0, y0, x1, y1, 0.01);
305  h->Draw();
306  a->SetLineColor(2);
307 
308  a->Draw();
309 
310  for (Int_t ih = 0; ih < nh; ih++) {
312  TMarker* m = new TMarker(ref->X(), ref->Y(), 20);
313  m->Draw();
314  m->SetMarkerSize(0.4);
315 
316  }
317 }
318 
319 
321 {
322 //
323 // Reorder and expand the track reference tree in order to match the kinematics tree.
324 // Copy the information from different branches into one
325 //
326 // TreeTR
327 
328  fTmpFileTR = new TFile("TrackRefsTmp.root", "recreate");
329  fTmpTreeTR = new TTree("TreeTR", "TrackReferences");
330  if (!fTRBuffer) fTRBuffer = new TClonesArray("AliTrackReference", 100);
331  fTmpTreeTR->Branch("TrackReferences", "TClonesArray", &fTRBuffer, 64000, 0);
332 
333 
334 //
335 // Activate the used branches only. Otherwisw we get a bad memory leak.
336  if (fTreeTR) {
337  fTreeTR->SetBranchStatus("*", 0);
338  fTreeTR->SetBranchStatus("AliRun.*", 1);
339  fTreeTR->SetBranchStatus("ITS.*", 1);
340  fTreeTR->SetBranchStatus("TPC.*", 1);
341  fTreeTR->SetBranchStatus("TRD.*", 1);
342  fTreeTR->SetBranchStatus("TOF.*", 1);
343  fTreeTR->SetBranchStatus("FRAME.*", 1);
344  fTreeTR->SetBranchStatus("MUON.*", 1);
345  }
346 
347 //
348 // Connect the active branches
349  TClonesArray* trefs[7];
350  for (Int_t i = 0; i < 7; i++) trefs[i] = 0;
351  if (fTreeTR){
352  // make branch for central track references
353  if (fTreeTR->GetBranch("AliRun")) fTreeTR->SetBranchAddress("AliRun", &trefs[0]);
354  if (fTreeTR->GetBranch("ITS")) fTreeTR->SetBranchAddress("ITS", &trefs[1]);
355  if (fTreeTR->GetBranch("TPC")) fTreeTR->SetBranchAddress("TPC", &trefs[2]);
356  if (fTreeTR->GetBranch("TRD")) fTreeTR->SetBranchAddress("TRD", &trefs[3]);
357  if (fTreeTR->GetBranch("TOF")) fTreeTR->SetBranchAddress("TOF", &trefs[4]);
358  if (fTreeTR->GetBranch("FRAME")) fTreeTR->SetBranchAddress("FRAME", &trefs[5]);
359  if (fTreeTR->GetBranch("MUON")) fTreeTR->SetBranchAddress("MUON", &trefs[6]);
360  }
361 
362  Int_t np = fStack->GetNprimary();
363  Int_t nt = fTreeTR->GetEntries();
364 
365  //
366  // Loop over tracks and find the secondaries with the help of the kine tree
367  Int_t ifills = 0;
368  Int_t it = 0;
369  Int_t itlast = 0;
370  TParticle* part;
371 
372  for (Int_t ip = np - 1; ip > -1; ip--) {
373  part = fStack->Particle(ip,kTRUE);
374 // printf("Particle %5d %5d %5d %5d %5d %5d \n",
375 // ip, part->GetPdgCode(), part->GetFirstMother(), part->GetFirstDaughter(),
376 // part->GetLastDaughter(), part->TestBit(kTransportBit));
377 
378  // Determine range of secondaries produced by this primary during transport
379  Int_t dau1 = part->GetFirstDaughter();
380  if (dau1 < np) continue; // This particle has no secondaries produced during transport
381  Int_t dau2 = -1;
382  if (dau1 > -1) {
383  Int_t inext = ip - 1;
384  while (dau2 < 0) {
385  if (inext >= 0) {
386  part = fStack->Particle(inext,kTRUE);
387  dau2 = part->GetFirstDaughter();
388  if (dau2 == -1 || dau2 < np) {
389  dau2 = -1;
390  } else {
391  dau2--;
392  }
393  } else {
394  dau2 = fStack->GetNtrack() - 1;
395  }
396  inext--;
397  } // find upper bound
398  } // dau2 < 0
399 
400 
401 // printf("Check (1) %5d %5d %5d %5d %5d \n", ip, np, it, dau1, dau2);
402 //
403 // Loop over reference hits and find secondary label
404 // First the tricky part: find the entry in treeTR than contains the hits or
405 // make sure that no hits exist.
406 //
407  Bool_t hasHits = kFALSE;
408  Bool_t isOutside = kFALSE;
409 
410  it = itlast;
411  while (!hasHits && !isOutside && it < nt) {
412  fTreeTR->GetEntry(it++);
413  for (Int_t ib = 0; ib < 7; ib++) {
414  if (!trefs[ib]) continue;
415  Int_t nh = trefs[ib]->GetEntries();
416  for (Int_t ih = 0; ih < nh; ih++) {
417  AliTrackReference* tr = (AliTrackReference*) trefs[ib]->At(ih);
418  Int_t label = tr->Label();
419  if (label >= dau1 && label <= dau2) {
420  hasHits = kTRUE;
421  itlast = it - 1;
422  break;
423  }
424  if (label > dau2 || label < ip) {
425  isOutside = kTRUE;
426  itlast = it - 1;
427  break;
428  }
429  } // hits
430  if (hasHits || isOutside) break;
431  } // branches
432  } // entries
433 
434  if (!hasHits) {
435  // Write empty entries
436  for (Int_t id = dau1; (id <= dau2); id++) {
437  fTmpTreeTR->Fill();
438  ifills++;
439  }
440  } else {
441  // Collect all hits
442  fTreeTR->GetEntry(itlast);
443  for (Int_t id = dau1; (id <= dau2) && (dau1 > -1); id++) {
444  for (Int_t ib = 0; ib < 7; ib++) {
445  if (!trefs[ib]) continue;
446  Int_t nh = trefs[ib]->GetEntries();
447  for (Int_t ih = 0; ih < nh; ih++) {
448  AliTrackReference* tr = (AliTrackReference*) trefs[ib]->At(ih);
449  Int_t label = tr->Label();
450  // Skip primaries
451  if (label == ip) continue;
452  if (label > dau2 || label < dau1)
453  printf("AliMCEventHandler::Track Reference Label out of range !: %5d %5d %5d %5d \n",
454  itlast, label, dau1, dau2);
455  if (label == id) {
456  // secondary found
457  tr->SetDetectorId(ib-1);
458  Int_t nref = fTRBuffer->GetEntriesFast();
459  TClonesArray &lref = *fTRBuffer;
460  new(lref[nref]) AliTrackReference(*tr);
461  }
462  } // hits
463  } // branches
464  fTmpTreeTR->Fill();
465  fTRBuffer->Delete();
466  ifills++;
467  } // daughters
468  } // has hits
469  } // tracks
470 
471  //
472  // Now loop again and write the primaries
473  //
474  it = nt - 1;
475  for (Int_t ip = 0; ip < np; ip++) {
476  Int_t labmax = -1;
477  while (labmax < ip && it > -1) {
478  fTreeTR->GetEntry(it--);
479  for (Int_t ib = 0; ib < 7; ib++) {
480  if (!trefs[ib]) continue;
481  Int_t nh = trefs[ib]->GetEntries();
482  //
483  // Loop over reference hits and find primary labels
484  for (Int_t ih = 0; ih < nh; ih++) {
485  AliTrackReference* tr = (AliTrackReference*) trefs[ib]->At(ih);
486  Int_t label = tr->Label();
487  if (label < np && label > labmax) {
488  labmax = label;
489  }
490 
491  if (label == ip) {
492  tr->SetDetectorId(ib-1);
493  Int_t nref = fTRBuffer->GetEntriesFast();
494  TClonesArray &lref = *fTRBuffer;
495  new(lref[nref]) AliTrackReference(*tr);
496  }
497  } // hits
498  } // branches
499  } // entries
500  it++;
501  fTmpTreeTR->Fill();
502  fTRBuffer->Delete();
503  ifills++;
504  } // tracks
505  // Check
506 
507 
508  // Clean-up
509  delete fTreeTR; fTreeTR = 0;
510 
511  for (Int_t ib = 0; ib < 7; ib++) {
512  if (trefs[ib]) {
513  trefs[ib]->Clear();
514  delete trefs[ib];
515  trefs[ib] = 0;
516  }
517  }
518 
519  if (ifills != fStack->GetNtrack())
520  printf("AliMCEvent:Number of entries in TreeTR (%5d) unequal to TreeK (%5d) \n",
521  ifills, fStack->GetNtrack());
522 
523  fTmpTreeTR->Write();
525 }
526 
528 {
529  // returns true if particle id is from subsidiary (to which the signal was embedded) event
530  if (id >= BgLabelOffset() && fSubsidiaryEvents) return kTRUE;
531  if (fSubsidiaryEvents) {
532  AliMCEvent* mc;
533  FindIndexAndEvent(id, mc);
534  if (mc != fSubsidiaryEvents->At(0)) return kTRUE;
535  }
536  return kFALSE;
537 }
538 
539 
541 {
542  // Get MC Particle i
543  //
544 
545  if (fExternal) {
546  return ((AliVParticle*) (fMCParticles->At(i)));
547  }
548 
549  //
550  // Check first if this explicitely accesses the subsidiary event
551 
552  if (i >= BgLabelOffset()) {
553  if (fSubsidiaryEvents) {
554  AliMCEvent* bgEvent=0;
555  i = FindIndexAndEvent(i, bgEvent);
556  return bgEvent->GetTrack(i);
557  } else {
558  return (AliVParticle*)GetDummyTrack();
559  }
560  }
561 
562  //
563  AliMCParticle *mcParticle = 0;
564  TParticle *particle = 0;
565  TClonesArray *trefs = 0;
566  Int_t ntref = 0;
567  TObjArray *rarray = 0;
568 
569  // Out of range check
570  if (i < 0 || i >= fNparticles) {
571  if (i==gkDummyLabel) return 0;
572  AliWarning(Form("AliMCEvent::GetEntry: Index out of range"));
573  mcParticle = 0;
574  return (mcParticle);
575  }
576 
577 
578  if (fSubsidiaryEvents) {
579  AliMCEvent* mc;
580  Int_t idx = FindIndexAndEvent(i, mc);
581  return (mc->GetTrack(idx));
582  }
583 
584  //
585  // First check If the MC Particle has been already cached
586  if(!fMCParticleMap->At(i)) {
587  // Get particle from the stack
588  particle = fStack->Particle(i,kTRUE);
589  // Get track references from Tree TR
590  if (fTreeTR) {
591  fTreeTR->GetEntry(fStack->TreeKEntry(i,kTRUE));
592  trefs = fTRBuffer;
593  ntref = trefs->GetEntriesFast();
594  rarray = new TObjArray(ntref);
595  Int_t nen = fTrackReferences->GetEntriesFast();
596  for (Int_t j = 0; j < ntref; j++) {
597  // Save the track references in a TClonesArray
598  AliTrackReference* ref = dynamic_cast<AliTrackReference*>((*fTRBuffer)[j]);
599  // Save the pointer in a TRefArray
600  if (ref) {
601  new ((*fTrackReferences)[nen]) AliTrackReference(*ref);
602  rarray->AddAt((*fTrackReferences)[nen], j);
603  nen++;
604  }
605  } // loop over track references for entry i
606  } // if TreeTR available
607  Int_t nentries = fMCParticles->GetEntriesFast();
608  mcParticle = new ((*fMCParticles)[nentries]) AliMCParticle(particle, rarray, i);
609  fMCParticleMap->AddAt(mcParticle, i);
610  if (mcParticle) {
611  TParticle* part = mcParticle->Particle();
612  Int_t imo = part->GetFirstMother();
613  Int_t id1 = part->GetFirstDaughter();
614  Int_t id2 = part->GetLastDaughter();
615  mcParticle->SetLabel(i); // RS mcParticle should refer to its position in its parent stack
616  mcParticle->SetStack(fStack);
617  if (fPrimaryOffset > 0 || fSecondaryOffset > 0) {
618  // Remapping of the mother and daughter indices
619  if (imo>=0) {
620  mcParticle->SetMother( imo<fNprimaries ? imo + fPrimaryOffset : imo + fSecondaryOffset - fNprimaries);
621  }
622  if (id1>=0) {
623  if (id1 < fNprimaries) {
624  mcParticle->SetFirstDaughter(id1 + fPrimaryOffset);
625  mcParticle->SetLastDaughter (id2 + fPrimaryOffset);
626  } else {
627  mcParticle->SetFirstDaughter(id1 + fSecondaryOffset - fNprimaries);
628  mcParticle->SetLastDaughter (id2 + fSecondaryOffset - fNprimaries);
629  }
630  }
631  //
632  /* // RS: this breacks convention on label
633  if (i > fNprimaries) {
634  mcParticle->SetLabel(i + fPrimaryOffset);
635  } else {
636  mcParticle->SetLabel(i + fSecondaryOffset - fNprimaries);
637  }
638  */
639  } else {
640  mcParticle->SetFirstDaughter(id1);
641  mcParticle->SetLastDaughter (id2);
642  mcParticle->SetMother (imo);
643  }
644  }
645  } else {
646  mcParticle = dynamic_cast<AliMCParticle*>(fMCParticleMap->At(i));
647  }
648 
649  //Printf("mcParticleGetMother %d",mcParticle->GetMother());
650  return mcParticle;
651 }
652 
653 TParticle* AliMCEvent::ParticleFromStack(Int_t i) const
654 {
655  // Get MC Particle i from original stack, accounting for eventual label offset in case of embedding
656  //
657  if (fExternal) {
658  AliMCParticle* mcp = (AliMCParticle*)fMCParticles->At(i);
659  return mcp ? mcp->Particle() : 0;
660  }
661  if (fSubsidiaryEvents) {
663  return event->Stack()->Particle(i%BgLabelOffset(),kTRUE);
664  }
665  return fStack->Particle(i,kTRUE);
666 }
667 
669 {
670  if (!fExternal) {
671  // ESD
672  return (fHeader->GenEventHeader());
673  } else {
674  // AOD
675  if (fAODMCHeader) {
676  TList * lh = fAODMCHeader->GetCocktailHeaders();
677  if (lh) {return ((AliGenEventHeader*) lh->At(0));}
678  }
679  }
680  return 0;
681 }
682 
683 
685 {
686  // Add a subsidiary event to the list; for example merged background event.
687  if (!fSubsidiaryEvents) {
688  TList* events = new TList();
689  events->SetOwner(kFALSE);
690  events->Add(new AliMCEvent(*this));
691  fSubsidiaryEvents = events;
692  }
693 
694  fSubsidiaryEvents->Add(event);
695  if (fStack) fStack->SetMCEmbeddingFlag(kTRUE);
696  event->SetTopEvent(this);
697 }
698 
700  //
701  // Get Header belonging to this track;
702  // only works for primaries (i.e. particles coming from the Generator)
703  // Also sorts out the case of Cocktail event (get header of subevent in cocktail generetor header)
704  //
705 
706  AliMCEvent *event = this;
707 
708  if (fSubsidiaryEvents) {
709  // Get pointer to subevent if needed
710  ipart = FindIndexAndEvent(ipart,event);
711  }
712 
713  AliGenEventHeader* header = event->GenEventHeader();
714  if (ipart >= header->NProduced()) {
715  AliWarning(Form("Not a primary -- returning 0 (idx %d, nPrimary %d)",ipart,header->NProduced()));
716  return 0;
717  }
718  AliGenCocktailEventHeader *coHeader = dynamic_cast<AliGenCocktailEventHeader*>(header);
719  if (coHeader) { // Cocktail event
720  TList* headerList = coHeader->GetHeaders();
721  TIter headIt(headerList);
722  Int_t nproduced = 0;
723  do { // Go trhough all headers and look for the correct one
724  header = (AliGenEventHeader*) headIt();
725  if (header) nproduced += header->NProduced();
726  } while (header && ipart >= nproduced);
727  }
728 
729  return header;
730 }
731 
732 Int_t AliMCEvent::FindIndexAndEvent(Int_t oldidx, AliMCEvent*& event) const
733 {
734  // Find the index and event in case of composed events like signal + background
735 
736  // Check first if this explicitely accesses the subsidiary event
737  if (oldidx >= BgLabelOffset()) {
738  event = (AliMCEvent*) (fSubsidiaryEvents->At(oldidx/BgLabelOffset()));
739  return oldidx%BgLabelOffset();
740  }
741  if (fSubsidiaryEvents) {
742  TIter next(fSubsidiaryEvents);
743  next.Reset();
744  if (oldidx < fNprimaries) {
745  while((event = (AliMCEvent*)next())) {
746  if (oldidx < (event->GetPrimaryOffset() + event->GetNumberOfPrimaries())) break;
747  }
748  if (event) {
749  return (oldidx - event->GetPrimaryOffset());
750  } else {
751  return (-1);
752  }
753  } else {
754  while((event = (AliMCEvent*)next())) {
755  if (oldidx < (event->GetSecondaryOffset() + (event->GetNumberOfTracks() - event->GetNumberOfPrimaries()))) break;
756  }
757  if (event) {
758  return (oldidx - event->GetSecondaryOffset() + event->GetNumberOfPrimaries());
759  } else {
760  return (-1);
761  }
762  }
763  } else {
764  return oldidx;
765  }
766 }
767 
768 Int_t AliMCEvent::BgLabelToIndex(Int_t label)
769 {
770  // Convert a background label to an absolute index
771  if (fSubsidiaryEvents) {
772  AliMCEvent* bgEvent = (AliMCEvent*) (fSubsidiaryEvents->At(1));
773  label -= BgLabelOffset();
774  if (label < bgEvent->GetNumberOfPrimaries()) {
775  label += bgEvent->GetPrimaryOffset();
776  } else {
777  label += (bgEvent->GetSecondaryOffset() - fNprimaries);
778  }
779  }
780  return (label);
781 }
782 
783 
784 Bool_t AliMCEvent::IsPhysicalPrimary(Int_t i) const
785 {
786 //
787 // Delegate to subevent if necesarry
788 
789 
790  if (!fSubsidiaryEvents) {
791  return (i >= BgLabelOffset()) ? kFALSE : fStack->IsPhysicalPrimary(i,kTRUE);
792  } else {
793  AliMCEvent* evt = 0;
794  Int_t idx = FindIndexAndEvent(i, evt);
795  return (evt->IsPhysicalPrimary(idx));
796  }
797 }
798 
800 {
801 //
802 // Delegate to subevent if necesarry
803  if (!fSubsidiaryEvents) {
804  return (i >= BgLabelOffset()) ? kFALSE : fStack->IsSecondaryFromWeakDecay(i,kTRUE);
805  } else {
806  AliMCEvent* evt = 0;
807  Int_t idx = FindIndexAndEvent(i, evt);
808  return (evt->IsSecondaryFromWeakDecay(idx));
809  }
810 }
811 
813 {
814 //
815 // Delegate to subevent if necesarry
816  if (!fSubsidiaryEvents) {
817  return (i >= BgLabelOffset()) ? kFALSE : fStack->IsSecondaryFromMaterial(i,kTRUE);
818  } else {
819  AliMCEvent* evt = 0;
820  Int_t idx = FindIndexAndEvent(i, evt);
821  return (evt->IsSecondaryFromMaterial(idx));
822  }
823 }
824 
825 
827 {
828 //
829 // Initialize the subsidiary event structure
830  if (fSubsidiaryEvents) {
831  TIter next(fSubsidiaryEvents);
832  AliMCEvent* evt;
833  fNprimaries = 0;
834  fNparticles = 0;
835 
836  while((evt = (AliMCEvent*)next())) {
838  fNparticles += evt->GetNumberOfTracks();
839  }
840 
841  Int_t ioffp = 0;
842  Int_t ioffs = fNprimaries;
843  next.Reset();
844 
845  while((evt = (AliMCEvent*)next())) {
846  evt->SetPrimaryOffset(ioffp);
847  evt->SetSecondaryOffset(ioffs);
848  ioffp += evt->GetNumberOfPrimaries();
849  ioffs += (evt->GetNumberOfTracks() - evt->GetNumberOfPrimaries());
850  }
851  }
852 }
853 
855 {
856  // Preread the MC information
857  if (fSubsidiaryEvents) { // prereading should be done only once all sub events read and initialized
858  TIter next(fSubsidiaryEvents);
859  AliMCEvent* evt;
860  while((evt = (AliMCEvent*)next())) {
861  evt->PreReadAll();
862  }
863  return;
864  }
865 
866 
867  Int_t i;
868  // secondaries
869  for (i = fStack->GetNprimary(); i < fStack->GetNtrack(); i++)
870  {
871  GetTrack(i);
872  }
873  // primaries
874  for (i = 0; i < fStack->GetNprimary(); i++)
875  {
876  GetTrack(i);
877  }
879 }
880 
882 {
883  // Create a MCVertex object from the MCHeader information
884  TArrayF v;
886  if (!fVertex) {
887  fVertex = new AliMCVertex(v[0], v[1], v[2]);
888  } else {
889  ((AliMCVertex*) fVertex)->SetPosition(v[0], v[1], v[2]);
890  }
891  return fVertex;
892 }
893 
894 Bool_t AliMCEvent::IsFromBGEvent(Int_t index)
895 {
896  // Checks if a particle is from the background events
897  // Works for HIJING inside Cocktail
898  if (index >= BgLabelOffset() && !fSubsidiaryEvents) return kTRUE;
899  if (fNBG == -1) {
900  AliGenCocktailEventHeader* coHeader =
901  dynamic_cast<AliGenCocktailEventHeader*> (GenEventHeader());
902  if (!coHeader) return (0);
903  TList* list = coHeader->GetHeaders();
904  AliGenHijingEventHeader* hijingH = dynamic_cast<AliGenHijingEventHeader*>(list->FindObject("Hijing"));
905  if (!hijingH) return (0);
906  fNBG = hijingH->NProduced();
907  }
908 
909  return (index < fNBG);
910 }
911 
912 
914 {
915  //gives the CocktailHeaders when reading ESDs/AODs (corresponding to fExteral=kFALSE/kTRUE)
916  //the AODMC header (and the aodmc array) is passed as an instance to MCEvent by the AliAODInputHandler
917  if(fExternal==kFALSE) {
919  if(!coHeader) {
920  return 0;
921  } else {
922  return (coHeader->GetHeaders());
923  }
924  } else {
925  if(!fAODMCHeader) {
926  return 0;
927  } else {
928  return (fAODMCHeader->GetCocktailHeaders());
929  }
930  }
931 }
932 
933 
934 TString AliMCEvent::GetGenerator(Int_t index)
935 {
936  if (index >= BgLabelOffset() && !fSubsidiaryEvents) {
937  TString retv = "suppressed";
938  return retv;
939  }
940  Int_t nsumpart=fNprimaries;
941  TList* lh = GetCocktailList();
942  if(!lh){ TString noheader="nococktailheader";
943  return noheader;}
944  Int_t nh=lh->GetEntries();
945  for (Int_t i = nh-1; i >= 0; i--){
946  AliGenEventHeader* gh=(AliGenEventHeader*)lh->At(i);
947  TString genname=gh->GetName();
948  Int_t npart=gh->NProduced();
949  if (i == 0) npart = nsumpart;
950  if(index < nsumpart && index >= (nsumpart-npart)) return genname;
951  nsumpart-=npart;
952  }
953  TString empty="";
954  return empty;
955 }
956 
958  //
959  // Assign the generator index to each particle
960  //
961  TList* list = GetCocktailList();
962  if (fNprimaries <= 0) {
963  AliWarning(Form("AliMCEvent::AssignGeneratorIndex: no primaries %10d\n", fNprimaries));
964  return;
965 }
966  if (!list) {
967  return;
968  } else {
969  Int_t nh = list->GetEntries();
970  Int_t nsumpart = fNprimaries;
971  for(Int_t i = nh-1; i >= 0; i--){
972  AliGenEventHeader* gh = (AliGenEventHeader*)list->At(i);
973  Int_t npart = gh->NProduced();
974  if (i==0) {
975  if (npart != nsumpart) {
976  // printf("Header inconsistent ! %5d %5d \n", npart, nsumpart);
977  }
978  npart = nsumpart;
979  }
980  //
981  // Loop over primary particles for generator i
982  for (Int_t j = nsumpart-1; j >= nsumpart-npart; j--) {
983  AliVParticle* part = fTopEvent->GetTrack(j); // after 1st GetTrack indices correspond to top event
984  if (!part) {
985  AliWarning(Form("AliMCEvent::AssignGeneratorIndex: 0-pointer to particle j %8d npart %8d nsumpart %8d Nprimaries %8d\n",
986  j, npart, nsumpart, fNprimaries));
987  break;
988  }
989  part->SetGeneratorIndex(i);
990  Int_t dmin = part->GetFirstDaughter();
991  Int_t dmax = part->GetLastDaughter();
992  if (dmin == -1) continue;
993  AssignGeneratorIndex(i, dmin, dmax);
994  }
995  nsumpart -= npart;
996  }
997  }
998 }
999 void AliMCEvent::AssignGeneratorIndex(Int_t index, Int_t dmin, Int_t dmax) {
1000  for (Int_t k = dmin; k <= dmax; k++) {
1001  AliVParticle* dpart = fTopEvent->GetTrack(k);
1002  dpart->SetGeneratorIndex(index);
1003  Int_t d1 = dpart->GetFirstDaughter();
1004  Int_t d2 = dpart->GetLastDaughter();
1005  if (d1 > -1) {
1006  AssignGeneratorIndex(index, d1, d2);
1007  }
1008  }
1009 }
1010 
1011 Bool_t AliMCEvent::GetCocktailGenerator(Int_t index,TString &nameGen){
1012  //method that gives the generator for a given particle with label index (or that of the corresponding primary)
1013  AliVParticle* mcpart0 = (AliVParticle*) (fTopEvent->GetTrack(index));
1014  if(!mcpart0){
1015  printf("AliMCEvent-BREAK: No valid AliMCParticle at label %i\n",index);
1016  return 0;
1017  }
1018  /*
1019  Int_t ig = mcpart0->GetGeneratorIndex();
1020  if (ig != -1) {
1021  nameGen = ((AliGenEventHeader*)GetCocktailList()->At(ig))->GetName();
1022  return 1;
1023  }
1024  */
1025  nameGen=GetGenerator(index);
1026  if(nameGen.Contains("nococktailheader") )return 0;
1027  Int_t lab=index;
1028 
1029  while(nameGen.IsWhitespace()){
1030 
1031 
1032  AliVParticle* mcpart = (AliVParticle*) (fTopEvent->GetTrack(lab));
1033 
1034  if(!mcpart){
1035  printf("AliMCEvent-BREAK: No valid AliMCParticle at label %i\n",lab);
1036  break;}
1037  Int_t mother=0;
1038  mother = mcpart->GetMother();
1039 
1040  if(mother<0){
1041  printf("AliMCEvent - BREAK: Reached primary particle without valid mother\n");
1042  break;
1043  }
1044  AliVParticle* mcmom = (AliVParticle*) (fTopEvent->GetTrack(mother));
1045  if(!mcmom){
1046  printf("AliMCEvent-BREAK: No valid AliMCParticle mother at label %i\n",mother);
1047  break;
1048  }
1049  lab=mother;
1050 
1051  nameGen=GetGenerator(mother);
1052  }
1053 
1054  return 1;
1055 }
1056 
1057 void AliMCEvent::SetParticleArray(TClonesArray* mcParticles)
1058  {
1059  fMCParticles = mcParticles;
1060  fNparticles = fMCParticles->GetEntries();
1061  fExternal = kTRUE;
1062  fNprimaries = 0;
1063  struct Local {
1064  static Int_t binaryfirst(TClonesArray* a, Int_t low, Int_t high)
1065  {
1066  Int_t mid = low + (high - low)/2;
1067  if (low > a->GetEntries()-1) return (a->GetEntries()-1);
1068  if (!((AliVParticle*) a->At(mid))->IsPrimary()) {
1069  if (mid > 1 && !((AliVParticle*) a->At(mid-1))->IsPrimary()) {
1070  return binaryfirst(a, low, mid-1);
1071  } else {
1072  return mid;
1073  }
1074  } else {
1075  return binaryfirst(a, mid+1, high);
1076  }
1077  }
1078  };
1079  fNprimaries = Local::binaryfirst(mcParticles, 0, mcParticles->GetEntries()-1);
1081  }
1082 
1084 {
1085  return AliVEvent::kMC;
1086 }
1087 
1088 TParticle* AliMCEvent::Particle(int i) const
1089 {
1090  // extract Particle from the MCTrack with global index i
1091  const AliMCParticle* mcpart = (const AliMCParticle*)GetTrack(i);
1092  return mcpart ? mcpart->Particle() : 0;
1093 }
1094 
1095 Int_t AliMCEvent::Raw2MergedLabel(int lbRaw) const
1096 {
1097  // convert raw label corresponding to stack and eventual embedded MC component to global
1098  // label corresponding to MCEvent::GetTrack conventions (first all primiraies then all secondaries)
1099  if (!fSubsidiaryEvents) return lbRaw;
1100  int lb = lbRaw%BgLabelOffset();
1101  AliMCEvent* mcev = (AliMCEvent*)fSubsidiaryEvents->At(lbRaw/BgLabelOffset());
1102  int nprim = mcev->GetNumberOfPrimaries();
1103  lb += lb<nprim ? mcev->GetPrimaryOffset() : mcev->GetSecondaryOffset() - nprim;
1104  return lb;
1105 }
1106 
1107 //_____________________________________________________________________________
1108 Int_t AliMCEvent::GetPrimary(Int_t id)
1109 {
1110  //
1111  // Return number of primary that has generated track
1112  //
1113 
1114  int current, parent;
1115  //
1116  parent=id;
1117  while (1) {
1118  current=parent;
1119  parent=Particle(current)->GetFirstMother();
1120  if(parent<0) return current;
1121  }
1122 }
1123 
1124 //_________________________________________________________________
1126 {
1128  return &dummy;
1129 }
1130 
1131 ClassImp(AliMCEvent)
virtual const AliVVertex * GetPrimaryVertex() const
Definition: AliMCEvent.cxx:881
virtual Int_t GetLastDaughter() const
Definition: AliVParticle.h:107
AliHeader * fHeader
Definition: AliMCEvent.h:187
virtual void AddSubsidiaryEvent(AliMCEvent *event)
Definition: AliMCEvent.cxx:684
printf("Chi2/npoints = %f\n", TMath::Sqrt(chi2/npoints))
virtual Bool_t IsPhysicalPrimary(Int_t i) const
Definition: AliMCEvent.cxx:784
Bool_t GetEvent()
Definition: AliStack.cxx:988
const Int_t nt
Definition: pdfIO.C:2
virtual Int_t GetNumberOfPrimaries() const
Definition: AliMCEvent.h:128
void SetMother(Int_t idx)
Definition: AliMCParticle.h:82
AliGenEventHeader * GenEventHeader() const
Definition: AliMCEvent.cxx:668
static TParticle * GetDummyParticle()
Definition: AliStack.cxx:1171
virtual void PrimaryVertex(TArrayF &o) const
virtual void FinishEvent()
Definition: AliMCEvent.cxx:245
const AliMCEvent * fTopEvent
Definition: AliMCEvent.h:200
Int_t fPrimaryOffset
Definition: AliMCEvent.h:197
#define TObjArray
virtual void DrawCheck(Int_t i, Int_t search)
Definition: AliMCEvent.cxx:269
virtual void InitEvent()
Definition: AliMCEvent.cxx:826
virtual Bool_t IsSecondaryFromMaterial(Int_t index)
Definition: AliMCEvent.cxx:812
virtual void SetSecondaryOffset(Int_t ioff)
Definition: AliMCEvent.h:132
Bool_t IsSecondaryFromWeakDecay(Int_t index, Bool_t useInEmbedding=kFALSE)
Definition: AliStack.cxx:1125
Bool_t fExternal
Definition: AliMCEvent.h:199
virtual void ConnectTreeK(TTree *tree)
Definition: AliMCEvent.cxx:121
TFile * fTmpFileTR
Definition: AliMCEvent.h:193
TClonesArray * fTRBuffer
Definition: AliMCEvent.h:189
virtual void ConnectTreeTR(TTree *tree)
Definition: AliMCEvent.cxx:169
TList * fSubsidiaryEvents
Definition: AliMCEvent.h:196
virtual Bool_t IsFromBGEvent(Int_t index)
Definition: AliMCEvent.cxx:894
AliMCEvent & operator=(const AliMCEvent &mcEvnt)
Definition: AliMCEvent.cxx:100
virtual void ConnectHeaderAndStack(AliHeader *header)
Definition: AliMCEvent.cxx:133
TClonesArray * fMCParticles
Definition: AliMCEvent.h:185
virtual Int_t BgLabelToIndex(Int_t label)
Definition: AliMCEvent.cxx:768
AliStack * fStack
Definition: AliMCEvent.h:184
virtual AliStack * Stack() const
Definition: AliHeader.cxx:180
virtual void ConnectTreeE(TTree *tree)
Definition: AliMCEvent.cxx:115
TTree * fTmpTreeTR
Definition: AliMCEvent.h:192
virtual AliVEvent::EDataLayoutType GetDataLayoutType() const
TList * GetCocktailList()
Definition: AliMCEvent.cxx:913
#define AliWarning(message)
Definition: AliLog.h:541
Int_t fNBG
Definition: AliMCEvent.h:203
virtual Int_t GetParticleAndTR(Int_t i, TParticle *&particle, TClonesArray *&trefs)
Definition: AliMCEvent.cxx:188
Int_t GetNprimary() const
Definition: AliStack.h:137
virtual Int_t FindIndexAndEvent(Int_t oldidx, AliMCEvent *&event) const
Definition: AliMCEvent.cxx:732
void SetFirstDaughter(Int_t idx)
Definition: AliMCParticle.h:83
TTree * tree
virtual Float_t Y() const
Bool_t IsPhysicalPrimary(Int_t i, Bool_t useInEmbedding=kFALSE)
Definition: AliStack.cxx:1047
Int_t GetPrimary(Int_t id)
virtual Int_t GetNtrack() const
Definition: AliStack.h:134
virtual void AssignGeneratorIndex()
Definition: AliMCEvent.cxx:957
static Int_t fgkBgLabelOffset
Top MCEvent (if not embedded, then itself)
Definition: AliMCEvent.h:201
AliVHeader * fAODMCHeader
Definition: AliMCEvent.h:188
Int_t TreeKEntry(Int_t id, Bool_t useInEmbedding=kFALSE) const
Definition: AliStack.cxx:739
void ConnectTree(TTree *tree)
Definition: AliStack.cxx:935
virtual AliVParticle * GetTrack(Int_t i) const
Definition: AliMCEvent.cxx:540
virtual Int_t NProduced() const
virtual Int_t GetMother() const
Definition: AliVParticle.h:105
static Int_t BgLabelOffset()
Definition: AliMCEvent.h:138
Int_t fNparticles
Definition: AliMCEvent.h:195
TTree * fTreeTR
Definition: AliMCEvent.h:191
virtual void Clean()
Definition: AliMCEvent.cxx:230
static AliMCParticle * GetDummyTrack()
TParticle * ParticleFromStack(Int_t i) const
Definition: AliMCEvent.cxx:653
virtual void SetParticleArray(TClonesArray *mcParticles)
virtual Int_t GetFirstDaughter() const
Definition: AliVParticle.h:106
virtual TList * GetCocktailHeaders()
Definition: AliVHeader.h:32
Bool_t GetCocktailGenerator(Int_t index, TString &nameGen)
TString GetGenerator(Int_t index)
Definition: AliMCEvent.cxx:934
AliVEvent & operator=(const AliVEvent &vEvnt)
Definition: AliVEvent.cxx:29
virtual void SetDetectorId(Int_t id)
Int_t fNprimaries
Definition: AliMCEvent.h:194
virtual Int_t Label() const
virtual AliGenEventHeader * FindHeader(Int_t ipart)
Definition: AliMCEvent.cxx:699
Bool_t IsSecondaryFromMaterial(Int_t index, Bool_t useInEmbedding=kFALSE)
Definition: AliStack.cxx:1156
virtual Int_t GetNumberOfTracks() const
Definition: AliMCEvent.h:98
virtual Int_t GetSecondaryOffset() const
Definition: AliMCEvent.h:130
EDataLayoutType
Definition: AliVEvent.h:46
TParticle * Particle(Int_t id, Bool_t useInEmbedding=kFALSE)
Definition: AliStack.cxx:689
#define AliDebug(logLevel, message)
Definition: AliLog.h:300
virtual AliGenEventHeader * GenEventHeader() const
Definition: AliHeader.cxx:244
virtual Int_t GetEventNrInRun() const
Definition: AliHeader.h:51
Int_t fSecondaryOffset
Definition: AliMCEvent.h:198
virtual TParticle * Particle() const
Definition: AliMCParticle.h:63
virtual void PreReadAll()
Definition: AliMCEvent.cxx:854
virtual Int_t GetPrimaryOffset() const
Definition: AliMCEvent.h:129
AliVVertex * fVertex
Definition: AliMCEvent.h:202
TClonesArray * fTrackReferences
Definition: AliMCEvent.h:190
void Reset(Int_t size=0)
Definition: AliStack.cxx:653
TParticle * Particle(int i) const
virtual void SetGeneratorIndex(Short_t)
Definition: AliVParticle.h:113
void SetLabel(Int_t label)
Definition: AliMCParticle.h:85
void SetLastDaughter(Int_t idx)
Definition: AliMCParticle.h:84
Int_t Raw2MergedLabel(int lbRaw) const
virtual ~AliMCEvent()
Definition: AliMCEvent.cxx:110
virtual void ReorderAndExpandTreeTR()
Definition: AliMCEvent.cxx:320
virtual Float_t X() const
TObjArray * fMCParticleMap
Definition: AliMCEvent.h:186
void SetMCEmbeddingFlag(Bool_t v=kTRUE)
Definition: AliStack.h:91
const int gkDummyLabel
Bool_t IsFromSubsidiaryEvent(int id) const
Definition: AliMCEvent.cxx:527
void SetStack(AliStack *st)
Definition: AliMCParticle.h:90
virtual Bool_t IsSecondaryFromWeakDecay(Int_t index)
Definition: AliMCEvent.cxx:799
virtual void SetPrimaryOffset(Int_t ioff)
Definition: AliMCEvent.h:131
virtual Int_t GetEvent() const
Definition: AliHeader.h:48
void UpdateEventInformation()
Definition: AliMCEvent.cxx:143