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