]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliRun.cxx
Set run loader for modules
[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(TObject &) 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, const 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      mod->SetRunLoader(fRunLoader);
315      AliDetector *det = dynamic_cast<AliDetector*>(mod);
316      if (det) 
317       {
318         if (GetDebug()) Info("InitLoaders"," Adding %s ",det->GetName());
319         fRunLoader->AddLoader(det);
320       }
321    }
322   if (GetDebug()) Info("InitLoaders","Done");
323 }
324 //_____________________________________________________________________________
325
326 void AliRun::FinishRun()
327 {
328   //
329   // Called at the end of the run.
330   //
331   
332   if(fLego) 
333    {
334     if (GetDebug()) Info("FinishRun"," Finish Lego");
335     fRunLoader->CdGAFile();
336     fLego->FinishRun();
337    }
338   
339   // Clean detector information
340   TIter next(fModules);
341   AliModule *detector;
342   while((detector = dynamic_cast<AliModule*>(next()))) {
343     if (GetDebug()) Info("FinishRun"," %s->FinishRun()",detector->GetName());
344     detector->FinishRun();
345   }
346   
347   if (GetDebug()) Info("FinishRun"," fRunLoader->WriteHeader(OVERWRITE)");
348   fRunLoader->WriteHeader("OVERWRITE");
349
350   // Write AliRun info and all detectors parameters
351   fRunLoader->CdGAFile();
352   Write(0,TObject::kOverwrite);//write AliRun
353   fRunLoader->Write(0,TObject::kOverwrite);//write RunLoader itself
354   
355   // Clean tree information
356   if (GetDebug()) Info("FinishRun"," fRunLoader->Stack()->FinishRun()");
357   fRunLoader->Stack()->FinishRun();
358
359   if(fMCApp) fMCApp->FinishRun();
360
361   fRunLoader->Synchronize();
362 }
363
364 //_______________________________________________________________________
365 void AliRun::Announce() const
366 {
367   //
368   // Announce the current version of AliRoot
369   //
370   printf("%70s",
371          "****************************************************************\n");
372   printf("%6s","*");printf("%64s","*\n");
373
374   printf("%6s","*");
375   printf("    You are running AliRoot version NewIO\n");
376
377   printf("%6s","*");
378   printf("    The cvs tag for the current program is $Name$\n");
379
380   printf("%6s","*");printf("%64s","*\n");
381   printf("%70s",
382          "****************************************************************\n");
383 }
384
385 //_______________________________________________________________________
386 AliModule *AliRun::GetModule(const char *name) const
387 {
388   //
389   // Return pointer to detector from name
390   //
391   return dynamic_cast<AliModule*>(fModules->FindObject(name));
392 }
393  
394 //_______________________________________________________________________
395 AliDetector *AliRun::GetDetector(const char *name) const
396 {
397   //
398   // Return pointer to detector from name
399   //
400   return dynamic_cast<AliDetector*>(fModules->FindObject(name));
401 }
402  
403 //_______________________________________________________________________
404 Int_t AliRun::GetModuleID(const char *name) const
405 {
406   //
407   // Return galice internal detector identifier from name
408   //
409   Int_t i=-1;
410   TObject *mod=fModules->FindObject(name);
411   if(mod) i=fModules->IndexOf(mod);
412   return i;
413 }
414  
415 //_______________________________________________________________________
416 Int_t AliRun::GetEvent(Int_t event)
417 {
418 //
419 // Reloads data containers in folders # event
420 // Set branch addresses
421 //
422   if (fRunLoader == 0x0)
423    {
424      Error("GetEvent","RunLoader is not set. Can not load data.");
425      return -1;
426    }
427 /*****************************************/ 
428 /****   P R E    R E L O A D I N G    ****/
429 /*****************************************/ 
430 // Reset existing structures
431   fMCApp->ResetHits();
432   fMCApp->ResetTrackReferences();
433   ResetDigits();
434   ResetSDigits();
435
436 /*****************************************/ 
437 /****       R  E  L  O  A  D          ****/
438 /*****************************************/
439
440   fRunLoader->GetEvent(event);
441
442 /*****************************************/ 
443 /****  P O S T    R E L O A D I N G   ****/
444 /*****************************************/ 
445
446   // Set Trees branch addresses
447   TIter next(fModules);
448   AliModule *detector;
449   while((detector = dynamic_cast<AliModule*>(next()))) 
450    {
451      detector->SetTreeAddress();
452    }
453  
454   return fRunLoader->GetHeader()->GetNtrack();
455 }
456
457 //_______________________________________________________________________
458 TGeometry *AliRun::GetGeometry()
459 {
460   //
461   // Import Alice geometry from current file
462   // Return pointer to geometry object
463   //
464   if (!fGeometry) fGeometry = dynamic_cast<TGeometry*>(gDirectory->Get("AliceGeom"));
465   //
466   // Unlink and relink nodes in detectors
467   // This is bad and there must be a better way...
468   //
469   
470   TIter next(fModules);
471   AliModule *detector;
472   while((detector = dynamic_cast<AliModule*>(next()))) {
473     TList *dnodes=detector->Nodes();
474     Int_t j;
475     TNode *node, *node1;
476     for ( j=0; j<dnodes->GetSize(); j++) {
477       node = dynamic_cast<TNode*>(dnodes->At(j));
478       node1 = fGeometry->GetNode(node->GetName());
479       dnodes->Remove(node);
480       dnodes->AddAt(node1,j);
481     }
482   }
483   return fGeometry;
484 }
485
486 //_______________________________________________________________________
487 void AliRun::SetBaseFile(const char *filename)
488 {
489   fBaseFileName = filename;
490 }
491
492 //_______________________________________________________________________
493 void AliRun::ResetDigits()
494 {
495   //
496   //  Reset all Detectors digits
497   //
498   TIter next(fModules);
499   AliModule *detector;
500   while((detector = dynamic_cast<AliModule*>(next()))) {
501      detector->ResetDigits();
502   }
503 }
504
505 //_______________________________________________________________________
506 void AliRun::ResetSDigits()
507 {
508   //
509   //  Reset all Detectors digits
510   //
511   TIter next(fModules);
512   AliModule *detector;
513   while((detector = dynamic_cast<AliModule*>(next()))) {
514      detector->ResetSDigits();
515   }
516 }
517
518
519 //_______________________________________________________________________
520
521 void AliRun::ResetPoints()
522 {
523   //
524   // Reset all Detectors points
525   //
526   TIter next(fModules);
527   AliModule *detector;
528   while((detector = dynamic_cast<AliModule*>(next()))) {
529      detector->ResetPoints();
530   }
531 }
532 //_______________________________________________________________________
533
534 void AliRun::InitMC(const char *setup)
535 {
536   //
537   // Initialize ALICE Simulation run
538   //
539   Announce();
540
541   if(fInitDone) {
542     Warning("Init","Cannot initialise AliRun twice!\n");
543     return;
544   }
545     
546   fMCApp=new AliMC(GetName(),GetTitle());
547     
548   gROOT->LoadMacro(setup);
549   gInterpreter->ProcessLine(fConfigFunction.Data());
550
551   fRunLoader->CdGAFile();
552
553   AliPDG::AddParticlesToPdgDataBase();  
554
555   fNdets = fModules->GetLast()+1;
556
557   // Added also after in case of interactive initialisation of modules
558   fNdets = fModules->GetLast()+1;
559
560   TIter next(fModules);
561   for(Int_t i=0; i<fNdets; ++i)
562    {
563      TObject *objfirst, *objlast;
564      AliModule *detector=dynamic_cast<AliModule*>(fModules->At(i));
565      objlast = gDirectory->GetList()->Last();
566       
567      // Add Detector histograms in Detector list of histograms
568      if (objlast) objfirst = gDirectory->GetList()->After(objlast);
569      else         objfirst = gDirectory->GetList()->First();
570      while (objfirst) 
571       {
572         detector->Histograms()->Add(objfirst);
573         objfirst = gDirectory->GetList()->After(objfirst);
574       }
575    }
576    
577    fMCApp->Init();
578    
579    //Must be here because some MCs (G4) adds detectors here and not in Config.C
580    InitLoaders();
581    fRunLoader->MakeTree("E");
582    if (fLego == 0x0)
583     {
584       fRunLoader->LoadKinematics("RECREATE");
585       fRunLoader->LoadTrackRefs("RECREATE");
586       fRunLoader->LoadHits("all","RECREATE");
587     }
588    fInitDone = kTRUE;
589    //
590    // Save stuff at the beginning of the file to avoid file corruption
591    fRunLoader->CdGAFile();
592    Write();
593    fEventNrInRun = -1; //important - we start Begin event from increasing current number in run
594 }
595
596 //_______________________________________________________________________
597
598 void AliRun::RunMC(Int_t nevent, const char *setup)
599 {
600   //
601   // Main function to be called to process a galice run
602   // example
603   //    Root > gAlice.Run(); 
604   // a positive number of events will cause the finish routine
605   // to be called
606   //
607   fEventsPerRun = nevent;
608   // check if initialisation has been done
609   if (!fInitDone) InitMC(setup);
610   
611   // Create the Root Tree with one branch per detector
612   //Hits moved to begin event -> now we are crating separate tree for each event
613
614   gMC->ProcessRun(nevent);
615
616   // End of this run, close files
617   if(nevent>0) FinishRun();
618 }
619
620 //_______________________________________________________________________
621 void AliRun::RunReco(const char *selected, Int_t first, Int_t last)
622 {
623   //
624   // Main function to be called to reconstruct Alice event
625   // 
626    Int_t nev = fRunLoader->GetNumberOfEvents();
627    if (GetDebug()) Info("RunReco","Found %d events",nev);
628    Int_t nFirst = first;
629    Int_t nLast  = (last < 0)? nev : last;
630    
631    for (Int_t nevent = nFirst; nevent <= nLast; nevent++) {
632      if (GetDebug()) Info("RunReco","Processing event %d",nevent);
633      GetEvent(nevent);
634      Digits2Reco(selected);
635    }
636 }
637
638 //_______________________________________________________________________
639
640 void AliRun::Hits2Digits(const char *selected)
641 {
642
643    // Convert Hits to sumable digits
644    // 
645    for (Int_t nevent=0; nevent<gAlice->TreeE()->GetEntries(); nevent++) {
646      GetEvent(nevent);
647      Hits2SDigits(selected);
648      SDigits2Digits(selected);
649    }  
650 }
651
652
653 //_______________________________________________________________________
654
655 void AliRun::Tree2Tree(Option_t *option, const char *selected)
656 {
657   //
658   // Function to transform the content of
659   //  
660   // - TreeH to TreeS (option "S")
661   // - TreeS to TreeD (option "D")
662   // - TreeD to TreeR (option "R")
663   // 
664   // If multiple options are specified ("SDR"), transformation will be done in sequence for
665   // selected detector and for all detectors if none is selected (detector string 
666   // can contain blank separated list of detector names). 
667
668
669    const char *oS = strstr(option,"S");
670    const char *oD = strstr(option,"D");
671    const char *oR = strstr(option,"R");
672    
673    TObjArray *detectors = Detectors();
674
675    TIter next(detectors);
676
677    AliDetector *detector = 0;
678
679    while((detector = dynamic_cast<AliDetector*>(next()))) {
680      if (selected) 
681        if (strcmp(detector->GetName(),selected)) continue;
682      if (detector->IsActive())
683       { 
684        
685        AliLoader* loader = detector->GetLoader();
686        if (loader == 0x0) continue;
687        
688        if (oS) 
689         {
690           if (GetDebug()) Info("Tree2Tree","Processing Hits2SDigits for %s ...",detector->GetName());
691           loader->LoadHits("read");
692           if (loader->TreeS() == 0x0) loader->MakeTree("S");
693           detector->MakeBranch(option);
694           detector->SetTreeAddress();
695           detector->Hits2SDigits();
696           loader->UnloadHits();
697           loader->UnloadSDigits();
698         }  
699        if (oD) 
700         {
701           if (GetDebug()) Info("Tree2Tree","Processing SDigits2Digits for %s ...",detector->GetName());
702           loader->LoadSDigits("read");
703           if (loader->TreeD() == 0x0) loader->MakeTree("D");
704           detector->MakeBranch(option);
705           detector->SetTreeAddress();
706           detector->SDigits2Digits();
707           loader->UnloadSDigits();
708           loader->UnloadDigits();
709         } 
710        if (oR) 
711         {
712           if (GetDebug()) Info("Tree2Tree","Processing Digits2Reco for %s ...",detector->GetName());
713           loader->LoadDigits("read");
714           if (loader->TreeR() == 0x0) loader->MakeTree("R");
715           detector->MakeBranch(option);
716           detector->SetTreeAddress();
717           detector->Digits2Reco(); 
718           loader->UnloadDigits();
719           loader->UnloadRecPoints();
720
721         }
722      }   
723    }
724 }
725
726 //_______________________________________________________________________
727 void AliRun::RunLego(const char *setup, Int_t nc1, Float_t c1min,
728                      Float_t c1max,Int_t nc2,Float_t c2min,Float_t c2max,
729                      Float_t rmin,Float_t rmax,Float_t zmax, AliLegoGenerator* gener)
730 {
731   //
732   // Generates lego plots of:
733   //    - radiation length map phi vs theta
734   //    - radiation length map phi vs eta
735   //    - interaction length map
736   //    - g/cm2 length map
737   //
738   //  ntheta    bins in theta, eta
739   //  themin    minimum angle in theta (degrees)
740   //  themax    maximum angle in theta (degrees)
741   //  nphi      bins in phi
742   //  phimin    minimum angle in phi (degrees)
743   //  phimax    maximum angle in phi (degrees)
744   //  rmin      minimum radius
745   //  rmax      maximum radius
746   //  
747   //
748   //  The number of events generated = ntheta*nphi
749   //  run input parameters in macro setup (default="Config.C")
750   //
751   //  Use macro "lego.C" to visualize the 3 lego plots in spherical coordinates
752   //Begin_Html
753   /*
754     <img src="picts/AliRunLego1.gif">
755   */
756   //End_Html
757   //Begin_Html
758   /*
759     <img src="picts/AliRunLego2.gif">
760   */
761   //End_Html
762   //Begin_Html
763   /*
764     <img src="picts/AliRunLego3.gif">
765   */
766   //End_Html
767   //
768
769   // check if initialisation has been done
770   // If runloader has been initialized, set the number of events per file to nc1 * nc2
771
772   // Set new generator
773   if (!gener) gener  = new AliLegoGenerator();
774   //
775   // Configure Generator
776   gener->SetRadiusRange(rmin, rmax);
777   gener->SetZMax(zmax);
778   gener->SetCoor1Range(nc1, c1min, c1max);
779   gener->SetCoor2Range(nc2, c2min, c2max);
780   
781   
782   //Create Lego object  
783   fLego = new AliLego("lego",gener);
784
785   if (!fInitDone) InitMC(setup);
786   //Save current generator
787   
788   AliGenerator *gen=fMCApp->Generator();
789   fMCApp->ResetGenerator(gener);
790   //Prepare MC for Lego Run
791   gMC->InitLego();
792   
793   //Run Lego Object
794
795   if (fRunLoader) fRunLoader->SetNumberOfEventsPerFile(nc1 * nc2);
796   //gMC->ProcessRun(nc1*nc2+1);
797   gMC->ProcessRun(nc1*nc2);
798   
799   // End of this run, close files
800   FinishRun();
801   // Restore current generator
802   fMCApp->ResetGenerator(gen);
803   // Delete Lego Object
804   delete fLego; fLego=0;
805 }
806
807 //_______________________________________________________________________
808 void AliRun::SetConfigFunction(const char * config) 
809 {
810   //
811   // Set the signature of the function contained in Config.C to configure
812   // the run
813   //
814   fConfigFunction=config;
815 }
816
817 // 
818 // MC Application
819 // 
820
821 //_______________________________________________________________________
822 void AliRun::Field(const Double_t* x, Double_t *b) const
823 {
824    Float_t xfloat[3];
825    for (Int_t i=0; i<3; i++) xfloat[i] = x[i]; 
826
827    if (Field()) {
828          Float_t bfloat[3];
829          Field()->Field(xfloat,bfloat);
830          for (Int_t j=0; j<3; j++) b[j] = bfloat[j]; 
831    } 
832    else {
833          printf("No mag field defined!\n");
834          b[0]=b[1]=b[2]=0.;
835    }
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   fRunLoader = rloader;
882   if (fRunLoader == 0x0) return;
883   
884   TString evfoldname;
885   TFolder* evfold = fRunLoader->GetEventFolder();
886   if (evfold) evfoldname = evfold->GetName();
887   else Warning("SetRunLoader","Did not get Event Folder from Run Loader");
888   
889   if ( fRunLoader->GetAliRun() )
890    {//if alrun already exists in folder
891     if (fRunLoader->GetAliRun() != this )
892      {//and is different than this - crash
893        Fatal("AliRun","AliRun is already in Folder and it is not this object");
894        return;//pro forma
895      }//else do nothing
896    }
897   else
898    {
899      evfold->Add(this);//Post this AliRun to Folder
900    }
901   
902   TIter next(fModules);
903   AliModule *module;
904   while((module = (AliModule*)next())) 
905    {
906      if (evfold) AliConfig::Instance()->Add(module,evfoldname);
907      module->SetRunLoader(fRunLoader);
908      AliDetector* detector = dynamic_cast<AliDetector*>(module);
909      if (detector)
910       {
911         AliLoader* loader = fRunLoader->GetLoader(detector);
912         if (loader == 0x0)
913          {
914            Error("SetRunLoader","Can not get loader for detector %s",detector->GetName());
915          }
916         else
917          {
918            if (GetDebug()) Info("SetRunLoader","Setting loader for detector %s",detector->GetName());
919            detector->SetLoader(loader);
920          }
921       }
922    }
923 }
924
925 void AliRun::AddModule(AliModule* mod)
926 {
927   if (mod == 0x0) return;
928   if (strlen(mod->GetName()) == 0) return;
929   if (GetModuleID(mod->GetName()) >= 0) return;
930   
931   if (GetDebug()) Info("AddModule","%s",mod->GetName());
932   if (fRunLoader == 0x0) AliConfig::Instance()->Add(mod);
933   else AliConfig::Instance()->Add(mod,fRunLoader->GetEventFolder()->GetName());
934
935   Modules()->Add(mod);
936 }