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