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