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