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