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