]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliSimulation.cxx
The standalone QA data maker is called from AliSimulation and AliReconstruction outsi...
[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
114 #include "AliCodeTimer.h"
115 #include "AliCDBStorage.h"
116 #include "AliCDBEntry.h"
117 #include "AliCDBManager.h"
118 #include "AliGeomManager.h"
119 #include "AliAlignObj.h"
120 #include "AliCentralTrigger.h"
121 #include "AliDAQ.h"
122 #include "AliDigitizer.h"
123 #include "AliGenerator.h"
124 #include "AliLog.h"
125 #include "AliModule.h"
126 #include "AliRun.h"
127 #include "AliRunDigitizer.h"
128 #include "AliRunLoader.h"
129 #include "AliSimulation.h"
130 #include "AliVertexGenFile.h"
131 #include "AliCentralTrigger.h"
132 #include "AliCTPRawData.h"
133 #include "AliRawReaderFile.h"
134 #include "AliRawReaderRoot.h"
135 #include "AliRawReaderDate.h"
136 #include "AliESD.h"
137 #include "AliHeader.h"
138 #include "AliGenEventHeader.h"
139 #include "AliMC.h"
140 #include "AliHLTSimulation.h"
141 #include "AliQA.h"
142 #include "AliQADataMakerSteer.h"
143
144 ClassImp(AliSimulation)
145
146 AliSimulation *AliSimulation::fgInstance = 0;
147 const char* AliSimulation::fgkDetectorName[AliSimulation::fgkNDetectors] = {"ITS", "TPC", "TRD", "TOF", "PHOS", "HMPID", "EMCAL", "MUON", "FMD", "ZDC", "PMD", "T0", "VZERO", "ACORDE", "HLT"};
148
149 //_____________________________________________________________________________
150 AliSimulation::AliSimulation(const char* configFileName, const char* cdbUri,
151                              const char* name, const char* title) :
152   TNamed(name, title),
153
154   fRunGeneration(kTRUE),
155   fRunSimulation(kTRUE),
156   fLoadAlignFromCDB(kTRUE),
157   fLoadAlObjsListOfDets("ALL"),
158   fMakeSDigits("ALL"),
159   fMakeDigits("ALL"),
160   fMakeTrigger(""),
161   fMakeDigitsFromHits(""),
162   fWriteRawData(""),
163   fRawDataFileName(""),
164   fDeleteIntermediateFiles(kFALSE),
165   fStopOnError(kFALSE),
166
167   fNEvents(1),
168   fConfigFileName(configFileName),
169   fGAliceFileName("galice.root"),
170   fEventsPerFile(),
171   fBkgrdFileNames(NULL),
172   fAlignObjArray(NULL),
173   fUseBkgrdVertex(kTRUE),
174   fRegionOfInterest(kFALSE),
175   fCDBUri(cdbUri),
176   fRemoteCDBUri(""),
177   fSpecCDBUri(),
178   fEmbeddingFlag(kFALSE),
179   fRunHLT("default")
180 {
181 // create simulation object with default parameters
182   fgInstance = this;
183   SetGAliceFile("galice.root");
184   
185 // for QA
186    for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) 
187         fQACycles[iDet] = 999999;
188 }
189
190 //_____________________________________________________________________________
191 AliSimulation::AliSimulation(const AliSimulation& sim) :
192   TNamed(sim),
193
194   fRunGeneration(sim.fRunGeneration),
195   fRunSimulation(sim.fRunSimulation),
196   fLoadAlignFromCDB(sim.fLoadAlignFromCDB),
197   fLoadAlObjsListOfDets(sim.fLoadAlObjsListOfDets),
198   fMakeSDigits(sim.fMakeSDigits),
199   fMakeDigits(sim.fMakeDigits),
200   fMakeTrigger(sim.fMakeTrigger),
201   fMakeDigitsFromHits(sim.fMakeDigitsFromHits),
202   fWriteRawData(sim.fWriteRawData),
203   fRawDataFileName(""),
204   fDeleteIntermediateFiles(kFALSE),
205   fStopOnError(sim.fStopOnError),
206
207   fNEvents(sim.fNEvents),
208   fConfigFileName(sim.fConfigFileName),
209   fGAliceFileName(sim.fGAliceFileName),
210   fEventsPerFile(),
211   fBkgrdFileNames(NULL),
212   fAlignObjArray(NULL),
213   fUseBkgrdVertex(sim.fUseBkgrdVertex),
214   fRegionOfInterest(sim.fRegionOfInterest),
215   fCDBUri(sim.fCDBUri),
216   fRemoteCDBUri(sim.fRemoteCDBUri),
217   fSpecCDBUri(),
218   fEmbeddingFlag(sim.fEmbeddingFlag),
219   fRunHLT(sim.fRunHLT)
220 {
221 // copy constructor
222
223   for (Int_t i = 0; i < sim.fEventsPerFile.GetEntriesFast(); i++) {
224     if (!sim.fEventsPerFile[i]) continue;
225     fEventsPerFile.Add(sim.fEventsPerFile[i]->Clone());
226   }
227
228   fBkgrdFileNames = new TObjArray;
229   for (Int_t i = 0; i < sim.fBkgrdFileNames->GetEntriesFast(); i++) {
230     if (!sim.fBkgrdFileNames->At(i)) continue;
231     fBkgrdFileNames->Add(sim.fBkgrdFileNames->At(i)->Clone());
232   }
233
234   for (Int_t i = 0; i < sim.fSpecCDBUri.GetEntriesFast(); i++) {
235     if (sim.fSpecCDBUri[i]) fSpecCDBUri.Add(sim.fSpecCDBUri[i]->Clone());
236   }
237   fgInstance = this;
238
239 // for QA
240    for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) 
241         fQACycles[iDet] = sim.fQACycles[iDet];
242 }
243
244 //_____________________________________________________________________________
245 AliSimulation& AliSimulation::operator = (const AliSimulation& sim)
246 {
247 // assignment operator
248
249   this->~AliSimulation();
250   new(this) AliSimulation(sim);
251   return *this;
252 }
253
254 //_____________________________________________________________________________
255 AliSimulation::~AliSimulation()
256 {
257 // clean up
258
259   fEventsPerFile.Delete();
260 //  if(fAlignObjArray) fAlignObjArray->Delete(); // fAlignObjArray->RemoveAll() ???
261 //  delete fAlignObjArray; fAlignObjArray=0;
262
263   if (fBkgrdFileNames) {
264     fBkgrdFileNames->Delete();
265     delete fBkgrdFileNames;
266   }
267
268   fSpecCDBUri.Delete();
269   if (fgInstance==this) fgInstance = 0;
270
271   AliCodeTimer::Instance()->Print();
272 }
273
274
275 //_____________________________________________________________________________
276 void AliSimulation::SetNumberOfEvents(Int_t nEvents)
277 {
278 // set the number of events for one run
279
280   fNEvents = nEvents;
281 }
282
283 //_____________________________________________________________________________
284 void AliSimulation::InitCDBStorage()
285 {
286 // activate a default CDB storage
287 // First check if we have any CDB storage set, because it is used 
288 // to retrieve the calibration and alignment constants
289
290   AliCDBManager* man = AliCDBManager::Instance();
291   if (man->IsDefaultStorageSet())
292   {
293     AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
294     AliWarning("Default CDB storage has been already set !");
295     AliWarning(Form("Ignoring the default storage declared in AliSimulation: %s",fCDBUri.Data()));
296     AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
297     fCDBUri = "";
298   }
299   else {
300     AliDebug(2,"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
301     AliDebug(2, Form("Default CDB storage is set to: %s",fCDBUri.Data()));
302     AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
303     man->SetDefaultStorage(fCDBUri);
304   }
305
306   // Remote storage (the Grid storage) is used if it is activated
307   // and if the object is not found in the default storage
308   // OBSOLETE: Removed
309   //   if (man->IsRemoteStorageSet())
310   //   {
311   //     AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
312   //     AliWarning("Remote CDB storage has been already set !");
313   //     AliWarning(Form("Ignoring the remote storage declared in AliSimulation: %s",fRemoteCDBUri.Data()));
314   //     AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
315   //     fRemoteCDBUri = "";
316   //   }
317   //   else {
318   //     AliDebug(2,"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
319   //     AliDebug(2, Form("Remote CDB storage is set to: %s",fRemoteCDBUri.Data()));
320   //     AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
321   //     man->SetRemoteStorage(fRemoteCDBUri);
322   //   }
323
324   // Now activate the detector specific CDB storage locations
325   for (Int_t i = 0; i < fSpecCDBUri.GetEntriesFast(); i++) {
326     TObject* obj = fSpecCDBUri[i];
327     if (!obj) continue;
328     AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
329     AliDebug(2, Form("Specific CDB storage for %s is set to: %s",obj->GetName(),obj->GetTitle()));
330     AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
331     man->SetSpecificStorage(obj->GetName(), obj->GetTitle());
332   }
333   man->Print();
334 }
335
336 //_____________________________________________________________________________
337 void AliSimulation::SetDefaultStorage(const char* uri) {
338 // Store the desired default CDB storage location
339 // Activate it later within the Run() method
340
341   fCDBUri = uri;
342
343 }
344
345 //_____________________________________________________________________________
346 void AliSimulation::SetRemoteStorage(const char* uri) {
347 // Store the desired remote CDB storage location
348 // Activate it later within the Run() method
349 // Remote storage (the Grid storage) is used if it is activated
350 // and if the object is not found in the default storage (the local cache)
351
352   fRemoteCDBUri = uri;
353
354 }
355
356 //_____________________________________________________________________________
357 void AliSimulation::SetSpecificStorage(const char* calibType, const char* uri) {
358 // Store a detector-specific CDB storage location
359 // Activate it later within the Run() method
360
361   AliCDBPath aPath(calibType);
362   if(!aPath.IsValid()){
363         AliError(Form("Not a valid path: %s", calibType));
364         return;
365   }
366
367   TObject* obj = fSpecCDBUri.FindObject(calibType);
368   if (obj) fSpecCDBUri.Remove(obj);
369   fSpecCDBUri.Add(new TNamed(calibType, uri));
370
371 }
372
373 //_____________________________________________________________________________
374 void AliSimulation::SetConfigFile(const char* fileName)
375 {
376 // set the name of the config file
377
378   fConfigFileName = fileName;
379 }
380
381 //_____________________________________________________________________________
382 void AliSimulation::SetGAliceFile(const char* fileName)
383 {
384 // set the name of the galice file
385 // the path is converted to an absolute one if it is relative
386
387   fGAliceFileName = fileName;
388   if (!gSystem->IsAbsoluteFileName(fGAliceFileName)) {
389     char* absFileName = gSystem->ConcatFileName(gSystem->WorkingDirectory(),
390                                                 fGAliceFileName);
391     fGAliceFileName = absFileName;
392     delete[] absFileName;
393   }
394
395   AliDebug(2, Form("galice file name set to %s", fileName));
396 }
397
398 //_____________________________________________________________________________
399 void AliSimulation::SetEventsPerFile(const char* detector, const char* type, 
400                                      Int_t nEvents)
401 {
402 // set the number of events per file for the given detector and data type
403 // ("Hits", "Summable Digits", "Digits", "Reconstructed Points" or "Tracks")
404
405   TNamed* obj = new TNamed(detector, type);
406   obj->SetUniqueID(nEvents);
407   fEventsPerFile.Add(obj);
408 }
409
410 //_____________________________________________________________________________
411 Bool_t AliSimulation::MisalignGeometry(AliRunLoader *runLoader)
412 {
413   // Read the alignment objects from CDB.
414   // Each detector is supposed to have the
415   // alignment objects in DET/Align/Data CDB path.
416   // All the detector objects are then collected,
417   // sorted by geometry level (starting from ALIC) and
418   // then applied to the TGeo geometry.
419   // Finally an overlaps check is performed.
420
421   if (!AliGeomManager::GetGeometry() || !AliGeomManager::GetGeometry()->IsClosed()) {
422     AliError("Can't apply the misalignment! Geometry is not loaded or it is still opened!");
423     return kFALSE;
424   }  
425   Bool_t delRunLoader = kFALSE;
426   if (!runLoader) {
427     runLoader = LoadRun("READ");
428     if (!runLoader) return kFALSE;
429     delRunLoader = kTRUE;
430   }
431
432   // Export ideal geometry 
433   if(!gAlice->IsRootGeometry()) AliGeomManager::GetGeometry()->Export("geometry.root");
434
435   // Load alignment data from CDB and apply to geometry through AliGeomManager
436   if(fLoadAlignFromCDB){
437     
438     TString detStr = fLoadAlObjsListOfDets;
439     TString loadAlObjsListOfDets = "";
440     
441     TObjArray* detArray = runLoader->GetAliRun()->Detectors();
442     for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
443       AliModule* det = (AliModule*) detArray->At(iDet);
444       if (!det || !det->IsActive()) continue;
445       if (IsSelected(det->GetName(), detStr)) {
446         //add det to list of dets to be aligned from CDB
447         loadAlObjsListOfDets += det->GetName();
448         loadAlObjsListOfDets += " ";
449       }
450     } // end loop over detectors
451     loadAlObjsListOfDets.Prepend("GRP "); //add alignment objects for non-sensitive modules
452     AliGeomManager::ApplyAlignObjsFromCDB(loadAlObjsListOfDets.Data());
453   }else{
454     // Check if the array with alignment objects was
455     // provided by the user. If yes, apply the objects
456     // to the present TGeo geometry
457     if (fAlignObjArray) {
458       if (AliGeomManager::ApplyAlignObjsToGeom(*fAlignObjArray) == kFALSE) {
459         AliError("The misalignment of one or more volumes failed!"
460                  "Compare the list of simulated detectors and the list of detector alignment data!");
461         if (delRunLoader) delete runLoader;
462         return kFALSE;
463       }
464     }
465   }
466
467   // Update the internal geometry of modules (ITS needs it)
468   TString detStr = fLoadAlObjsListOfDets;
469   TObjArray* detArray = runLoader->GetAliRun()->Detectors();
470   for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
471
472     AliModule* det = (AliModule*) detArray->At(iDet);
473     if (!det || !det->IsActive()) continue;
474     if (IsSelected(det->GetName(), detStr)) {
475       det->UpdateInternalGeometry();
476     }
477   } // end loop over detectors
478
479
480   if (delRunLoader) delete runLoader;
481
482   return kTRUE;
483 }
484
485
486 //_____________________________________________________________________________
487 Bool_t AliSimulation::SetRunNumber()
488 {
489   // Set the CDB manager run number
490   // The run number is retrieved from gAlice
491
492   if(AliCDBManager::Instance()->GetRun() < 0) {
493     AliRunLoader* runLoader = LoadRun("READ");
494     if (!runLoader) return kFALSE;
495     else {
496       AliCDBManager::Instance()->SetRun(runLoader->GetAliRun()->GetRunNumber());
497       AliInfo(Form("Run number: %d",AliCDBManager::Instance()->GetRun()));
498       delete runLoader;
499     }
500   }
501   return kTRUE;
502 }
503
504 //_____________________________________________________________________________
505 void AliSimulation::MergeWith(const char* fileName, Int_t nSignalPerBkgrd)
506 {
507 // add a file with background events for merging
508
509   TObjString* fileNameStr = new TObjString(fileName);
510   fileNameStr->SetUniqueID(nSignalPerBkgrd);
511   if (!fBkgrdFileNames) fBkgrdFileNames = new TObjArray;
512   fBkgrdFileNames->Add(fileNameStr);
513 }
514
515 void AliSimulation::EmbedInto(const char* fileName, Int_t nSignalPerBkgrd)
516 {
517 // add a file with background events for embeddin
518   MergeWith(fileName, nSignalPerBkgrd);
519   fEmbeddingFlag = kTRUE;
520 }
521
522 //_____________________________________________________________________________
523 Bool_t AliSimulation::Run(Int_t nEvents)
524 {
525 // run the generation, simulation and digitization
526
527  
528    AliCodeTimerAuto("")
529   
530   InitCDBStorage();
531
532   if (nEvents > 0) fNEvents = nEvents;
533
534   // generation and simulation -> hits
535   if (fRunGeneration) {
536     if (!RunSimulation()) if (fStopOnError) return kFALSE;
537   }
538
539 //QA
540         AliQADataMakerSteer qas ; 
541         qas.Run(AliQA::kHITS);
542
543   // Set run number in CDBManager (if it is not already set in RunSimulation)
544   if (!SetRunNumber()) if (fStopOnError) return kFALSE;
545
546   // If RunSimulation was not called, load the geometry and misalign it
547   if (!AliGeomManager::GetGeometry()) {
548     // Initialize the geometry manager
549     AliGeomManager::LoadGeometry("geometry.root");
550     if (!AliGeomManager::GetGeometry()) if (fStopOnError) return kFALSE;
551     // Misalign geometry
552     if(!MisalignGeometry()) if (fStopOnError) return kFALSE;
553   }
554
555   // hits -> summable digits
556   if (!fMakeSDigits.IsNull()) {
557     if (!RunSDigitization(fMakeSDigits)) if (fStopOnError) return kFALSE;
558   }
559   
560   //QA
561         qas.Reset() ; 
562         qas.Run(AliQA::kSDIGITS);
563
564   // summable digits -> digits
565   if (!fMakeDigits.IsNull()) {
566     if (!RunDigitization(fMakeDigits, fMakeDigitsFromHits)) {
567       if (fStopOnError) return kFALSE;
568     }
569   }
570
571   // hits -> digits
572   if (!fMakeDigitsFromHits.IsNull()) {
573     if (fBkgrdFileNames && (fBkgrdFileNames->GetEntriesFast() > 0)) {
574       AliWarning(Form("Merging and direct creation of digits from hits " 
575                  "was selected for some detectors. "
576                  "No merging will be done for the following detectors: %s",
577                  fMakeDigitsFromHits.Data()));
578     }
579     if (!RunHitsDigitization(fMakeDigitsFromHits)) {
580       if (fStopOnError) return kFALSE;
581     }
582   }
583   
584   //QA
585         qas.Reset() ; 
586         qas.Run(AliQA::kDIGITS);
587
588   // digits -> trigger
589   if (!RunTrigger(fMakeTrigger)) {
590     if (fStopOnError) return kFALSE;
591   }
592
593   // digits -> raw data
594   if (!fWriteRawData.IsNull()) {
595     if (!WriteRawData(fWriteRawData, fRawDataFileName, 
596                       fDeleteIntermediateFiles)) {
597       if (fStopOnError) return kFALSE;
598     }
599   }
600
601   // run HLT simulation
602   if (!fRunHLT.IsNull()) {
603     if (!RunHLT()) {
604       if (fStopOnError) return kFALSE;
605     }
606   }
607
608   return kTRUE;
609 }
610
611 //_____________________________________________________________________________
612 Bool_t AliSimulation::RunTrigger(const char* descriptors)
613 {
614   // run the trigger
615
616   AliCodeTimerAuto("")
617
618    AliRunLoader* runLoader = LoadRun("READ");
619    if (!runLoader) return kFALSE;
620    TString des = descriptors;
621
622    if (des.IsNull()) {
623      if (gAlice->GetTriggerDescriptor() != "") {
624        des = gAlice->GetTriggerDescriptor();
625      }
626      else {
627        AliWarning("No trigger descriptor is specified. Skipping the trigger simulation...");
628        return kTRUE;
629      }
630    }
631
632    runLoader->MakeTree( "GG" );
633    AliCentralTrigger* aCTP = runLoader->GetTrigger();
634   // Load Descriptors
635    aCTP->LoadDescriptor( des );
636
637   // digits -> trigger
638    if( !aCTP->RunTrigger( runLoader ) ) {
639       if (fStopOnError) {
640     //  delete aCTP;
641          return kFALSE;
642       }
643    }
644
645    delete runLoader;
646
647    return kTRUE;
648 }
649
650 //_____________________________________________________________________________
651 Bool_t AliSimulation::WriteTriggerRawData()
652 {
653   // Writes the CTP (trigger) DDL raw data
654   // Details of the format are given in the
655   // trigger TDR - pages 134 and 135.
656   AliCTPRawData writer;
657   writer.RawData();
658
659   return kTRUE;
660 }
661
662 //_____________________________________________________________________________
663 Bool_t AliSimulation::RunSimulation(Int_t nEvents)
664 {
665 // run the generation and simulation
666
667   AliCodeTimerAuto("")
668
669   if (!gAlice) {
670     AliError("no gAlice object. Restart aliroot and try again.");
671     return kFALSE;
672   }
673   if (gAlice->Modules()->GetEntries() > 0) {
674     AliError("gAlice was already run. Restart aliroot and try again.");
675     return kFALSE;
676   }
677
678   AliInfo(Form("initializing gAlice with config file %s",
679           fConfigFileName.Data()));
680   StdoutToAliInfo(StderrToAliError(
681     gAlice->Init(fConfigFileName.Data());
682   ););
683
684   // Get the trigger descriptor string
685   // Either from AliSimulation or from
686   // gAlice
687   if (fMakeTrigger.IsNull()) {
688     if (gAlice->GetTriggerDescriptor() != "")
689       fMakeTrigger = gAlice->GetTriggerDescriptor();
690   }
691   else
692     gAlice->SetTriggerDescriptor(fMakeTrigger.Data());
693
694   // Set run number in CDBManager
695   AliInfo(Form("Run number: %d",AliCDBManager::Instance()->GetRun()));
696
697   AliRunLoader* runLoader = gAlice->GetRunLoader();
698   if (!runLoader) {
699              AliError(Form("gAlice has no run loader object. "
700                              "Check your config file: %s", fConfigFileName.Data()));
701              return kFALSE;
702   }
703   SetGAliceFile(runLoader->GetFileName());
704  
705   // Misalign geometry
706 #if ROOT_VERSION_CODE < 331527
707   AliGeomManager::SetGeometry(gGeoManager);
708   MisalignGeometry(runLoader);
709 #endif
710
711 //   AliRunLoader* runLoader = gAlice->GetRunLoader();
712 //   if (!runLoader) {
713 //     AliError(Form("gAlice has no run loader object. "
714 //                   "Check your config file: %s", fConfigFileName.Data()));
715 //     return kFALSE;
716 //   }
717 //   SetGAliceFile(runLoader->GetFileName());
718
719   if (!gAlice->Generator()) {
720     AliError(Form("gAlice has no generator object. "
721                   "Check your config file: %s", fConfigFileName.Data()));
722     return kFALSE;
723   }
724   if (nEvents <= 0) nEvents = fNEvents;
725
726   // get vertex from background file in case of merging
727   if (fUseBkgrdVertex &&
728       fBkgrdFileNames && (fBkgrdFileNames->GetEntriesFast() > 0)) {
729     Int_t signalPerBkgrd = GetNSignalPerBkgrd(nEvents);
730     const char* fileName = ((TObjString*)
731                             (fBkgrdFileNames->At(0)))->GetName();
732     AliInfo(Form("The vertex will be taken from the background "
733                  "file %s with nSignalPerBackground = %d", 
734                  fileName, signalPerBkgrd));
735     AliVertexGenFile* vtxGen = new AliVertexGenFile(fileName, signalPerBkgrd);
736     gAlice->Generator()->SetVertexGenerator(vtxGen);
737   }
738
739   if (!fRunSimulation) {
740     gAlice->Generator()->SetTrackingFlag(0);
741   }
742
743   // set the number of events per file for given detectors and data types
744   for (Int_t i = 0; i < fEventsPerFile.GetEntriesFast(); i++) {
745     if (!fEventsPerFile[i]) continue;
746     const char* detName = fEventsPerFile[i]->GetName();
747     const char* typeName = fEventsPerFile[i]->GetTitle();
748     TString loaderName(detName);
749     loaderName += "Loader";
750     AliLoader* loader = runLoader->GetLoader(loaderName);
751     if (!loader) {
752       AliError(Form("RunSimulation", "no loader for %s found\n"
753                     "Number of events per file not set for %s %s", 
754                     detName, typeName, detName));
755       continue;
756     }
757     AliDataLoader* dataLoader = 
758       loader->GetDataLoader(typeName);
759     if (!dataLoader) {
760       AliError(Form("no data loader for %s found\n"
761                     "Number of events per file not set for %s %s", 
762                     typeName, detName, typeName));
763       continue;
764     }
765     dataLoader->SetNumberOfEventsPerFile(fEventsPerFile[i]->GetUniqueID());
766     AliDebug(1, Form("number of events per file set to %d for %s %s",
767                      fEventsPerFile[i]->GetUniqueID(), detName, typeName));
768   }
769
770   AliInfo("running gAlice");
771   StdoutToAliInfo(StderrToAliError(
772     gAlice->Run(nEvents);
773   ););
774
775   delete runLoader;
776
777
778   return kTRUE;
779 }
780
781 //_____________________________________________________________________________
782 Bool_t AliSimulation::RunSDigitization(const char* detectors)
783 {
784 // run the digitization and produce summable digits
785
786   AliCodeTimerAuto("")
787
788   AliRunLoader* runLoader = LoadRun();
789   if (!runLoader) return kFALSE;
790
791   TString detStr = detectors;
792   TObjArray* detArray = runLoader->GetAliRun()->Detectors();
793   for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
794     AliModule* det = (AliModule*) detArray->At(iDet);
795     if (!det || !det->IsActive()) continue;
796     if (IsSelected(det->GetName(), detStr)) {
797       AliInfo(Form("creating summable digits for %s", det->GetName()));
798       AliCodeTimerAuto(Form("creating summable digits for %s", det->GetName()));
799           
800       det->Hits2SDigits();
801     }
802   }
803
804   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
805     AliError(Form("the following detectors were not found: %s",
806                   detStr.Data()));
807     if (fStopOnError) return kFALSE;
808   }
809
810   delete runLoader;
811
812   return kTRUE;
813 }
814
815
816 //_____________________________________________________________________________
817 Bool_t AliSimulation::RunDigitization(const char* detectors, 
818                                       const char* excludeDetectors)
819 {
820 // run the digitization and produce digits from sdigits
821
822   AliCodeTimerAuto("")
823
824   while (AliRunLoader::GetRunLoader()) delete AliRunLoader::GetRunLoader();
825   if (gAlice) delete gAlice;
826   gAlice = NULL;
827
828   Int_t nStreams = 1;
829   if (fBkgrdFileNames) nStreams = fBkgrdFileNames->GetEntriesFast() + 1;
830   Int_t signalPerBkgrd = GetNSignalPerBkgrd();
831   AliRunDigitizer* manager = new AliRunDigitizer(nStreams, signalPerBkgrd);
832   // manager->SetEmbeddingFlag(fEmbeddingFlag);
833   manager->SetInputStream(0, fGAliceFileName.Data());
834   for (Int_t iStream = 1; iStream < nStreams; iStream++) {
835     const char* fileName = ((TObjString*)
836                             (fBkgrdFileNames->At(iStream-1)))->GetName();
837     manager->SetInputStream(iStream, fileName);
838   }
839
840   TString detStr = detectors;
841   TString detExcl = excludeDetectors;
842   manager->GetInputStream(0)->ImportgAlice();
843   AliRunLoader* runLoader = 
844     AliRunLoader::GetRunLoader(manager->GetInputStream(0)->GetFolderName());
845   TObjArray* detArray = runLoader->GetAliRun()->Detectors();
846   for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
847     AliModule* det = (AliModule*) detArray->At(iDet);
848     if (!det || !det->IsActive()) continue;
849     if (IsSelected(det->GetName(), detStr) && 
850         !IsSelected(det->GetName(), detExcl)) {
851       AliDigitizer* digitizer = det->CreateDigitizer(manager);
852       
853       if (!digitizer) {
854         AliError(Form("no digitizer for %s", det->GetName()));
855         if (fStopOnError) return kFALSE;
856       } else {
857         digitizer->SetRegionOfInterest(fRegionOfInterest);
858       }
859     }
860   }
861
862   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
863     AliError(Form("the following detectors were not found: %s", 
864                   detStr.Data()));
865     if (fStopOnError) return kFALSE;
866   }
867
868   if (!manager->GetListOfTasks()->IsEmpty()) {
869     AliInfo("executing digitization");
870     manager->Exec("");
871   }
872
873   delete manager;
874
875   return kTRUE;
876 }
877
878 //_____________________________________________________________________________
879 Bool_t AliSimulation::RunHitsDigitization(const char* detectors)
880 {
881 // run the digitization and produce digits from hits
882
883   AliCodeTimerAuto("")
884
885   AliRunLoader* runLoader = LoadRun("READ");
886   if (!runLoader) return kFALSE;
887
888   TString detStr = detectors;
889   TObjArray* detArray = runLoader->GetAliRun()->Detectors();
890   for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
891     AliModule* det = (AliModule*) detArray->At(iDet);
892     if (!det || !det->IsActive()) continue;
893     if (IsSelected(det->GetName(), detStr)) {
894       AliInfo(Form("creating digits from hits for %s", det->GetName()));
895       det->Hits2Digits();
896     }
897   }
898
899   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
900     AliError(Form("the following detectors were not found: %s", 
901                   detStr.Data()));
902     if (fStopOnError) return kFALSE;
903   }
904
905   delete runLoader;
906   //PH Temporary fix to avoid interference with the PHOS loder/getter
907   //PH The problem has to be solved in more general way 09/06/05
908
909   return kTRUE;
910 }
911
912 //_____________________________________________________________________________
913 Bool_t AliSimulation::WriteRawData(const char* detectors, 
914                                    const char* fileName,
915                                    Bool_t deleteIntermediateFiles)
916 {
917 // convert the digits to raw data
918 // First DDL raw data files for the given detectors are created.
919 // If a file name is given, the DDL files are then converted to a DATE file.
920 // If deleteIntermediateFiles is true, the DDL raw files are deleted 
921 // afterwards.
922 // If the file name has the extension ".root", the DATE file is converted
923 // to a root file.
924 // If deleteIntermediateFiles is true, the DATE file is deleted afterwards.
925
926   AliCodeTimerAuto("")
927
928   if (!WriteRawFiles(detectors)) {
929     if (fStopOnError) return kFALSE;
930   }
931
932   TString dateFileName(fileName);
933   if (!dateFileName.IsNull()) {
934     Bool_t rootOutput = dateFileName.EndsWith(".root");
935     if (rootOutput) dateFileName += ".date";
936     if (!ConvertRawFilesToDate(dateFileName)) {
937       if (fStopOnError) return kFALSE;
938     }
939     if (deleteIntermediateFiles) {
940       AliRunLoader* runLoader = LoadRun("READ");
941       if (runLoader) for (Int_t iEvent = 0; 
942                           iEvent < runLoader->GetNumberOfEvents(); iEvent++) {
943         char command[256];
944         sprintf(command, "rm -r raw%d", iEvent);
945         gSystem->Exec(command);
946       }
947     }
948
949     if (rootOutput) {
950       if (!ConvertDateToRoot(dateFileName, fileName)) {
951         if (fStopOnError) return kFALSE;
952       }
953       if (deleteIntermediateFiles) {
954         gSystem->Unlink(dateFileName);
955       }
956     }
957   }
958
959   return kTRUE;
960 }
961
962 //_____________________________________________________________________________
963 Bool_t AliSimulation::WriteRawFiles(const char* detectors)
964 {
965 // convert the digits to raw data DDL files
966
967   AliCodeTimerAuto("")
968   
969   AliRunLoader* runLoader = LoadRun("READ");
970   if (!runLoader) return kFALSE;
971
972   // write raw data to DDL files
973   for (Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); iEvent++) {
974     AliInfo(Form("processing event %d", iEvent));
975     runLoader->GetEvent(iEvent);
976     TString baseDir = gSystem->WorkingDirectory();
977     char dirName[256];
978     sprintf(dirName, "raw%d", iEvent);
979     gSystem->MakeDirectory(dirName);
980     if (!gSystem->ChangeDirectory(dirName)) {
981       AliError(Form("couldn't change to directory %s", dirName));
982       if (fStopOnError) return kFALSE; else continue;
983     }
984
985     TString detStr = detectors;
986     TObjArray* detArray = runLoader->GetAliRun()->Detectors();
987     for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
988       AliModule* det = (AliModule*) detArray->At(iDet);
989       if (!det || !det->IsActive()) continue;
990       if (IsSelected(det->GetName(), detStr)) {
991         AliInfo(Form("creating raw data from digits for %s", det->GetName()));
992         det->Digits2Raw();
993       }
994     }
995
996     if (!WriteTriggerRawData())
997       if (fStopOnError) return kFALSE;
998
999     gSystem->ChangeDirectory(baseDir);
1000     if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
1001       AliError(Form("the following detectors were not found: %s", 
1002                     detStr.Data()));
1003       if (fStopOnError) return kFALSE;
1004     }
1005   }
1006
1007   delete runLoader;
1008   
1009   return kTRUE;
1010 }
1011
1012 //_____________________________________________________________________________
1013 Bool_t AliSimulation::ConvertRawFilesToDate(const char* dateFileName)
1014 {
1015 // convert raw data DDL files to a DATE file with the program "dateStream"
1016
1017   AliCodeTimerAuto("")
1018   
1019   char* path = gSystem->Which(gSystem->Getenv("PATH"), "dateStream");
1020   if (!path) {
1021     AliError("the program dateStream was not found");
1022     if (fStopOnError) return kFALSE;
1023   } else {
1024     delete[] path;
1025   }
1026
1027   AliRunLoader* runLoader = LoadRun("READ");
1028   if (!runLoader) return kFALSE;
1029
1030   AliInfo(Form("converting raw data DDL files to DATE file %s", dateFileName));
1031   char command[256];
1032   // Note the option -s. It is used in order to avoid
1033   // the generation of SOR/EOR events.
1034   sprintf(command, "dateStream -s -D -o %s -# %d -C", 
1035           dateFileName, runLoader->GetNumberOfEvents());
1036   FILE* pipe = gSystem->OpenPipe(command, "w");
1037
1038   for (Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); iEvent++) {
1039     fprintf(pipe, "GDC\n");
1040     Float_t ldc = 0;
1041     Int_t prevLDC = -1;
1042
1043     // loop over detectors and DDLs
1044     for (Int_t iDet = 0; iDet < AliDAQ::kNDetectors; iDet++) {
1045       for (Int_t iDDL = 0; iDDL < AliDAQ::NumberOfDdls(iDet); iDDL++) {
1046
1047         Int_t ddlID = AliDAQ::DdlID(iDet,iDDL);
1048         Int_t ldcID = Int_t(ldc + 0.0001);
1049         ldc += AliDAQ::NumberOfLdcs(iDet) / AliDAQ::NumberOfDdls(iDet);
1050
1051         char rawFileName[256];
1052         sprintf(rawFileName, "raw%d/%s", 
1053                 iEvent, AliDAQ::DdlFileName(iDet,iDDL));
1054
1055         // check existence and size of raw data file
1056         FILE* file = fopen(rawFileName, "rb");
1057         if (!file) continue;
1058         fseek(file, 0, SEEK_END);
1059         unsigned long size = ftell(file);
1060         fclose(file);
1061         if (!size) continue;
1062
1063         if (ldcID != prevLDC) {
1064           fprintf(pipe, " LDC Id %d\n", ldcID);
1065           prevLDC = ldcID;
1066         }
1067         fprintf(pipe, "  Equipment Id %d Payload %s\n", ddlID, rawFileName);
1068       }
1069     }
1070   }
1071
1072   Int_t result = gSystem->ClosePipe(pipe);
1073
1074   delete runLoader;
1075   return (result == 0);
1076 }
1077
1078 //_____________________________________________________________________________
1079 Bool_t AliSimulation::ConvertDateToRoot(const char* dateFileName,
1080                                         const char* rootFileName)
1081 {
1082 // convert a DATE file to a root file with the program "alimdc"
1083
1084   // ALIMDC setup
1085   const Int_t kDBSize = 2000000000;
1086   const Int_t kTagDBSize = 1000000000;
1087   const Bool_t kFilter = kFALSE;
1088   const Int_t kCompression = 1;
1089
1090   char* path = gSystem->Which(gSystem->Getenv("PATH"), "alimdc");
1091   if (!path) {
1092     AliError("the program alimdc was not found");
1093     if (fStopOnError) return kFALSE;
1094   } else {
1095     delete[] path;
1096   }
1097
1098   AliInfo(Form("converting DATE file %s to root file %s", 
1099                dateFileName, rootFileName));
1100
1101   const char* rawDBFS[2] = { "/tmp/mdc1", "/tmp/mdc2" };
1102   const char* tagDBFS    = "/tmp/mdc1/tags";
1103
1104   // User defined file system locations
1105   if (gSystem->Getenv("ALIMDC_RAWDB1")) 
1106     rawDBFS[0] = gSystem->Getenv("ALIMDC_RAWDB1");
1107   if (gSystem->Getenv("ALIMDC_RAWDB2")) 
1108     rawDBFS[1] = gSystem->Getenv("ALIMDC_RAWDB2");
1109   if (gSystem->Getenv("ALIMDC_TAGDB")) 
1110     tagDBFS = gSystem->Getenv("ALIMDC_TAGDB");
1111
1112   gSystem->Exec(Form("rm -rf %s",rawDBFS[0]));
1113   gSystem->Exec(Form("rm -rf %s",rawDBFS[1]));
1114   gSystem->Exec(Form("rm -rf %s",tagDBFS));
1115
1116   gSystem->Exec(Form("mkdir %s",rawDBFS[0]));
1117   gSystem->Exec(Form("mkdir %s",rawDBFS[1]));
1118   gSystem->Exec(Form("mkdir %s",tagDBFS));
1119
1120   Int_t result = gSystem->Exec(Form("alimdc %d %d %d %d %s", 
1121                                     kDBSize, kTagDBSize, kFilter, kCompression, dateFileName));
1122   gSystem->Exec(Form("mv %s/*.root %s", rawDBFS[0], rootFileName));
1123
1124   gSystem->Exec(Form("rm -rf %s",rawDBFS[0]));
1125   gSystem->Exec(Form("rm -rf %s",rawDBFS[1]));
1126   gSystem->Exec(Form("rm -rf %s",tagDBFS));
1127
1128   return (result == 0);
1129 }
1130
1131
1132 //_____________________________________________________________________________
1133 AliRunLoader* AliSimulation::LoadRun(const char* mode) const
1134 {
1135 // delete existing run loaders, open a new one and load gAlice
1136
1137   while (AliRunLoader::GetRunLoader()) delete AliRunLoader::GetRunLoader();
1138   AliRunLoader* runLoader = 
1139     AliRunLoader::Open(fGAliceFileName.Data(), 
1140                        AliConfig::GetDefaultEventFolderName(), mode);
1141   if (!runLoader) {
1142     AliError(Form("no run loader found in file %s", fGAliceFileName.Data()));
1143     return NULL;
1144   }
1145   runLoader->LoadgAlice();
1146   gAlice = runLoader->GetAliRun();
1147   if (!gAlice) {
1148     AliError(Form("no gAlice object found in file %s", 
1149                   fGAliceFileName.Data()));
1150     return NULL;
1151   }
1152   return runLoader;
1153 }
1154
1155 //_____________________________________________________________________________
1156 Int_t AliSimulation::GetNSignalPerBkgrd(Int_t nEvents) const
1157 {
1158 // get or calculate the number of signal events per background event
1159
1160   if (!fBkgrdFileNames) return 1;
1161   Int_t nBkgrdFiles = fBkgrdFileNames->GetEntriesFast();
1162   if (nBkgrdFiles == 0) return 1;
1163
1164   // get the number of signal events
1165   if (nEvents <= 0) {
1166     AliRunLoader* runLoader = 
1167         AliRunLoader::Open(fGAliceFileName.Data(), "SIGNAL");
1168     if (!runLoader) return 1;
1169     
1170     nEvents = runLoader->GetNumberOfEvents();
1171     delete runLoader;
1172   }
1173
1174   Int_t result = 0;
1175   for (Int_t iBkgrdFile = 0; iBkgrdFile < nBkgrdFiles; iBkgrdFile++) {
1176     // get the number of background events
1177     const char* fileName = ((TObjString*)
1178                             (fBkgrdFileNames->At(iBkgrdFile)))->GetName();
1179     AliRunLoader* runLoader =
1180       AliRunLoader::Open(fileName, "BKGRD");
1181     if (!runLoader) continue;
1182     Int_t nBkgrdEvents = runLoader->GetNumberOfEvents();
1183     delete runLoader;
1184   
1185     // get or calculate the number of signal per background events
1186     Int_t nSignalPerBkgrd = fBkgrdFileNames->At(iBkgrdFile)->GetUniqueID();
1187     if (nSignalPerBkgrd <= 0) {
1188       nSignalPerBkgrd = (nEvents-1) / nBkgrdEvents + 1;
1189     } else if (result && (result != nSignalPerBkgrd)) {
1190       AliInfo(Form("the number of signal events per background event "
1191                    "will be changed from %d to %d for stream %d", 
1192                    nSignalPerBkgrd, result, iBkgrdFile+1));
1193       nSignalPerBkgrd = result;
1194     }
1195
1196     if (!result) result = nSignalPerBkgrd;
1197     if (nSignalPerBkgrd * nBkgrdEvents < nEvents) {
1198       AliWarning(Form("not enough background events (%d) for %d signal events "
1199                       "using %d signal per background events for stream %d",
1200                       nBkgrdEvents, nEvents, nSignalPerBkgrd, iBkgrdFile+1));
1201     }
1202   }
1203
1204   return result;
1205 }
1206
1207 //_____________________________________________________________________________
1208 Bool_t AliSimulation::IsSelected(TString detName, TString& detectors) const
1209 {
1210 // check whether detName is contained in detectors
1211 // if yes, it is removed from detectors
1212
1213   // check if all detectors are selected
1214   if ((detectors.CompareTo("ALL") == 0) ||
1215       detectors.BeginsWith("ALL ") ||
1216       detectors.EndsWith(" ALL") ||
1217       detectors.Contains(" ALL ")) {
1218     detectors = "ALL";
1219     return kTRUE;
1220   }
1221
1222   // search for the given detector
1223   Bool_t result = kFALSE;
1224   if ((detectors.CompareTo(detName) == 0) ||
1225       detectors.BeginsWith(detName+" ") ||
1226       detectors.EndsWith(" "+detName) ||
1227       detectors.Contains(" "+detName+" ")) {
1228     detectors.ReplaceAll(detName, "");
1229     result = kTRUE;
1230   }
1231
1232   // clean up the detectors string
1233   while (detectors.Contains("  ")) detectors.ReplaceAll("  ", " ");
1234   while (detectors.BeginsWith(" ")) detectors.Remove(0, 1);
1235   while (detectors.EndsWith(" ")) detectors.Remove(detectors.Length()-1, 1);
1236
1237   return result;
1238 }
1239
1240 Bool_t AliSimulation::ConvertRaw2SDigits(const char* rawDirectory, const char* esdFileName) 
1241 {
1242 //
1243 // Steering routine  to convert raw data in directory rawDirectory/ to fake SDigits. 
1244 // These can be used for embedding of MC tracks into RAW data using the standard 
1245 // merging procedure.
1246 //
1247 // If an ESD file is given the reconstructed vertex is taken from it and stored in the event header.
1248 //
1249     if (!gAlice) {
1250         AliError("no gAlice object. Restart aliroot and try again.");
1251         return kFALSE;
1252     }
1253     if (gAlice->Modules()->GetEntries() > 0) {
1254         AliError("gAlice was already run. Restart aliroot and try again.");
1255         return kFALSE;
1256     }
1257     
1258     AliInfo(Form("initializing gAlice with config file %s",fConfigFileName.Data()));
1259     StdoutToAliInfo(StderrToAliError(gAlice->Init(fConfigFileName.Data());););
1260 //
1261 //  Initialize CDB     
1262     InitCDBStorage();
1263     AliCDBManager* man = AliCDBManager::Instance();
1264     man->SetRun(0); // Should this come from rawdata header ?
1265     
1266     Int_t iDet;
1267     //
1268     // Get the runloader
1269     AliRunLoader* runLoader = gAlice->GetRunLoader();
1270     //
1271     // Open esd file if available
1272     TFile* esdFile = TFile::Open(esdFileName);
1273     Bool_t esdOK = (esdFile != 0);
1274     AliESD* esd = new AliESD;
1275     TTree* treeESD = 0;
1276     if (esdOK) {
1277         treeESD = (TTree*) esdFile->Get("esdTree");
1278         if (!treeESD) {
1279             AliWarning("No ESD tree found");
1280             esdOK = kFALSE;
1281         } else {
1282             treeESD->SetBranchAddress("ESD", &esd);
1283         }
1284     }
1285     //
1286     // Create the RawReader
1287     TString fileName(rawDirectory);
1288     AliRawReader* rawReader = 0x0;
1289     if (fileName.EndsWith("/")) {
1290       rawReader = new AliRawReaderFile(fileName);
1291     } else if (fileName.EndsWith(".root")) {
1292       rawReader = new AliRawReaderRoot(fileName);
1293     } else if (!fileName.IsNull()) {
1294       rawReader = new AliRawReaderDate(fileName);
1295       rawReader->SelectEvents(7);
1296     }
1297 //     if (!fEquipIdMap.IsNull() && fRawReader)
1298 //       fRawReader->LoadEquipmentIdsMap(fEquipIdMap);
1299     //
1300     // Get list of detectors
1301     TObjArray* detArray = runLoader->GetAliRun()->Detectors();
1302     //
1303     // Get Header
1304     AliHeader* header = runLoader->GetHeader();
1305     //
1306     TString detStr = fMakeSDigits;
1307     // Event loop
1308     Int_t nev = 0;
1309     while(kTRUE) {
1310         if (!(rawReader->NextEvent())) break;
1311         //
1312         // Detector loop
1313         for (iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
1314             AliModule* det = (AliModule*) detArray->At(iDet);
1315             if (!det || !det->IsActive()) continue;
1316             if (IsSelected(det->GetName(), detStr)) {
1317               AliInfo(Form("Calling Raw2SDigits for %s\n", det->GetName()));
1318               det->Raw2SDigits(rawReader);
1319               rawReader->Reset();
1320             }
1321         } // detectors
1322
1323
1324         //
1325         //  If ESD information available obtain reconstructed vertex and store in header.
1326         if (esdOK) {
1327             treeESD->GetEvent(nev);
1328             const AliESDVertex* esdVertex = esd->GetPrimaryVertex();
1329             Double_t position[3];
1330             esdVertex->GetXYZ(position);
1331             AliGenEventHeader* mcHeader = new  AliGenEventHeader("ESD");
1332             TArrayF mcV;
1333             mcV.Set(3);
1334             for (Int_t i = 0; i < 3; i++) mcV[i] = position[i];
1335             mcHeader->SetPrimaryVertex(mcV);
1336             header->Reset(0,nev);
1337             header->SetGenEventHeader(mcHeader);
1338             printf("***** Saved vertex %f %f %f \n", position[0], position[1], position[2]);
1339         }
1340         nev++;
1341 //
1342 //      Finish the event
1343         runLoader->TreeE()->Fill();
1344         runLoader->SetNextEvent();
1345     } // events
1346  
1347     delete rawReader;
1348 //
1349 //  Finish the run 
1350     runLoader->CdGAFile();
1351     runLoader->WriteHeader("OVERWRITE");
1352     runLoader->WriteRunLoader();
1353
1354     return kTRUE;
1355 }
1356
1357 //_____________________________________________________________________________
1358 Int_t AliSimulation::GetDetIndex(const char* detector)
1359 {
1360   // return the detector index corresponding to detector
1361   Int_t index = -1 ; 
1362   for (index = 0; index < fgkNDetectors ; index++) {
1363     if ( strcmp(detector, fgkDetectorName[index]) == 0 )
1364           break ; 
1365   }     
1366   return index ; 
1367 }
1368
1369 //_____________________________________________________________________________
1370 Bool_t AliSimulation::RunHLT()
1371 {
1372   // Run the HLT simulation
1373   // HLT simulation is implemented in HLT/sim/AliHLTSimulation
1374   // Disabled if fRunHLT is empty, default vaule is "default".
1375   // AliSimulation::SetRunHLT can be used to set the options for HLT simulation
1376   // The default simulation depends on the HLT component libraries and their
1377   // corresponding agents which define components and chains to run. See
1378   // http://web.ift.uib.no/~kjeks/doc/alice-hlt/
1379   // http://web.ift.uib.no/~kjeks/doc/alice-hlt/classAliHLTModuleAgent.html
1380   //
1381   // The libraries to be loaded can be specified as an option.
1382   // <pre>
1383   // AliSimulation sim;
1384   // sim.SetRunHLT("libAliHLTSample.so");
1385   // </pre>
1386   // will only load <tt>libAliHLTSample.so</tt>
1387
1388   // Other available options:
1389   // \li loglevel=<i>level</i> <br>
1390   //     logging level for this processing
1391   // \li alilog=off
1392   //     disable redirection of log messages to AliLog class
1393   // \li config=<i>macro</i>
1394   //     configuration macro
1395   // \li localrec=<i>configuration</i>
1396   //     comma separated list of configurations to be run during simulation
1397
1398   int iResult=0;
1399   AliRunLoader* pRunLoader = LoadRun("READ");
1400   if (!pRunLoader) return kFALSE;
1401
1402   // load the library dynamically
1403   gSystem->Load(ALIHLTSIMULATION_LIBRARY);
1404
1405   // check for the library version
1406   AliHLTSimulationGetLibraryVersion_t fctVersion=(AliHLTSimulationGetLibraryVersion_t)(gSystem->DynFindSymbol(ALIHLTSIMULATION_LIBRARY, ALIHLTSIMULATION_GET_LIBRARY_VERSION));
1407   if (!fctVersion) {
1408     AliError(Form("can not load library %s", ALIHLTSIMULATION_LIBRARY));
1409     return kFALSE;
1410   }
1411   if (fctVersion()!= ALIHLTSIMULATION_LIBRARY_VERSION) {
1412     AliError(Form("%s version does not match: compiled for version %d, loaded %d", ALIHLTSIMULATION_LIBRARY, ALIHLTSIMULATION_LIBRARY_VERSION, fctVersion()));
1413     return kFALSE;
1414   }
1415
1416   // print compile info
1417   typedef void (*CompileInfo)( char*& date, char*& time);
1418   CompileInfo fctInfo=(CompileInfo)gSystem->DynFindSymbol(ALIHLTSIMULATION_LIBRARY, "CompileInfo");
1419   if (fctInfo) {
1420     char* date="";
1421     char* time="";
1422     (*fctInfo)(date, time);
1423     if (!date) date="unknown";
1424     if (!time) time="unknown";
1425     AliInfo(Form("%s build on %s (%s)", ALIHLTSIMULATION_LIBRARY, date, time));
1426   } else {
1427     AliInfo(Form("no build info available for %s", ALIHLTSIMULATION_LIBRARY));
1428   }
1429
1430   // create instance of the HLT simulation
1431   AliHLTSimulationCreateInstance_t fctCreate=(AliHLTSimulationCreateInstance_t)(gSystem->DynFindSymbol(ALIHLTSIMULATION_LIBRARY, ALIHLTSIMULATION_CREATE_INSTANCE));
1432   AliHLTSimulation* pHLT=NULL;
1433   if (fctCreate==NULL || (pHLT=(fctCreate()))==NULL) {
1434     AliError(Form("can not create instance of HLT simulation (creator %p)", fctCreate));
1435     return kFALSE;    
1436   }
1437
1438   // init the HLT simulation
1439   if (fRunHLT.CompareTo("default")==0) fRunHLT="";
1440   AliHLTSimulationInit_t fctInit=(AliHLTSimulationInit_t)(gSystem->DynFindSymbol(ALIHLTSIMULATION_LIBRARY, ALIHLTSIMULATION_INIT));
1441   if (fctInit==NULL || (iResult=(fctInit(pHLT, pRunLoader, fRunHLT.Data())))<0) {
1442     AliError(Form("can not init HLT simulation: error %d (init %p)", iResult, fctInit));
1443   } else {
1444     // run the HLT simulation
1445     AliHLTSimulationRun_t fctRun=(AliHLTSimulationRun_t)(gSystem->DynFindSymbol(ALIHLTSIMULATION_LIBRARY, ALIHLTSIMULATION_RUN));
1446     if (fctRun==NULL || (iResult=(fctRun(pHLT, pRunLoader)))<0) {
1447       AliError(Form("can not run HLT simulation: error %d (run %p)", iResult, fctRun));
1448     }
1449   }
1450
1451   // delete the instance
1452   AliHLTSimulationDeleteInstance_t fctDelete=(AliHLTSimulationDeleteInstance_t)(gSystem->DynFindSymbol(ALIHLTSIMULATION_LIBRARY, ALIHLTSIMULATION_DELETE_INSTANCE));
1453   if (fctDelete==NULL || fctDelete(pHLT)<0) {
1454     AliError(Form("can not delete instance of HLT simulation (creator %p)", fctDelete));
1455   }
1456   pHLT=NULL;
1457
1458   return iResult>=0?kTRUE:kFALSE;
1459 }