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