]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliRun.cxx
pyquen added.
[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   if (!fMCApp)  
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   TIter next(fModules);
557   for(Int_t i=0; i<fNdets; ++i)
558    {
559      TObject *objfirst, *objlast;
560      AliModule *detector=dynamic_cast<AliModule*>(fModules->At(i));
561      objlast = gDirectory->GetList()->Last();
562       
563      // Add Detector histograms in Detector list of histograms
564      if (objlast) objfirst = gDirectory->GetList()->After(objlast);
565      else         objfirst = gDirectory->GetList()->First();
566      while (objfirst) 
567       {
568         detector->Histograms()->Add(objfirst);
569         objfirst = gDirectory->GetList()->After(objfirst);
570       }
571    }
572    
573    fMCApp->Init();
574    
575    //Must be here because some MCs (G4) adds detectors here and not in Config.C
576    InitLoaders();
577    fRunLoader->MakeTree("E");
578    if (fLego == 0x0)
579     {
580       fRunLoader->LoadKinematics("RECREATE");
581       fRunLoader->LoadTrackRefs("RECREATE");
582       fRunLoader->LoadHits("all","RECREATE");
583     }
584    fInitDone = kTRUE;
585    //
586    // Save stuff at the beginning of the file to avoid file corruption
587    fRunLoader->CdGAFile();
588    Write();
589    fEventNrInRun = -1; //important - we start Begin event from increasing current number in run
590 }
591
592 //_______________________________________________________________________
593
594 void AliRun::RunMC(Int_t nevent, const char *setup)
595 {
596   //
597   // Main function to be called to process a galice run
598   // example
599   //    Root > gAlice.Run(); 
600   // a positive number of events will cause the finish routine
601   // to be called
602   //
603   fEventsPerRun = nevent;
604   // check if initialisation has been done
605   if (!fInitDone) InitMC(setup);
606   
607   // Create the Root Tree with one branch per detector
608   //Hits moved to begin event -> now we are crating separate tree for each event
609
610   gMC->ProcessRun(nevent);
611
612   // End of this run, close files
613   if(nevent>0) FinishRun();
614 }
615
616 //_______________________________________________________________________
617 void AliRun::RunReco(const char *selected, Int_t first, Int_t last)
618 {
619   //
620   // Main function to be called to reconstruct Alice event
621   // 
622    Int_t nev = fRunLoader->GetNumberOfEvents();
623    if (GetDebug()) Info("RunReco","Found %d events",nev);
624    Int_t nFirst = first;
625    Int_t nLast  = (last < 0)? nev : last;
626    
627    for (Int_t nevent = nFirst; nevent <= nLast; nevent++) {
628      if (GetDebug()) Info("RunReco","Processing event %d",nevent);
629      GetEvent(nevent);
630      Digits2Reco(selected);
631    }
632 }
633
634 //_______________________________________________________________________
635
636 void AliRun::Hits2Digits(const char *selected)
637 {
638
639    // Convert Hits to sumable digits
640    // 
641    for (Int_t nevent=0; nevent<gAlice->TreeE()->GetEntries(); nevent++) {
642      GetEvent(nevent);
643      Hits2SDigits(selected);
644      SDigits2Digits(selected);
645    }  
646 }
647
648
649 //_______________________________________________________________________
650
651 void AliRun::Tree2Tree(Option_t *option, const char *selected)
652 {
653   //
654   // Function to transform the content of
655   //  
656   // - TreeH to TreeS (option "S")
657   // - TreeS to TreeD (option "D")
658   // - TreeD to TreeR (option "R")
659   // 
660   // If multiple options are specified ("SDR"), transformation will be done in sequence for
661   // selected detector and for all detectors if none is selected (detector string 
662   // can contain blank separated list of detector names). 
663
664
665    const char *oS = strstr(option,"S");
666    const char *oD = strstr(option,"D");
667    const char *oR = strstr(option,"R");
668    
669    TObjArray *detectors = Detectors();
670
671    TIter next(detectors);
672
673    AliDetector *detector = 0;
674
675    while((detector = dynamic_cast<AliDetector*>(next()))) {
676      if (selected) 
677        if (strcmp(detector->GetName(),selected)) continue;
678      if (detector->IsActive())
679       { 
680        
681        AliLoader* loader = detector->GetLoader();
682        if (loader == 0x0) continue;
683        
684        if (oS) 
685         {
686           if (GetDebug()) Info("Tree2Tree","Processing Hits2SDigits for %s ...",detector->GetName());
687           loader->LoadHits("read");
688           if (loader->TreeS() == 0x0) loader->MakeTree("S");
689           detector->MakeBranch(option);
690           detector->SetTreeAddress();
691           detector->Hits2SDigits();
692           loader->UnloadHits();
693           loader->UnloadSDigits();
694         }  
695        if (oD) 
696         {
697           if (GetDebug()) Info("Tree2Tree","Processing SDigits2Digits for %s ...",detector->GetName());
698           loader->LoadSDigits("read");
699           if (loader->TreeD() == 0x0) loader->MakeTree("D");
700           detector->MakeBranch(option);
701           detector->SetTreeAddress();
702           detector->SDigits2Digits();
703           loader->UnloadSDigits();
704           loader->UnloadDigits();
705         } 
706        if (oR) 
707         {
708           if (GetDebug()) Info("Tree2Tree","Processing Digits2Reco for %s ...",detector->GetName());
709           loader->LoadDigits("read");
710           if (loader->TreeR() == 0x0) loader->MakeTree("R");
711           detector->MakeBranch(option);
712           detector->SetTreeAddress();
713           detector->Digits2Reco(); 
714           loader->UnloadDigits();
715           loader->UnloadRecPoints();
716
717         }
718      }   
719    }
720 }
721
722 //_______________________________________________________________________
723 void AliRun::RunLego(const char *setup, Int_t nc1, Float_t c1min,
724                      Float_t c1max,Int_t nc2,Float_t c2min,Float_t c2max,
725                      Float_t rmin,Float_t rmax,Float_t zmax, AliLegoGenerator* gener)
726 {
727   //
728   // Generates lego plots of:
729   //    - radiation length map phi vs theta
730   //    - radiation length map phi vs eta
731   //    - interaction length map
732   //    - g/cm2 length map
733   //
734   //  ntheta    bins in theta, eta
735   //  themin    minimum angle in theta (degrees)
736   //  themax    maximum angle in theta (degrees)
737   //  nphi      bins in phi
738   //  phimin    minimum angle in phi (degrees)
739   //  phimax    maximum angle in phi (degrees)
740   //  rmin      minimum radius
741   //  rmax      maximum radius
742   //  
743   //
744   //  The number of events generated = ntheta*nphi
745   //  run input parameters in macro setup (default="Config.C")
746   //
747   //  Use macro "lego.C" to visualize the 3 lego plots in spherical coordinates
748   //Begin_Html
749   /*
750     <img src="picts/AliRunLego1.gif">
751   */
752   //End_Html
753   //Begin_Html
754   /*
755     <img src="picts/AliRunLego2.gif">
756   */
757   //End_Html
758   //Begin_Html
759   /*
760     <img src="picts/AliRunLego3.gif">
761   */
762   //End_Html
763   //
764
765   // check if initialisation has been done
766   // If runloader has been initialized, set the number of events per file to nc1 * nc2
767
768   // Set new generator
769   if (!gener) gener  = new AliLegoGenerator();
770   //
771   // Configure Generator
772   gener->SetRadiusRange(rmin, rmax);
773   gener->SetZMax(zmax);
774   gener->SetCoor1Range(nc1, c1min, c1max);
775   gener->SetCoor2Range(nc2, c2min, c2max);
776   
777   
778   //Create Lego object  
779   fLego = new AliLego("lego",gener);
780
781   if (!fInitDone) InitMC(setup);
782   //Save current generator
783   
784   AliGenerator *gen=fMCApp->Generator();
785   fMCApp->ResetGenerator(gener);
786   //Prepare MC for Lego Run
787   gMC->InitLego();
788   
789   //Run Lego Object
790
791   if (fRunLoader) fRunLoader->SetNumberOfEventsPerFile(nc1 * nc2);
792   //gMC->ProcessRun(nc1*nc2+1);
793   gMC->ProcessRun(nc1*nc2);
794   
795   // End of this run, close files
796   FinishRun();
797   // Restore current generator
798   fMCApp->ResetGenerator(gen);
799   // Delete Lego Object
800   delete fLego; fLego=0;
801 }
802
803 //_______________________________________________________________________
804 void AliRun::SetConfigFunction(const char * config) 
805 {
806   //
807   // Set the signature of the function contained in Config.C to configure
808   // the run
809   //
810   fConfigFunction=config;
811 }
812
813 // 
814 // MC Application
815 // 
816
817 //_______________________________________________________________________
818 void AliRun::Field(const Double_t* x, Double_t *b) const
819 {
820   //
821   // Return the value of the magnetic field
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 // End of MC Application
839 // 
840
841 //_______________________________________________________________________
842 void AliRun::Streamer(TBuffer &R__b)
843 {
844   // Stream an object of class AliRun.
845
846   if (R__b.IsReading()) {
847     if (!gAlice) gAlice = this;
848     AliRun::Class()->ReadBuffer(R__b, this);
849     gROOT->GetListOfBrowsables()->Add(this,"Run");
850
851     gRandom = fRandom;
852   } else {
853     AliRun::Class()->WriteBuffer(R__b, this);
854   }
855 }
856 //_______________________________________________________________________
857
858 void AliRun::SetGenEventHeader(AliGenEventHeader* header)
859 {
860   fRunLoader->GetHeader()->SetGenEventHeader(header);
861 }
862 //_______________________________________________________________________
863
864 Int_t AliRun::GetEvNumber() const
865
866 //Returns number of current event  
867   if (fRunLoader == 0x0)
868    {
869      Error("GetEvent","RunLoader is not set. Can not load data.");
870      return -1;
871    }
872
873   return fRunLoader->GetEventNumber();
874 }
875 //_______________________________________________________________________
876
877 void AliRun::SetRunLoader(AliRunLoader* rloader)
878 {
879   //
880   // Set the loader of the run
881   //
882   fRunLoader = rloader;
883   if (fRunLoader == 0x0) return;
884   
885   TString evfoldname;
886   TFolder* evfold = fRunLoader->GetEventFolder();
887   if (evfold) evfoldname = evfold->GetName();
888   else Warning("SetRunLoader","Did not get Event Folder from Run Loader");
889   
890   if ( fRunLoader->GetAliRun() )
891    {//if alrun already exists in folder
892     if (fRunLoader->GetAliRun() != this )
893      {//and is different than this - crash
894        Fatal("AliRun","AliRun is already in Folder and it is not this object");
895        return;//pro forma
896      }//else do nothing
897    }
898   else
899    {
900      evfold->Add(this);//Post this AliRun to Folder
901    }
902   
903   TIter next(fModules);
904   AliModule *module;
905   while((module = (AliModule*)next())) 
906    {
907      if (evfold) AliConfig::Instance()->Add(module,evfoldname);
908      module->SetRunLoader(fRunLoader);
909      AliDetector* detector = dynamic_cast<AliDetector*>(module);
910      if (detector)
911       {
912         AliLoader* loader = fRunLoader->GetLoader(detector);
913         if (loader == 0x0)
914          {
915            Error("SetRunLoader","Can not get loader for detector %s",detector->GetName());
916          }
917         else
918          {
919            if (GetDebug()) Info("SetRunLoader","Setting loader for detector %s",detector->GetName());
920            detector->SetLoader(loader);
921          }
922       }
923    }
924 }
925
926 void AliRun::AddModule(AliModule* mod)
927 {
928   //
929   // Add a module to the module list
930   //
931   if (mod == 0x0) return;
932   if (strlen(mod->GetName()) == 0) return;
933   if (GetModuleID(mod->GetName()) >= 0) return;
934   
935   if (GetDebug()) Info("AddModule","%s",mod->GetName());
936   if (fRunLoader == 0x0) AliConfig::Instance()->Add(mod);
937   else AliConfig::Instance()->Add(mod,fRunLoader->GetEventFolder()->GetName());
938
939   Modules()->Add(mod);
940   
941   fNdets++;
942 }