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