]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliSimulation.cxx
06e8b8a716d8f111aa627f6a3dc6ad9cb2af3f1b
[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
1267     UInt_t detectorPattern = 0;
1268     runLoader->GetEvent(iEvent);
1269     if (!runLoader->LoadTrigger()) {
1270       AliCentralTrigger *aCTP = runLoader->GetTrigger();
1271       detectorPattern = aCTP->GetClusterMask();
1272       // Check if the event was triggered by CTP
1273       if (selrawdata) {
1274         if (aCTP->GetClassMask()) selEvents++;
1275       }
1276     }
1277     else {
1278       AliWarning("No trigger can be loaded! Some fields in the event header will be empty !");
1279       if (selrawdata) {
1280         AliWarning("No trigger can be loaded! Writing of selected raw data is abandoned !");
1281         selrawdata = kFALSE;
1282       }
1283     }
1284
1285     fprintf(pipe, "GDC DetectorPattern %u\n", detectorPattern);
1286     Float_t ldc = 0;
1287     Int_t prevLDC = -1;
1288
1289     // loop over detectors and DDLs
1290     for (Int_t iDet = 0; iDet < AliDAQ::kNDetectors; iDet++) {
1291       for (Int_t iDDL = 0; iDDL < AliDAQ::NumberOfDdls(iDet); iDDL++) {
1292
1293         Int_t ddlID = AliDAQ::DdlID(iDet,iDDL);
1294         Int_t ldcID = Int_t(ldc + 0.0001);
1295         ldc += AliDAQ::NumberOfLdcs(iDet) / AliDAQ::NumberOfDdls(iDet);
1296
1297         char rawFileName[256];
1298         sprintf(rawFileName, "raw%d/%s", 
1299                 iEvent, AliDAQ::DdlFileName(iDet,iDDL));
1300
1301         // check existence and size of raw data file
1302         FILE* file = fopen(rawFileName, "rb");
1303         if (!file) continue;
1304         fseek(file, 0, SEEK_END);
1305         unsigned long size = ftell(file);
1306         fclose(file);
1307         if (!size) continue;
1308
1309         if (ldcID != prevLDC) {
1310           fprintf(pipe, " LDC Id %d\n", ldcID);
1311           prevLDC = ldcID;
1312         }
1313         fprintf(pipe, "  Equipment Id %d Payload %s\n", ddlID, rawFileName);
1314       }
1315     }
1316   }
1317
1318   Int_t result = gSystem->ClosePipe(pipe);
1319
1320   if (!(selrawdata && selEvents > 0)) {
1321     delete runLoader;
1322     return (result == 0);
1323   }
1324
1325   AliInfo(Form("converting selected by trigger cluster raw data DDL files to DATE file %s", selDateFileName));
1326   
1327   sprintf(command, "dateStream -c -s -D -o %s -# %d -C -run %d", 
1328           selDateFileName,selEvents,runLoader->GetHeader()->GetRun());
1329   FILE* pipe2 = gSystem->OpenPipe(command, "w");
1330
1331   for (Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); iEvent++) {
1332
1333     // Get the trigger decision and cluster
1334     UInt_t detectorPattern = 0;
1335     TString detClust;
1336     runLoader->GetEvent(iEvent);
1337     if (!runLoader->LoadTrigger()) {
1338       AliCentralTrigger *aCTP = runLoader->GetTrigger();
1339       if (aCTP->GetClassMask() == 0) continue;
1340       detectorPattern = aCTP->GetClusterMask();
1341       detClust = AliDAQ::ListOfTriggeredDetectors(detectorPattern);
1342       AliInfo(Form("List of detectors to be read out: %s",detClust.Data()));
1343     }
1344
1345     fprintf(pipe2, "GDC DetectorPattern %u\n", detectorPattern);
1346     Float_t ldc = 0;
1347     Int_t prevLDC = -1;
1348
1349     // loop over detectors and DDLs
1350     for (Int_t iDet = 0; iDet < AliDAQ::kNDetectors; iDet++) {
1351       // Write only raw data from detectors that
1352       // are contained in the trigger cluster(s)
1353       if (!IsSelected(AliDAQ::DetectorName(iDet),detClust)) continue;
1354
1355       for (Int_t iDDL = 0; iDDL < AliDAQ::NumberOfDdls(iDet); iDDL++) {
1356
1357         Int_t ddlID = AliDAQ::DdlID(iDet,iDDL);
1358         Int_t ldcID = Int_t(ldc + 0.0001);
1359         ldc += AliDAQ::NumberOfLdcs(iDet) / AliDAQ::NumberOfDdls(iDet);
1360
1361         char rawFileName[256];
1362         sprintf(rawFileName, "raw%d/%s", 
1363                 iEvent, AliDAQ::DdlFileName(iDet,iDDL));
1364
1365         // check existence and size of raw data file
1366         FILE* file = fopen(rawFileName, "rb");
1367         if (!file) continue;
1368         fseek(file, 0, SEEK_END);
1369         unsigned long size = ftell(file);
1370         fclose(file);
1371         if (!size) continue;
1372
1373         if (ldcID != prevLDC) {
1374           fprintf(pipe2, " LDC Id %d\n", ldcID);
1375           prevLDC = ldcID;
1376         }
1377         fprintf(pipe2, "  Equipment Id %d Payload %s\n", ddlID, rawFileName);
1378       }
1379     }
1380   }
1381
1382   Int_t result2 = gSystem->ClosePipe(pipe2);
1383
1384   delete runLoader;
1385   return ((result == 0) && (result2 == 0));
1386 }
1387
1388 //_____________________________________________________________________________
1389 Bool_t AliSimulation::ConvertDateToRoot(const char* dateFileName,
1390                                         const char* rootFileName)
1391 {
1392 // convert a DATE file to a root file with the program "alimdc"
1393
1394   // ALIMDC setup
1395   const Int_t kDBSize = 2000000000;
1396   const Int_t kTagDBSize = 1000000000;
1397   const Bool_t kFilter = kFALSE;
1398   const Int_t kCompression = 1;
1399
1400   char* path = gSystem->Which(gSystem->Getenv("PATH"), "alimdc");
1401   if (!path) {
1402     AliError("the program alimdc was not found");
1403     if (fStopOnError) return kFALSE;
1404   } else {
1405     delete[] path;
1406   }
1407
1408   AliInfo(Form("converting DATE file %s to root file %s", 
1409                dateFileName, rootFileName));
1410
1411   const char* rawDBFS[2] = { "/tmp/mdc1", "/tmp/mdc2" };
1412   const char* tagDBFS    = "/tmp/mdc1/tags";
1413
1414   // User defined file system locations
1415   if (gSystem->Getenv("ALIMDC_RAWDB1")) 
1416     rawDBFS[0] = gSystem->Getenv("ALIMDC_RAWDB1");
1417   if (gSystem->Getenv("ALIMDC_RAWDB2")) 
1418     rawDBFS[1] = gSystem->Getenv("ALIMDC_RAWDB2");
1419   if (gSystem->Getenv("ALIMDC_TAGDB")) 
1420     tagDBFS = gSystem->Getenv("ALIMDC_TAGDB");
1421
1422   gSystem->Exec(Form("rm -rf %s",rawDBFS[0]));
1423   gSystem->Exec(Form("rm -rf %s",rawDBFS[1]));
1424   gSystem->Exec(Form("rm -rf %s",tagDBFS));
1425
1426   gSystem->Exec(Form("mkdir %s",rawDBFS[0]));
1427   gSystem->Exec(Form("mkdir %s",rawDBFS[1]));
1428   gSystem->Exec(Form("mkdir %s",tagDBFS));
1429
1430   Int_t result = gSystem->Exec(Form("alimdc %d %d %d %d %s", 
1431                                     kDBSize, kTagDBSize, kFilter, kCompression, dateFileName));
1432   gSystem->Exec(Form("mv %s/*.root %s", rawDBFS[0], rootFileName));
1433
1434   gSystem->Exec(Form("rm -rf %s",rawDBFS[0]));
1435   gSystem->Exec(Form("rm -rf %s",rawDBFS[1]));
1436   gSystem->Exec(Form("rm -rf %s",tagDBFS));
1437
1438   return (result == 0);
1439 }
1440
1441
1442 //_____________________________________________________________________________
1443 AliRunLoader* AliSimulation::LoadRun(const char* mode) const
1444 {
1445 // delete existing run loaders, open a new one and load gAlice
1446
1447   while (AliRunLoader::GetRunLoader()) delete AliRunLoader::GetRunLoader();
1448   AliRunLoader* runLoader = 
1449     AliRunLoader::Open(fGAliceFileName.Data(), 
1450                        AliConfig::GetDefaultEventFolderName(), mode);
1451   if (!runLoader) {
1452     AliError(Form("no run loader found in file %s", fGAliceFileName.Data()));
1453     return NULL;
1454   }
1455   runLoader->LoadgAlice();
1456   runLoader->LoadHeader();
1457   gAlice = runLoader->GetAliRun();
1458   if (!gAlice) {
1459     AliError(Form("no gAlice object found in file %s", 
1460                   fGAliceFileName.Data()));
1461     return NULL;
1462   }
1463   return runLoader;
1464 }
1465
1466 //_____________________________________________________________________________
1467 Int_t AliSimulation::GetNSignalPerBkgrd(Int_t nEvents) const
1468 {
1469 // get or calculate the number of signal events per background event
1470
1471   if (!fBkgrdFileNames) return 1;
1472   Int_t nBkgrdFiles = fBkgrdFileNames->GetEntriesFast();
1473   if (nBkgrdFiles == 0) return 1;
1474
1475   // get the number of signal events
1476   if (nEvents <= 0) {
1477     AliRunLoader* runLoader = 
1478         AliRunLoader::Open(fGAliceFileName.Data(), "SIGNAL");
1479     if (!runLoader) return 1;
1480     
1481     nEvents = runLoader->GetNumberOfEvents();
1482     delete runLoader;
1483   }
1484
1485   Int_t result = 0;
1486   for (Int_t iBkgrdFile = 0; iBkgrdFile < nBkgrdFiles; iBkgrdFile++) {
1487     // get the number of background events
1488     const char* fileName = ((TObjString*)
1489                             (fBkgrdFileNames->At(iBkgrdFile)))->GetName();
1490     AliRunLoader* runLoader =
1491       AliRunLoader::Open(fileName, "BKGRD");
1492     if (!runLoader) continue;
1493     Int_t nBkgrdEvents = runLoader->GetNumberOfEvents();
1494     delete runLoader;
1495   
1496     // get or calculate the number of signal per background events
1497     Int_t nSignalPerBkgrd = fBkgrdFileNames->At(iBkgrdFile)->GetUniqueID();
1498     if (nSignalPerBkgrd <= 0) {
1499       nSignalPerBkgrd = (nEvents-1) / nBkgrdEvents + 1;
1500     } else if (result && (result != nSignalPerBkgrd)) {
1501       AliInfo(Form("the number of signal events per background event "
1502                    "will be changed from %d to %d for stream %d", 
1503                    nSignalPerBkgrd, result, iBkgrdFile+1));
1504       nSignalPerBkgrd = result;
1505     }
1506
1507     if (!result) result = nSignalPerBkgrd;
1508     if (nSignalPerBkgrd * nBkgrdEvents < nEvents) {
1509       AliWarning(Form("not enough background events (%d) for %d signal events "
1510                       "using %d signal per background events for stream %d",
1511                       nBkgrdEvents, nEvents, nSignalPerBkgrd, iBkgrdFile+1));
1512     }
1513   }
1514
1515   return result;
1516 }
1517
1518 //_____________________________________________________________________________
1519 Bool_t AliSimulation::IsSelected(TString detName, TString& detectors) const
1520 {
1521 // check whether detName is contained in detectors
1522 // if yes, it is removed from detectors
1523
1524   // check if all detectors are selected
1525   if ((detectors.CompareTo("ALL") == 0) ||
1526       detectors.BeginsWith("ALL ") ||
1527       detectors.EndsWith(" ALL") ||
1528       detectors.Contains(" ALL ")) {
1529     detectors = "ALL";
1530     return kTRUE;
1531   }
1532
1533   // search for the given detector
1534   Bool_t result = kFALSE;
1535   if ((detectors.CompareTo(detName) == 0) ||
1536       detectors.BeginsWith(detName+" ") ||
1537       detectors.EndsWith(" "+detName) ||
1538       detectors.Contains(" "+detName+" ")) {
1539     detectors.ReplaceAll(detName, "");
1540     result = kTRUE;
1541   }
1542
1543   // clean up the detectors string
1544   while (detectors.Contains("  ")) detectors.ReplaceAll("  ", " ");
1545   while (detectors.BeginsWith(" ")) detectors.Remove(0, 1);
1546   while (detectors.EndsWith(" ")) detectors.Remove(detectors.Length()-1, 1);
1547
1548   return result;
1549 }
1550
1551 //_____________________________________________________________________________
1552 Bool_t AliSimulation::ConvertRaw2SDigits(const char* rawDirectory, const char* esdFileName) 
1553 {
1554 //
1555 // Steering routine  to convert raw data in directory rawDirectory/ to fake SDigits. 
1556 // These can be used for embedding of MC tracks into RAW data using the standard 
1557 // merging procedure.
1558 //
1559 // If an ESD file is given the reconstructed vertex is taken from it and stored in the event header.
1560 //
1561     if (!gAlice) {
1562         AliError("no gAlice object. Restart aliroot and try again.");
1563         return kFALSE;
1564     }
1565     if (gAlice->Modules()->GetEntries() > 0) {
1566         AliError("gAlice was already run. Restart aliroot and try again.");
1567         return kFALSE;
1568     }
1569     
1570     AliInfo(Form("initializing gAlice with config file %s",fConfigFileName.Data()));
1571     StdoutToAliInfo(StderrToAliError(gAlice->Init(fConfigFileName.Data());););
1572 //
1573 //  Initialize CDB     
1574     InitCDB();
1575     //AliCDBManager* man = AliCDBManager::Instance();
1576     //man->SetRun(0); // Should this come from rawdata header ?
1577     
1578     Int_t iDet;
1579     //
1580     // Get the runloader
1581     AliRunLoader* runLoader = gAlice->GetRunLoader();
1582     //
1583     // Open esd file if available
1584     TFile* esdFile = TFile::Open(esdFileName);
1585     Bool_t esdOK = (esdFile != 0);
1586     AliESD* esd = new AliESD;
1587     TTree* treeESD = 0;
1588     if (esdOK) {
1589         treeESD = (TTree*) esdFile->Get("esdTree");
1590         if (!treeESD) {
1591             AliWarning("No ESD tree found");
1592             esdOK = kFALSE;
1593         } else {
1594             treeESD->SetBranchAddress("ESD", &esd);
1595         }
1596     }
1597     //
1598     // Create the RawReader
1599     TString fileName(rawDirectory);
1600     AliRawReader* rawReader = 0x0;
1601     if (fileName.EndsWith("/")) {
1602       rawReader = new AliRawReaderFile(fileName);
1603     } else if (fileName.EndsWith(".root")) {
1604       rawReader = new AliRawReaderRoot(fileName);
1605     } else if (!fileName.IsNull()) {
1606       rawReader = new AliRawReaderDate(fileName);
1607     }
1608 //     if (!fEquipIdMap.IsNull() && fRawReader)
1609 //       fRawReader->LoadEquipmentIdsMap(fEquipIdMap);
1610     //
1611     // Get list of detectors
1612     TObjArray* detArray = runLoader->GetAliRun()->Detectors();
1613     //
1614     // Get Header
1615     AliHeader* header = runLoader->GetHeader();
1616     //
1617     TString detStr = fMakeSDigits;
1618     // Event loop
1619     Int_t nev = 0;
1620     while(kTRUE) {
1621         if (!(rawReader->NextEvent())) break;
1622         //
1623         // Detector loop
1624         for (iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
1625             AliModule* det = (AliModule*) detArray->At(iDet);
1626             if (!det || !det->IsActive()) continue;
1627             if (IsSelected(det->GetName(), detStr)) {
1628               AliInfo(Form("Calling Raw2SDigits for %s\n", det->GetName()));
1629               det->Raw2SDigits(rawReader);
1630               rawReader->Reset();
1631             }
1632         } // detectors
1633
1634
1635         //
1636         //  If ESD information available obtain reconstructed vertex and store in header.
1637         if (esdOK) {
1638             treeESD->GetEvent(nev);
1639             const AliESDVertex* esdVertex = esd->GetPrimaryVertex();
1640             Double_t position[3];
1641             esdVertex->GetXYZ(position);
1642             AliGenEventHeader* mcHeader = new  AliGenEventHeader("ESD");
1643             TArrayF mcV;
1644             mcV.Set(3);
1645             for (Int_t i = 0; i < 3; i++) mcV[i] = position[i];
1646             mcHeader->SetPrimaryVertex(mcV);
1647             header->Reset(0,nev);
1648             header->SetGenEventHeader(mcHeader);
1649             printf("***** Saved vertex %f %f %f \n", position[0], position[1], position[2]);
1650         }
1651         nev++;
1652 //
1653 //      Finish the event
1654         runLoader->TreeE()->Fill();
1655         runLoader->SetNextEvent();
1656     } // events
1657  
1658     delete rawReader;
1659 //
1660 //  Finish the run 
1661     runLoader->CdGAFile();
1662     runLoader->WriteHeader("OVERWRITE");
1663     runLoader->WriteRunLoader();
1664
1665     return kTRUE;
1666 }
1667
1668 //_____________________________________________________________________________
1669 Int_t AliSimulation::GetDetIndex(const char* detector)
1670 {
1671   // return the detector index corresponding to detector
1672   Int_t index = -1 ; 
1673   for (index = 0; index < fgkNDetectors ; index++) {
1674     if ( strcmp(detector, fgkDetectorName[index]) == 0 )
1675           break ; 
1676   }     
1677   return index ; 
1678 }
1679
1680 //_____________________________________________________________________________
1681 Bool_t AliSimulation::RunHLT()
1682 {
1683   // Run the HLT simulation
1684   // HLT simulation is implemented in HLT/sim/AliHLTSimulation
1685   // Disabled if fRunHLT is empty, default vaule is "default".
1686   // AliSimulation::SetRunHLT can be used to set the options for HLT simulation
1687   // The default simulation depends on the HLT component libraries and their
1688   // corresponding agents which define components and chains to run. See
1689   // http://web.ift.uib.no/~kjeks/doc/alice-hlt/
1690   // http://web.ift.uib.no/~kjeks/doc/alice-hlt/classAliHLTModuleAgent.html
1691   //
1692   // The libraries to be loaded can be specified as an option.
1693   // <pre>
1694   // AliSimulation sim;
1695   // sim.SetRunHLT("libAliHLTSample.so");
1696   // </pre>
1697   // will only load <tt>libAliHLTSample.so</tt>
1698
1699   // Other available options:
1700   // \li loglevel=<i>level</i> <br>
1701   //     logging level for this processing
1702   // \li alilog=off
1703   //     disable redirection of log messages to AliLog class
1704   // \li config=<i>macro</i>
1705   //     configuration macro
1706   // \li localrec=<i>configuration</i>
1707   //     comma separated list of configurations to be run during simulation
1708
1709   int iResult=0;
1710   AliRunLoader* pRunLoader = LoadRun("READ");
1711   if (!pRunLoader) return kFALSE;
1712
1713   // initialize CDB storage, run number, set CDB lock
1714   InitCDB();
1715   if (!SetRunNumberFromData()) if (fStopOnError) return kFALSE;
1716   SetCDBLock();
1717   
1718   // load the library dynamically
1719   gSystem->Load(ALIHLTSIMULATION_LIBRARY);
1720
1721   // check for the library version
1722   AliHLTSimulationGetLibraryVersion_t fctVersion=(AliHLTSimulationGetLibraryVersion_t)(gSystem->DynFindSymbol(ALIHLTSIMULATION_LIBRARY, ALIHLTSIMULATION_GET_LIBRARY_VERSION));
1723   if (!fctVersion) {
1724     AliError(Form("can not load library %s", ALIHLTSIMULATION_LIBRARY));
1725     return kFALSE;
1726   }
1727   if (fctVersion()!= ALIHLTSIMULATION_LIBRARY_VERSION) {
1728     AliError(Form("%s version does not match: compiled for version %d, loaded %d", ALIHLTSIMULATION_LIBRARY, ALIHLTSIMULATION_LIBRARY_VERSION, fctVersion()));
1729     return kFALSE;
1730   }
1731
1732   // print compile info
1733   typedef void (*CompileInfo)( char*& date, char*& time);
1734   CompileInfo fctInfo=(CompileInfo)gSystem->DynFindSymbol(ALIHLTSIMULATION_LIBRARY, "CompileInfo");
1735   if (fctInfo) {
1736     char* date="";
1737     char* time="";
1738     (*fctInfo)(date, time);
1739     if (!date) date="unknown";
1740     if (!time) time="unknown";
1741     AliInfo(Form("%s build on %s (%s)", ALIHLTSIMULATION_LIBRARY, date, time));
1742   } else {
1743     AliInfo(Form("no build info available for %s", ALIHLTSIMULATION_LIBRARY));
1744   }
1745
1746   // create instance of the HLT simulation
1747   AliHLTSimulationCreateInstance_t fctCreate=(AliHLTSimulationCreateInstance_t)(gSystem->DynFindSymbol(ALIHLTSIMULATION_LIBRARY, ALIHLTSIMULATION_CREATE_INSTANCE));
1748   AliHLTSimulation* pHLT=NULL;
1749   if (fctCreate==NULL || (pHLT=(fctCreate()))==NULL) {
1750     AliError(Form("can not create instance of HLT simulation (creator %p)", fctCreate));
1751     return kFALSE;    
1752   }
1753
1754   // init the HLT simulation
1755   TString options;
1756   if (fRunHLT.CompareTo("default")!=0) options=fRunHLT;
1757   if (!IsSelected("HLT", fWriteRawData)) {
1758     options+=" writerawfiles=";
1759   } else {
1760     options+=" writerawfiles=HLT";
1761   }
1762   AliHLTSimulationInit_t fctInit=(AliHLTSimulationInit_t)(gSystem->DynFindSymbol(ALIHLTSIMULATION_LIBRARY, ALIHLTSIMULATION_INIT));
1763   if (fctInit==NULL || (iResult=(fctInit(pHLT, pRunLoader, options.Data())))<0) {
1764     AliError(Form("can not init HLT simulation: error %d (init %p)", iResult, fctInit));
1765   } else {
1766     // run the HLT simulation
1767     AliHLTSimulationRun_t fctRun=(AliHLTSimulationRun_t)(gSystem->DynFindSymbol(ALIHLTSIMULATION_LIBRARY, ALIHLTSIMULATION_RUN));
1768     if (fctRun==NULL || (iResult=(fctRun(pHLT, pRunLoader)))<0) {
1769       AliError(Form("can not run HLT simulation: error %d (run %p)", iResult, fctRun));
1770     }
1771   }
1772
1773   // delete the instance
1774   AliHLTSimulationDeleteInstance_t fctDelete=(AliHLTSimulationDeleteInstance_t)(gSystem->DynFindSymbol(ALIHLTSIMULATION_LIBRARY, ALIHLTSIMULATION_DELETE_INSTANCE));
1775   if (fctDelete==NULL || fctDelete(pHLT)<0) {
1776     AliError(Form("can not delete instance of HLT simulation (creator %p)", fctDelete));
1777   }
1778   pHLT=NULL;
1779
1780   return iResult>=0?kTRUE:kFALSE;
1781 }
1782
1783 //_____________________________________________________________________________
1784 Bool_t AliSimulation::RunQA()
1785 {
1786         // run the QA on summable hits, digits or digits
1787         
1788         fQASteer->SetRunLoader(gAlice->GetRunLoader()) ;
1789
1790         TString detectorsw("") ;  
1791         Bool_t rv = kTRUE ; 
1792         detectorsw = fQASteer->Run(fQADetectors.Data()) ; 
1793         if ( detectorsw.IsNull() ) 
1794                 rv = kFALSE ; 
1795         return rv ; 
1796 }
1797
1798 //_____________________________________________________________________________
1799 Bool_t AliSimulation::SetRunQA(TString detAndAction) 
1800 {
1801         // Allows to run QA for a selected set of detectors
1802         // and a selected set of tasks among HITS, SDIGITS and DIGITS
1803         // all selected detectors run the same selected tasks
1804         
1805         if (!detAndAction.Contains(":")) {
1806                 AliError( Form("%s is a wrong syntax, use \"DetectorList:ActionList\" \n", detAndAction.Data()) ) ;
1807                 fRunQA = kFALSE ;
1808                 return kFALSE ;                 
1809         }
1810         Int_t colon = detAndAction.Index(":") ; 
1811         fQADetectors = detAndAction(0, colon) ; 
1812         if (fQADetectors.Contains("ALL") )
1813                 fQADetectors = Form("%s %s", fMakeDigits.Data(), fMakeDigitsFromHits.Data()) ; 
1814                 fQATasks   = detAndAction(colon+1, detAndAction.Sizeof() ) ; 
1815         if (fQATasks.Contains("ALL") ) {
1816                 fQATasks = Form("%d %d %d", AliQA::kHITS, AliQA::kSDIGITS, AliQA::kDIGITS) ; 
1817         } else {
1818                 fQATasks.ToUpper() ; 
1819                 TString tempo("") ; 
1820                 if ( fQATasks.Contains("HIT") ) 
1821                         tempo = Form("%d ", AliQA::kHITS) ; 
1822                 if ( fQATasks.Contains("SDIGIT") ) 
1823                         tempo += Form("%d ", AliQA::kSDIGITS) ; 
1824                 if ( fQATasks.Contains("DIGIT") ) 
1825                         tempo += Form("%d ", AliQA::kDIGITS) ; 
1826                 fQATasks = tempo ; 
1827                 if (fQATasks.IsNull()) {
1828                         AliInfo("No QA requested\n")  ;
1829                         fRunQA = kFALSE ;
1830                         return kTRUE ; 
1831                 }
1832         }       
1833         TString tempo(fQATasks) ; 
1834     tempo.ReplaceAll(Form("%d", AliQA::kHITS), AliQA::GetTaskName(AliQA::kHITS))        ;
1835     tempo.ReplaceAll(Form("%d", AliQA::kSDIGITS), AliQA::GetTaskName(AliQA::kSDIGITS)) ;        
1836     tempo.ReplaceAll(Form("%d", AliQA::kDIGITS), AliQA::GetTaskName(AliQA::kDIGITS)) ;  
1837         AliInfo( Form("QA will be done on \"%s\" for \"%s\"\n", fQADetectors.Data(), tempo.Data()) ) ;  
1838         fRunQA = kTRUE ;
1839         fQASteer->SetActiveDetectors(fQADetectors) ; 
1840         fQASteer->SetTasks(fQATasks) ; 
1841         return kTRUE; 
1842
1843
1844 //_____________________________________________________________________________
1845 void AliSimulation::ProcessEnvironmentVars()
1846 {
1847 // Extract run number and random generator seed from env variables
1848
1849     AliInfo("Processing environment variables");
1850     
1851     // Random Number seed
1852     
1853     // first check that seed is not already set
1854     if (fSeed == 0) {
1855         if (gSystem->Getenv("CONFIG_SEED")) {
1856                 fSeed = atoi(gSystem->Getenv("CONFIG_SEED"));
1857         }
1858     } else {
1859         if (gSystem->Getenv("CONFIG_SEED")) {
1860                 AliInfo(Form("Seed for random number generation already set (%d)"
1861                              ": CONFIG_SEED variable ignored!", fSeed));
1862         }
1863     }
1864    
1865     AliInfo(Form("Seed for random number generation = %d ", fSeed)); 
1866
1867     // Run Number
1868     
1869     // first check that run number is not already set
1870     if(fRun < 0) {    
1871         if (gSystem->Getenv("DC_RUN")) {
1872                 fRun = atoi(gSystem->Getenv("DC_RUN"));
1873         }
1874     } else {
1875         if (gSystem->Getenv("DC_RUN")) {
1876                 AliInfo(Form("Run number already set (%d): DC_RUN variable ignored!", fRun));
1877         }
1878     }
1879     
1880     AliInfo(Form("Run number = %d", fRun)); 
1881 }
1882
1883 //_____________________________________________________________________________
1884 void AliSimulation::WriteGRPEntry()
1885 {
1886   // Get the necessary information from galice (generator, trigger etc) and
1887   // write a GRP entry corresponding to the settings in the Config.C used
1888   AliInfo("Writing global run parameters entry into the OCDB");
1889
1890   TMap *grpMap = new TMap();
1891   grpMap->SetName("MONTECARLO");
1892
1893   grpMap->Add(new TObjString("fRunType"),new TObjString("PHYSICS"));
1894   grpMap->Add(new TObjString("fAliceStartTime"),new TObjString("0"));
1895   grpMap->Add(new TObjString("fAliceStopTime"),new TObjString("9999"));
1896
1897   const AliGenerator *gen = gAlice->Generator();
1898   if (gen) {
1899     grpMap->Add(new TObjString("fAliceBeamEnergy"),new TObjString(Form("%f",gen->GetEnergyCMS())));
1900     TString projectile;
1901     Int_t a,z;
1902     gen->GetProjectile(projectile,a,z);
1903     TString target;
1904     gen->GetTarget(target,a,z);
1905     TString beamType = projectile + "-" + target;
1906     if (!beamType.CompareTo("-")) {
1907       grpMap->Add(new TObjString("fAliceBeamType"),new TObjString("UNKNOWN"));
1908     }
1909     else {
1910       grpMap->Add(new TObjString("fAliceBeamType"),new TObjString(beamType.Data()));
1911     }
1912   }
1913   else {
1914     AliWarning("Unknown beam type and energy!");
1915     grpMap->Add(new TObjString("fAliceBeamEnergy"),new TObjString("UNKNOWN"));
1916     grpMap->Add(new TObjString("fAliceBeamType"),new TObjString("0"));
1917   }
1918
1919   UInt_t detectorPattern  = 0;
1920   Int_t nDets = 0;
1921   TObjArray *detArray = gAlice->Detectors();
1922   for (Int_t iDet = 0; iDet < AliDAQ::kNDetectors-1; iDet++) {
1923     if (detArray->FindObject(AliDAQ::OfflineModuleName(iDet))) {
1924       detectorPattern |= (1 << iDet);
1925       nDets++;
1926     }
1927   }
1928   // HLT
1929   if (!fRunHLT.IsNull())
1930     detectorPattern |= (1 << AliDAQ::kHLTId);
1931
1932   grpMap->Add(new TObjString("fNumberOfDetectors"),new TObjString(Form("%d",nDets)));
1933   grpMap->Add(new TObjString("fDetectorMask"),new TObjString(Form("%u",detectorPattern)));
1934  
1935   grpMap->Add(new TObjString("fLHCPeriod"),new TObjString("LHC08c"));
1936
1937   grpMap->Add(new TObjString("fLHCState"),new TObjString("STABLE BEAMS"));
1938   grpMap->Add(new TObjString("fLHCCondition"),new TObjString("0"));
1939   grpMap->Add(new TObjString("fLHCLuminosity"),new TObjString("0"));
1940   grpMap->Add(new TObjString("fBeamIntensity"),new TObjString("0"));
1941
1942   AliMagF *field = gAlice->Field();
1943   Float_t solenoidField = TMath::Abs(field->SolenoidField());
1944   Float_t factor = field->Factor();
1945   Float_t l3current = TMath::Abs(factor)*solenoidField*30000./5.;
1946   grpMap->Add(new TObjString("fL3Current"),new TObjString(Form("%f",l3current)));
1947   
1948   if (factor > 0) {
1949     grpMap->Add(new TObjString("fL3Polarity"),new TObjString("0"));
1950     grpMap->Add(new TObjString("fDipolePolarity"),new TObjString("0"));
1951   }
1952   else {
1953     grpMap->Add(new TObjString("fL3Polarity"),new TObjString("1"));
1954     grpMap->Add(new TObjString("fDipolePolarity"),new TObjString("1"));
1955   }
1956
1957   if (TMath::Abs(factor) != 0)
1958     grpMap->Add(new TObjString("fDipoleCurrent"),new TObjString("6000"));
1959   else 
1960     grpMap->Add(new TObjString("fDipoleCurrent"),new TObjString("0"));
1961
1962   grpMap->Add(new TObjString("fCavernTemperature"),new TObjString("0"));
1963   grpMap->Add(new TObjString("fCavernPressure"),new TObjString("0"));
1964
1965   // Now store the entry in OCDB
1966   AliCDBManager* man = AliCDBManager::Instance();
1967
1968   AliCDBId id("GRP/GRP/Data", man->GetRun(), man->GetRun());
1969   AliCDBMetaData *metadata= new AliCDBMetaData();
1970
1971   metadata->SetResponsible("alice-off@cern.ch");
1972   metadata->SetComment("Automatically produced GRP entry for Monte Carlo");
1973  
1974   man->Put(grpMap,id,metadata);
1975 }