]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliSimulation.cxx
Fix fixed-string length bug
[u/mrichter/AliRoot.git] / STEER / AliSimulation.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 // class for running generation, simulation and digitization                 //
21 //                                                                           //
22 // Hits, sdigits and digits are created for all detectors by typing:         //
23 //                                                                           //
24 //   AliSimulation sim;                                                      //
25 //   sim.Run();                                                              //
26 //                                                                           //
27 // The Run method returns kTRUE in case of successful execution.             //
28 // The number of events can be given as argument to the Run method or it     //
29 // can be set by                                                             //
30 //                                                                           //
31 //   sim.SetNumberOfEvents(n);                                               //
32 //                                                                           //
33 // The name of the configuration file can be passed as argument to the       //
34 // AliSimulation constructor or can be specified by                          //
35 //                                                                           //
36 //   sim.SetConfigFile("...");                                               //
37 //                                                                           //
38 // The generation of particles and the simulation of detector hits can be    //
39 // switched on or off by                                                     //
40 //                                                                           //
41 //   sim.SetRunGeneration(kTRUE);   // generation of primary particles       //
42 //   sim.SetRunSimulation(kFALSE);  // but no tracking                       //
43 //                                                                           //
44 // For which detectors sdigits and digits will be created, can be steered    //
45 // by                                                                        //
46 //                                                                           //
47 //   sim.SetMakeSDigits("ALL");     // make sdigits for all detectors        //
48 //   sim.SetMakeDigits("ITS TPC");  // make digits only for ITS and TPC      //
49 //                                                                           //
50 // The argument is a (case sensitive) string with the names of the           //
51 // detectors separated by a space. An empty string ("") can be used to       //
52 // disable the creation of sdigits or digits. The special string "ALL"       //
53 // selects all available detectors. This is the default.                     //
54 //                                                                           //
55 // The creation of digits from hits instead of from sdigits can be selected  //
56 // by                                                                        //
57 //                                                                           //
58 //   sim.SetMakeDigitsFromHits("TRD");                                       //
59 //                                                                           //
60 // The argument is again a string with the selected detectors. Be aware that //
61 // this feature is not available for all detectors and that merging is not   //
62 // possible, when digits are created directly from hits.                     //
63 //                                                                           //
64 // Background events can be merged by calling                                //
65 //                                                                           //
66 //   sim.MergeWith("background/galice.root", 2);                             //
67 //                                                                           //
68 // The first argument is the file name of the background galice file. The    //
69 // second argument is the number of signal events per background event.      //
70 // By default this number is calculated from the number of available         //
71 // background events. MergeWith can be called several times to merge more    //
72 // than two event streams. It is assumed that the sdigits were already       //
73 // produced for the background events.                                       //
74 //                                                                           //
75 // The output of raw data can be switched on by calling                      //
76 //                                                                           //
77 //   sim.SetWriteRawData("MUON");   // write raw data for MUON               //
78 //                                                                           //
79 // The default output format of the raw data are DDL files. They are         //
80 // converted to a DATE file, if a file name is given as second argument.     //
81 // For this conversion the program "dateStream" is required. If the file     //
82 // name has the extension ".root", the DATE file is converted to a root      //
83 // file. The program "alimdc" is used for this purpose. For the conversion   //
84 // to DATE and root format the two conversion programs have to be installed. //
85 // Only the raw data in the final format is kept if the third argument is    //
86 // kTRUE.                                                                    //
87 //                                                                           //
88 // The methods RunSimulation, RunSDigitization, RunDigitization,             //
89 // RunHitsDigitization and WriteRawData can be used to run only parts of     //
90 // the full simulation chain. The creation of raw data DDL files and their   //
91 // conversion to the DATE or root format can be run directly by calling      //
92 // the methods WriteRawFiles, ConvertRawFilesToDate and ConvertDateToRoot.   //
93 //                                                                           //
94 // The default number of events per file, which is usually set in the        //
95 // config file, can be changed for individual detectors and data types       //
96 // by calling                                                                //
97 //                                                                           //
98 //   sim.SetEventsPerFile("PHOS", "Reconstructed Points", 3);                //
99 //                                                                           //
100 // The first argument is the detector, the second one the data type and the  //
101 // last one the number of events per file. Valid data types are "Hits",      //
102 // "Summable Digits", "Digits", "Reconstructed Points" and "Tracks".         //
103 // The number of events per file has to be set before the simulation of      //
104 // hits. Otherwise it has no effect.                                         //
105 //                                                                           //
106 ///////////////////////////////////////////////////////////////////////////////
107
108 #include <TVirtualMCApplication.h>
109 #include <TGeoManager.h>
110 #include <TObjString.h>
111 #include <TSystem.h>
112 #include <TFile.h>
113 #include <TROOT.h>
114
115 #include "AliCodeTimer.h"
116 #include "AliCDBStorage.h"
117 #include "AliCDBEntry.h"
118 #include "AliCDBManager.h"
119 #include "AliGeomManager.h"
120 #include "AliAlignObj.h"
121 #include "AliCentralTrigger.h"
122 #include "AliDAQ.h"
123 #include "AliDigitizer.h"
124 #include "AliGenerator.h"
125 #include "AliLog.h"
126 #include "AliModule.h"
127 #include "AliRun.h"
128 #include "AliRunDigitizer.h"
129 #include "AliRunLoader.h"
130 #include "AliSimulation.h"
131 #include "AliVertexGenFile.h"
132 #include "AliCentralTrigger.h"
133 #include "AliCTPRawData.h"
134 #include "AliRawReaderFile.h"
135 #include "AliRawReaderRoot.h"
136 #include "AliRawReaderDate.h"
137 #include "AliESD.h"
138 #include "AliHeader.h"
139 #include "AliGenEventHeader.h"
140 #include "AliMC.h"
141 #include "AliHLTSimulation.h"
142 #include "AliQADataMakerSteer.h"
143 #include "AliSysInfo.h"
144 #include "AliMagF.h"
145
146 ClassImp(AliSimulation)
147
148 AliSimulation *AliSimulation::fgInstance = 0;
149 const char* AliSimulation::fgkDetectorName[AliSimulation::fgkNDetectors] = {"ITS", "TPC", "TRD", "TOF", "PHOS", "HMPID", "EMCAL", "MUON", "FMD", "ZDC", "PMD", "T0", "VZERO", "ACORDE", "HLT"};
150
151 //_____________________________________________________________________________
152 AliSimulation::AliSimulation(const char* configFileName,
153                              const char* name, const char* title) :
154   TNamed(name, title),
155
156   fRunGeneration(kTRUE),
157   fRunSimulation(kTRUE),
158   fLoadAlignFromCDB(kTRUE),
159   fLoadAlObjsListOfDets("ALL"),
160   fMakeSDigits("ALL"),
161   fMakeDigits("ALL"),
162   fMakeTrigger(""),
163   fMakeDigitsFromHits(""),
164   fWriteRawData(""),
165   fRawDataFileName(""),
166   fDeleteIntermediateFiles(kFALSE),
167   fWriteSelRawData(kFALSE),
168   fStopOnError(kFALSE),
169
170   fNEvents(1),
171   fConfigFileName(configFileName),
172   fGAliceFileName("galice.root"),
173   fEventsPerFile(),
174   fBkgrdFileNames(NULL),
175   fAlignObjArray(NULL),
176   fUseBkgrdVertex(kTRUE),
177   fRegionOfInterest(kFALSE),
178   fCDBUri(""),
179   fSpecCDBUri(),
180   fRun(-1),
181   fSeed(0),
182   fInitCDBCalled(kFALSE),
183   fInitRunNumberCalled(kFALSE),
184   fSetRunNumberFromDataCalled(kFALSE),
185   fEmbeddingFlag(kFALSE),
186   fQADetectors("ALL"),                  
187   fQATasks("ALL"),      
188   fQASteer(NULL), 
189   fRunQA(kTRUE), 
190   fRunHLT("default"),
191   fWriteGRPEntry(kTRUE)
192 {
193 // create simulation object with default parameters
194   fgInstance = this;
195   SetGAliceFile("galice.root");
196   
197 // for QA
198    for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) 
199                  fQACycles[iDet] = 999999;
200         fQASteer = new AliQADataMakerSteer("sim") ; 
201         fQASteer->SetActiveDetectors(fQADetectors) ; 
202         fQATasks = Form("%d %d %d", AliQA::kHITS, AliQA::kSDIGITS, AliQA::kDIGITS) ; 
203         fQASteer->SetTasks(fQATasks) ;  
204 }
205
206 //_____________________________________________________________________________
207 AliSimulation::AliSimulation(const AliSimulation& sim) :
208   TNamed(sim),
209
210   fRunGeneration(sim.fRunGeneration),
211   fRunSimulation(sim.fRunSimulation),
212   fLoadAlignFromCDB(sim.fLoadAlignFromCDB),
213   fLoadAlObjsListOfDets(sim.fLoadAlObjsListOfDets),
214   fMakeSDigits(sim.fMakeSDigits),
215   fMakeDigits(sim.fMakeDigits),
216   fMakeTrigger(sim.fMakeTrigger),
217   fMakeDigitsFromHits(sim.fMakeDigitsFromHits),
218   fWriteRawData(sim.fWriteRawData),
219   fRawDataFileName(""),
220   fDeleteIntermediateFiles(kFALSE),
221   fWriteSelRawData(kFALSE),
222   fStopOnError(sim.fStopOnError),
223
224   fNEvents(sim.fNEvents),
225   fConfigFileName(sim.fConfigFileName),
226   fGAliceFileName(sim.fGAliceFileName),
227   fEventsPerFile(),
228   fBkgrdFileNames(NULL),
229   fAlignObjArray(NULL),
230   fUseBkgrdVertex(sim.fUseBkgrdVertex),
231   fRegionOfInterest(sim.fRegionOfInterest),
232   fCDBUri(sim.fCDBUri),
233   fSpecCDBUri(),
234   fRun(-1),
235   fSeed(0),
236   fInitCDBCalled(sim.fInitCDBCalled),
237   fInitRunNumberCalled(sim.fInitRunNumberCalled),
238   fSetRunNumberFromDataCalled(sim.fSetRunNumberFromDataCalled),
239   fEmbeddingFlag(sim.fEmbeddingFlag),
240   fQADetectors(sim.fQADetectors),                  
241         fQATasks(sim.fQATasks), 
242         fQASteer(sim.fQASteer), 
243   fRunQA(sim.fRunQA), 
244   fRunHLT(sim.fRunHLT),
245   fWriteGRPEntry(sim.fWriteGRPEntry)
246 {
247 // copy constructor
248
249   for (Int_t i = 0; i < sim.fEventsPerFile.GetEntriesFast(); i++) {
250     if (!sim.fEventsPerFile[i]) continue;
251     fEventsPerFile.Add(sim.fEventsPerFile[i]->Clone());
252   }
253
254   fBkgrdFileNames = new TObjArray;
255   for (Int_t i = 0; i < sim.fBkgrdFileNames->GetEntriesFast(); i++) {
256     if (!sim.fBkgrdFileNames->At(i)) continue;
257     fBkgrdFileNames->Add(sim.fBkgrdFileNames->At(i)->Clone());
258   }
259
260   for (Int_t i = 0; i < sim.fSpecCDBUri.GetEntriesFast(); i++) {
261     if (sim.fSpecCDBUri[i]) fSpecCDBUri.Add(sim.fSpecCDBUri[i]->Clone());
262   }
263   fgInstance = this;
264
265 // for QA
266    for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) 
267         fQACycles[iDet] = sim.fQACycles[iDet];
268 }
269
270 //_____________________________________________________________________________
271 AliSimulation& AliSimulation::operator = (const AliSimulation& sim)
272 {
273 // assignment operator
274
275   this->~AliSimulation();
276   new(this) AliSimulation(sim);
277   return *this;
278 }
279
280 //_____________________________________________________________________________
281 AliSimulation::~AliSimulation()
282 {
283 // clean up
284
285   fEventsPerFile.Delete();
286 //  if(fAlignObjArray) fAlignObjArray->Delete(); // fAlignObjArray->RemoveAll() ???
287 //  delete fAlignObjArray; fAlignObjArray=0;
288
289   if (fBkgrdFileNames) {
290     fBkgrdFileNames->Delete();
291     delete fBkgrdFileNames;
292   }
293
294   fSpecCDBUri.Delete();
295   if (fgInstance==this) fgInstance = 0;
296
297         delete fQASteer ; 
298         
299   AliCodeTimer::Instance()->Print();
300 }
301
302
303 //_____________________________________________________________________________
304 void AliSimulation::SetNumberOfEvents(Int_t nEvents)
305 {
306 // set the number of events for one run
307
308   fNEvents = nEvents;
309 }
310
311 //_____________________________________________________________________________
312 void AliSimulation::InitCDB()
313 {
314 // activate a default CDB storage
315 // First check if we have any CDB storage set, because it is used 
316 // to retrieve the calibration and alignment constants
317
318   if (fInitCDBCalled) return;
319   fInitCDBCalled = kTRUE;
320
321   AliCDBManager* man = AliCDBManager::Instance();
322   if (man->IsDefaultStorageSet())
323   {
324     AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
325     AliWarning("Default CDB storage has been already set !");
326     AliWarning(Form("Ignoring the default storage declared in AliSimulation: %s",fCDBUri.Data()));
327     AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
328     fCDBUri = man->GetDefaultStorage()->GetURI();
329   }
330   else {
331     if (fCDBUri.Length() > 0) 
332     {
333         AliDebug(2,"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
334         AliDebug(2, Form("Default CDB storage is set to: %s", fCDBUri.Data()));
335         AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
336     } else {
337         fCDBUri="local://$ALICE_ROOT";
338         AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
339         AliWarning("Default CDB storage not yet set !!!!");
340         AliWarning(Form("Setting it now to: %s", fCDBUri.Data()));
341         AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
342                 
343     }
344     man->SetDefaultStorage(fCDBUri);
345   }
346
347   // Now activate the detector specific CDB storage locations
348   for (Int_t i = 0; i < fSpecCDBUri.GetEntriesFast(); i++) {
349     TObject* obj = fSpecCDBUri[i];
350     if (!obj) continue;
351     AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
352     AliDebug(2, Form("Specific CDB storage for %s is set to: %s",obj->GetName(),obj->GetTitle()));
353     AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
354     man->SetSpecificStorage(obj->GetName(), obj->GetTitle());
355   }
356       
357 }
358
359 //_____________________________________________________________________________
360 void AliSimulation::InitRunNumber(){
361 // check run number. If not set, set it to 0 !!!!
362   
363   if (fInitRunNumberCalled) return;
364   fInitRunNumberCalled = kTRUE;
365   
366   AliCDBManager* man = AliCDBManager::Instance();
367   if (man->GetRun() >= 0)
368   {
369         AliFatal(Form("Run number cannot be set in AliCDBManager before start of simulation: "
370                         "Use external variable DC_RUN or AliSimulation::SetRun()!"));
371   }
372     
373   if(fRun >= 0) {
374         AliDebug(2,"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
375         AliDebug(2, Form("Setting CDB run number to: %d",fRun));
376         AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
377   } else {
378         fRun=0;
379         AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
380         AliWarning("Run number not yet set !!!!");
381         AliWarning(Form("Setting it now to: %d", fRun));
382         AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
383         
384   }
385   man->SetRun(fRun);
386
387   man->Print();
388
389 }
390
391 //_____________________________________________________________________________
392 void AliSimulation::SetCDBLock() {
393   // Set CDB lock: from now on it is forbidden to reset the run number
394   // or the default storage or to activate any further storage!
395   
396   AliCDBManager::Instance()->SetLock(1);
397 }
398
399 //_____________________________________________________________________________
400 void AliSimulation::SetDefaultStorage(const char* uri) {
401 // Store the desired default CDB storage location
402 // Activate it later within the Run() method
403
404   fCDBUri = uri;
405
406 }
407
408 //_____________________________________________________________________________
409 void AliSimulation::SetSpecificStorage(const char* calibType, const char* uri) {
410 // Store a detector-specific CDB storage location
411 // Activate it later within the Run() method
412
413   AliCDBPath aPath(calibType);
414   if(!aPath.IsValid()){
415         AliError(Form("Not a valid path: %s", calibType));
416         return;
417   }
418
419   TObject* obj = fSpecCDBUri.FindObject(calibType);
420   if (obj) fSpecCDBUri.Remove(obj);
421   fSpecCDBUri.Add(new TNamed(calibType, uri));
422
423 }
424
425 //_____________________________________________________________________________
426 void AliSimulation::SetRunNumber(Int_t run)
427 {
428 // sets run number
429 // Activate it later within the Run() method
430
431         fRun = run;
432 }
433
434 //_____________________________________________________________________________
435 void AliSimulation::SetSeed(Int_t seed)
436 {
437 // sets seed number
438 // Activate it later within the Run() method
439
440         fSeed = seed;
441 }
442
443 //_____________________________________________________________________________
444 Bool_t AliSimulation::SetRunNumberFromData()
445 {
446   // Set the CDB manager run number
447   // The run number is retrieved from gAlice
448
449     if (fSetRunNumberFromDataCalled) return kTRUE;
450     fSetRunNumberFromDataCalled = kTRUE;    
451   
452     AliCDBManager* man = AliCDBManager::Instance();
453     Int_t runData = -1, runCDB = -1;
454   
455     AliRunLoader* runLoader = LoadRun("READ");
456     if (!runLoader) return kFALSE;
457     else {
458         runData = runLoader->GetAliRun()->GetHeader()->GetRun();
459         delete runLoader;
460     }
461   
462     runCDB = man->GetRun();
463     if(runCDB >= 0) {
464         if (runCDB != runData) {
465                 AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
466                 AliWarning(Form("A run number was previously set in AliCDBManager: %d !", runCDB));
467                 AliWarning(Form("It will be replaced with the run number got from run header: %d !", runData));
468                 AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");    
469         }
470         
471     }
472       
473     man->SetRun(runData);
474     fRun = runData;
475     
476     if(man->GetRun() < 0) {
477         AliError("Run number not properly initalized!");
478         return kFALSE;
479     }
480   
481     man->Print();
482     
483     return kTRUE;
484 }
485
486 //_____________________________________________________________________________
487 void AliSimulation::SetConfigFile(const char* fileName)
488 {
489 // set the name of the config file
490
491   fConfigFileName = fileName;
492 }
493
494 //_____________________________________________________________________________
495 void AliSimulation::SetGAliceFile(const char* fileName)
496 {
497 // set the name of the galice file
498 // the path is converted to an absolute one if it is relative
499
500   fGAliceFileName = fileName;
501   if (!gSystem->IsAbsoluteFileName(fGAliceFileName)) {
502     char* absFileName = gSystem->ConcatFileName(gSystem->WorkingDirectory(),
503                                                 fGAliceFileName);
504     fGAliceFileName = absFileName;
505     delete[] absFileName;
506   }
507
508   AliDebug(2, Form("galice file name set to %s", fileName));
509 }
510
511 //_____________________________________________________________________________
512 void AliSimulation::SetEventsPerFile(const char* detector, const char* type, 
513                                      Int_t nEvents)
514 {
515 // set the number of events per file for the given detector and data type
516 // ("Hits", "Summable Digits", "Digits", "Reconstructed Points" or "Tracks")
517
518   TNamed* obj = new TNamed(detector, type);
519   obj->SetUniqueID(nEvents);
520   fEventsPerFile.Add(obj);
521 }
522
523 //_____________________________________________________________________________
524 Bool_t AliSimulation::MisalignGeometry(AliRunLoader *runLoader)
525 {
526   // Read the alignment objects from CDB.
527   // Each detector is supposed to have the
528   // alignment objects in DET/Align/Data CDB path.
529   // All the detector objects are then collected,
530   // sorted by geometry level (starting from ALIC) and
531   // then applied to the TGeo geometry.
532   // Finally an overlaps check is performed.
533
534   if (!AliGeomManager::GetGeometry() || !AliGeomManager::GetGeometry()->IsClosed()) {
535     AliError("Can't apply the misalignment! Geometry is not loaded or it is still opened!");
536     return kFALSE;
537   }  
538   
539   // initialize CDB storage, run number, set CDB lock
540   InitCDB();
541 //  if (!SetRunNumberFromData()) if (fStopOnError) return kFALSE;
542   SetCDBLock();
543     
544   Bool_t delRunLoader = kFALSE;
545   if (!runLoader) {
546     runLoader = LoadRun("READ");
547     if (!runLoader) return kFALSE;
548     delRunLoader = kTRUE;
549   }
550   
551   // Export ideal geometry 
552   if(!gAlice->IsRootGeometry()) AliGeomManager::GetGeometry()->Export("geometry.root");
553
554   // Load alignment data from CDB and apply to geometry through AliGeomManager
555   if(fLoadAlignFromCDB){
556     
557     TString detStr = fLoadAlObjsListOfDets;
558     TString loadAlObjsListOfDets = "";
559     
560     TObjArray* detArray = runLoader->GetAliRun()->Detectors();
561     for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
562       AliModule* det = (AliModule*) detArray->At(iDet);
563       if (!det || !det->IsActive()) continue;
564       if (IsSelected(det->GetName(), detStr)) {
565         //add det to list of dets to be aligned from CDB
566         loadAlObjsListOfDets += det->GetName();
567         loadAlObjsListOfDets += " ";
568       }
569     } // end loop over detectors
570     loadAlObjsListOfDets.Prepend("GRP "); //add alignment objects for non-sensitive modules
571     AliGeomManager::ApplyAlignObjsFromCDB(loadAlObjsListOfDets.Data());
572   }else{
573     // Check if the array with alignment objects was
574     // provided by the user. If yes, apply the objects
575     // to the present TGeo geometry
576     if (fAlignObjArray) {
577       if (AliGeomManager::ApplyAlignObjsToGeom(*fAlignObjArray) == kFALSE) {
578         AliError("The misalignment of one or more volumes failed!"
579                  "Compare the list of simulated detectors and the list of detector alignment data!");
580         if (delRunLoader) delete runLoader;
581         return kFALSE;
582       }
583     }
584   }
585
586   // Update the internal geometry of modules (ITS needs it)
587   TString detStr = fLoadAlObjsListOfDets;
588   TObjArray* detArray = runLoader->GetAliRun()->Detectors();
589   for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
590
591     AliModule* det = (AliModule*) detArray->At(iDet);
592     if (!det || !det->IsActive()) continue;
593     if (IsSelected(det->GetName(), detStr)) {
594       det->UpdateInternalGeometry();
595     }
596   } // end loop over detectors
597
598
599   if (delRunLoader) delete runLoader;
600
601   return kTRUE;
602 }
603
604 //_____________________________________________________________________________
605 void AliSimulation::MergeWith(const char* fileName, Int_t nSignalPerBkgrd)
606 {
607 // add a file with background events for merging
608
609   TObjString* fileNameStr = new TObjString(fileName);
610   fileNameStr->SetUniqueID(nSignalPerBkgrd);
611   if (!fBkgrdFileNames) fBkgrdFileNames = new TObjArray;
612   fBkgrdFileNames->Add(fileNameStr);
613 }
614
615 void AliSimulation::EmbedInto(const char* fileName, Int_t nSignalPerBkgrd)
616 {
617 // add a file with background events for embeddin
618   MergeWith(fileName, nSignalPerBkgrd);
619   fEmbeddingFlag = kTRUE;
620 }
621
622 //_____________________________________________________________________________
623 Bool_t AliSimulation::Run(Int_t nEvents)
624 {
625 // run the generation, simulation and digitization
626
627  
628   AliCodeTimerAuto("")
629   
630   // Load run number and seed from environmental vars
631   ProcessEnvironmentVars();
632
633   gRandom->SetSeed(fSeed);
634    
635   if (nEvents > 0) fNEvents = nEvents;
636
637   // generation and simulation -> hits
638   if (fRunGeneration) {
639     if (!RunSimulation()) if (fStopOnError) return kFALSE;
640   }
641            
642   // initialize CDB storage from external environment
643   // (either CDB manager or AliSimulation setters),
644   // if not already done in RunSimulation()
645   InitCDB();
646   
647   // Set run number in CDBManager from data 
648   // From this point on the run number must be always loaded from data!
649   if (!SetRunNumberFromData()) if (fStopOnError) return kFALSE;
650   
651   // Set CDB lock: from now on it is forbidden to reset the run number
652   // or the default storage or to activate any further storage!
653   SetCDBLock();
654
655   // If RunSimulation was not called, load the geometry and misalign it
656   if (!AliGeomManager::GetGeometry()) {
657     // Initialize the geometry manager
658     AliGeomManager::LoadGeometry("geometry.root");
659     
660 //    // Check that the consistency of symbolic names for the activated subdetectors
661 //    // in the geometry loaded by AliGeomManager
662 //    AliRunLoader* runLoader = LoadRun("READ");
663 //    if (!runLoader) return kFALSE;
664 //
665 //    TString detsToBeChecked = "";
666 //    TObjArray* detArray = runLoader->GetAliRun()->Detectors();
667 //    for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
668 //      AliModule* det = (AliModule*) detArray->At(iDet);
669 //      if (!det || !det->IsActive()) continue;
670 //      detsToBeChecked += det->GetName();
671 //      detsToBeChecked += " ";
672 //    } // end loop over detectors
673 //    if(!AliGeomManager::CheckSymNamesLUT(detsToBeChecked.Data()))
674     if(!AliGeomManager::CheckSymNamesLUT("ALL"))
675         AliFatalClass("Current loaded geometry differs in the definition of symbolic names!");
676         
677     if (!AliGeomManager::GetGeometry()) if (fStopOnError) return kFALSE;
678     // Misalign geometry
679     if(!MisalignGeometry()) if (fStopOnError) return kFALSE;
680   }
681
682
683   // hits -> summable digits
684   AliSysInfo::AddStamp("Start_sdigitization");
685   if (!fMakeSDigits.IsNull()) {
686     if (!RunSDigitization(fMakeSDigits)) if (fStopOnError) return kFALSE;
687  
688   }
689   AliSysInfo::AddStamp("Stop_sdigitization");
690   
691   AliSysInfo::AddStamp("Start_digitization");  
692   // summable digits -> digits  
693   if (!fMakeDigits.IsNull()) {
694     if (!RunDigitization(fMakeDigits, fMakeDigitsFromHits)) {
695       if (fStopOnError) return kFALSE;
696     }
697    }
698   AliSysInfo::AddStamp("Stop_digitization");
699
700   
701   
702   // hits -> digits
703   if (!fMakeDigitsFromHits.IsNull()) {
704     if (fBkgrdFileNames && (fBkgrdFileNames->GetEntriesFast() > 0)) {
705       AliWarning(Form("Merging and direct creation of digits from hits " 
706                  "was selected for some detectors. "
707                  "No merging will be done for the following detectors: %s",
708                  fMakeDigitsFromHits.Data()));
709     }
710     if (!RunHitsDigitization(fMakeDigitsFromHits)) {
711       if (fStopOnError) return kFALSE;
712     }
713   }
714
715   
716   
717   // digits -> trigger
718   if (!RunTrigger(fMakeTrigger,fMakeDigits)) {
719     if (fStopOnError) return kFALSE;
720   }
721
722   
723   
724   // digits -> raw data
725   if (!fWriteRawData.IsNull()) {
726     if (!WriteRawData(fWriteRawData, fRawDataFileName, 
727                       fDeleteIntermediateFiles,fWriteSelRawData)) {
728       if (fStopOnError) return kFALSE;
729     }
730   }
731
732   
733   
734   // run HLT simulation
735   if (!fRunHLT.IsNull()) {
736     if (!RunHLT()) {
737       if (fStopOnError) return kFALSE;
738     }
739   }
740   
741   //QA
742         if (fRunQA) {
743                 Bool_t rv = RunQA() ; 
744                 if (!rv)
745                         if (fStopOnError) 
746                                 return kFALSE ;         
747         }
748
749   // Cleanup of CDB manager: cache and active storages!
750   AliCDBManager::Instance()->ClearCache();
751
752   return kTRUE;
753 }
754
755 //_____________________________________________________________________________
756 Bool_t AliSimulation::RunTrigger(const char* config, const char* detectors)
757 {
758   // run the trigger
759
760   AliCodeTimerAuto("")
761
762   // initialize CDB storage from external environment
763   // (either CDB manager or AliSimulation setters),
764   // if not already done in RunSimulation()
765   InitCDB();
766   
767   // Set run number in CDBManager from data 
768   // From this point on the run number must be always loaded from data!
769   if (!SetRunNumberFromData()) if (fStopOnError) return kFALSE;
770   
771   // Set CDB lock: from now on it is forbidden to reset the run number
772   // or the default storage or to activate any further storage!
773   SetCDBLock();
774    
775    AliRunLoader* runLoader = LoadRun("READ");
776    if (!runLoader) return kFALSE;
777    TString trconfiguration = config;
778
779    if (trconfiguration.IsNull()) {
780      if (gAlice->GetTriggerDescriptor() != "") {
781        trconfiguration = gAlice->GetTriggerDescriptor();
782      }
783      else
784        AliWarning("No trigger descriptor is specified. Loading the one that is in the CDB.");
785    }
786
787    runLoader->MakeTree( "GG" );
788    AliCentralTrigger* aCTP = runLoader->GetTrigger();
789    // Load Configuration
790    if (!aCTP->LoadConfiguration( trconfiguration ))
791      return kFALSE;
792
793    // digits -> trigger
794    if( !aCTP->RunTrigger( runLoader , detectors ) ) {
795       if (fStopOnError) {
796         //  delete aCTP;
797         return kFALSE;
798       }
799    }
800
801    delete runLoader;
802
803    return kTRUE;
804 }
805
806 //_____________________________________________________________________________
807 Bool_t AliSimulation::WriteTriggerRawData()
808 {
809   // Writes the CTP (trigger) DDL raw data
810   // Details of the format are given in the
811   // trigger TDR - pages 134 and 135.
812   AliCTPRawData writer;
813   writer.RawData();
814
815   return kTRUE;
816 }
817
818 //_____________________________________________________________________________
819 Bool_t AliSimulation::RunSimulation(Int_t nEvents)
820 {
821 // run the generation and simulation
822
823   AliCodeTimerAuto("")
824
825   // initialize CDB storage and run number from external environment
826   // (either CDB manager or AliSimulation setters)
827   InitCDB();
828   InitRunNumber();
829   SetCDBLock();
830   
831   if (!gAlice) {
832     AliError("no gAlice object. Restart aliroot and try again.");
833     return kFALSE;
834   }
835   if (gAlice->Modules()->GetEntries() > 0) {
836     AliError("gAlice was already run. Restart aliroot and try again.");
837     return kFALSE;
838   }
839
840   AliInfo(Form("initializing gAlice with config file %s",
841           fConfigFileName.Data()));
842   StdoutToAliInfo(StderrToAliError(
843     gAlice->Init(fConfigFileName.Data());
844   ););
845   
846   // Get the trigger descriptor string
847   // Either from AliSimulation or from
848   // gAlice
849   if (fMakeTrigger.IsNull()) {
850     if (gAlice->GetTriggerDescriptor() != "")
851       fMakeTrigger = gAlice->GetTriggerDescriptor();
852   }
853   else
854     gAlice->SetTriggerDescriptor(fMakeTrigger.Data());
855
856   // Set run number in CDBManager
857   AliInfo(Form("Run number: %d",AliCDBManager::Instance()->GetRun()));
858
859   AliRunLoader* runLoader = gAlice->GetRunLoader();
860   if (!runLoader) {
861              AliError(Form("gAlice has no run loader object. "
862                              "Check your config file: %s", fConfigFileName.Data()));
863              return kFALSE;
864   }
865   SetGAliceFile(runLoader->GetFileName());
866       
867   // Misalign geometry
868 #if ROOT_VERSION_CODE < 331527
869   AliGeomManager::SetGeometry(gGeoManager);
870   
871   // Check that the consistency of symbolic names for the activated subdetectors
872   // in the geometry loaded by AliGeomManager
873   TString detsToBeChecked = "";
874   TObjArray* detArray = runLoader->GetAliRun()->Detectors();
875   for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
876     AliModule* det = (AliModule*) detArray->At(iDet);
877     if (!det || !det->IsActive()) continue;
878     detsToBeChecked += det->GetName();
879     detsToBeChecked += " ";
880   } // end loop over detectors
881   if(!AliGeomManager::CheckSymNamesLUT(detsToBeChecked.Data()))
882     AliFatalClass("Current loaded geometry differs in the definition of symbolic names!");
883   MisalignGeometry(runLoader);
884 #endif
885
886 //   AliRunLoader* runLoader = gAlice->GetRunLoader();
887 //   if (!runLoader) {
888 //     AliError(Form("gAlice has no run loader object. "
889 //                   "Check your config file: %s", fConfigFileName.Data()));
890 //     return kFALSE;
891 //   }
892 //   SetGAliceFile(runLoader->GetFileName());
893
894   if (!gAlice->Generator()) {
895     AliError(Form("gAlice has no generator object. "
896                   "Check your config file: %s", fConfigFileName.Data()));
897     return kFALSE;
898   }
899
900   // Write GRP entry corresponding to the setting found in Cofig.C
901   if (fWriteGRPEntry)
902     WriteGRPEntry();
903
904   if (nEvents <= 0) nEvents = fNEvents;
905
906   // get vertex from background file in case of merging
907   if (fUseBkgrdVertex &&
908       fBkgrdFileNames && (fBkgrdFileNames->GetEntriesFast() > 0)) {
909     Int_t signalPerBkgrd = GetNSignalPerBkgrd(nEvents);
910     const char* fileName = ((TObjString*)
911                             (fBkgrdFileNames->At(0)))->GetName();
912     AliInfo(Form("The vertex will be taken from the background "
913                  "file %s with nSignalPerBackground = %d", 
914                  fileName, signalPerBkgrd));
915     AliVertexGenFile* vtxGen = new AliVertexGenFile(fileName, signalPerBkgrd);
916     gAlice->Generator()->SetVertexGenerator(vtxGen);
917   }
918
919   if (!fRunSimulation) {
920     gAlice->Generator()->SetTrackingFlag(0);
921   }
922
923   // set the number of events per file for given detectors and data types
924   for (Int_t i = 0; i < fEventsPerFile.GetEntriesFast(); i++) {
925     if (!fEventsPerFile[i]) continue;
926     const char* detName = fEventsPerFile[i]->GetName();
927     const char* typeName = fEventsPerFile[i]->GetTitle();
928     TString loaderName(detName);
929     loaderName += "Loader";
930     AliLoader* loader = runLoader->GetLoader(loaderName);
931     if (!loader) {
932       AliError(Form("RunSimulation", "no loader for %s found\n"
933                     "Number of events per file not set for %s %s", 
934                     detName, typeName, detName));
935       continue;
936     }
937     AliDataLoader* dataLoader = 
938       loader->GetDataLoader(typeName);
939     if (!dataLoader) {
940       AliError(Form("no data loader for %s found\n"
941                     "Number of events per file not set for %s %s", 
942                     typeName, detName, typeName));
943       continue;
944     }
945     dataLoader->SetNumberOfEventsPerFile(fEventsPerFile[i]->GetUniqueID());
946     AliDebug(1, Form("number of events per file set to %d for %s %s",
947                      fEventsPerFile[i]->GetUniqueID(), detName, typeName));
948   }
949
950   AliInfo("running gAlice");
951   AliSysInfo::AddStamp("Start_simulation");
952   StdoutToAliInfo(StderrToAliError(
953     gAlice->Run(nEvents);
954   ););
955   AliSysInfo::AddStamp("Stop_simulation");
956   delete runLoader;
957
958   return kTRUE;
959 }
960
961 //_____________________________________________________________________________
962 Bool_t AliSimulation::RunSDigitization(const char* detectors)
963 {
964 // run the digitization and produce summable digits
965   static Int_t eventNr=0;
966   AliCodeTimerAuto("")
967
968   // initialize CDB storage, run number, set CDB lock
969   InitCDB();
970   if (!SetRunNumberFromData()) if (fStopOnError) return kFALSE;
971   SetCDBLock();
972   
973   AliRunLoader* runLoader = LoadRun();
974   if (!runLoader) return kFALSE;
975
976   TString detStr = detectors;
977   TObjArray* detArray = runLoader->GetAliRun()->Detectors();
978   for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
979     AliModule* det = (AliModule*) detArray->At(iDet);
980     if (!det || !det->IsActive()) continue;
981     if (IsSelected(det->GetName(), detStr)) {
982       AliInfo(Form("creating summable digits for %s", det->GetName()));
983       AliCodeTimerAuto(Form("creating summable digits for %s", det->GetName()));
984       det->Hits2SDigits();
985       AliSysInfo::AddStamp(Form("Digit_%s_%d",det->GetName(),eventNr), 0,1, eventNr);
986     }
987   }
988
989   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
990     AliError(Form("the following detectors were not found: %s",
991                   detStr.Data()));
992     if (fStopOnError) return kFALSE;
993   }
994   eventNr++;
995   delete runLoader;
996
997   return kTRUE;
998 }
999
1000
1001 //_____________________________________________________________________________
1002 Bool_t AliSimulation::RunDigitization(const char* detectors, 
1003                                       const char* excludeDetectors)
1004 {
1005 // run the digitization and produce digits from sdigits
1006
1007   AliCodeTimerAuto("")
1008
1009   // initialize CDB storage, run number, set CDB lock
1010   InitCDB();
1011   if (!SetRunNumberFromData()) if (fStopOnError) return kFALSE;
1012   SetCDBLock();
1013   
1014   while (AliRunLoader::GetRunLoader()) delete AliRunLoader::GetRunLoader();
1015   if (gAlice) delete gAlice;
1016   gAlice = NULL;
1017
1018   Int_t nStreams = 1;
1019   if (fBkgrdFileNames) nStreams = fBkgrdFileNames->GetEntriesFast() + 1;
1020   Int_t signalPerBkgrd = GetNSignalPerBkgrd();
1021   AliRunDigitizer* manager = new AliRunDigitizer(nStreams, signalPerBkgrd);
1022   // manager->SetEmbeddingFlag(fEmbeddingFlag);
1023   manager->SetInputStream(0, fGAliceFileName.Data());
1024   for (Int_t iStream = 1; iStream < nStreams; iStream++) {
1025     const char* fileName = ((TObjString*)
1026                             (fBkgrdFileNames->At(iStream-1)))->GetName();
1027     manager->SetInputStream(iStream, fileName);
1028   }
1029
1030   TString detStr = detectors;
1031   TString detExcl = excludeDetectors;
1032   manager->GetInputStream(0)->ImportgAlice();
1033   AliRunLoader* runLoader = 
1034     AliRunLoader::GetRunLoader(manager->GetInputStream(0)->GetFolderName());
1035   TObjArray* detArray = runLoader->GetAliRun()->Detectors();
1036   for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
1037     AliModule* det = (AliModule*) detArray->At(iDet);
1038     if (!det || !det->IsActive()) continue;
1039     if (IsSelected(det->GetName(), detStr) && 
1040         !IsSelected(det->GetName(), detExcl)) {
1041       AliDigitizer* digitizer = det->CreateDigitizer(manager);
1042       
1043       if (!digitizer) {
1044         AliError(Form("no digitizer for %s", det->GetName()));
1045         if (fStopOnError) return kFALSE;
1046       } else {
1047         digitizer->SetRegionOfInterest(fRegionOfInterest);
1048       }
1049     }
1050   }
1051
1052   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
1053     AliError(Form("the following detectors were not found: %s", 
1054                   detStr.Data()));
1055     if (fStopOnError) return kFALSE;
1056   }
1057
1058   if (!manager->GetListOfTasks()->IsEmpty()) {
1059     AliInfo("executing digitization");
1060     manager->Exec("");
1061   }
1062
1063   delete manager;
1064
1065   return kTRUE;
1066 }
1067
1068 //_____________________________________________________________________________
1069 Bool_t AliSimulation::RunHitsDigitization(const char* detectors)
1070 {
1071 // run the digitization and produce digits from hits
1072
1073   AliCodeTimerAuto("")
1074
1075   // initialize CDB storage, run number, set CDB lock
1076   InitCDB();
1077   if (!SetRunNumberFromData()) if (fStopOnError) return kFALSE;
1078   SetCDBLock();
1079   
1080   AliRunLoader* runLoader = LoadRun("READ");
1081   if (!runLoader) return kFALSE;
1082
1083   TString detStr = detectors;
1084   TObjArray* detArray = runLoader->GetAliRun()->Detectors();
1085   for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
1086     AliModule* det = (AliModule*) detArray->At(iDet);
1087     if (!det || !det->IsActive()) continue;
1088     if (IsSelected(det->GetName(), detStr)) {
1089       AliInfo(Form("creating digits from hits for %s", det->GetName()));
1090       det->Hits2Digits();
1091     }
1092   }
1093
1094   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
1095     AliError(Form("the following detectors were not found: %s", 
1096                   detStr.Data()));
1097     if (fStopOnError) return kFALSE;
1098   }
1099
1100   delete runLoader;
1101   //PH Temporary fix to avoid interference with the PHOS loder/getter
1102   //PH The problem has to be solved in more general way 09/06/05
1103
1104   return kTRUE;
1105 }
1106
1107 //_____________________________________________________________________________
1108 Bool_t AliSimulation::WriteRawData(const char* detectors, 
1109                                    const char* fileName,
1110                                    Bool_t deleteIntermediateFiles,
1111                                    Bool_t selrawdata)
1112 {
1113 // convert the digits to raw data
1114 // First DDL raw data files for the given detectors are created.
1115 // If a file name is given, the DDL files are then converted to a DATE file.
1116 // If deleteIntermediateFiles is true, the DDL raw files are deleted 
1117 // afterwards.
1118 // If the file name has the extension ".root", the DATE file is converted
1119 // to a root file.
1120 // If deleteIntermediateFiles is true, the DATE file is deleted afterwards.
1121 // 'selrawdata' flag can be used to enable writing of detectors raw data
1122 // accoring to the trigger cluster.
1123
1124   AliCodeTimerAuto("")
1125   
1126   TString detStr = detectors;
1127   if (IsSelected("HLT", detStr))
1128   {
1129         // Do nothing. "HLT" will be removed from detStr because the HLT raw
1130         // data files are generated in RunHLT.
1131   }
1132
1133   if (!WriteRawFiles(detStr.Data())) {
1134     if (fStopOnError) return kFALSE;
1135   }
1136
1137   TString dateFileName(fileName);
1138   if (!dateFileName.IsNull()) {
1139     Bool_t rootOutput = dateFileName.EndsWith(".root");
1140     if (rootOutput) dateFileName += ".date";
1141     TString selDateFileName;
1142     if (selrawdata) {
1143       selDateFileName = "selected.";
1144       selDateFileName+= dateFileName;
1145     }
1146     if (!ConvertRawFilesToDate(dateFileName,selDateFileName)) {
1147       if (fStopOnError) return kFALSE;
1148     }
1149     if (deleteIntermediateFiles) {
1150       AliRunLoader* runLoader = LoadRun("READ");
1151       if (runLoader) for (Int_t iEvent = 0; 
1152                           iEvent < runLoader->GetNumberOfEvents(); iEvent++) {
1153         char command[256];
1154         sprintf(command, "rm -r raw%d", iEvent);
1155         gSystem->Exec(command);
1156       }
1157     }
1158
1159     if (rootOutput) {
1160       if (!ConvertDateToRoot(dateFileName, fileName)) {
1161         if (fStopOnError) return kFALSE;
1162       }
1163       if (deleteIntermediateFiles) {
1164         gSystem->Unlink(dateFileName);
1165       }
1166       if (selrawdata) {
1167         TString selFileName = "selected.";
1168         selFileName        += fileName;
1169         if (!ConvertDateToRoot(selDateFileName, selFileName)) {
1170           if (fStopOnError) return kFALSE;
1171         }
1172         if (deleteIntermediateFiles) {
1173           gSystem->Unlink(selDateFileName);
1174         }
1175       }
1176     }
1177   }
1178
1179   return kTRUE;
1180 }
1181
1182 //_____________________________________________________________________________
1183 Bool_t AliSimulation::WriteRawFiles(const char* detectors)
1184 {
1185 // convert the digits to raw data DDL files
1186
1187   AliCodeTimerAuto("")
1188   
1189   AliRunLoader* runLoader = LoadRun("READ");
1190   if (!runLoader) return kFALSE;
1191
1192   // write raw data to DDL files
1193   for (Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); iEvent++) {
1194     AliInfo(Form("processing event %d", iEvent));
1195     runLoader->GetEvent(iEvent);
1196     TString baseDir = gSystem->WorkingDirectory();
1197     char dirName[256];
1198     sprintf(dirName, "raw%d", iEvent);
1199     gSystem->MakeDirectory(dirName);
1200     if (!gSystem->ChangeDirectory(dirName)) {
1201       AliError(Form("couldn't change to directory %s", dirName));
1202       if (fStopOnError) return kFALSE; else continue;
1203     }
1204
1205     TString detStr = detectors;
1206     TObjArray* detArray = runLoader->GetAliRun()->Detectors();
1207     for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
1208       AliModule* det = (AliModule*) detArray->At(iDet);
1209       if (!det || !det->IsActive()) continue;
1210       if (IsSelected(det->GetName(), detStr)) {
1211         AliInfo(Form("creating raw data from digits for %s", det->GetName()));
1212         det->Digits2Raw();
1213       }
1214     }
1215
1216     if (!WriteTriggerRawData())
1217       if (fStopOnError) return kFALSE;
1218
1219     gSystem->ChangeDirectory(baseDir);
1220     if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
1221       AliError(Form("the following detectors were not found: %s", 
1222                     detStr.Data()));
1223       if (fStopOnError) return kFALSE;
1224     }
1225   }
1226
1227   delete runLoader;
1228   
1229   return kTRUE;
1230 }
1231
1232 //_____________________________________________________________________________
1233 Bool_t AliSimulation::ConvertRawFilesToDate(const char* dateFileName,
1234                                             const char* selDateFileName)
1235 {
1236 // convert raw data DDL files to a DATE file with the program "dateStream"
1237 // The second argument is not empty when the user decides to write
1238 // the detectors raw data according to the trigger cluster.
1239
1240   AliCodeTimerAuto("")
1241   
1242   char* path = gSystem->Which(gSystem->Getenv("PATH"), "dateStream");
1243   if (!path) {
1244     AliError("the program dateStream was not found");
1245     if (fStopOnError) return kFALSE;
1246   } else {
1247     delete[] path;
1248   }
1249
1250   AliRunLoader* runLoader = LoadRun("READ");
1251   if (!runLoader) return kFALSE;
1252
1253   AliInfo(Form("converting raw data DDL files to DATE file %s", dateFileName));
1254   Bool_t selrawdata = kFALSE;
1255   if (strcmp(selDateFileName,"") != 0) selrawdata = kTRUE;
1256
1257   char command[256];
1258   // Note the option -s. It is used in order to avoid
1259   // the generation of SOR/EOR events.
1260   sprintf(command, "dateStream -c -s -D -o %s -# %d -C -run %d", 
1261           dateFileName, runLoader->GetNumberOfEvents(),runLoader->GetHeader()->GetRun());
1262   FILE* pipe = gSystem->OpenPipe(command, "w");
1263
1264   Int_t selEvents = 0;
1265   for (Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); iEvent++) {
1266     fprintf(pipe, "GDC\n");
1267     Float_t ldc = 0;
1268     Int_t prevLDC = -1;
1269
1270     if (selrawdata) {
1271       // Check if the event was triggered by CTP
1272       runLoader->GetEvent(iEvent);
1273       if (!runLoader->LoadTrigger()) {
1274         AliCentralTrigger *aCTP = runLoader->GetTrigger();
1275         if (aCTP->GetClassMask()) selEvents++;
1276       }
1277       else {
1278         AliWarning("No trigger can be loaded! Writing of selected raw data is abandoned !");
1279         selrawdata = kFALSE;
1280       }
1281     }
1282
1283     // loop over detectors and DDLs
1284     for (Int_t iDet = 0; iDet < AliDAQ::kNDetectors; iDet++) {
1285       for (Int_t iDDL = 0; iDDL < AliDAQ::NumberOfDdls(iDet); iDDL++) {
1286
1287         Int_t ddlID = AliDAQ::DdlID(iDet,iDDL);
1288         Int_t ldcID = Int_t(ldc + 0.0001);
1289         ldc += AliDAQ::NumberOfLdcs(iDet) / AliDAQ::NumberOfDdls(iDet);
1290
1291         char rawFileName[256];
1292         sprintf(rawFileName, "raw%d/%s", 
1293                 iEvent, AliDAQ::DdlFileName(iDet,iDDL));
1294
1295         // check existence and size of raw data file
1296         FILE* file = fopen(rawFileName, "rb");
1297         if (!file) continue;
1298         fseek(file, 0, SEEK_END);
1299         unsigned long size = ftell(file);
1300         fclose(file);
1301         if (!size) continue;
1302
1303         if (ldcID != prevLDC) {
1304           fprintf(pipe, " LDC Id %d\n", ldcID);
1305           prevLDC = ldcID;
1306         }
1307         fprintf(pipe, "  Equipment Id %d Payload %s\n", ddlID, rawFileName);
1308       }
1309     }
1310   }
1311
1312   Int_t result = gSystem->ClosePipe(pipe);
1313
1314   if (!(selrawdata && selEvents > 0)) {
1315     delete runLoader;
1316     return (result == 0);
1317   }
1318
1319   AliInfo(Form("converting selected by trigger cluster raw data DDL files to DATE file %s", selDateFileName));
1320   
1321   sprintf(command, "dateStream -c -s -D -o %s -# %d -C -run %d", 
1322           selDateFileName,selEvents,runLoader->GetHeader()->GetRun());
1323   FILE* pipe2 = gSystem->OpenPipe(command, "w");
1324
1325   for (Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); iEvent++) {
1326
1327     // Get the trigger decision and cluster
1328     TString detClust;
1329     runLoader->GetEvent(iEvent);
1330     if (!runLoader->LoadTrigger()) {
1331       AliCentralTrigger *aCTP = runLoader->GetTrigger();
1332       if (aCTP->GetClassMask() == 0) continue;
1333       detClust = AliDAQ::ListOfTriggeredDetectors(aCTP->GetClusterMask());
1334       AliInfo(Form("List of detectors to be read out: %s",detClust.Data()));
1335     }
1336
1337     fprintf(pipe2, "GDC\n");
1338     Float_t ldc = 0;
1339     Int_t prevLDC = -1;
1340
1341     // loop over detectors and DDLs
1342     for (Int_t iDet = 0; iDet < AliDAQ::kNDetectors; iDet++) {
1343       // Write only raw data from detectors that
1344       // are contained in the trigger cluster(s)
1345       if (!IsSelected(AliDAQ::DetectorName(iDet),detClust)) continue;
1346
1347       for (Int_t iDDL = 0; iDDL < AliDAQ::NumberOfDdls(iDet); iDDL++) {
1348
1349         Int_t ddlID = AliDAQ::DdlID(iDet,iDDL);
1350         Int_t ldcID = Int_t(ldc + 0.0001);
1351         ldc += AliDAQ::NumberOfLdcs(iDet) / AliDAQ::NumberOfDdls(iDet);
1352
1353         char rawFileName[256];
1354         sprintf(rawFileName, "raw%d/%s", 
1355                 iEvent, AliDAQ::DdlFileName(iDet,iDDL));
1356
1357         // check existence and size of raw data file
1358         FILE* file = fopen(rawFileName, "rb");
1359         if (!file) continue;
1360         fseek(file, 0, SEEK_END);
1361         unsigned long size = ftell(file);
1362         fclose(file);
1363         if (!size) continue;
1364
1365         if (ldcID != prevLDC) {
1366           fprintf(pipe2, " LDC Id %d\n", ldcID);
1367           prevLDC = ldcID;
1368         }
1369         fprintf(pipe2, "  Equipment Id %d Payload %s\n", ddlID, rawFileName);
1370       }
1371     }
1372   }
1373
1374   Int_t result2 = gSystem->ClosePipe(pipe2);
1375
1376   delete runLoader;
1377   return ((result == 0) && (result2 == 0));
1378 }
1379
1380 //_____________________________________________________________________________
1381 Bool_t AliSimulation::ConvertDateToRoot(const char* dateFileName,
1382                                         const char* rootFileName)
1383 {
1384 // convert a DATE file to a root file with the program "alimdc"
1385
1386   // ALIMDC setup
1387   const Int_t kDBSize = 2000000000;
1388   const Int_t kTagDBSize = 1000000000;
1389   const Bool_t kFilter = kFALSE;
1390   const Int_t kCompression = 1;
1391
1392   char* path = gSystem->Which(gSystem->Getenv("PATH"), "alimdc");
1393   if (!path) {
1394     AliError("the program alimdc was not found");
1395     if (fStopOnError) return kFALSE;
1396   } else {
1397     delete[] path;
1398   }
1399
1400   AliInfo(Form("converting DATE file %s to root file %s", 
1401                dateFileName, rootFileName));
1402
1403   const char* rawDBFS[2] = { "/tmp/mdc1", "/tmp/mdc2" };
1404   const char* tagDBFS    = "/tmp/mdc1/tags";
1405
1406   // User defined file system locations
1407   if (gSystem->Getenv("ALIMDC_RAWDB1")) 
1408     rawDBFS[0] = gSystem->Getenv("ALIMDC_RAWDB1");
1409   if (gSystem->Getenv("ALIMDC_RAWDB2")) 
1410     rawDBFS[1] = gSystem->Getenv("ALIMDC_RAWDB2");
1411   if (gSystem->Getenv("ALIMDC_TAGDB")) 
1412     tagDBFS = gSystem->Getenv("ALIMDC_TAGDB");
1413
1414   gSystem->Exec(Form("rm -rf %s",rawDBFS[0]));
1415   gSystem->Exec(Form("rm -rf %s",rawDBFS[1]));
1416   gSystem->Exec(Form("rm -rf %s",tagDBFS));
1417
1418   gSystem->Exec(Form("mkdir %s",rawDBFS[0]));
1419   gSystem->Exec(Form("mkdir %s",rawDBFS[1]));
1420   gSystem->Exec(Form("mkdir %s",tagDBFS));
1421
1422   Int_t result = gSystem->Exec(Form("alimdc %d %d %d %d %s", 
1423                                     kDBSize, kTagDBSize, kFilter, kCompression, dateFileName));
1424   gSystem->Exec(Form("mv %s/*.root %s", rawDBFS[0], rootFileName));
1425
1426   gSystem->Exec(Form("rm -rf %s",rawDBFS[0]));
1427   gSystem->Exec(Form("rm -rf %s",rawDBFS[1]));
1428   gSystem->Exec(Form("rm -rf %s",tagDBFS));
1429
1430   return (result == 0);
1431 }
1432
1433
1434 //_____________________________________________________________________________
1435 AliRunLoader* AliSimulation::LoadRun(const char* mode) const
1436 {
1437 // delete existing run loaders, open a new one and load gAlice
1438
1439   while (AliRunLoader::GetRunLoader()) delete AliRunLoader::GetRunLoader();
1440   AliRunLoader* runLoader = 
1441     AliRunLoader::Open(fGAliceFileName.Data(), 
1442                        AliConfig::GetDefaultEventFolderName(), mode);
1443   if (!runLoader) {
1444     AliError(Form("no run loader found in file %s", fGAliceFileName.Data()));
1445     return NULL;
1446   }
1447   runLoader->LoadgAlice();
1448   runLoader->LoadHeader();
1449   gAlice = runLoader->GetAliRun();
1450   if (!gAlice) {
1451     AliError(Form("no gAlice object found in file %s", 
1452                   fGAliceFileName.Data()));
1453     return NULL;
1454   }
1455   return runLoader;
1456 }
1457
1458 //_____________________________________________________________________________
1459 Int_t AliSimulation::GetNSignalPerBkgrd(Int_t nEvents) const
1460 {
1461 // get or calculate the number of signal events per background event
1462
1463   if (!fBkgrdFileNames) return 1;
1464   Int_t nBkgrdFiles = fBkgrdFileNames->GetEntriesFast();
1465   if (nBkgrdFiles == 0) return 1;
1466
1467   // get the number of signal events
1468   if (nEvents <= 0) {
1469     AliRunLoader* runLoader = 
1470         AliRunLoader::Open(fGAliceFileName.Data(), "SIGNAL");
1471     if (!runLoader) return 1;
1472     
1473     nEvents = runLoader->GetNumberOfEvents();
1474     delete runLoader;
1475   }
1476
1477   Int_t result = 0;
1478   for (Int_t iBkgrdFile = 0; iBkgrdFile < nBkgrdFiles; iBkgrdFile++) {
1479     // get the number of background events
1480     const char* fileName = ((TObjString*)
1481                             (fBkgrdFileNames->At(iBkgrdFile)))->GetName();
1482     AliRunLoader* runLoader =
1483       AliRunLoader::Open(fileName, "BKGRD");
1484     if (!runLoader) continue;
1485     Int_t nBkgrdEvents = runLoader->GetNumberOfEvents();
1486     delete runLoader;
1487   
1488     // get or calculate the number of signal per background events
1489     Int_t nSignalPerBkgrd = fBkgrdFileNames->At(iBkgrdFile)->GetUniqueID();
1490     if (nSignalPerBkgrd <= 0) {
1491       nSignalPerBkgrd = (nEvents-1) / nBkgrdEvents + 1;
1492     } else if (result && (result != nSignalPerBkgrd)) {
1493       AliInfo(Form("the number of signal events per background event "
1494                    "will be changed from %d to %d for stream %d", 
1495                    nSignalPerBkgrd, result, iBkgrdFile+1));
1496       nSignalPerBkgrd = result;
1497     }
1498
1499     if (!result) result = nSignalPerBkgrd;
1500     if (nSignalPerBkgrd * nBkgrdEvents < nEvents) {
1501       AliWarning(Form("not enough background events (%d) for %d signal events "
1502                       "using %d signal per background events for stream %d",
1503                       nBkgrdEvents, nEvents, nSignalPerBkgrd, iBkgrdFile+1));
1504     }
1505   }
1506
1507   return result;
1508 }
1509
1510 //_____________________________________________________________________________
1511 Bool_t AliSimulation::IsSelected(TString detName, TString& detectors) const
1512 {
1513 // check whether detName is contained in detectors
1514 // if yes, it is removed from detectors
1515
1516   // check if all detectors are selected
1517   if ((detectors.CompareTo("ALL") == 0) ||
1518       detectors.BeginsWith("ALL ") ||
1519       detectors.EndsWith(" ALL") ||
1520       detectors.Contains(" ALL ")) {
1521     detectors = "ALL";
1522     return kTRUE;
1523   }
1524
1525   // search for the given detector
1526   Bool_t result = kFALSE;
1527   if ((detectors.CompareTo(detName) == 0) ||
1528       detectors.BeginsWith(detName+" ") ||
1529       detectors.EndsWith(" "+detName) ||
1530       detectors.Contains(" "+detName+" ")) {
1531     detectors.ReplaceAll(detName, "");
1532     result = kTRUE;
1533   }
1534
1535   // clean up the detectors string
1536   while (detectors.Contains("  ")) detectors.ReplaceAll("  ", " ");
1537   while (detectors.BeginsWith(" ")) detectors.Remove(0, 1);
1538   while (detectors.EndsWith(" ")) detectors.Remove(detectors.Length()-1, 1);
1539
1540   return result;
1541 }
1542
1543 //_____________________________________________________________________________
1544 Bool_t AliSimulation::ConvertRaw2SDigits(const char* rawDirectory, const char* esdFileName) 
1545 {
1546 //
1547 // Steering routine  to convert raw data in directory rawDirectory/ to fake SDigits. 
1548 // These can be used for embedding of MC tracks into RAW data using the standard 
1549 // merging procedure.
1550 //
1551 // If an ESD file is given the reconstructed vertex is taken from it and stored in the event header.
1552 //
1553     if (!gAlice) {
1554         AliError("no gAlice object. Restart aliroot and try again.");
1555         return kFALSE;
1556     }
1557     if (gAlice->Modules()->GetEntries() > 0) {
1558         AliError("gAlice was already run. Restart aliroot and try again.");
1559         return kFALSE;
1560     }
1561     
1562     AliInfo(Form("initializing gAlice with config file %s",fConfigFileName.Data()));
1563     StdoutToAliInfo(StderrToAliError(gAlice->Init(fConfigFileName.Data());););
1564 //
1565 //  Initialize CDB     
1566     InitCDB();
1567     //AliCDBManager* man = AliCDBManager::Instance();
1568     //man->SetRun(0); // Should this come from rawdata header ?
1569     
1570     Int_t iDet;
1571     //
1572     // Get the runloader
1573     AliRunLoader* runLoader = gAlice->GetRunLoader();
1574     //
1575     // Open esd file if available
1576     TFile* esdFile = TFile::Open(esdFileName);
1577     Bool_t esdOK = (esdFile != 0);
1578     AliESD* esd = new AliESD;
1579     TTree* treeESD = 0;
1580     if (esdOK) {
1581         treeESD = (TTree*) esdFile->Get("esdTree");
1582         if (!treeESD) {
1583             AliWarning("No ESD tree found");
1584             esdOK = kFALSE;
1585         } else {
1586             treeESD->SetBranchAddress("ESD", &esd);
1587         }
1588     }
1589     //
1590     // Create the RawReader
1591     TString fileName(rawDirectory);
1592     AliRawReader* rawReader = 0x0;
1593     if (fileName.EndsWith("/")) {
1594       rawReader = new AliRawReaderFile(fileName);
1595     } else if (fileName.EndsWith(".root")) {
1596       rawReader = new AliRawReaderRoot(fileName);
1597     } else if (!fileName.IsNull()) {
1598       rawReader = new AliRawReaderDate(fileName);
1599     }
1600 //     if (!fEquipIdMap.IsNull() && fRawReader)
1601 //       fRawReader->LoadEquipmentIdsMap(fEquipIdMap);
1602     //
1603     // Get list of detectors
1604     TObjArray* detArray = runLoader->GetAliRun()->Detectors();
1605     //
1606     // Get Header
1607     AliHeader* header = runLoader->GetHeader();
1608     //
1609     TString detStr = fMakeSDigits;
1610     // Event loop
1611     Int_t nev = 0;
1612     while(kTRUE) {
1613         if (!(rawReader->NextEvent())) break;
1614         //
1615         // Detector loop
1616         for (iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
1617             AliModule* det = (AliModule*) detArray->At(iDet);
1618             if (!det || !det->IsActive()) continue;
1619             if (IsSelected(det->GetName(), detStr)) {
1620               AliInfo(Form("Calling Raw2SDigits for %s\n", det->GetName()));
1621               det->Raw2SDigits(rawReader);
1622               rawReader->Reset();
1623             }
1624         } // detectors
1625
1626
1627         //
1628         //  If ESD information available obtain reconstructed vertex and store in header.
1629         if (esdOK) {
1630             treeESD->GetEvent(nev);
1631             const AliESDVertex* esdVertex = esd->GetPrimaryVertex();
1632             Double_t position[3];
1633             esdVertex->GetXYZ(position);
1634             AliGenEventHeader* mcHeader = new  AliGenEventHeader("ESD");
1635             TArrayF mcV;
1636             mcV.Set(3);
1637             for (Int_t i = 0; i < 3; i++) mcV[i] = position[i];
1638             mcHeader->SetPrimaryVertex(mcV);
1639             header->Reset(0,nev);
1640             header->SetGenEventHeader(mcHeader);
1641             printf("***** Saved vertex %f %f %f \n", position[0], position[1], position[2]);
1642         }
1643         nev++;
1644 //
1645 //      Finish the event
1646         runLoader->TreeE()->Fill();
1647         runLoader->SetNextEvent();
1648     } // events
1649  
1650     delete rawReader;
1651 //
1652 //  Finish the run 
1653     runLoader->CdGAFile();
1654     runLoader->WriteHeader("OVERWRITE");
1655     runLoader->WriteRunLoader();
1656
1657     return kTRUE;
1658 }
1659
1660 //_____________________________________________________________________________
1661 Int_t AliSimulation::GetDetIndex(const char* detector)
1662 {
1663   // return the detector index corresponding to detector
1664   Int_t index = -1 ; 
1665   for (index = 0; index < fgkNDetectors ; index++) {
1666     if ( strcmp(detector, fgkDetectorName[index]) == 0 )
1667           break ; 
1668   }     
1669   return index ; 
1670 }
1671
1672 //_____________________________________________________________________________
1673 Bool_t AliSimulation::RunHLT()
1674 {
1675   // Run the HLT simulation
1676   // HLT simulation is implemented in HLT/sim/AliHLTSimulation
1677   // Disabled if fRunHLT is empty, default vaule is "default".
1678   // AliSimulation::SetRunHLT can be used to set the options for HLT simulation
1679   // The default simulation depends on the HLT component libraries and their
1680   // corresponding agents which define components and chains to run. See
1681   // http://web.ift.uib.no/~kjeks/doc/alice-hlt/
1682   // http://web.ift.uib.no/~kjeks/doc/alice-hlt/classAliHLTModuleAgent.html
1683   //
1684   // The libraries to be loaded can be specified as an option.
1685   // <pre>
1686   // AliSimulation sim;
1687   // sim.SetRunHLT("libAliHLTSample.so");
1688   // </pre>
1689   // will only load <tt>libAliHLTSample.so</tt>
1690
1691   // Other available options:
1692   // \li loglevel=<i>level</i> <br>
1693   //     logging level for this processing
1694   // \li alilog=off
1695   //     disable redirection of log messages to AliLog class
1696   // \li config=<i>macro</i>
1697   //     configuration macro
1698   // \li localrec=<i>configuration</i>
1699   //     comma separated list of configurations to be run during simulation
1700
1701   int iResult=0;
1702   AliRunLoader* pRunLoader = LoadRun("READ");
1703   if (!pRunLoader) return kFALSE;
1704
1705   // initialize CDB storage, run number, set CDB lock
1706   InitCDB();
1707   if (!SetRunNumberFromData()) if (fStopOnError) return kFALSE;
1708   SetCDBLock();
1709   
1710   // load the library dynamically
1711   gSystem->Load(ALIHLTSIMULATION_LIBRARY);
1712
1713   // check for the library version
1714   AliHLTSimulationGetLibraryVersion_t fctVersion=(AliHLTSimulationGetLibraryVersion_t)(gSystem->DynFindSymbol(ALIHLTSIMULATION_LIBRARY, ALIHLTSIMULATION_GET_LIBRARY_VERSION));
1715   if (!fctVersion) {
1716     AliError(Form("can not load library %s", ALIHLTSIMULATION_LIBRARY));
1717     return kFALSE;
1718   }
1719   if (fctVersion()!= ALIHLTSIMULATION_LIBRARY_VERSION) {
1720     AliError(Form("%s version does not match: compiled for version %d, loaded %d", ALIHLTSIMULATION_LIBRARY, ALIHLTSIMULATION_LIBRARY_VERSION, fctVersion()));
1721     return kFALSE;
1722   }
1723
1724   // print compile info
1725   typedef void (*CompileInfo)( char*& date, char*& time);
1726   CompileInfo fctInfo=(CompileInfo)gSystem->DynFindSymbol(ALIHLTSIMULATION_LIBRARY, "CompileInfo");
1727   if (fctInfo) {
1728     char* date="";
1729     char* time="";
1730     (*fctInfo)(date, time);
1731     if (!date) date="unknown";
1732     if (!time) time="unknown";
1733     AliInfo(Form("%s build on %s (%s)", ALIHLTSIMULATION_LIBRARY, date, time));
1734   } else {
1735     AliInfo(Form("no build info available for %s", ALIHLTSIMULATION_LIBRARY));
1736   }
1737
1738   // create instance of the HLT simulation
1739   AliHLTSimulationCreateInstance_t fctCreate=(AliHLTSimulationCreateInstance_t)(gSystem->DynFindSymbol(ALIHLTSIMULATION_LIBRARY, ALIHLTSIMULATION_CREATE_INSTANCE));
1740   AliHLTSimulation* pHLT=NULL;
1741   if (fctCreate==NULL || (pHLT=(fctCreate()))==NULL) {
1742     AliError(Form("can not create instance of HLT simulation (creator %p)", fctCreate));
1743     return kFALSE;    
1744   }
1745
1746   // init the HLT simulation
1747   TString options;
1748   if (fRunHLT.CompareTo("default")!=0) options=fRunHLT;
1749   if (!IsSelected("HLT", fWriteRawData)) {
1750     options+=" writerawfiles=";
1751   } else {
1752     options+=" writerawfiles=HLT";
1753   }
1754   AliHLTSimulationInit_t fctInit=(AliHLTSimulationInit_t)(gSystem->DynFindSymbol(ALIHLTSIMULATION_LIBRARY, ALIHLTSIMULATION_INIT));
1755   if (fctInit==NULL || (iResult=(fctInit(pHLT, pRunLoader, options.Data())))<0) {
1756     AliError(Form("can not init HLT simulation: error %d (init %p)", iResult, fctInit));
1757   } else {
1758     // run the HLT simulation
1759     AliHLTSimulationRun_t fctRun=(AliHLTSimulationRun_t)(gSystem->DynFindSymbol(ALIHLTSIMULATION_LIBRARY, ALIHLTSIMULATION_RUN));
1760     if (fctRun==NULL || (iResult=(fctRun(pHLT, pRunLoader)))<0) {
1761       AliError(Form("can not run HLT simulation: error %d (run %p)", iResult, fctRun));
1762     }
1763   }
1764
1765   // delete the instance
1766   AliHLTSimulationDeleteInstance_t fctDelete=(AliHLTSimulationDeleteInstance_t)(gSystem->DynFindSymbol(ALIHLTSIMULATION_LIBRARY, ALIHLTSIMULATION_DELETE_INSTANCE));
1767   if (fctDelete==NULL || fctDelete(pHLT)<0) {
1768     AliError(Form("can not delete instance of HLT simulation (creator %p)", fctDelete));
1769   }
1770   pHLT=NULL;
1771
1772   return iResult>=0?kTRUE:kFALSE;
1773 }
1774
1775 //_____________________________________________________________________________
1776 Bool_t AliSimulation::RunQA()
1777 {
1778         // run the QA on summable hits, digits or digits
1779         
1780         fQASteer->SetRunLoader(gAlice->GetRunLoader()) ;
1781
1782         TString detectorsw("") ;  
1783         Bool_t rv = kTRUE ; 
1784         detectorsw = fQASteer->Run(fQADetectors.Data()) ; 
1785         if ( detectorsw.IsNull() ) 
1786                 rv = kFALSE ; 
1787         return rv ; 
1788 }
1789
1790 //_____________________________________________________________________________
1791 Bool_t AliSimulation::SetRunQA(TString detAndAction) 
1792 {
1793         // Allows to run QA for a selected set of detectors
1794         // and a selected set of tasks among HITS, SDIGITS and DIGITS
1795         // all selected detectors run the same selected tasks
1796         
1797         if (!detAndAction.Contains(":")) {
1798                 AliError( Form("%s is a wrong syntax, use \"DetectorList:ActionList\" \n", detAndAction.Data()) ) ;
1799                 fRunQA = kFALSE ;
1800                 return kFALSE ;                 
1801         }
1802         Int_t colon = detAndAction.Index(":") ; 
1803         fQADetectors = detAndAction(0, colon) ; 
1804         if (fQADetectors.Contains("ALL") )
1805                 fQADetectors = Form("%s %s", fMakeDigits.Data(), fMakeDigitsFromHits.Data()) ; 
1806                 fQATasks   = detAndAction(colon+1, detAndAction.Sizeof() ) ; 
1807         if (fQATasks.Contains("ALL") ) {
1808                 fQATasks = Form("%d %d %d", AliQA::kHITS, AliQA::kSDIGITS, AliQA::kDIGITS) ; 
1809         } else {
1810                 fQATasks.ToUpper() ; 
1811                 TString tempo("") ; 
1812                 if ( fQATasks.Contains("HIT") ) 
1813                         tempo = Form("%d ", AliQA::kHITS) ; 
1814                 if ( fQATasks.Contains("SDIGIT") ) 
1815                         tempo += Form("%d ", AliQA::kSDIGITS) ; 
1816                 if ( fQATasks.Contains("DIGIT") ) 
1817                         tempo += Form("%d ", AliQA::kDIGITS) ; 
1818                 fQATasks = tempo ; 
1819                 if (fQATasks.IsNull()) {
1820                         AliInfo("No QA requested\n")  ;
1821                         fRunQA = kFALSE ;
1822                         return kTRUE ; 
1823                 }
1824         }       
1825         TString tempo(fQATasks) ; 
1826     tempo.ReplaceAll(Form("%d", AliQA::kHITS), AliQA::GetTaskName(AliQA::kHITS))        ;
1827     tempo.ReplaceAll(Form("%d", AliQA::kSDIGITS), AliQA::GetTaskName(AliQA::kSDIGITS)) ;        
1828     tempo.ReplaceAll(Form("%d", AliQA::kDIGITS), AliQA::GetTaskName(AliQA::kDIGITS)) ;  
1829         AliInfo( Form("QA will be done on \"%s\" for \"%s\"\n", fQADetectors.Data(), tempo.Data()) ) ;  
1830         fRunQA = kTRUE ;
1831         fQASteer->SetActiveDetectors(fQADetectors) ; 
1832         fQASteer->SetTasks(fQATasks) ; 
1833         return kTRUE; 
1834
1835
1836 //_____________________________________________________________________________
1837 void AliSimulation::ProcessEnvironmentVars()
1838 {
1839 // Extract run number and random generator seed from env variables
1840
1841     AliInfo("Processing environment variables");
1842     
1843     // Random Number seed
1844     
1845     // first check that seed is not already set
1846     if (fSeed == 0) {
1847         if (gSystem->Getenv("CONFIG_SEED")) {
1848                 fSeed = atoi(gSystem->Getenv("CONFIG_SEED"));
1849         }
1850     } else {
1851         if (gSystem->Getenv("CONFIG_SEED")) {
1852                 AliInfo(Form("Seed for random number generation already set (%d)"
1853                              ": CONFIG_SEED variable ignored!", fSeed));
1854         }
1855     }
1856    
1857     AliInfo(Form("Seed for random number generation = %d ", fSeed)); 
1858
1859     // Run Number
1860     
1861     // first check that run number is not already set
1862     if(fRun < 0) {    
1863         if (gSystem->Getenv("DC_RUN")) {
1864                 fRun = atoi(gSystem->Getenv("DC_RUN"));
1865         }
1866     } else {
1867         if (gSystem->Getenv("DC_RUN")) {
1868                 AliInfo(Form("Run number already set (%d): DC_RUN variable ignored!", fRun));
1869         }
1870     }
1871     
1872     AliInfo(Form("Run number = %d", fRun)); 
1873 }
1874
1875 //_____________________________________________________________________________
1876 void AliSimulation::WriteGRPEntry()
1877 {
1878   // Get the necessary information from galice (generator, trigger etc) and
1879   // write a GRP entry corresponding to the settings in the Config.C used
1880   AliInfo("Writing global run parameters entry into the OCDB");
1881
1882   TMap *grpMap = new TMap();
1883   grpMap->SetName("MONTECARLO");
1884
1885   grpMap->Add(new TObjString("fRunType"),new TObjString("PHYSICS"));
1886   grpMap->Add(new TObjString("fAliceStartTime"),new TObjString("0"));
1887   grpMap->Add(new TObjString("fAliceStopTime"),new TObjString("9999"));
1888
1889   const AliGenerator *gen = gAlice->Generator();
1890   if (gen) {
1891     grpMap->Add(new TObjString("fAliceBeamEnergy"),new TObjString(Form("%f",gen->GetEnergyCMS())));
1892     TString projectile;
1893     Int_t a,z;
1894     gen->GetProjectile(projectile,a,z);
1895     TString target;
1896     gen->GetTarget(target,a,z);
1897     TString beamType = projectile + "-" + target;
1898     if (!beamType.CompareTo("-")) {
1899       grpMap->Add(new TObjString("fAliceBeamType"),new TObjString("UNKNOWN"));
1900     }
1901     else {
1902       grpMap->Add(new TObjString("fAliceBeamType"),new TObjString(beamType.Data()));
1903     }
1904   }
1905   else {
1906     AliWarning("Unknown beam type and energy!");
1907     grpMap->Add(new TObjString("fAliceBeamEnergy"),new TObjString("UNKNOWN"));
1908     grpMap->Add(new TObjString("fAliceBeamType"),new TObjString("0"));
1909   }
1910
1911   UInt_t detectorPattern  = 0;
1912   Int_t nDets = 0;
1913   TObjArray *detArray = gAlice->Detectors();
1914   for (Int_t iDet = 0; iDet < AliDAQ::kNDetectors-1; iDet++) {
1915     if (detArray->FindObject(AliDAQ::OfflineModuleName(iDet))) {
1916       detectorPattern |= (1 << iDet);
1917       nDets++;
1918     }
1919   }
1920   // HLT
1921   if (!fRunHLT.IsNull())
1922     detectorPattern |= (1 << AliDAQ::kHLTId);
1923
1924   grpMap->Add(new TObjString("fNumberOfDetectors"),new TObjString(Form("%d",nDets)));
1925   grpMap->Add(new TObjString("fDetectorMask"),new TObjString(Form("%u",detectorPattern)));
1926  
1927   grpMap->Add(new TObjString("fLHCPeriod"),new TObjString("LHC08c"));
1928
1929   grpMap->Add(new TObjString("fLHCState"),new TObjString("STABLE BEAMS"));
1930   grpMap->Add(new TObjString("fLHCCondition"),new TObjString("0"));
1931   grpMap->Add(new TObjString("fLHCLuminosity"),new TObjString("0"));
1932   grpMap->Add(new TObjString("fBeamIntensity"),new TObjString("0"));
1933
1934   AliMagF *field = gAlice->Field();
1935   Float_t solenoidField = TMath::Abs(field->SolenoidField());
1936   Float_t factor = field->Factor();
1937   Float_t l3current = TMath::Abs(factor)*solenoidField*30000./5.;
1938   grpMap->Add(new TObjString("fL3Current"),new TObjString(Form("%f",l3current)));
1939   
1940   if (factor > 0) {
1941     grpMap->Add(new TObjString("fL3Polarity"),new TObjString("0"));
1942     grpMap->Add(new TObjString("fDipolePolarity"),new TObjString("0"));
1943   }
1944   else {
1945     grpMap->Add(new TObjString("fL3Polarity"),new TObjString("1"));
1946     grpMap->Add(new TObjString("fDipolePolarity"),new TObjString("1"));
1947   }
1948
1949   if (TMath::Abs(factor) != 0)
1950     grpMap->Add(new TObjString("fDipoleCurrent"),new TObjString("6000"));
1951   else 
1952     grpMap->Add(new TObjString("fDipoleCurrent"),new TObjString("0"));
1953
1954   grpMap->Add(new TObjString("fCavernTemperature"),new TObjString("0"));
1955   grpMap->Add(new TObjString("fCavernPressure"),new TObjString("0"));
1956
1957   // Now store the entry in OCDB
1958   AliCDBManager* man = AliCDBManager::Instance();
1959
1960   AliCDBId id("GRP/GRP/Data", man->GetRun(), man->GetRun());
1961   AliCDBMetaData *metadata= new AliCDBMetaData();
1962
1963   metadata->SetResponsible("alice-off@cern.ch");
1964   metadata->SetComment("Automatically produced GRP entry for Monte Carlo");
1965  
1966   man->Put(grpMap,id,metadata);
1967 }