Changes suggested by Effective C++ (F.Carminati)
[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 /* $Id$ */
17
18 ///////////////////////////////////////////////////////////////////////////////
19 //                                                                           //
20 //  Control class for Alice C++                                              //
21 //  Only one single instance of this class exists.                           //
22 //  The object is created in main program aliroot                            //
23 //  and is pointed by the global gAlice.                                     //
24 //                                                                           //
25 //   -Supports the list of all Alice Detectors (fModules).                 //
26 //   -Supports the list of particles (fParticles).                           //
27 //   -Supports the Trees.                                                    //
28 //   -Supports the geometry.                                                 //
29 //   -Supports the event display.                                            //
30 //Begin_Html
31 /*
32 <img src="picts/AliRunClass.gif">
33 */
34 //End_Html
35 //Begin_Html
36 /*
37 <img src="picts/alirun.gif">
38 */
39 //End_Html
40 //                                                                           //
41 ///////////////////////////////////////////////////////////////////////////////
42
43 #include <TBRIK.h> 
44 #include <TCint.h> 
45 #include <TDatabasePDG.h>
46 #include <TGeometry.h>
47 #include <TNode.h>
48 #include <TROOT.h>
49 #include <TRandom3.h>
50 #include <TSystem.h>
51 #include <TVirtualMC.h>
52 // 
53 #include "AliLog.h"
54 #include "AliDetector.h"
55 #include "AliDisplay.h"
56 #include "AliHeader.h"
57 #include "AliLego.h"
58 #include "AliLegoGenerator.h"
59 #include "AliMC.h"
60 #include "AliMagFC.h"
61 #include "AliMagFCM.h"
62 #include "AliMagFDM.h"
63 #include "AliPDG.h"
64 #include "AliRun.h"
65 #include "AliStack.h"
66 #ifdef __APPLE__
67 #include "AliTPCTrackHitsInterfaces.h"
68 #endif
69
70 AliRun *gAlice;
71
72 ClassImp(AliRun)
73
74 //_______________________________________________________________________
75 AliRun::AliRun():
76   fRun(0),
77   fEvent(0),
78   fEventNrInRun(0),
79   fEventsPerRun(0),
80   fModules(0),
81   fGeometry(0),
82   fMCApp(0),
83   fDisplay(0),
84   fField(0),
85   fMC(0),
86   fNdets(0),
87   fInitDone(kFALSE),
88   fLego(0),
89   fPDGDB(0),  //Particle factory object
90   fConfigFunction("\0"),
91   fRandom(0),
92   fBaseFileName(),
93   fRunLoader(0x0)
94 {
95   //
96   // Default constructor for AliRun
97   //
98   AliConfig::Instance();//skowron 29 Feb 2002
99                         //ensures that the folder structure is build
100 }
101
102 //_______________________________________________________________________
103 AliRun::AliRun(const AliRun& arun):
104   TNamed(arun),
105   fRun(0),
106   fEvent(0),
107   fEventNrInRun(0),
108   fEventsPerRun(0),
109   fModules(0),
110   fGeometry(0),
111   fMCApp(0),
112   fDisplay(0),
113   fField(0),
114   fMC(0),
115   fNdets(0),
116   fInitDone(kFALSE),
117   fLego(0),
118   fPDGDB(0),  //Particle factory object
119   fConfigFunction("\0"),
120   fRandom(0),
121   fBaseFileName(),
122   fRunLoader(0x0)
123 {
124   //
125   // Copy constructor for AliRun
126   //
127   arun.Copy(*this);
128 }
129
130 //_____________________________________________________________________________
131 AliRun::AliRun(const char *name, const char *title):
132   TNamed(name,title),
133   fRun(0),
134   fEvent(0),
135   fEventNrInRun(0),
136   fEventsPerRun(0),
137   fModules(new TObjArray(77)), // Support list for the Detectors
138   fGeometry(0),
139   fMCApp(0),
140   fDisplay(0),
141   fField(0),
142   fMC(gMC),
143   fNdets(0),
144   fInitDone(kFALSE),
145   fLego(0),
146   fPDGDB(TDatabasePDG::Instance()),        //Particle factory object!
147   fConfigFunction("Config();"),
148   fRandom(new TRandom3()),
149   fBaseFileName(),
150   fRunLoader(0x0)
151 {
152   //
153   //  Constructor for the main processor.
154   //  Creates the geometry
155   //  Creates the list of Detectors.
156   //  Creates the list of particles.
157   //
158
159   gAlice     = this;
160
161   // Set random number generator
162   gRandom = fRandom;
163
164   if (gSystem->Getenv("CONFIG_SEED")) {
165      gRandom->SetSeed(static_cast<UInt_t>(atoi(gSystem->Getenv("CONFIG_SEED"))));
166   }
167
168   // Add to list of browsable  
169   gROOT->GetListOfBrowsables()->Add(this,name);
170   // Create the TNode geometry for the event display
171   BuildSimpleGeometry();
172   
173   // Create default mag field
174   SetField();
175
176   // Add particle list to configuration
177   AliConfig::Instance()->Add(fPDGDB); 
178
179 #ifdef __APPLE__
180   // Terrible hack to avoid problem with the initialisation of 
181   // static and globals on Mac OS X 
182   AliClassAliTrackHitsInfo p1=galiclass____AliClassAliTrackHitsInfo;
183   AliClassAliTrackHitsParam p2=galiclass____AliTrackHitsParam;
184   AliClassAliHitInfo p3=galiclass____AliHitInfo;
185 #endif
186
187 }
188
189
190 //_______________________________________________________________________
191 AliRun::~AliRun()
192 {
193   //
194   // Default AliRun destructor
195   //
196   gROOT->GetListOfBrowsables()->Remove(this);
197
198   if (fRunLoader)
199    {
200     TFolder* evfold = fRunLoader->GetEventFolder();
201     TFolder* modfold = dynamic_cast<TFolder*>(evfold->FindObjectAny(AliConfig::GetModulesFolderName()));
202     TIter next(fModules);
203     AliModule *mod;
204     while((mod = (AliModule*)next()))
205      { 
206        modfold->Remove(mod);
207      }
208    }
209   
210   
211   delete fField;
212   delete fMCApp;
213   delete gMC; gMC=0;
214   delete fGeometry;
215   delete fDisplay;
216   delete fLego;
217   if (fModules) {
218     fModules->Delete();
219     delete fModules;
220   }
221   
222   delete fPDGDB;
223 }
224
225 //_______________________________________________________________________
226 void AliRun::Copy(TObject &) const
227 {
228   AliFatal("Not implemented!");
229 }
230
231 //_______________________________________________________________________
232 void AliRun::Build()
233 {
234   //
235   // Initialize Alice geometry
236   // Dummy routine
237   //
238 }
239  
240 //_______________________________________________________________________
241 void AliRun::BuildSimpleGeometry()
242 {
243   //
244   // Create a simple TNode geometry used by Root display engine
245   //
246   // Initialise geometry
247   //
248   fGeometry = new TGeometry("AliceGeom","Galice Geometry for Hits");
249   new TMaterial("void","Vacuum",0,0,0);  //Everything is void
250   TBRIK *brik = new TBRIK("S_alice","alice volume","void",2000,2000,3000);
251   brik->SetVisibility(0);
252   new TNode("alice","alice","S_alice");
253 }
254
255 //_______________________________________________________________________
256 void AliRun::CleanDetectors()
257 {
258   //
259   // Clean Detectors at the end of event
260   //
261    fRunLoader->CleanDetectors();
262 }
263
264 //_______________________________________________________________________
265 void AliRun::ResetHits() 
266 {
267   fMCApp->ResetHits();
268 }
269
270 //_______________________________________________________________________
271 AliGenerator* AliRun::Generator() const 
272 {
273   return fMCApp->Generator();
274 }
275
276 //_______________________________________________________________________
277 void  AliRun::SetField(AliMagF* magField)
278 {
279   //
280   // Set Magnetic Field Map
281   //
282   fField = magField;
283   fField->ReadField();
284 }
285
286 //_______________________________________________________________________
287 void AliRun::SetField(Int_t type, Int_t version, Float_t scale,
288                       Float_t maxField, const char* filename)
289 {
290   //
291   //  Set magnetic field parameters
292   //  type      Magnetic field transport flag 0=no field, 2=helix, 3=Runge Kutta
293   //  version   Magnetic field map version (only 1 active now)
294   //  scale     Scale factor for the magnetic field
295   //  maxField  Maximum value for the magnetic field
296
297   //
298   // --- Sanity check on mag field flags
299   if(fField) delete fField;
300   if(version==1) {
301     fField = new AliMagFC("Map1"," ",type,scale,maxField);
302   } else if(version<=2) {
303     fField = new AliMagFCM("Map2-3",filename,type,scale,maxField);
304     fField->ReadField();
305   } else if(version==3) {
306     fField = new AliMagFDM("Map4",filename,type,scale,maxField);
307     fField->ReadField();
308   } else {
309     AliWarning(Form("Invalid map %d",version));
310   }
311 }
312
313 //_____________________________________________________________________________
314
315 void AliRun::InitLoaders()
316 {
317   //creates list of getters
318   AliDebug(1, "");
319   TIter next(fModules);
320   AliModule *mod;
321   while((mod = (AliModule*)next()))
322    { 
323      mod->SetRunLoader(fRunLoader);
324      AliDetector *det = dynamic_cast<AliDetector*>(mod);
325      if (det) 
326       {
327         AliDebug(2, Form("Adding %s", det->GetName()));
328         fRunLoader->AddLoader(det);
329       }
330    }
331   AliDebug(1, "Done");
332 }
333 //_____________________________________________________________________________
334
335 void AliRun::FinishRun()
336 {
337   //
338   // Called at the end of the run.
339   //
340   
341   if(fLego) 
342    {
343     AliDebug(1, "Finish Lego");
344     fRunLoader->CdGAFile();
345     fLego->FinishRun();
346    }
347   
348   // Clean detector information
349   TIter next(fModules);
350   AliModule *detector;
351   while((detector = dynamic_cast<AliModule*>(next()))) {
352     AliDebug(2, Form("%s->FinishRun()", detector->GetName()));
353     detector->FinishRun();
354   }
355   
356   AliDebug(1, "fRunLoader->WriteHeader(OVERWRITE)");
357   fRunLoader->WriteHeader("OVERWRITE");
358
359   // Write AliRun info and all detectors parameters
360   fRunLoader->CdGAFile();
361   Write(0,TObject::kOverwrite);//write AliRun
362   fRunLoader->Write(0,TObject::kOverwrite);//write RunLoader itself
363   
364   // Clean tree information
365   AliDebug(1, "fRunLoader->Stack()->FinishRun()");
366   fRunLoader->Stack()->FinishRun();
367
368   if(fMCApp) fMCApp->FinishRun();
369
370   fRunLoader->Synchronize();
371 }
372
373 //_______________________________________________________________________
374 void AliRun::Announce() const
375 {
376   //
377   // Announce the current version of AliRoot
378   //
379   printf("%70s",
380          "****************************************************************\n");
381   printf("%6s","*");printf("%64s","*\n");
382
383   printf("%6s","*");
384   printf("    You are running AliRoot version NewIO\n");
385
386   printf("%6s","*");
387   printf("    The cvs tag for the current program is $Name$\n");
388
389   printf("%6s","*");printf("%64s","*\n");
390   printf("%70s",
391          "****************************************************************\n");
392 }
393
394 //_______________________________________________________________________
395 AliModule *AliRun::GetModule(const char *name) const
396 {
397   //
398   // Return pointer to detector from name
399   //
400   return dynamic_cast<AliModule*>(fModules->FindObject(name));
401 }
402  
403 //_______________________________________________________________________
404 AliDetector *AliRun::GetDetector(const char *name) const
405 {
406   //
407   // Return pointer to detector from name
408   //
409   return dynamic_cast<AliDetector*>(fModules->FindObject(name));
410 }
411  
412 //_______________________________________________________________________
413 Int_t AliRun::GetModuleID(const char *name) const
414 {
415   //
416   // Return galice internal detector identifier from name
417   //
418   Int_t i=-1;
419   TObject *mod=fModules->FindObject(name);
420   if(mod) i=fModules->IndexOf(mod);
421   return i;
422 }
423  
424 //_______________________________________________________________________
425 Int_t AliRun::GetEvent(Int_t event)
426 {
427 //
428 // Reloads data containers in folders # event
429 // Set branch addresses
430 //
431   if (fRunLoader == 0x0)
432    {
433      AliError("RunLoader is not set. Can not load data.");
434      return -1;
435    }
436 /*****************************************/ 
437 /****   P R E    R E L O A D I N G    ****/
438 /*****************************************/ 
439 // Reset existing structures
440   fMCApp->ResetHits();
441   fMCApp->ResetTrackReferences();
442   ResetDigits();
443   ResetSDigits();
444
445 /*****************************************/ 
446 /****       R  E  L  O  A  D          ****/
447 /*****************************************/
448
449   fRunLoader->GetEvent(event);
450
451 /*****************************************/ 
452 /****  P O S T    R E L O A D I N G   ****/
453 /*****************************************/ 
454
455   // Set Trees branch addresses
456   TIter next(fModules);
457   AliModule *detector;
458   while((detector = dynamic_cast<AliModule*>(next()))) 
459    {
460      detector->SetTreeAddress();
461    }
462  
463   return fRunLoader->GetHeader()->GetNtrack();
464 }
465
466 //_______________________________________________________________________
467 TGeometry *AliRun::GetGeometry()
468 {
469   //
470   // Import Alice geometry from current file
471   // Return pointer to geometry object
472   //
473   if (!fGeometry) fGeometry = dynamic_cast<TGeometry*>(gDirectory->Get("AliceGeom"));
474   //
475   // Unlink and relink nodes in detectors
476   // This is bad and there must be a better way...
477   //
478   
479   TIter next(fModules);
480   AliModule *detector;
481   while((detector = dynamic_cast<AliModule*>(next()))) {
482     TList *dnodes=detector->Nodes();
483     Int_t j;
484     TNode *node, *node1;
485     for ( j=0; j<dnodes->GetSize(); j++) {
486       node = dynamic_cast<TNode*>(dnodes->At(j));
487       node1 = fGeometry->GetNode(node->GetName());
488       dnodes->Remove(node);
489       dnodes->AddAt(node1,j);
490     }
491   }
492   return fGeometry;
493 }
494
495 //_______________________________________________________________________
496 void AliRun::SetBaseFile(const char *filename)
497 {
498   fBaseFileName = filename;
499 }
500
501 //_______________________________________________________________________
502 void AliRun::ResetDigits()
503 {
504   //
505   //  Reset all Detectors digits
506   //
507   TIter next(fModules);
508   AliModule *detector;
509   while((detector = dynamic_cast<AliModule*>(next()))) {
510      detector->ResetDigits();
511   }
512 }
513
514 //_______________________________________________________________________
515 void AliRun::ResetSDigits()
516 {
517   //
518   //  Reset all Detectors digits
519   //
520   TIter next(fModules);
521   AliModule *detector;
522   while((detector = dynamic_cast<AliModule*>(next()))) {
523      detector->ResetSDigits();
524   }
525 }
526
527
528 //_______________________________________________________________________
529
530 void AliRun::ResetPoints()
531 {
532   //
533   // Reset all Detectors points
534   //
535   TIter next(fModules);
536   AliModule *detector;
537   while((detector = dynamic_cast<AliModule*>(next()))) {
538      detector->ResetPoints();
539   }
540 }
541 //_______________________________________________________________________
542
543 void AliRun::InitMC(const char *setup)
544 {
545   //
546   // Initialize ALICE Simulation run
547   //
548   Announce();
549
550   if(fInitDone) {
551     AliWarning("Cannot initialise AliRun twice!");
552     return;
553   }
554     
555   if (!fMCApp)  
556     fMCApp=new AliMC(GetName(),GetTitle());
557     
558   gROOT->LoadMacro(setup);
559   gInterpreter->ProcessLine(fConfigFunction.Data());
560
561   fRunLoader->CdGAFile();
562
563   AliPDG::AddParticlesToPdgDataBase();  
564
565   fNdets = fModules->GetLast()+1;
566
567   TIter next(fModules);
568   for(Int_t i=0; i<fNdets; ++i)
569    {
570      TObject *objfirst, *objlast;
571      AliModule *detector=dynamic_cast<AliModule*>(fModules->At(i));
572      objlast = gDirectory->GetList()->Last();
573       
574      // Add Detector histograms in Detector list of histograms
575      if (objlast) objfirst = gDirectory->GetList()->After(objlast);
576      else         objfirst = gDirectory->GetList()->First();
577      while (objfirst) 
578       {
579         detector->Histograms()->Add(objfirst);
580         objfirst = gDirectory->GetList()->After(objfirst);
581       }
582    }
583    
584    fMCApp->Init();
585    
586    //Must be here because some MCs (G4) adds detectors here and not in Config.C
587    InitLoaders();
588    fRunLoader->MakeTree("E");
589    if (fLego == 0x0)
590     {
591       fRunLoader->LoadKinematics("RECREATE");
592       fRunLoader->LoadTrackRefs("RECREATE");
593       fRunLoader->LoadHits("all","RECREATE");
594     }
595    fInitDone = kTRUE;
596    //
597    // Save stuff at the beginning of the file to avoid file corruption
598    fRunLoader->CdGAFile();
599    Write();
600    fEventNrInRun = -1; //important - we start Begin event from increasing current number in run
601 }
602
603 //_______________________________________________________________________
604
605 void AliRun::RunMC(Int_t nevent, const char *setup)
606 {
607   //
608   // Main function to be called to process a galice run
609   // example
610   //    Root > gAlice.Run(); 
611   // a positive number of events will cause the finish routine
612   // to be called
613   //
614   fEventsPerRun = nevent;
615   // check if initialisation has been done
616   if (!fInitDone) InitMC(setup);
617   
618   // Create the Root Tree with one branch per detector
619   //Hits moved to begin event -> now we are crating separate tree for each event
620
621   gMC->ProcessRun(nevent);
622
623   // End of this run, close files
624   if(nevent>0) FinishRun();
625 }
626
627 //_______________________________________________________________________
628 void AliRun::RunReco(const char *selected, Int_t first, Int_t last)
629 {
630   //
631   // Main function to be called to reconstruct Alice event
632   // 
633    Int_t nev = fRunLoader->GetNumberOfEvents();
634    AliDebug(1, Form("Found %d events", nev));
635    Int_t nFirst = first;
636    Int_t nLast  = (last < 0)? nev : last;
637    
638    for (Int_t nevent = nFirst; nevent <= nLast; nevent++) {
639      AliDebug(1, Form("Processing event %d", nevent));
640      GetEvent(nevent);
641      Digits2Reco(selected);
642    }
643 }
644
645 //_______________________________________________________________________
646
647 void AliRun::Hits2Digits(const char *selected)
648 {
649
650    // Convert Hits to sumable digits
651    // 
652    for (Int_t nevent=0; nevent<gAlice->TreeE()->GetEntries(); nevent++) {
653      GetEvent(nevent);
654      Hits2SDigits(selected);
655      SDigits2Digits(selected);
656    }  
657 }
658
659
660 //_______________________________________________________________________
661
662 void AliRun::Tree2Tree(Option_t *option, const char *selected)
663 {
664   //
665   // Function to transform the content of
666   //  
667   // - TreeH to TreeS (option "S")
668   // - TreeS to TreeD (option "D")
669   // - TreeD to TreeR (option "R")
670   // 
671   // If multiple options are specified ("SDR"), transformation will be done in sequence for
672   // selected detector and for all detectors if none is selected (detector string 
673   // can contain blank separated list of detector names). 
674
675
676    const char *oS = strstr(option,"S");
677    const char *oD = strstr(option,"D");
678    const char *oR = strstr(option,"R");
679    
680    TObjArray *detectors = Detectors();
681
682    TIter next(detectors);
683
684    AliDetector *detector = 0;
685
686    while((detector = dynamic_cast<AliDetector*>(next()))) {
687      if (selected) 
688        if (strcmp(detector->GetName(),selected)) continue;
689      if (detector->IsActive())
690       { 
691        
692        AliLoader* loader = detector->GetLoader();
693        if (loader == 0x0) continue;
694        
695        if (oS) 
696         {
697           AliDebug(1, Form("Processing Hits2SDigits for %s ...", detector->GetName()));
698           loader->LoadHits("read");
699           if (loader->TreeS() == 0x0) loader->MakeTree("S");
700           detector->MakeBranch(option);
701           detector->SetTreeAddress();
702           detector->Hits2SDigits();
703           loader->UnloadHits();
704           loader->UnloadSDigits();
705         }  
706        if (oD) 
707         {
708           AliDebug(1, Form("Processing SDigits2Digits for %s ...", detector->GetName()));
709           loader->LoadSDigits("read");
710           if (loader->TreeD() == 0x0) loader->MakeTree("D");
711           detector->MakeBranch(option);
712           detector->SetTreeAddress();
713           detector->SDigits2Digits();
714           loader->UnloadSDigits();
715           loader->UnloadDigits();
716         } 
717        if (oR) 
718         {
719           AliDebug(1, Form("Processing Digits2Reco for %s ...", detector->GetName()));
720           loader->LoadDigits("read");
721           if (loader->TreeR() == 0x0) loader->MakeTree("R");
722           detector->MakeBranch(option);
723           detector->SetTreeAddress();
724           detector->Digits2Reco(); 
725           loader->UnloadDigits();
726           loader->UnloadRecPoints();
727
728         }
729      }   
730    }
731 }
732
733 //_______________________________________________________________________
734 void AliRun::RunLego(const char *setup, Int_t nc1, Float_t c1min,
735                      Float_t c1max,Int_t nc2,Float_t c2min,Float_t c2max,
736                      Float_t rmin,Float_t rmax,Float_t zmax, AliLegoGenerator* gener)
737 {
738   //
739   // Generates lego plots of:
740   //    - radiation length map phi vs theta
741   //    - radiation length map phi vs eta
742   //    - interaction length map
743   //    - g/cm2 length map
744   //
745   //  ntheta    bins in theta, eta
746   //  themin    minimum angle in theta (degrees)
747   //  themax    maximum angle in theta (degrees)
748   //  nphi      bins in phi
749   //  phimin    minimum angle in phi (degrees)
750   //  phimax    maximum angle in phi (degrees)
751   //  rmin      minimum radius
752   //  rmax      maximum radius
753   //  
754   //
755   //  The number of events generated = ntheta*nphi
756   //  run input parameters in macro setup (default="Config.C")
757   //
758   //  Use macro "lego.C" to visualize the 3 lego plots in spherical coordinates
759   //Begin_Html
760   /*
761     <img src="picts/AliRunLego1.gif">
762   */
763   //End_Html
764   //Begin_Html
765   /*
766     <img src="picts/AliRunLego2.gif">
767   */
768   //End_Html
769   //Begin_Html
770   /*
771     <img src="picts/AliRunLego3.gif">
772   */
773   //End_Html
774   //
775
776   // check if initialisation has been done
777   // If runloader has been initialized, set the number of events per file to nc1 * nc2
778
779   // Set new generator
780   if (!gener) gener  = new AliLegoGenerator();
781   //
782   // Configure Generator
783   gener->SetRadiusRange(rmin, rmax);
784   gener->SetZMax(zmax);
785   gener->SetCoor1Range(nc1, c1min, c1max);
786   gener->SetCoor2Range(nc2, c2min, c2max);
787   
788   
789   //Create Lego object  
790   fLego = new AliLego("lego",gener);
791
792   if (!fInitDone) InitMC(setup);
793   //Save current generator
794   
795   AliGenerator *gen=fMCApp->Generator();
796   fMCApp->ResetGenerator(gener);
797   //Prepare MC for Lego Run
798   gMC->InitLego();
799   
800   //Run Lego Object
801
802   if (fRunLoader) fRunLoader->SetNumberOfEventsPerFile(nc1 * nc2);
803   //gMC->ProcessRun(nc1*nc2+1);
804   gMC->ProcessRun(nc1*nc2);
805   
806   // End of this run, close files
807   FinishRun();
808   // Restore current generator
809   fMCApp->ResetGenerator(gen);
810   // Delete Lego Object
811   delete fLego; fLego=0;
812 }
813
814 //_______________________________________________________________________
815 void AliRun::SetConfigFunction(const char * config) 
816 {
817   //
818   // Set the signature of the function contained in Config.C to configure
819   // the run
820   //
821   fConfigFunction=config;
822 }
823
824 // 
825 // MC Application
826 // 
827
828 //_______________________________________________________________________
829 void AliRun::Field(const Double_t* x, Double_t *b) const
830 {
831   //
832   // Return the value of the magnetic field
833   //
834   Float_t xfloat[3];
835   for (Int_t i=0; i<3; i++) xfloat[i] = x[i]; 
836   
837   if (Field()) {
838     Float_t bfloat[3];
839     Field()->Field(xfloat,bfloat);
840     for (Int_t j=0; j<3; j++) b[j] = bfloat[j]; 
841   } 
842   else {
843     AliError("No mag field defined!");
844     b[0]=b[1]=b[2]=0.;
845   }
846 }      
847
848 // 
849 // End of MC Application
850 // 
851
852 //_______________________________________________________________________
853 void AliRun::Streamer(TBuffer &R__b)
854 {
855   // Stream an object of class AliRun.
856
857   if (R__b.IsReading()) {
858     if (!gAlice) gAlice = this;
859     AliRun::Class()->ReadBuffer(R__b, this);
860     gROOT->GetListOfBrowsables()->Add(this,"Run");
861
862     gRandom = fRandom;
863   } else {
864     AliRun::Class()->WriteBuffer(R__b, this);
865   }
866 }
867 //_______________________________________________________________________
868
869 void AliRun::SetGenEventHeader(AliGenEventHeader* header)
870 {
871   fRunLoader->GetHeader()->SetGenEventHeader(header);
872 }
873 //_______________________________________________________________________
874
875 Int_t AliRun::GetEvNumber() const
876
877 //Returns number of current event  
878   if (fRunLoader == 0x0)
879    {
880      AliError("RunLoader is not set. Can not load data.");
881      return -1;
882    }
883
884   return fRunLoader->GetEventNumber();
885 }
886 //_______________________________________________________________________
887
888 void AliRun::SetRunLoader(AliRunLoader* rloader)
889 {
890   //
891   // Set the loader of the run
892   //
893   fRunLoader = rloader;
894   if (fRunLoader == 0x0) return;
895   
896   TString evfoldname;
897   TFolder* evfold = fRunLoader->GetEventFolder();
898   if (evfold) evfoldname = evfold->GetName();
899   else AliWarning("Did not get Event Folder from Run Loader");
900   
901   if ( fRunLoader->GetAliRun() )
902    {//if alrun already exists in folder
903     if (fRunLoader->GetAliRun() != this )
904      {//and is different than this - crash
905        AliFatal("AliRun is already in Folder and it is not this object");
906        return;//pro forma
907      }//else do nothing
908    }
909   else
910    {
911      evfold->Add(this);//Post this AliRun to Folder
912    }
913   
914   TIter next(fModules);
915   AliModule *module;
916   while((module = (AliModule*)next())) 
917    {
918      if (evfold) AliConfig::Instance()->Add(module,evfoldname);
919      module->SetRunLoader(fRunLoader);
920      AliDetector* detector = dynamic_cast<AliDetector*>(module);
921      if (detector)
922       {
923         AliLoader* loader = fRunLoader->GetLoader(detector);
924         if (loader == 0x0)
925          {
926            AliError(Form("Can not get loader for detector %s", detector->GetName()));
927          }
928         else
929          {
930            AliDebug(1, Form("Setting loader for detector %s", detector->GetName()));
931            detector->SetLoader(loader);
932          }
933       }
934    }
935 }
936
937 void AliRun::AddModule(AliModule* mod)
938 {
939   //
940   // Add a module to the module list
941   //
942   if (mod == 0x0) return;
943   if (strlen(mod->GetName()) == 0) return;
944   if (GetModuleID(mod->GetName()) >= 0) return;
945   
946   AliDebug(1, mod->GetName());
947   if (fRunLoader == 0x0) AliConfig::Instance()->Add(mod);
948   else AliConfig::Instance()->Add(mod,fRunLoader->GetEventFolder()->GetName());
949
950   Modules()->Add(mod);
951   
952   fNdets++;
953 }
954
955
956 //_______________________________________________________________________
957 Int_t AliRun::GetDebug() const
958 {
959   AliWarning("Don't use this method any more, use AliDebug instead");
960   return AliDebugLevel();
961 }
962
963 //_______________________________________________________________________
964 void AliRun::SetDebug(Int_t level)
965 {
966   AliWarning("Don't use this method any more, use AliLog instead");
967   AliLog::SetClassDebugLevel("AliRun", level);
968 }