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