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