]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliRun.cxx
Coding Conventions Corrections
[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 }