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