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