]> git.uio.no Git - u/mrichter/AliRoot.git/blame - STEER/AliRun.cxx
Removal of useless dependencies via forward declarations
[u/mrichter/AliRoot.git] / STEER / AliRun.cxx
CommitLineData
99d554c8 1/**************************************************************************
2 * Copyright(c) 1998-1999, 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/*
17$Log$
94de3818 18Revision 1.41 2000/07/13 16:19:09 fca
19Mainly coding conventions + some small bug fixes
20
ef42d733 21Revision 1.40 2000/07/12 08:56:25 fca
22Coding convention correction and warning removal
23
8918e700 24Revision 1.39 2000/07/11 18:24:59 fca
25Coding convention corrections + few minor bug fixes
26
aee8290b 27Revision 1.38 2000/06/20 13:05:45 fca
28Writing down the TREE headers before job starts
29
51e0e89d 30Revision 1.37 2000/06/09 20:05:11 morsch
31Introduce possibility to chose magnetic field version 3: AliMagFDM + field02.dat
32
f1b9d7c3 33Revision 1.36 2000/06/08 14:03:58 hristov
34Only one initializer for a default argument
35
d33c0226 36Revision 1.35 2000/06/07 10:13:14 hristov
37Delete only existent objects.
38
d2ecd553 39Revision 1.34 2000/05/18 10:45:38 fca
40Delete Particle Factory properly
41
c222d2b0 42Revision 1.33 2000/05/16 13:10:40 fca
43New method IsNewTrack and fix for a problem in Father-Daughter relations
44
a01a8b12 45Revision 1.32 2000/04/27 10:38:21 fca
46Correct termination of Lego Run and introduce Lego getter in AliRun
47
838edcaf 48Revision 1.31 2000/04/26 10:17:32 fca
49Changes in Lego for G4 compatibility
50
dffd31ef 51Revision 1.30 2000/04/18 19:11:40 fca
52Introduce variable Config.C function signature
53
45189757 54Revision 1.29 2000/04/07 11:12:34 fca
55G4 compatibility changes
56
875c717b 57Revision 1.28 2000/04/05 06:51:06 fca
58Workaround for an HP compiler problem
59
5eb58812 60Revision 1.27 2000/03/22 18:08:07 fca
61Rationalisation of the virtual MC interfaces
62
80762cb1 63Revision 1.26 2000/03/22 13:42:26 fca
64SetGenerator does not replace an existing generator, ResetGenerator does
65
ee1dd322 66Revision 1.25 2000/02/23 16:25:22 fca
67AliVMC and AliGeant3 classes introduced
68ReadEuclid moved from AliRun to AliModule
69
b13db077 70Revision 1.24 2000/01/19 17:17:20 fca
71Introducing a list of lists of hits -- more hits allowed for detector now
72
1cedd08a 73Revision 1.23 1999/12/03 11:14:31 fca
74Fixing previous wrong checking
75
00719c1b 76Revision 1.21 1999/11/25 10:40:08 fca
77Fixing daughters information also in primary tracks
78
ae23d366 79Revision 1.20 1999/10/04 18:08:49 fca
80Adding protection against inconsistent Euclid files
81
3fcc96a1 82Revision 1.19 1999/09/29 07:50:40 fca
83Introduction of the Copyright and cvs Log
84
99d554c8 85*/
86
fe4da5cc 87///////////////////////////////////////////////////////////////////////////////
88// //
89// Control class for Alice C++ //
90// Only one single instance of this class exists. //
91// The object is created in main program aliroot //
92// and is pointed by the global gAlice. //
93// //
8494b010 94// -Supports the list of all Alice Detectors (fModules). //
fe4da5cc 95// -Supports the list of particles (fParticles). //
96// -Supports the Trees. //
97// -Supports the geometry. //
98// -Supports the event display. //
99//Begin_Html
100/*
1439f98e 101<img src="picts/AliRunClass.gif">
fe4da5cc 102*/
103//End_Html
104//Begin_Html
105/*
1439f98e 106<img src="picts/alirun.gif">
fe4da5cc 107*/
108//End_Html
109// //
110///////////////////////////////////////////////////////////////////////////////
111
94de3818 112#include <stdlib.h>
113#include <stdio.h>
114#include <string.h>
115
fe4da5cc 116#include <TFile.h>
117#include <TRandom.h>
118#include <TBRIK.h>
119#include <TNode.h>
fe4da5cc 120#include <TCint.h>
121#include <TSystem.h>
a8f1fb7c 122#include <TObjectTable.h>
94de3818 123#include <TTree.h>
124#include <TGeometry.h>
125#include <TROOT.h>
126#include "TBrowser.h"
fe4da5cc 127
1578254f 128#include "TParticle.h"
fe4da5cc 129#include "AliRun.h"
fe4da5cc 130#include "AliDisplay.h"
875c717b 131#include "AliMC.h"
dffd31ef 132#include "AliLego.h"
aee8290b 133#include "AliMagFC.h"
134#include "AliMagFCM.h"
135#include "AliMagFDM.h"
94de3818 136#include "AliHit.h"
137
138#include "AliDetector.h"
fe4da5cc 139
fe4da5cc 140AliRun *gAlice;
141
aee8290b 142static AliHeader *gAliHeader;
fe4da5cc 143
fe4da5cc 144ClassImp(AliRun)
145
146//_____________________________________________________________________________
147AliRun::AliRun()
148{
149 //
150 // Default constructor for AliRun
151 //
aee8290b 152 gAliHeader=&fHeader;
fe4da5cc 153 fRun = 0;
154 fEvent = 0;
155 fCurrent = -1;
8494b010 156 fModules = 0;
fe4da5cc 157 fGenerator = 0;
158 fTreeD = 0;
159 fTreeK = 0;
160 fTreeH = 0;
161 fTreeE = 0;
162 fTreeR = 0;
163 fParticles = 0;
164 fGeometry = 0;
165 fDisplay = 0;
166 fField = 0;
875c717b 167 fMC = 0;
fe4da5cc 168 fNdets = 0;
169 fImedia = 0;
170 fTrRmax = 1.e10;
171 fTrZmax = 1.e10;
fe4da5cc 172 fInitDone = kFALSE;
173 fLego = 0;
1578254f 174 fPDGDB = 0; //Particle factory object!
1cedd08a 175 fHitLists = 0;
45189757 176 fConfigFunction = "\0";
fe4da5cc 177}
178
179//_____________________________________________________________________________
180AliRun::AliRun(const char *name, const char *title)
181 : TNamed(name,title)
182{
183 //
184 // Constructor for the main processor.
185 // Creates the geometry
186 // Creates the list of Detectors.
187 // Creates the list of particles.
188 //
189 Int_t i;
190
191 gAlice = this;
192 fTreeD = 0;
193 fTreeK = 0;
194 fTreeH = 0;
195 fTreeE = 0;
196 fTreeR = 0;
197 fTrRmax = 1.e10;
198 fTrZmax = 1.e10;
1141f8e4 199 fGenerator = 0;
fe4da5cc 200 fInitDone = kFALSE;
201 fLego = 0;
202 fField = 0;
45189757 203 fConfigFunction = "Config();";
fe4da5cc 204
205 gROOT->GetListOfBrowsables()->Add(this,name);
206 //
207 // create the support list for the various Detectors
8494b010 208 fModules = new TObjArray(77);
fe4da5cc 209 //
210 // Create the TNode geometry for the event display
211
212 BuildSimpleGeometry();
213
214
215 fNtrack=0;
216 fHgwmk=0;
217 fCurrent=-1;
aee8290b 218 gAliHeader=&fHeader;
fe4da5cc 219 fRun = 0;
220 fEvent = 0;
221 //
222 // Create the particle stack
1578254f 223 fParticles = new TClonesArray("TParticle",100);
fe4da5cc 224
225 fDisplay = 0;
226 //
227 // Create default mag field
228 SetField();
229 //
875c717b 230 fMC = gMC;
fe4da5cc 231 //
232 // Prepare the tracking medium lists
233 fImedia = new TArrayI(1000);
234 for(i=0;i<1000;i++) (*fImedia)[i]=-99;
1578254f 235 //
236 // Make particles
237 fPDGDB = TDatabasePDG::Instance(); //Particle factory object!
1cedd08a 238 //
239 // Create HitLists list
240 fHitLists = new TList();
fe4da5cc 241}
242
aee8290b 243
fe4da5cc 244//_____________________________________________________________________________
245AliRun::~AliRun()
246{
247 //
248 // Defaullt AliRun destructor
249 //
fe4da5cc 250 delete fImedia;
251 delete fField;
875c717b 252 delete fMC;
fe4da5cc 253 delete fGeometry;
254 delete fDisplay;
255 delete fGenerator;
256 delete fLego;
257 delete fTreeD;
258 delete fTreeK;
259 delete fTreeH;
260 delete fTreeE;
261 delete fTreeR;
8494b010 262 if (fModules) {
263 fModules->Delete();
264 delete fModules;
fe4da5cc 265 }
266 if (fParticles) {
267 fParticles->Delete();
268 delete fParticles;
269 }
1cedd08a 270 delete fHitLists;
c222d2b0 271 delete fPDGDB;
fe4da5cc 272}
273
274//_____________________________________________________________________________
275void AliRun::AddHit(Int_t id, Int_t track, Int_t *vol, Float_t *hits) const
276{
277 //
278 // Add a hit to detector id
279 //
8494b010 280 TObjArray &dets = *fModules;
281 if(dets[id]) ((AliModule*) dets[id])->AddHit(track,vol,hits);
fe4da5cc 282}
283
284//_____________________________________________________________________________
285void AliRun::AddDigit(Int_t id, Int_t *tracks, Int_t *digits) const
286{
287 //
288 // Add digit to detector id
289 //
8494b010 290 TObjArray &dets = *fModules;
291 if(dets[id]) ((AliModule*) dets[id])->AddDigit(tracks,digits);
fe4da5cc 292}
293
294//_____________________________________________________________________________
295void AliRun::Browse(TBrowser *b)
296{
297 //
298 // Called when the item "Run" is clicked on the left pane
299 // of the Root browser.
300 // It displays the Root Trees and all detectors.
301 //
302 if (fTreeK) b->Add(fTreeK,fTreeK->GetName());
303 if (fTreeH) b->Add(fTreeH,fTreeH->GetName());
304 if (fTreeD) b->Add(fTreeD,fTreeD->GetName());
305 if (fTreeE) b->Add(fTreeE,fTreeE->GetName());
306 if (fTreeR) b->Add(fTreeR,fTreeR->GetName());
307
8494b010 308 TIter next(fModules);
309 AliModule *detector;
310 while((detector = (AliModule*)next())) {
fe4da5cc 311 b->Add(detector,detector->GetName());
312 }
313}
314
315//_____________________________________________________________________________
316void AliRun::Build()
317{
318 //
319 // Initialize Alice geometry
320 // Dummy routine
321 //
322}
323
324//_____________________________________________________________________________
325void AliRun::BuildSimpleGeometry()
326{
327 //
328 // Create a simple TNode geometry used by Root display engine
329 //
330 // Initialise geometry
331 //
332 fGeometry = new TGeometry("AliceGeom","Galice Geometry for Hits");
333 new TMaterial("void","Vacuum",0,0,0); //Everything is void
334 TBRIK *brik = new TBRIK("S_alice","alice volume","void",2000,2000,3000);
335 brik->SetVisibility(0);
336 new TNode("alice","alice","S_alice");
337}
338
339//_____________________________________________________________________________
340void AliRun::CleanDetectors()
341{
342 //
343 // Clean Detectors at the end of event
344 //
8494b010 345 TIter next(fModules);
346 AliModule *detector;
347 while((detector = (AliModule*)next())) {
fe4da5cc 348 detector->FinishEvent();
349 }
350}
351
352//_____________________________________________________________________________
353void AliRun::CleanParents()
354{
355 //
356 // Clean Particles stack.
1578254f 357 // Set parent/daughter relations
fe4da5cc 358 //
359 TClonesArray &particles = *(gAlice->Particles());
1578254f 360 TParticle *part;
fe4da5cc 361 int i;
362 for(i=0; i<fNtrack; i++) {
1578254f 363 part = (TParticle *)particles.UncheckedAt(i);
aee8290b 364 if(!part->TestBit(kDaughtersBit)) {
1578254f 365 part->SetFirstDaughter(-1);
366 part->SetLastDaughter(-1);
fe4da5cc 367 }
368 }
369}
370
371//_____________________________________________________________________________
372Int_t AliRun::DistancetoPrimitive(Int_t, Int_t)
373{
374 //
375 // Return the distance from the mouse to the AliRun object
376 // Dummy routine
377 //
378 return 9999;
379}
380
381//_____________________________________________________________________________
94de3818 382void AliRun::DumpPart (Int_t i) const
fe4da5cc 383{
384 //
385 // Dumps particle i in the stack
386 //
387 TClonesArray &particles = *fParticles;
1578254f 388 ((TParticle*) particles[i])->Print();
fe4da5cc 389}
390
391//_____________________________________________________________________________
94de3818 392void AliRun::DumpPStack () const
fe4da5cc 393{
394 //
395 // Dumps the particle stack
396 //
397 TClonesArray &particles = *fParticles;
398 printf(
399 "\n\n=======================================================================\n");
400 for (Int_t i=0;i<fNtrack;i++)
401 {
1578254f 402 printf("-> %d ",i); ((TParticle*) particles[i])->Print();
fe4da5cc 403 printf("--------------------------------------------------------------\n");
404 }
405 printf(
406 "\n=======================================================================\n\n");
407}
408
409//_____________________________________________________________________________
410void AliRun::SetField(Int_t type, Int_t version, Float_t scale,
411 Float_t maxField, char* filename)
412{
413 //
414 // Set magnetic field parameters
415 // type Magnetic field transport flag 0=no field, 2=helix, 3=Runge Kutta
416 // version Magnetic field map version (only 1 active now)
417 // scale Scale factor for the magnetic field
418 // maxField Maximum value for the magnetic field
419
420 //
421 // --- Sanity check on mag field flags
422 if(type<0 || type > 2) {
23370b7a 423 Warning("SetField",
424 "Invalid magnetic field flag: %5d; Helix tracking chosen instead\n"
fe4da5cc 425 ,type);
426 type=2;
427 }
428 if(fField) delete fField;
429 if(version==1) {
430 fField = new AliMagFC("Map1"," ",type,version,scale,maxField);
f1b9d7c3 431 } else if(version<=2) {
fe4da5cc 432 fField = new AliMagFCM("Map2-3",filename,type,version,scale,maxField);
433 fField->ReadField();
f1b9d7c3 434 } else if(version==3) {
435 fField = new AliMagFDM("Map4",filename,type,version,scale,maxField);
436 fField->ReadField();
fe4da5cc 437 } else {
23370b7a 438 Warning("SetField","Invalid map %d\n",version);
fe4da5cc 439 }
440}
441
442//_____________________________________________________________________________
443void AliRun::FillTree()
444{
445 //
446 // Fills all AliRun TTrees
447 //
448 if (fTreeK) fTreeK->Fill();
449 if (fTreeH) fTreeH->Fill();
450 if (fTreeD) fTreeD->Fill();
451 if (fTreeR) fTreeR->Fill();
452}
453
454//_____________________________________________________________________________
455void AliRun::FinishPrimary()
456{
457 //
458 // Called at the end of each primary track
459 //
460
6c9704e6 461 // static Int_t count=0;
462 // const Int_t times=10;
fe4da5cc 463 // This primary is finished, purify stack
80762cb1 464 PurifyKine();
fe4da5cc 465
466 // Write out hits if any
467 if (gAlice->TreeH()) {
468 gAlice->TreeH()->Fill();
469 }
470
471 // Reset Hits info
472 gAlice->ResetHits();
a8f1fb7c 473
474 //
475 // if(++count%times==1) gObjectTable->Print();
fe4da5cc 476}
477
478//_____________________________________________________________________________
479void AliRun::FinishEvent()
480{
481 //
482 // Called at the end of the event.
483 //
7fb01480 484
dffd31ef 485 //
486 if(fLego) fLego->FinishEvent();
487
fe4da5cc 488 //Update the energy deposit tables
489 Int_t i;
875c717b 490 for(i=0;i<fEventEnergy.GetSize();i++) {
491 fSummEnergy[i]+=fEventEnergy[i];
492 fSum2Energy[i]+=fEventEnergy[i]*fEventEnergy[i];
fe4da5cc 493 }
875c717b 494 fEventEnergy.Reset();
fe4da5cc 495
496 // Clean detector information
497 CleanDetectors();
498
499 // Write out the kinematics
500 if (fTreeK) {
501 CleanParents();
502 fTreeK->Fill();
503 }
504
505 // Write out the digits
506 if (fTreeD) {
507 fTreeD->Fill();
508 ResetDigits();
509 }
510
511 // Write out reconstructed clusters
512 if (fTreeR) {
513 fTreeR->Fill();
514 }
515
516 // Write out the event Header information
517 if (fTreeE) fTreeE->Fill();
518
519 // Reset stack info
520 ResetStack();
521
522 // Write Tree headers
59fe9bd2 523 // Int_t ievent = fHeader.GetEvent();
524 // char hname[30];
525 // sprintf(hname,"TreeK%d",ievent);
51e0e89d 526 if (fTreeK) fTreeK->Write(0,TObject::kOverwrite);
59fe9bd2 527 // sprintf(hname,"TreeH%d",ievent);
51e0e89d 528 if (fTreeH) fTreeH->Write(0,TObject::kOverwrite);
59fe9bd2 529 // sprintf(hname,"TreeD%d",ievent);
51e0e89d 530 if (fTreeD) fTreeD->Write(0,TObject::kOverwrite);
59fe9bd2 531 // sprintf(hname,"TreeR%d",ievent);
51e0e89d 532 if (fTreeR) fTreeR->Write(0,TObject::kOverwrite);
875c717b 533
534 ++fEvent;
fe4da5cc 535}
536
537//_____________________________________________________________________________
538void AliRun::FinishRun()
539{
540 //
541 // Called at the end of the run.
542 //
543
dffd31ef 544 //
545 if(fLego) fLego->FinishRun();
546
fe4da5cc 547 // Clean detector information
8494b010 548 TIter next(fModules);
549 AliModule *detector;
550 while((detector = (AliModule*)next())) {
fe4da5cc 551 detector->FinishRun();
552 }
553
554 //Output energy summary tables
555 EnergySummary();
556
557 // file is retrieved from whatever tree
aee8290b 558 TFile *file = 0;
559 if (fTreeK) file = fTreeK->GetCurrentFile();
560 if ((!file) && (fTreeH)) file = fTreeH->GetCurrentFile();
561 if ((!file) && (fTreeD)) file = fTreeD->GetCurrentFile();
562 if ((!file) && (fTreeE)) file = fTreeE->GetCurrentFile();
563 if( NULL==file ) {
fe4da5cc 564 Error("FinishRun","There isn't root file!");
565 exit(1);
566 }
aee8290b 567 file->cd();
51e0e89d 568 fTreeE->Write(0,TObject::kOverwrite);
fe4da5cc 569
570 // Clean tree information
d2ecd553 571 if (fTreeK) {
572 delete fTreeK; fTreeK = 0;
573 }
574 if (fTreeH) {
575 delete fTreeH; fTreeH = 0;
576 }
577 if (fTreeD) {
578 delete fTreeD; fTreeD = 0;
579 }
580 if (fTreeR) {
581 delete fTreeR; fTreeR = 0;
582 }
583 if (fTreeE) {
584 delete fTreeE; fTreeE = 0;
585 }
fe4da5cc 586
587 // Write AliRun info and all detectors parameters
588 Write();
589
590 // Close output file
aee8290b 591 file->Write();
fe4da5cc 592}
593
594//_____________________________________________________________________________
595void AliRun::FlagTrack(Int_t track)
596{
597 //
598 // Flags a track and all its family tree to be kept
599 //
600 int curr;
1578254f 601 TParticle *particle;
fe4da5cc 602
603 curr=track;
604 while(1) {
1578254f 605 particle=(TParticle*)fParticles->UncheckedAt(curr);
fe4da5cc 606
607 // If the particle is flagged the three from here upward is saved already
aee8290b 608 if(particle->TestBit(kKeepBit)) return;
fe4da5cc 609
610 // Save this particle
aee8290b 611 particle->SetBit(kKeepBit);
fe4da5cc 612
613 // Move to father if any
1578254f 614 if((curr=particle->GetFirstMother())==-1) return;
fe4da5cc 615 }
616}
617
618//_____________________________________________________________________________
619void AliRun::EnergySummary()
620{
621 //
622 // Print summary of deposited energy
623 //
624
fe4da5cc 625 Int_t ndep=0;
626 Float_t edtot=0;
627 Float_t ed, ed2;
628 Int_t kn, i, left, j, id;
aee8290b 629 const Float_t kzero=0;
fe4da5cc 630 Int_t ievent=fHeader.GetEvent()+1;
631 //
632 // Energy loss information
633 if(ievent) {
634 printf("***************** Energy Loss Information per event (GEV) *****************\n");
875c717b 635 for(kn=1;kn<fEventEnergy.GetSize();kn++) {
636 ed=fSummEnergy[kn];
fe4da5cc 637 if(ed>0) {
875c717b 638 fEventEnergy[ndep]=kn;
fe4da5cc 639 if(ievent>1) {
640 ed=ed/ievent;
875c717b 641 ed2=fSum2Energy[kn];
fe4da5cc 642 ed2=ed2/ievent;
aee8290b 643 ed2=100*TMath::Sqrt(TMath::Max(ed2-ed*ed,kzero))/ed;
fe4da5cc 644 } else
645 ed2=99;
875c717b 646 fSummEnergy[ndep]=ed;
aee8290b 647 fSum2Energy[ndep]=TMath::Min((Float_t) 99.,TMath::Max(ed2,kzero));
fe4da5cc 648 edtot+=ed;
649 ndep++;
650 }
651 }
652 for(kn=0;kn<(ndep-1)/3+1;kn++) {
653 left=ndep-kn*3;
654 for(i=0;i<(3<left?3:left);i++) {
655 j=kn*3+i;
875c717b 656 id=Int_t (fEventEnergy[j]+0.1);
657 printf(" %s %10.3f +- %10.3f%%;",gMC->VolName(id),fSummEnergy[j],fSum2Energy[j]);
fe4da5cc 658 }
659 printf("\n");
660 }
661 //
662 // Relative energy loss in different detectors
663 printf("******************** Relative Energy Loss per event ********************\n");
664 printf("Total energy loss per event %10.3f GeV\n",edtot);
665 for(kn=0;kn<(ndep-1)/5+1;kn++) {
666 left=ndep-kn*5;
667 for(i=0;i<(5<left?5:left);i++) {
668 j=kn*5+i;
875c717b 669 id=Int_t (fEventEnergy[j]+0.1);
670 printf(" %s %10.3f%%;",gMC->VolName(id),100*fSummEnergy[j]/edtot);
fe4da5cc 671 }
672 printf("\n");
673 }
674 for(kn=0;kn<75;kn++) printf("*");
675 printf("\n");
676 }
677 //
678 // Reset the TArray's
875c717b 679 // fEventEnergy.Set(0);
680 // fSummEnergy.Set(0);
681 // fSum2Energy.Set(0);
fe4da5cc 682}
683
684//_____________________________________________________________________________
94de3818 685AliModule *AliRun::GetModule(const char *name) const
fe4da5cc 686{
687 //
688 // Return pointer to detector from name
689 //
8494b010 690 return (AliModule*)fModules->FindObject(name);
fe4da5cc 691}
692
a68348e9 693//_____________________________________________________________________________
94de3818 694AliDetector *AliRun::GetDetector(const char *name) const
a68348e9 695{
696 //
697 // Return pointer to detector from name
698 //
699 return (AliDetector*)fModules->FindObject(name);
700}
701
fe4da5cc 702//_____________________________________________________________________________
94de3818 703Int_t AliRun::GetModuleID(const char *name) const
fe4da5cc 704{
705 //
706 // Return galice internal detector identifier from name
707 //
23370b7a 708 Int_t i=-1;
709 TObject *mod=fModules->FindObject(name);
710 if(mod) i=fModules->IndexOf(mod);
711 return i;
fe4da5cc 712}
713
714//_____________________________________________________________________________
715Int_t AliRun::GetEvent(Int_t event)
716{
717 //
718 // Connect the Trees Kinematics and Hits for event # event
719 // Set branch addresses
720 //
fe4da5cc 721
722 // Reset existing structures
723 ResetStack();
724 ResetHits();
725 ResetDigits();
726
727 // Delete Trees already connected
728 if (fTreeK) delete fTreeK;
729 if (fTreeH) delete fTreeH;
730 if (fTreeD) delete fTreeD;
731 if (fTreeR) delete fTreeR;
59fe9bd2 732
733 // Get header from file
734 if(fTreeE) fTreeE->GetEntry(event);
735 else Error("GetEvent","Cannot file Header Tree\n");
fe4da5cc 736
737 // Get Kine Tree from file
738 char treeName[20];
739 sprintf(treeName,"TreeK%d",event);
740 fTreeK = (TTree*)gDirectory->Get(treeName);
741 if (fTreeK) fTreeK->SetBranchAddress("Particles", &fParticles);
23370b7a 742 else Error("GetEvent","cannot find Kine Tree for event:%d\n",event);
fe4da5cc 743
744 // Get Hits Tree header from file
745 sprintf(treeName,"TreeH%d",event);
746 fTreeH = (TTree*)gDirectory->Get(treeName);
747 if (!fTreeH) {
23370b7a 748 Error("GetEvent","cannot find Hits Tree for event:%d\n",event);
fe4da5cc 749 }
750
751 // Get Digits Tree header from file
752 sprintf(treeName,"TreeD%d",event);
753 fTreeD = (TTree*)gDirectory->Get(treeName);
754 if (!fTreeD) {
07a68c1d 755 Warning("GetEvent","cannot find Digits Tree for event:%d\n",event);
fe4da5cc 756 }
757
758
759 // Get Reconstruct Tree header from file
760 sprintf(treeName,"TreeR%d",event);
761 fTreeR = (TTree*)gDirectory->Get(treeName);
762 if (!fTreeR) {
763 // printf("WARNING: cannot find Reconstructed Tree for event:%d\n",event);
764 }
765
766 // Set Trees branch addresses
8494b010 767 TIter next(fModules);
768 AliModule *detector;
769 while((detector = (AliModule*)next())) {
fe4da5cc 770 detector->SetTreeAddress();
771 }
772
773 if (fTreeK) fTreeK->GetEvent(0);
774 fNtrack = Int_t (fParticles->GetEntries());
775 return fNtrack;
776}
777
778//_____________________________________________________________________________
779TGeometry *AliRun::GetGeometry()
780{
781 //
782 // Import Alice geometry from current file
783 // Return pointer to geometry object
784 //
785 if (!fGeometry) fGeometry = (TGeometry*)gDirectory->Get("AliceGeom");
786 //
787 // Unlink and relink nodes in detectors
788 // This is bad and there must be a better way...
789 //
fe4da5cc 790
8494b010 791 TIter next(fModules);
792 AliModule *detector;
793 while((detector = (AliModule*)next())) {
fe4da5cc 794 detector->SetTreeAddress();
795 TList *dnodes=detector->Nodes();
796 Int_t j;
797 TNode *node, *node1;
798 for ( j=0; j<dnodes->GetSize(); j++) {
799 node = (TNode*) dnodes->At(j);
52d0ab00 800 node1 = fGeometry->GetNode(node->GetName());
fe4da5cc 801 dnodes->Remove(node);
802 dnodes->AddAt(node1,j);
803 }
804 }
805 return fGeometry;
806}
807
808//_____________________________________________________________________________
809void AliRun::GetNextTrack(Int_t &mtrack, Int_t &ipart, Float_t *pmom,
810 Float_t &e, Float_t *vpos, Float_t *polar,
811 Float_t &tof)
812{
813 //
814 // Return next track from stack of particles
815 //
a8f1fb7c 816 TVector3 pol;
fe4da5cc 817 fCurrent=-1;
1578254f 818 TParticle *track;
fe4da5cc 819 for(Int_t i=fNtrack-1; i>=0; i--) {
1578254f 820 track=(TParticle*) fParticles->UncheckedAt(i);
aee8290b 821 if(!track->TestBit(kDoneBit)) {
fe4da5cc 822 //
823 // The track has not yet been processed
824 fCurrent=i;
1578254f 825 ipart=track->GetPdgCode();
826 pmom[0]=track->Px();
827 pmom[1]=track->Py();
828 pmom[2]=track->Pz();
829 e =track->Energy();
830 vpos[0]=track->Vx();
831 vpos[1]=track->Vy();
832 vpos[2]=track->Vz();
a8f1fb7c 833 track->GetPolarisation(pol);
834 polar[0]=pol.X();
835 polar[1]=pol.Y();
836 polar[2]=pol.Z();
1578254f 837 tof=track->T();
aee8290b 838 track->SetBit(kDoneBit);
fe4da5cc 839 break;
840 }
841 }
842 mtrack=fCurrent;
843 //
844 // stop and start timer when we start a primary track
845 Int_t nprimaries = fHeader.GetNprimary();
846 if (fCurrent >= nprimaries) return;
847 if (fCurrent < nprimaries-1) {
848 fTimer.Stop();
1578254f 849 track=(TParticle*) fParticles->UncheckedAt(fCurrent+1);
850 // track->SetProcessTime(fTimer.CpuTime());
fe4da5cc 851 }
852 fTimer.Start();
853}
854
855//_____________________________________________________________________________
94de3818 856Int_t AliRun::GetPrimary(Int_t track) const
fe4da5cc 857{
858 //
859 // return number of primary that has generated track
860 //
861 int current, parent;
1578254f 862 TParticle *part;
fe4da5cc 863 //
864 parent=track;
865 while (1) {
866 current=parent;
1578254f 867 part = (TParticle *)fParticles->UncheckedAt(current);
868 parent=part->GetFirstMother();
fe4da5cc 869 if(parent<0) return current;
870 }
871}
872
873//_____________________________________________________________________________
875c717b 874void AliRun::InitMC(const char *setup)
fe4da5cc 875{
876 //
877 // Initialize the Alice setup
878 //
879
51e0e89d 880 if(fInitDone) {
881 Warning("Init","Cannot initialise AliRun twice!\n");
882 return;
883 }
884
fe4da5cc 885 gROOT->LoadMacro(setup);
45189757 886 gInterpreter->ProcessLine(fConfigFunction.Data());
fe4da5cc 887
cfce8870 888 gMC->DefineParticles(); //Create standard MC particles
fe4da5cc 889
890 TObject *objfirst, *objlast;
891
23370b7a 892 fNdets = fModules->GetLast()+1;
893
fe4da5cc 894 //
875c717b 895 //=================Create Materials and geometry
896 gMC->Init();
897
8494b010 898 TIter next(fModules);
899 AliModule *detector;
900 while((detector = (AliModule*)next())) {
fe4da5cc 901 detector->SetTreeAddress();
902 objlast = gDirectory->GetList()->Last();
903
fe4da5cc 904 // Add Detector histograms in Detector list of histograms
905 if (objlast) objfirst = gDirectory->GetList()->After(objlast);
906 else objfirst = gDirectory->GetList()->First();
907 while (objfirst) {
908 detector->Histograms()->Add(objfirst);
909 objfirst = gDirectory->GetList()->After(objfirst);
910 }
911 }
912 SetTransPar(); //Read the cuts for all materials
913
914 MediaTable(); //Build the special IMEDIA table
915
fe4da5cc 916 //Initialise geometry deposition table
875c717b 917 fEventEnergy.Set(gMC->NofVolumes()+1);
918 fSummEnergy.Set(gMC->NofVolumes()+1);
919 fSum2Energy.Set(gMC->NofVolumes()+1);
fe4da5cc 920
fe4da5cc 921 //Compute cross-sections
875c717b 922 gMC->BuildPhysics();
fe4da5cc 923
924 //Write Geometry object to current file.
925 fGeometry->Write();
926
927 fInitDone = kTRUE;
51e0e89d 928
929 //
930 // Save stuff at the beginning of the file to avoid file corruption
931 Write();
fe4da5cc 932}
933
934//_____________________________________________________________________________
935void AliRun::MediaTable()
936{
937 //
938 // Built media table to get from the media number to
939 // the detector id
940 //
ad51aeb0 941 Int_t kz, nz, idt, lz, i, k, ind;
942 // Int_t ibeg;
fe4da5cc 943 TObjArray &dets = *gAlice->Detectors();
8494b010 944 AliModule *det;
fe4da5cc 945 //
946 // For all detectors
947 for (kz=0;kz<fNdets;kz++) {
948 // If detector is defined
8494b010 949 if((det=(AliModule*) dets[kz])) {
ad51aeb0 950 TArrayI &idtmed = *(det->GetIdtmed());
951 for(nz=0;nz<100;nz++) {
fe4da5cc 952 // Find max and min material number
ad51aeb0 953 if((idt=idtmed[nz])) {
fe4da5cc 954 det->LoMedium() = det->LoMedium() < idt ? det->LoMedium() : idt;
955 det->HiMedium() = det->HiMedium() > idt ? det->HiMedium() : idt;
956 }
957 }
958 if(det->LoMedium() > det->HiMedium()) {
959 det->LoMedium() = 0;
960 det->HiMedium() = 0;
961 } else {
962 if(det->HiMedium() > fImedia->GetSize()) {
ad51aeb0 963 Error("MediaTable","Increase fImedia from %d to %d",
964 fImedia->GetSize(),det->HiMedium());
fe4da5cc 965 return;
966 }
967 // Tag all materials in rage as belonging to detector kz
968 for(lz=det->LoMedium(); lz<= det->HiMedium(); lz++) {
969 (*fImedia)[lz]=kz;
970 }
971 }
972 }
973 }
974 //
975 // Print summary table
976 printf(" Traking media ranges:\n");
977 for(i=0;i<(fNdets-1)/6+1;i++) {
978 for(k=0;k< (6<fNdets-i*6?6:fNdets-i*6);k++) {
979 ind=i*6+k;
8494b010 980 det=(AliModule*)dets[ind];
fe4da5cc 981 if(det)
982 printf(" %6s: %3d -> %3d;",det->GetName(),det->LoMedium(),
983 det->HiMedium());
984 else
985 printf(" %6s: %3d -> %3d;","NULL",0,0);
986 }
987 printf("\n");
988 }
989}
990
991//____________________________________________________________________________
992void AliRun::SetGenerator(AliGenerator *generator)
ee1dd322 993{
994 //
995 // Load the event generator
996 //
997 if(!fGenerator) fGenerator = generator;
998}
999
1000//____________________________________________________________________________
1001void AliRun::ResetGenerator(AliGenerator *generator)
fe4da5cc 1002{
1003 //
1004 // Load the event generator
1005 //
b13db077 1006 if(fGenerator)
838edcaf 1007 if(generator)
1008 Warning("ResetGenerator","Replacing generator %s with %s\n",
1009 fGenerator->GetName(),generator->GetName());
1010 else
1011 Warning("ResetGenerator","Replacing generator %s with NULL\n",
1012 fGenerator->GetName());
b13db077 1013 fGenerator = generator;
fe4da5cc 1014}
1015
1016//____________________________________________________________________________
1017void AliRun::SetTransPar(char* filename)
1018{
1019 //
1020 // Read filename to set the transport parameters
1021 //
1022
fe4da5cc 1023
aee8290b 1024 const Int_t kncuts=10;
1025 const Int_t knflags=11;
1026 const Int_t knpars=kncuts+knflags;
1027 const char kpars[knpars][7] = {"CUTGAM" ,"CUTELE","CUTNEU","CUTHAD","CUTMUO",
fe4da5cc 1028 "BCUTE","BCUTM","DCUTE","DCUTM","PPCUTM","ANNI",
1029 "BREM","COMP","DCAY","DRAY","HADR","LOSS",
1030 "MULS","PAIR","PHOT","RAYL"};
1031 char line[256];
ad51aeb0 1032 char detName[7];
fe4da5cc 1033 char* filtmp;
aee8290b 1034 Float_t cut[kncuts];
1035 Int_t flag[knflags];
fe4da5cc 1036 Int_t i, itmed, iret, ktmed, kz;
1037 FILE *lun;
1038 //
1039 // See whether the file is there
1040 filtmp=gSystem->ExpandPathName(filename);
1041 lun=fopen(filtmp,"r");
1042 delete [] filtmp;
1043 if(!lun) {
ad51aeb0 1044 Warning("SetTransPar","File %s does not exist!\n",filename);
fe4da5cc 1045 return;
1046 }
1047 //
1048 printf(" "); for(i=0;i<60;i++) printf("*"); printf("\n");
1049 printf(" *%59s\n","*");
1050 printf(" * Please check carefully what you are doing!%10s\n","*");
1051 printf(" *%59s\n","*");
1052 //
1053 while(1) {
1054 // Initialise cuts and flags
aee8290b 1055 for(i=0;i<kncuts;i++) cut[i]=-99;
1056 for(i=0;i<knflags;i++) flag[i]=-99;
fe4da5cc 1057 itmed=0;
1058 for(i=0;i<256;i++) line[i]='\0';
1059 // Read up to the end of line excluded
1060 iret=fscanf(lun,"%[^\n]",line);
1061 if(iret<0) {
1062 //End of file
1063 fclose(lun);
1064 printf(" *%59s\n","*");
1065 printf(" "); for(i=0;i<60;i++) printf("*"); printf("\n");
1066 return;
1067 }
1068 // Read the end of line
1069 fscanf(lun,"%*c");
1070 if(!iret) continue;
1071 if(line[0]=='*') continue;
1072 // Read the numbers
ad51aeb0 1073 iret=sscanf(line,"%s %d %f %f %f %f %f %f %f %f %f %f %d %d %d %d %d %d %d %d %d %d %d",
1074 detName,&itmed,&cut[0],&cut[1],&cut[2],&cut[3],&cut[4],&cut[5],&cut[6],&cut[7],&cut[8],
1075 &cut[9],&flag[0],&flag[1],&flag[2],&flag[3],&flag[4],&flag[5],&flag[6],&flag[7],
1076 &flag[8],&flag[9],&flag[10]);
fe4da5cc 1077 if(!iret) continue;
1078 if(iret<0) {
1079 //reading error
ad51aeb0 1080 Warning("SetTransPar","Error reading file %s\n",filename);
fe4da5cc 1081 continue;
1082 }
ad51aeb0 1083 // Check that the module exist
1084 AliModule *mod = GetModule(detName);
1085 if(mod) {
1086 // Get the array of media numbers
1087 TArrayI &idtmed = *mod->GetIdtmed();
1088 // Check that the tracking medium code is valid
1089 if(0<=itmed && itmed < 100) {
1090 ktmed=idtmed[itmed];
1091 if(!ktmed) {
1092 Warning("SetTransPar","Invalid tracking medium code %d for %s\n",itmed,mod->GetName());
1093 continue;
fe4da5cc 1094 }
ad51aeb0 1095 // Set energy thresholds
aee8290b 1096 for(kz=0;kz<kncuts;kz++) {
ad51aeb0 1097 if(cut[kz]>=0) {
23370b7a 1098 printf(" * %-6s set to %10.3E for tracking medium code %4d for %s\n",
aee8290b 1099 kpars[kz],cut[kz],itmed,mod->GetName());
1100 gMC->Gstpar(ktmed,kpars[kz],cut[kz]);
ad51aeb0 1101 }
fe4da5cc 1102 }
ad51aeb0 1103 // Set transport mechanisms
aee8290b 1104 for(kz=0;kz<knflags;kz++) {
ad51aeb0 1105 if(flag[kz]>=0) {
1106 printf(" * %-6s set to %10d for tracking medium code %4d for %s\n",
aee8290b 1107 kpars[kncuts+kz],flag[kz],itmed,mod->GetName());
1108 gMC->Gstpar(ktmed,kpars[kncuts+kz],Float_t(flag[kz]));
ad51aeb0 1109 }
1110 }
1111 } else {
1112 Warning("SetTransPar","Invalid medium code %d *\n",itmed);
1113 continue;
fe4da5cc 1114 }
1115 } else {
ad51aeb0 1116 Warning("SetTransPar","Module %s not present\n",detName);
fe4da5cc 1117 continue;
1118 }
1119 }
1120}
1121
1122//_____________________________________________________________________________
1123void AliRun::MakeTree(Option_t *option)
1124{
1125 //
1126 // Create the ROOT trees
1127 // Loop on all detectors to create the Root branch (if any)
1128 //
1129
b13db077 1130 char hname[30];
fe4da5cc 1131 //
1132 // Analyse options
aee8290b 1133 char *oK = strstr(option,"K");
1134 char *oH = strstr(option,"H");
1135 char *oE = strstr(option,"E");
1136 char *oD = strstr(option,"D");
1137 char *oR = strstr(option,"R");
fe4da5cc 1138 //
aee8290b 1139 if (oK && !fTreeK) {
b13db077 1140 sprintf(hname,"TreeK%d",fEvent);
1141 fTreeK = new TTree(hname,"Kinematics");
1142 // Create a branch for particles
1143 fTreeK->Branch("Particles",&fParticles,4000);
51e0e89d 1144 fTreeK->Write();
b13db077 1145 }
aee8290b 1146 if (oH && !fTreeH) {
b13db077 1147 sprintf(hname,"TreeH%d",fEvent);
1148 fTreeH = new TTree(hname,"Hits");
1149 fTreeH->SetAutoSave(1000000000); //no autosave
51e0e89d 1150 fTreeH->Write();
b13db077 1151 }
aee8290b 1152 if (oD && !fTreeD) {
b13db077 1153 sprintf(hname,"TreeD%d",fEvent);
1154 fTreeD = new TTree(hname,"Digits");
51e0e89d 1155 fTreeD->Write();
b13db077 1156 }
aee8290b 1157 if (oR && !fTreeR) {
b13db077 1158 sprintf(hname,"TreeR%d",fEvent);
1159 fTreeR = new TTree(hname,"Reconstruction");
51e0e89d 1160 fTreeR->Write();
b13db077 1161 }
aee8290b 1162 if (oE && !fTreeE) {
b13db077 1163 fTreeE = new TTree("TE","Header");
1164 // Create a branch for Header
aee8290b 1165 fTreeE->Branch("Header","AliHeader",&gAliHeader,4000);
51e0e89d 1166 fTreeE->Write();
b13db077 1167 }
fe4da5cc 1168 //
1169 // Create a branch for hits/digits for each detector
1170 // Each branch is a TClonesArray. Each data member of the Hits classes
1171 // will be in turn a subbranch of the detector master branch
8494b010 1172 TIter next(fModules);
1173 AliModule *detector;
1174 while((detector = (AliModule*)next())) {
aee8290b 1175 if (oH || oD || oR) detector->MakeBranch(option);
fe4da5cc 1176 }
fe4da5cc 1177}
1178
1179//_____________________________________________________________________________
1180Int_t AliRun::PurifyKine(Int_t lastSavedTrack, Int_t nofTracks)
1181{
1182 //
1183 // PurifyKine with external parameters
1184 //
1185 fHgwmk = lastSavedTrack;
1186 fNtrack = nofTracks;
1187 PurifyKine();
1188 return fHgwmk;
1189}
1190
1191//_____________________________________________________________________________
1192void AliRun::PurifyKine()
1193{
1194 //
1195 // Compress kinematic tree keeping only flagged particles
1196 // and renaming the particle id's in all the hits
1197 //
1198 TClonesArray &particles = *fParticles;
1199 int nkeep=fHgwmk+1, parent, i;
1578254f 1200 TParticle *part, *partnew, *father;
fe4da5cc 1201 int *map = new int[particles.GetEntries()];
1202
1203 // Save in Header total number of tracks before compression
1204 fHeader.SetNtrack(fHeader.GetNtrack()+fNtrack-fHgwmk);
1205
a01a8b12 1206 // First pass, invalid Daughter information
fe4da5cc 1207 for(i=0; i<fNtrack; i++) {
a01a8b12 1208 // Preset map, to be removed later
1209 if(i<=fHgwmk) map[i]=i ; else map[i] = -99;
aee8290b 1210 ((TParticle *)particles.UncheckedAt(i))->ResetBit(kDaughtersBit);
a01a8b12 1211 }
fe4da5cc 1212 // Second pass, build map between old and new numbering
1213 for(i=fHgwmk+1; i<fNtrack; i++) {
1578254f 1214 part = (TParticle *)particles.UncheckedAt(i);
aee8290b 1215 if(part->TestBit(kKeepBit)) {
fe4da5cc 1216
1217 // This particle has to be kept
1218 map[i]=nkeep;
1219 if(i!=nkeep) {
1220
1221 // Old and new are different, have to copy
1578254f 1222 partnew = (TParticle *)particles.UncheckedAt(nkeep);
5eb58812 1223 // Change due to a bug in the HP compiler
1224 // *partnew = *part;
1225 memcpy(partnew,part,sizeof(TParticle));
fe4da5cc 1226 } else partnew = part;
1227
1228 // as the parent is always *before*, it must be already
1229 // in place. This is what we are checking anyway!
1578254f 1230 if((parent=partnew->GetFirstMother())>fHgwmk) {
fe4da5cc 1231 if(map[parent]==-99) printf("map[%d] = -99!\n",parent);
1578254f 1232 partnew->SetFirstMother(map[parent]);
fe4da5cc 1233 }
1234 nkeep++;
1235 }
1236 }
1237 fNtrack=nkeep;
1238
1578254f 1239 // Fix daughters information
ae23d366 1240 for (i=0; i<fNtrack; i++) {
1578254f 1241 part = (TParticle *)particles.UncheckedAt(i);
1242 parent = part->GetFirstMother();
ae23d366 1243 if(parent>=0) {
1244 father = (TParticle *)particles.UncheckedAt(parent);
aee8290b 1245 if(father->TestBit(kDaughtersBit)) {
fe4da5cc 1246
ae23d366 1247 if(i<father->GetFirstDaughter()) father->SetFirstDaughter(i);
1248 if(i>father->GetLastDaughter()) father->SetLastDaughter(i);
1249 } else {
1250 // Iitialise daughters info for first pass
1251 father->SetFirstDaughter(i);
1252 father->SetLastDaughter(i);
aee8290b 1253 father->SetBit(kDaughtersBit);
ae23d366 1254 }
fe4da5cc 1255 }
1256 }
1257
1cedd08a 1258#ifdef old
fe4da5cc 1259 // Now loop on all detectors and reset the hits
b13db077 1260 AliHit *OneHit;
8494b010 1261 TIter next(fModules);
1262 AliModule *detector;
1263 while((detector = (AliModule*)next())) {
fe4da5cc 1264 if (!detector->Hits()) continue;
1265 TClonesArray &vHits=*(detector->Hits());
1266 if(vHits.GetEntries() != detector->GetNhits())
1267 printf("vHits.GetEntries()!=detector->GetNhits(): %d != %d\n",
1268 vHits.GetEntries(),detector->GetNhits());
1269 for (i=0; i<detector->GetNhits(); i++) {
1270 OneHit = (AliHit *)vHits.UncheckedAt(i);
1271 OneHit->SetTrack(map[OneHit->GetTrack()]);
1272 }
1273 }
1cedd08a 1274#else
1275
1276 // Now loop on all registered hit lists
1277 TIter next(fHitLists);
1278 TCollection *hitList;
1279 while((hitList = (TCollection*)next())) {
1280 TIter nexthit(hitList);
1281 AliHit *hit;
1282 while((hit = (AliHit*)nexthit())) {
1283 hit->SetTrack(map[hit->GetTrack()]);
1284 }
1285 }
1286#endif
fe4da5cc 1287
1288 fHgwmk=nkeep-1;
1289 particles.SetLast(fHgwmk);
1290 delete [] map;
1291}
1292
1293//_____________________________________________________________________________
dffd31ef 1294void AliRun::BeginEvent()
fe4da5cc 1295{
1296 //
1297 // Reset all Detectors & kinematics & trees
1298 //
59fe9bd2 1299 char hname[30];
dffd31ef 1300 //
1301
1302 //
1303 if(fLego) {
1304 fLego->BeginEvent();
1305 return;
1306 }
1307
59fe9bd2 1308 //
fe4da5cc 1309 ResetStack();
1310 ResetHits();
1311 ResetDigits();
1312
1313 // Initialise event header
875c717b 1314 fHeader.Reset(fRun,fEvent);
fe4da5cc 1315
59fe9bd2 1316 if(fTreeK) {
1317 fTreeK->Reset();
875c717b 1318 sprintf(hname,"TreeK%d",fEvent);
59fe9bd2 1319 fTreeK->SetName(hname);
1320 }
1321 if(fTreeH) {
1322 fTreeH->Reset();
875c717b 1323 sprintf(hname,"TreeH%d",fEvent);
59fe9bd2 1324 fTreeH->SetName(hname);
1325 }
1326 if(fTreeD) {
1327 fTreeD->Reset();
875c717b 1328 sprintf(hname,"TreeD%d",fEvent);
59fe9bd2 1329 fTreeD->SetName(hname);
1330 }
1331 if(fTreeR) {
1332 fTreeR->Reset();
875c717b 1333 sprintf(hname,"TreeR%d",fEvent);
59fe9bd2 1334 fTreeR->SetName(hname);
1335 }
fe4da5cc 1336}
1337
1338//_____________________________________________________________________________
1339void AliRun::ResetDigits()
1340{
1341 //
1342 // Reset all Detectors digits
1343 //
8494b010 1344 TIter next(fModules);
1345 AliModule *detector;
1346 while((detector = (AliModule*)next())) {
fe4da5cc 1347 detector->ResetDigits();
1348 }
1349}
1350
1351//_____________________________________________________________________________
1352void AliRun::ResetHits()
1353{
1354 //
1355 // Reset all Detectors hits
1356 //
8494b010 1357 TIter next(fModules);
1358 AliModule *detector;
1359 while((detector = (AliModule*)next())) {
fe4da5cc 1360 detector->ResetHits();
1361 }
1362}
1363
1364//_____________________________________________________________________________
1365void AliRun::ResetPoints()
1366{
1367 //
1368 // Reset all Detectors points
1369 //
8494b010 1370 TIter next(fModules);
1371 AliModule *detector;
1372 while((detector = (AliModule*)next())) {
fe4da5cc 1373 detector->ResetPoints();
1374 }
1375}
1376
1377//_____________________________________________________________________________
875c717b 1378void AliRun::RunMC(Int_t nevent, const char *setup)
fe4da5cc 1379{
1380 //
1381 // Main function to be called to process a galice run
1382 // example
1383 // Root > gAlice.Run();
1384 // a positive number of events will cause the finish routine
1385 // to be called
1386 //
1387
fe4da5cc 1388 // check if initialisation has been done
875c717b 1389 if (!fInitDone) InitMC(setup);
fe4da5cc 1390
fe4da5cc 1391 // Create the Root Tree with one branch per detector
80762cb1 1392 MakeTree("KHDER");
fe4da5cc 1393
875c717b 1394 gMC->ProcessRun(nevent);
1395
fe4da5cc 1396 // End of this run, close files
80762cb1 1397 if(nevent>0) FinishRun();
fe4da5cc 1398}
1399
1400//_____________________________________________________________________________
1401void AliRun::RunLego(const char *setup,Int_t ntheta,Float_t themin,
1402 Float_t themax,Int_t nphi,Float_t phimin,Float_t phimax,
1403 Float_t rmin,Float_t rmax,Float_t zmax)
1404{
1405 //
1406 // Generates lego plots of:
1407 // - radiation length map phi vs theta
1408 // - radiation length map phi vs eta
1409 // - interaction length map
1410 // - g/cm2 length map
1411 //
1412 // ntheta bins in theta, eta
1413 // themin minimum angle in theta (degrees)
1414 // themax maximum angle in theta (degrees)
1415 // nphi bins in phi
1416 // phimin minimum angle in phi (degrees)
1417 // phimax maximum angle in phi (degrees)
1418 // rmin minimum radius
1419 // rmax maximum radius
1420 //
1421 //
1422 // The number of events generated = ntheta*nphi
1423 // run input parameters in macro setup (default="Config.C")
1424 //
1425 // Use macro "lego.C" to visualize the 3 lego plots in spherical coordinates
1426 //Begin_Html
1427 /*
1439f98e 1428 <img src="picts/AliRunLego1.gif">
fe4da5cc 1429 */
1430 //End_Html
1431 //Begin_Html
1432 /*
1439f98e 1433 <img src="picts/AliRunLego2.gif">
fe4da5cc 1434 */
1435 //End_Html
1436 //Begin_Html
1437 /*
1439f98e 1438 <img src="picts/AliRunLego3.gif">
fe4da5cc 1439 */
1440 //End_Html
1441 //
1442
1443 // check if initialisation has been done
875c717b 1444 if (!fInitDone) InitMC(setup);
b13db077 1445
838edcaf 1446 //Save current generator
1447 AliGenerator *gen=Generator();
1448
b13db077 1449 //Create Lego object
1450 fLego = new AliLego("lego",ntheta,themin,themax,nphi,phimin,phimax,rmin,rmax,zmax);
1451
dffd31ef 1452 //Prepare MC for Lego Run
1453 gMC->InitLego();
1454
b13db077 1455 //Run Lego Object
dffd31ef 1456 gMC->ProcessRun(ntheta*nphi+1);
fe4da5cc 1457
1458 // Create only the Root event Tree
80762cb1 1459 MakeTree("E");
fe4da5cc 1460
1461 // End of this run, close files
80762cb1 1462 FinishRun();
838edcaf 1463
1464 // Delete Lego Object
1465 delete fLego; fLego=0;
1466
1467 // Restore current generator
1468 SetGenerator(gen);
fe4da5cc 1469}
1470
94de3818 1471//_____________________________________________________________________________
1472void AliRun::SetConfigFunction(const char * config)
1473{
1474 //
1475 // Set the signature of the function contained in Config.C to configure
1476 // the run
1477 //
1478 fConfigFunction=config;
1479}
1480
fe4da5cc 1481//_____________________________________________________________________________
1482void AliRun::SetCurrentTrack(Int_t track)
1483{
1484 //
1485 // Set current track number
1486 //
1487 fCurrent = track;
1488}
1489
1490//_____________________________________________________________________________
1578254f 1491void AliRun::SetTrack(Int_t done, Int_t parent, Int_t pdg, Float_t *pmom,
fe4da5cc 1492 Float_t *vpos, Float_t *polar, Float_t tof,
8918e700 1493 const char* /* mecha */, Int_t &ntr, Float_t weight)
fe4da5cc 1494{
1495 //
1496 // Load a track on the stack
1497 //
1498 // done 0 if the track has to be transported
1499 // 1 if not
1500 // parent identifier of the parent track. -1 for a primary
1578254f 1501 // pdg particle code
fe4da5cc 1502 // pmom momentum GeV/c
1503 // vpos position
1504 // polar polarisation
1505 // tof time of flight in seconds
1506 // mecha production mechanism
1507 // ntr on output the number of the track stored
1508 //
1509 TClonesArray &particles = *fParticles;
1578254f 1510 TParticle *particle;
fe4da5cc 1511 Float_t mass;
aee8290b 1512 const Int_t kfirstdaughter=-1;
1513 const Int_t klastdaughter=-1;
1514 const Int_t kS=0;
1578254f 1515 // const Float_t tlife=0;
fe4da5cc 1516
1578254f 1517 //
1518 // Here we get the static mass
1519 // For MC is ok, but a more sophisticated method could be necessary
1520 // if the calculated mass is required
1521 // also, this method is potentially dangerous if the mass
1522 // used in the MC is not the same of the PDG database
1523 //
1524 mass = TDatabasePDG::Instance()->GetParticle(pdg)->Mass();
fe4da5cc 1525 Float_t e=TMath::Sqrt(mass*mass+pmom[0]*pmom[0]+
1526 pmom[1]*pmom[1]+pmom[2]*pmom[2]);
1527
aee8290b 1528 //printf("Loading particle %s mass %f ene %f No %d ip %d pos %f %f %f mom %f %f %f kS %d m %s\n",
1529 //pname,mass,e,fNtrack,pdg,vpos[0],vpos[1],vpos[2],pmom[0],pmom[1],pmom[2],kS,mecha);
fe4da5cc 1530
aee8290b 1531 particle=new(particles[fNtrack]) TParticle(pdg,kS,parent,-1,kfirstdaughter,
1532 klastdaughter,pmom[0],pmom[1],pmom[2],
1578254f 1533 e,vpos[0],vpos[1],vpos[2],tof);
1534 // polar[0],polar[1],polar[2],tof,
1535 // mecha,weight);
1536 ((TParticle*)particles[fNtrack])->SetPolarisation(TVector3(polar[0],polar[1],polar[2]));
1537 ((TParticle*)particles[fNtrack])->SetWeight(weight);
aee8290b 1538 if(!done) particle->SetBit(kDoneBit);
a01a8b12 1539 //Declare that the daughter information is valid
aee8290b 1540 ((TParticle*)particles[fNtrack])->SetBit(kDaughtersBit);
fe4da5cc 1541
1542 if(parent>=0) {
1578254f 1543 particle=(TParticle*) fParticles->UncheckedAt(parent);
1544 particle->SetLastDaughter(fNtrack);
1545 if(particle->GetFirstDaughter()<0) particle->SetFirstDaughter(fNtrack);
fe4da5cc 1546 } else {
1547 //
1548 // This is a primary track. Set high water mark for this event
1549 fHgwmk=fNtrack;
1550 //
1551 // Set also number if primary tracks
1552 fHeader.SetNprimary(fHgwmk+1);
1553 fHeader.SetNtrack(fHgwmk+1);
1554 }
1555 ntr = fNtrack++;
1556}
1557
1558//_____________________________________________________________________________
1559void AliRun::KeepTrack(const Int_t track)
1560{
1561 //
1562 // flags a track to be kept
1563 //
1564 TClonesArray &particles = *fParticles;
aee8290b 1565 ((TParticle*)particles[track])->SetBit(kKeepBit);
fe4da5cc 1566}
1567
1568//_____________________________________________________________________________
875c717b 1569void AliRun::StepManager(Int_t id)
fe4da5cc 1570{
1571 //
1572 // Called at every step during transport
1573 //
1574
fe4da5cc 1575 //
1576 // --- If lego option, do it and leave
b13db077 1577 if (fLego)
fe4da5cc 1578 fLego->StepManager();
b13db077 1579 else {
1580 Int_t copy;
1581 //Update energy deposition tables
875c717b 1582 AddEnergyDeposit(gMC->CurrentVolID(copy),gMC->Edep());
fe4da5cc 1583
b13db077 1584 //Call the appropriate stepping routine;
1585 AliModule *det = (AliModule*)fModules->At(id);
1586 if(det) det->StepManager();
fe4da5cc 1587 }
fe4da5cc 1588}
1589
fe4da5cc 1590//_____________________________________________________________________________
1591void AliRun::Streamer(TBuffer &R__b)
1592{
1593 //
1594 // Stream an object of class AliRun.
1595 //
1596 if (R__b.IsReading()) {
1597 Version_t R__v = R__b.ReadVersion(); if (R__v) { }
1598 TNamed::Streamer(R__b);
1599 if (!gAlice) gAlice = this;
1600 gROOT->GetListOfBrowsables()->Add(this,"Run");
59fe9bd2 1601 fTreeE = (TTree*)gDirectory->Get("TE");
aee8290b 1602 if (fTreeE) fTreeE->SetBranchAddress("Header", &gAliHeader);
59fe9bd2 1603 else Error("Streamer","cannot find Header Tree\n");
fe4da5cc 1604 R__b >> fNtrack;
1605 R__b >> fHgwmk;
1606 R__b >> fDebug;
1607 fHeader.Streamer(R__b);
8494b010 1608 R__b >> fModules;
fe4da5cc 1609 R__b >> fParticles;
1610 R__b >> fField;
875c717b 1611 // R__b >> fMC;
fe4da5cc 1612 R__b >> fNdets;
1613 R__b >> fTrRmax;
1614 R__b >> fTrZmax;
1615 R__b >> fGenerator;
59fe9bd2 1616 if(R__v>1) {
1617 R__b >> fPDGDB; //Particle factory object!
1618 fTreeE->GetEntry(0);
1619 } else {
1620 fHeader.SetEvent(0);
1621 fPDGDB = TDatabasePDG::Instance(); //Particle factory object!
1622 }
45189757 1623 if(R__v>2) {
1624 fConfigFunction.Streamer(R__b);
1625 } else {
1626 fConfigFunction="Config();";
1627 }
fe4da5cc 1628 } else {
1629 R__b.WriteVersion(AliRun::IsA());
1630 TNamed::Streamer(R__b);
1631 R__b << fNtrack;
1632 R__b << fHgwmk;
1633 R__b << fDebug;
1634 fHeader.Streamer(R__b);
8494b010 1635 R__b << fModules;
fe4da5cc 1636 R__b << fParticles;
1637 R__b << fField;
875c717b 1638 // R__b << fMC;
fe4da5cc 1639 R__b << fNdets;
1640 R__b << fTrRmax;
1641 R__b << fTrZmax;
1642 R__b << fGenerator;
1578254f 1643 R__b << fPDGDB; //Particle factory object!
45189757 1644 fConfigFunction.Streamer(R__b);
fe4da5cc 1645 }
1646}