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