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