8fcae1d7590f48f448c8e36a006bdbc02e625bd5
[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 "AliQADataMakerSteer.h"
142
143 ClassImp(AliSimulation)
144
145 AliSimulation *AliSimulation::fgInstance = 0;
146 const char* AliSimulation::fgkDetectorName[AliSimulation::fgkNDetectors] = {"ITS", "TPC", "TRD", "TOF", "PHOS", "HMPID", "EMCAL", "MUON", "FMD", "ZDC", "PMD", "T0", "VZERO", "ACORDE", "HLT"};
147
148 //_____________________________________________________________________________
149 AliSimulation::AliSimulation(const char* configFileName, const char* cdbUri,
150                              const char* name, const char* title) :
151   TNamed(name, title),
152
153   fRunGeneration(kTRUE),
154   fRunSimulation(kTRUE),
155   fLoadAlignFromCDB(kTRUE),
156   fLoadAlObjsListOfDets("ALL"),
157   fMakeSDigits("ALL"),
158   fMakeDigits("ALL"),
159   fMakeTrigger(""),
160   fMakeDigitsFromHits(""),
161   fWriteRawData(""),
162   fRawDataFileName(""),
163   fDeleteIntermediateFiles(kFALSE),
164   fStopOnError(kFALSE),
165
166   fNEvents(1),
167   fConfigFileName(configFileName),
168   fGAliceFileName("galice.root"),
169   fEventsPerFile(),
170   fBkgrdFileNames(NULL),
171   fAlignObjArray(NULL),
172   fUseBkgrdVertex(kTRUE),
173   fRegionOfInterest(kFALSE),
174   fCDBUri(cdbUri),
175   fRemoteCDBUri(""),
176   fSpecCDBUri(),
177   fEmbeddingFlag(kFALSE),
178   fRunQA(kTRUE), 
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   fRunQA(kTRUE), 
220   fRunHLT(sim.fRunHLT)
221 {
222 // copy constructor
223
224   for (Int_t i = 0; i < sim.fEventsPerFile.GetEntriesFast(); i++) {
225     if (!sim.fEventsPerFile[i]) continue;
226     fEventsPerFile.Add(sim.fEventsPerFile[i]->Clone());
227   }
228
229   fBkgrdFileNames = new TObjArray;
230   for (Int_t i = 0; i < sim.fBkgrdFileNames->GetEntriesFast(); i++) {
231     if (!sim.fBkgrdFileNames->At(i)) continue;
232     fBkgrdFileNames->Add(sim.fBkgrdFileNames->At(i)->Clone());
233   }
234
235   for (Int_t i = 0; i < sim.fSpecCDBUri.GetEntriesFast(); i++) {
236     if (sim.fSpecCDBUri[i]) fSpecCDBUri.Add(sim.fSpecCDBUri[i]->Clone());
237   }
238   fgInstance = this;
239
240 // for QA
241    for (Int_t iDet = 0; iDet < fgkNDetectors; iDet++) 
242         fQACycles[iDet] = sim.fQACycles[iDet];
243 }
244
245 //_____________________________________________________________________________
246 AliSimulation& AliSimulation::operator = (const AliSimulation& sim)
247 {
248 // assignment operator
249
250   this->~AliSimulation();
251   new(this) AliSimulation(sim);
252   return *this;
253 }
254
255 //_____________________________________________________________________________
256 AliSimulation::~AliSimulation()
257 {
258 // clean up
259
260   fEventsPerFile.Delete();
261 //  if(fAlignObjArray) fAlignObjArray->Delete(); // fAlignObjArray->RemoveAll() ???
262 //  delete fAlignObjArray; fAlignObjArray=0;
263
264   if (fBkgrdFileNames) {
265     fBkgrdFileNames->Delete();
266     delete fBkgrdFileNames;
267   }
268
269   fSpecCDBUri.Delete();
270   if (fgInstance==this) fgInstance = 0;
271
272   AliCodeTimer::Instance()->Print();
273 }
274
275
276 //_____________________________________________________________________________
277 void AliSimulation::SetNumberOfEvents(Int_t nEvents)
278 {
279 // set the number of events for one run
280
281   fNEvents = nEvents;
282 }
283
284 //_____________________________________________________________________________
285 void AliSimulation::InitCDBStorage()
286 {
287 // activate a default CDB storage
288 // First check if we have any CDB storage set, because it is used 
289 // to retrieve the calibration and alignment constants
290
291   AliCDBManager* man = AliCDBManager::Instance();
292   if (man->IsDefaultStorageSet())
293   {
294     AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
295     AliWarning("Default CDB storage has been already set !");
296     AliWarning(Form("Ignoring the default storage declared in AliSimulation: %s",fCDBUri.Data()));
297     AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
298     fCDBUri = "";
299   }
300   else {
301     AliDebug(2,"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
302     AliDebug(2, Form("Default CDB storage is set to: %s",fCDBUri.Data()));
303     AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
304     man->SetDefaultStorage(fCDBUri);
305   }
306
307   // Remote storage (the Grid storage) is used if it is activated
308   // and if the object is not found in the default storage
309   // OBSOLETE: Removed
310   //   if (man->IsRemoteStorageSet())
311   //   {
312   //     AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
313   //     AliWarning("Remote CDB storage has been already set !");
314   //     AliWarning(Form("Ignoring the remote storage declared in AliSimulation: %s",fRemoteCDBUri.Data()));
315   //     AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
316   //     fRemoteCDBUri = "";
317   //   }
318   //   else {
319   //     AliDebug(2,"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
320   //     AliDebug(2, Form("Remote CDB storage is set to: %s",fRemoteCDBUri.Data()));
321   //     AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
322   //     man->SetRemoteStorage(fRemoteCDBUri);
323   //   }
324
325   // Now activate the detector specific CDB storage locations
326   for (Int_t i = 0; i < fSpecCDBUri.GetEntriesFast(); i++) {
327     TObject* obj = fSpecCDBUri[i];
328     if (!obj) continue;
329     AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
330     AliDebug(2, Form("Specific CDB storage for %s is set to: %s",obj->GetName(),obj->GetTitle()));
331     AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
332     man->SetSpecificStorage(obj->GetName(), obj->GetTitle());
333   }
334   man->Print();
335 }
336
337 //_____________________________________________________________________________
338 void AliSimulation::SetDefaultStorage(const char* uri) {
339 // Store the desired default CDB storage location
340 // Activate it later within the Run() method
341
342   fCDBUri = uri;
343
344 }
345
346 //_____________________________________________________________________________
347 void AliSimulation::SetRemoteStorage(const char* uri) {
348 // Store the desired remote CDB storage location
349 // Activate it later within the Run() method
350 // Remote storage (the Grid storage) is used if it is activated
351 // and if the object is not found in the default storage (the local cache)
352
353   fRemoteCDBUri = uri;
354
355 }
356
357 //_____________________________________________________________________________
358 void AliSimulation::SetSpecificStorage(const char* calibType, const char* uri) {
359 // Store a detector-specific CDB storage location
360 // Activate it later within the Run() method
361
362   AliCDBPath aPath(calibType);
363   if(!aPath.IsValid()){
364         AliError(Form("Not a valid path: %s", calibType));
365         return;
366   }
367
368   TObject* obj = fSpecCDBUri.FindObject(calibType);
369   if (obj) fSpecCDBUri.Remove(obj);
370   fSpecCDBUri.Add(new TNamed(calibType, uri));
371
372 }
373
374 //_____________________________________________________________________________
375 void AliSimulation::SetConfigFile(const char* fileName)
376 {
377 // set the name of the config file
378
379   fConfigFileName = fileName;
380 }
381
382 //_____________________________________________________________________________
383 void AliSimulation::SetGAliceFile(const char* fileName)
384 {
385 // set the name of the galice file
386 // the path is converted to an absolute one if it is relative
387
388   fGAliceFileName = fileName;
389   if (!gSystem->IsAbsoluteFileName(fGAliceFileName)) {
390     char* absFileName = gSystem->ConcatFileName(gSystem->WorkingDirectory(),
391                                                 fGAliceFileName);
392     fGAliceFileName = absFileName;
393     delete[] absFileName;
394   }
395
396   AliDebug(2, Form("galice file name set to %s", fileName));
397 }
398
399 //_____________________________________________________________________________
400 void AliSimulation::SetEventsPerFile(const char* detector, const char* type, 
401                                      Int_t nEvents)
402 {
403 // set the number of events per file for the given detector and data type
404 // ("Hits", "Summable Digits", "Digits", "Reconstructed Points" or "Tracks")
405
406   TNamed* obj = new TNamed(detector, type);
407   obj->SetUniqueID(nEvents);
408   fEventsPerFile.Add(obj);
409 }
410
411 //_____________________________________________________________________________
412 Bool_t AliSimulation::MisalignGeometry(AliRunLoader *runLoader)
413 {
414   // Read the alignment objects from CDB.
415   // Each detector is supposed to have the
416   // alignment objects in DET/Align/Data CDB path.
417   // All the detector objects are then collected,
418   // sorted by geometry level (starting from ALIC) and
419   // then applied to the TGeo geometry.
420   // Finally an overlaps check is performed.
421
422   if (!AliGeomManager::GetGeometry() || !AliGeomManager::GetGeometry()->IsClosed()) {
423     AliError("Can't apply the misalignment! Geometry is not loaded or it is still opened!");
424     return kFALSE;
425   }  
426   Bool_t delRunLoader = kFALSE;
427   if (!runLoader) {
428     runLoader = LoadRun("READ");
429     if (!runLoader) return kFALSE;
430     delRunLoader = kTRUE;
431   }
432
433   // Export ideal geometry 
434   if(!gAlice->IsRootGeometry()) AliGeomManager::GetGeometry()->Export("geometry.root");
435
436   // Load alignment data from CDB and apply to geometry through AliGeomManager
437   if(fLoadAlignFromCDB){
438     
439     TString detStr = fLoadAlObjsListOfDets;
440     TString loadAlObjsListOfDets = "";
441     
442     TObjArray* detArray = runLoader->GetAliRun()->Detectors();
443     for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
444       AliModule* det = (AliModule*) detArray->At(iDet);
445       if (!det || !det->IsActive()) continue;
446       if (IsSelected(det->GetName(), detStr)) {
447         //add det to list of dets to be aligned from CDB
448         loadAlObjsListOfDets += det->GetName();
449         loadAlObjsListOfDets += " ";
450       }
451     } // end loop over detectors
452     loadAlObjsListOfDets.Prepend("GRP "); //add alignment objects for non-sensitive modules
453     AliGeomManager::ApplyAlignObjsFromCDB(loadAlObjsListOfDets.Data());
454   }else{
455     // Check if the array with alignment objects was
456     // provided by the user. If yes, apply the objects
457     // to the present TGeo geometry
458     if (fAlignObjArray) {
459       if (AliGeomManager::ApplyAlignObjsToGeom(*fAlignObjArray) == kFALSE) {
460         AliError("The misalignment of one or more volumes failed!"
461                  "Compare the list of simulated detectors and the list of detector alignment data!");
462         if (delRunLoader) delete runLoader;
463         return kFALSE;
464       }
465     }
466   }
467
468   // Update the internal geometry of modules (ITS needs it)
469   TString detStr = fLoadAlObjsListOfDets;
470   TObjArray* detArray = runLoader->GetAliRun()->Detectors();
471   for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
472
473     AliModule* det = (AliModule*) detArray->At(iDet);
474     if (!det || !det->IsActive()) continue;
475     if (IsSelected(det->GetName(), detStr)) {
476       det->UpdateInternalGeometry();
477     }
478   } // end loop over detectors
479
480
481   if (delRunLoader) delete runLoader;
482
483   return kTRUE;
484 }
485
486
487 //_____________________________________________________________________________
488 Bool_t AliSimulation::SetRunNumber()
489 {
490   // Set the CDB manager run number
491   // The run number is retrieved from gAlice
492
493   if(AliCDBManager::Instance()->GetRun() < 0) {
494     AliRunLoader* runLoader = LoadRun("READ");
495     if (!runLoader) return kFALSE;
496     else {
497       AliCDBManager::Instance()->SetRun(runLoader->GetAliRun()->GetRunNumber());
498       AliInfo(Form("Run number: %d",AliCDBManager::Instance()->GetRun()));
499       delete runLoader;
500     }
501   }
502   return kTRUE;
503 }
504
505 //_____________________________________________________________________________
506 void AliSimulation::MergeWith(const char* fileName, Int_t nSignalPerBkgrd)
507 {
508 // add a file with background events for merging
509
510   TObjString* fileNameStr = new TObjString(fileName);
511   fileNameStr->SetUniqueID(nSignalPerBkgrd);
512   if (!fBkgrdFileNames) fBkgrdFileNames = new TObjArray;
513   fBkgrdFileNames->Add(fileNameStr);
514 }
515
516 void AliSimulation::EmbedInto(const char* fileName, Int_t nSignalPerBkgrd)
517 {
518 // add a file with background events for embeddin
519   MergeWith(fileName, nSignalPerBkgrd);
520   fEmbeddingFlag = kTRUE;
521 }
522
523 //_____________________________________________________________________________
524 Bool_t AliSimulation::Run(Int_t nEvents)
525 {
526 // run the generation, simulation and digitization
527
528  
529    AliCodeTimerAuto("")
530   
531   InitCDBStorage();
532
533   if (nEvents > 0) fNEvents = nEvents;
534
535   // generation and simulation -> hits
536   if (fRunGeneration) {
537     if (!RunSimulation()) if (fStopOnError) return kFALSE;
538   }
539
540
541
542   // Set run number in CDBManager (if it is not already set in RunSimulation)
543   if (!SetRunNumber()) if (fStopOnError) return kFALSE;
544
545   // If RunSimulation was not called, load the geometry and misalign it
546   if (!AliGeomManager::GetGeometry()) {
547     // Initialize the geometry manager
548     AliGeomManager::LoadGeometry("geometry.root");
549     if (!AliGeomManager::GetGeometry()) if (fStopOnError) return kFALSE;
550     // Misalign geometry
551     if(!MisalignGeometry()) if (fStopOnError) return kFALSE;
552   }
553
554   // hits -> summable digits
555   if (!fMakeSDigits.IsNull()) {
556     if (!RunSDigitization(fMakeSDigits)) if (fStopOnError) return kFALSE;
557  
558   }
559   
560
561   // summable digits -> digits
562   if (!fMakeDigits.IsNull()) {
563     if (!RunDigitization(fMakeDigits, fMakeDigitsFromHits)) {
564       if (fStopOnError) return kFALSE;
565     }
566    }
567
568   // hits -> digits
569   if (!fMakeDigitsFromHits.IsNull()) {
570     if (fBkgrdFileNames && (fBkgrdFileNames->GetEntriesFast() > 0)) {
571       AliWarning(Form("Merging and direct creation of digits from hits " 
572                  "was selected for some detectors. "
573                  "No merging will be done for the following detectors: %s",
574                  fMakeDigitsFromHits.Data()));
575     }
576     if (!RunHitsDigitization(fMakeDigitsFromHits)) {
577       if (fStopOnError) return kFALSE;
578     }
579   }
580
581   // digits -> trigger
582   if (!RunTrigger(fMakeTrigger)) {
583     if (fStopOnError) return kFALSE;
584   }
585
586   // digits -> raw data
587   if (!fWriteRawData.IsNull()) {
588     if (!WriteRawData(fWriteRawData, fRawDataFileName, 
589                       fDeleteIntermediateFiles)) {
590       if (fStopOnError) return kFALSE;
591     }
592   }
593
594   // run HLT simulation
595   if (!fRunHLT.IsNull()) {
596     if (!RunHLT()) {
597       if (fStopOnError) return kFALSE;
598     }
599   }
600
601  // //QA
602 //      if (fRunQA) {
603 //              Bool_t rv = RunQA() ; 
604 //              if (!rv)
605 //                      if (fStopOnError) 
606 //                              return kFALSE ;         
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 }
1460
1461 //_____________________________________________________________________________
1462 Bool_t AliSimulation::RunQA()
1463 {
1464         // run the QA on summable hits, digits or digits
1465
1466         AliQADataMakerSteer qas ; 
1467     qas.SetRunLoader(gAlice->GetRunLoader()) ;
1468
1469         Bool_t rv =  qas.Run("ALL", AliQA::kHITS) ; 
1470 //      qas.Reset() ; 
1471         rv *= qas.Run(fMakeSDigits.Data(), AliQA::kSDIGITS) ;   
1472 //      qas.Reset() ; 
1473         rv *= qas.Run(fMakeDigits.Data(), AliQA::kDIGITS) ;     
1474 //      qas.Reset() ; 
1475         rv *= qas.Run(fMakeDigitsFromHits.Data(), AliQA::kDIGITS) ; 
1476
1477         return rv ; 
1478 }
1479