]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliSimulation.cxx
Removing run loader
[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 <TObjString.h>
109 #include <TStopwatch.h>
110 #include <TSystem.h>
111
112 #include "AliLog.h"
113 #include "AliDigitizer.h"
114 #include "AliGenerator.h"
115 #include "AliModule.h"
116 #include "AliRun.h"
117 #include "AliRunDigitizer.h"
118 #include "AliRunLoader.h"
119 #include "AliSimulation.h"
120 #include "AliVertexGenFile.h"
121
122 ClassImp(AliSimulation)
123
124
125 //_____________________________________________________________________________
126 AliSimulation::AliSimulation(const char* configFileName,
127                              const char* name, const char* title) :
128   TNamed(name, title),
129
130   fRunGeneration(kTRUE),
131   fRunSimulation(kTRUE),
132   fMakeSDigits("ALL"),
133   fMakeDigits("ALL"),
134   fMakeDigitsFromHits(""),
135   fWriteRawData(""),
136   fRawDataFileName(""),
137   fDeleteIntermediateFiles(kFALSE),
138   fStopOnError(kFALSE),
139
140   fNEvents(1),
141   fConfigFileName(configFileName),
142   fGAliceFileName("galice.root"),
143   fEventsPerFile(),
144   fBkgrdFileNames(NULL),
145   fUseBkgrdVertex(kTRUE),
146   fRegionOfInterest(kFALSE)
147 {
148 // create simulation object with default parameters
149
150   SetGAliceFile("galice.root");
151 }
152
153 //_____________________________________________________________________________
154 AliSimulation::AliSimulation(const AliSimulation& sim) :
155   TNamed(sim),
156
157   fRunGeneration(sim.fRunGeneration),
158   fRunSimulation(sim.fRunSimulation),
159   fMakeSDigits(sim.fMakeSDigits),
160   fMakeDigits(sim.fMakeDigits),
161   fMakeDigitsFromHits(sim.fMakeDigitsFromHits),
162   fWriteRawData(sim.fWriteRawData),
163   fRawDataFileName(""),
164   fDeleteIntermediateFiles(kFALSE),
165   fStopOnError(sim.fStopOnError),
166
167   fNEvents(sim.fNEvents),
168   fConfigFileName(sim.fConfigFileName),
169   fGAliceFileName(sim.fGAliceFileName),
170   fEventsPerFile(),
171   fBkgrdFileNames(NULL),
172   fUseBkgrdVertex(sim.fUseBkgrdVertex),
173   fRegionOfInterest(sim.fRegionOfInterest)
174 {
175 // copy constructor
176
177   for (Int_t i = 0; i < sim.fEventsPerFile.GetEntriesFast(); i++) {
178     if (!sim.fEventsPerFile[i]) continue;
179     fEventsPerFile.Add(sim.fEventsPerFile[i]->Clone());
180   }
181
182   fBkgrdFileNames = new TObjArray;
183   for (Int_t i = 0; i < sim.fBkgrdFileNames->GetEntriesFast(); i++) {
184     if (!sim.fBkgrdFileNames->At(i)) continue;
185     fBkgrdFileNames->Add(sim.fBkgrdFileNames->At(i)->Clone());
186   }
187 }
188
189 //_____________________________________________________________________________
190 AliSimulation& AliSimulation::operator = (const AliSimulation& sim)
191 {
192 // assignment operator
193
194   this->~AliSimulation();
195   new(this) AliSimulation(sim);
196   return *this;
197 }
198
199 //_____________________________________________________________________________
200 AliSimulation::~AliSimulation()
201 {
202 // clean up
203
204   fEventsPerFile.Delete();
205
206   if (fBkgrdFileNames) {
207     fBkgrdFileNames->Delete();
208     delete fBkgrdFileNames;
209   }
210 }
211
212
213 //_____________________________________________________________________________
214 void AliSimulation::SetNumberOfEvents(Int_t nEvents)
215 {
216 // set the number of events for one run
217
218   fNEvents = nEvents;
219 }
220
221 //_____________________________________________________________________________
222 void AliSimulation::SetConfigFile(const char* fileName)
223 {
224 // set the name of the config file
225
226   fConfigFileName = fileName;
227 }
228
229 //_____________________________________________________________________________
230 void AliSimulation::SetGAliceFile(const char* fileName)
231 {
232 // set the name of the galice file
233 // the path is converted to an absolute one if it is relative
234
235   fGAliceFileName = fileName;
236   if (!gSystem->IsAbsoluteFileName(fGAliceFileName)) {
237     char* absFileName = gSystem->ConcatFileName(gSystem->WorkingDirectory(),
238                                                 fGAliceFileName);
239     fGAliceFileName = absFileName;
240     delete[] absFileName;
241   }
242
243   AliDebug(2, Form("galice file name set to %s", fileName));
244 }
245
246 //_____________________________________________________________________________
247 void AliSimulation::SetEventsPerFile(const char* detector, const char* type, 
248                                      Int_t nEvents)
249 {
250 // set the number of events per file for the given detector and data type
251 // ("Hits", "Summable Digits", "Digits", "Reconstructed Points" or "Tracks")
252
253   TNamed* obj = new TNamed(detector, type);
254   obj->SetUniqueID(nEvents);
255   fEventsPerFile.Add(obj);
256 }
257
258 //_____________________________________________________________________________
259 void AliSimulation::MergeWith(const char* fileName, Int_t nSignalPerBkgrd)
260 {
261 // add a file with background events for merging
262
263   TObjString* fileNameStr = new TObjString(fileName);
264   fileNameStr->SetUniqueID(nSignalPerBkgrd);
265   if (!fBkgrdFileNames) fBkgrdFileNames = new TObjArray;
266   fBkgrdFileNames->Add(fileNameStr);
267 }
268
269
270 //_____________________________________________________________________________
271 Bool_t AliSimulation::Run(Int_t nEvents)
272 {
273 // run the generation, simulation and digitization
274
275   if (nEvents > 0) fNEvents = nEvents;
276
277   // generation and simulation -> hits
278   if (fRunGeneration) {
279     if (!RunSimulation()) if (fStopOnError) return kFALSE;
280   }
281
282   // hits -> summable digits
283   if (!fMakeSDigits.IsNull()) {
284     if (!RunSDigitization(fMakeSDigits)) if (fStopOnError) return kFALSE;
285   }
286
287   // summable digits -> digits
288   if (!fMakeDigits.IsNull()) {
289     if (!RunDigitization(fMakeDigits, fMakeDigitsFromHits)) {
290       if (fStopOnError) return kFALSE;
291     }
292   }
293
294   // hits -> digits
295   if (!fMakeDigitsFromHits.IsNull()) {
296     if (fBkgrdFileNames && (fBkgrdFileNames->GetEntriesFast() > 0)) {
297       AliWarning(Form("Merging and direct creation of digits from hits " 
298                  "was selected for some detectors. "
299                  "No merging will be done for the following detectors: %s",
300                  fMakeDigitsFromHits.Data()));
301     }
302     if (!RunHitsDigitization(fMakeDigitsFromHits)) {
303       if (fStopOnError) return kFALSE;
304     }
305   }
306
307   // digits -> raw data
308   if (!fWriteRawData.IsNull()) {
309     if (!WriteRawData(fWriteRawData, fRawDataFileName, 
310                       fDeleteIntermediateFiles)) {
311       if (fStopOnError) return kFALSE;
312     }
313   }
314
315   return kTRUE;
316 }
317
318 //_____________________________________________________________________________
319 Bool_t AliSimulation::RunSimulation(Int_t nEvents)
320 {
321 // run the generation and simulation
322
323   TStopwatch stopwatch;
324   stopwatch.Start();
325
326   if (!gAlice) {
327     AliError("no gAlice object. Restart aliroot and try again.");
328     return kFALSE;
329   }
330   if (gAlice->Modules()->GetEntries() > 0) {
331     AliError("gAlice was already run. Restart aliroot and try again.");
332     return kFALSE;
333   }
334
335   AliInfo(Form("initializing gAlice with config file %s",
336           fConfigFileName.Data()));
337   StdoutToAliInfo(StderrToAliError(
338     gAlice->Init(fConfigFileName.Data());
339   ););
340   AliRunLoader* runLoader = gAlice->GetRunLoader();
341   if (!runLoader) {
342     AliError(Form("gAlice has no run loader object. "
343                   "Check your config file: %s", fConfigFileName.Data()));
344     return kFALSE;
345   }
346   SetGAliceFile(runLoader->GetFileName());
347
348   if (!gAlice->Generator()) {
349     AliError(Form("gAlice has no generator object. "
350                   "Check your config file: %s", fConfigFileName.Data()));
351     return kFALSE;
352   }
353   if (nEvents <= 0) nEvents = fNEvents;
354
355   // get vertex from background file in case of merging
356   if (fUseBkgrdVertex &&
357       fBkgrdFileNames && (fBkgrdFileNames->GetEntriesFast() > 0)) {
358     Int_t signalPerBkgrd = GetNSignalPerBkgrd(nEvents);
359     const char* fileName = ((TObjString*)
360                             (fBkgrdFileNames->At(0)))->GetName();
361     AliInfo(Form("The vertex will be taken from the background "
362                  "file %s with nSignalPerBackground = %d", 
363                  fileName, signalPerBkgrd));
364     AliVertexGenFile* vtxGen = new AliVertexGenFile(fileName, signalPerBkgrd);
365     gAlice->Generator()->SetVertexGenerator(vtxGen);
366   }
367
368   if (!fRunSimulation) {
369     gAlice->Generator()->SetTrackingFlag(0);
370   }
371
372   // set the number of events per file for given detectors and data types
373   for (Int_t i = 0; i < fEventsPerFile.GetEntriesFast(); i++) {
374     if (!fEventsPerFile[i]) continue;
375     const char* detName = fEventsPerFile[i]->GetName();
376     const char* typeName = fEventsPerFile[i]->GetTitle();
377     TString loaderName(detName);
378     loaderName += "Loader";
379     AliLoader* loader = runLoader->GetLoader(loaderName);
380     if (!loader) {
381       AliError(Form("RunSimulation", "no loader for %s found\n"
382                     "Number of events per file not set for %s %s", 
383                     detName, typeName, detName));
384       continue;
385     }
386     AliDataLoader* dataLoader = 
387       loader->GetDataLoader(typeName);
388     if (!dataLoader) {
389       AliError(Form("no data loader for %s found\n"
390                     "Number of events per file not set for %s %s", 
391                     typeName, detName, typeName));
392       continue;
393     }
394     dataLoader->SetNumberOfEventsPerFile(fEventsPerFile[i]->GetUniqueID());
395     AliDebug(1, Form("number of events per file set to %d for %s %s",
396                      fEventsPerFile[i]->GetUniqueID(), detName, typeName));
397   }
398
399   AliInfo("running gAlice");
400   StdoutToAliInfo(StderrToAliError(
401     gAlice->Run(nEvents);
402   ););
403
404   delete runLoader;
405
406   AliInfo(Form("Execution time: R:%.2fs C:%.2fs",
407                stopwatch.RealTime(),stopwatch.CpuTime()));
408
409   return kTRUE;
410 }
411
412 //_____________________________________________________________________________
413 Bool_t AliSimulation::RunSDigitization(const char* detectors)
414 {
415 // run the digitization and produce summable digits
416
417   TStopwatch stopwatch;
418   stopwatch.Start();
419
420   AliRunLoader* runLoader = LoadRun();
421   if (!runLoader) return kFALSE;
422
423   TString detStr = detectors;
424   TObjArray* detArray = runLoader->GetAliRun()->Detectors();
425   for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
426     AliModule* det = (AliModule*) detArray->At(iDet);
427     if (!det || !det->IsActive()) continue;
428     if (IsSelected(det->GetName(), detStr)) {
429       AliInfo(Form("creating summable digits for %s", det->GetName()));
430       TStopwatch stopwatchDet;
431       stopwatchDet.Start();
432       det->Hits2SDigits();
433       AliInfo(Form("Execution time for %s: R:%.2fs C:%.2fs",
434            det->GetName(),stopwatchDet.RealTime(),stopwatchDet.CpuTime()));
435     }
436   }
437
438   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
439     AliError(Form("the following detectors were not found: %s",
440                   detStr.Data()));
441     if (fStopOnError) return kFALSE;
442   }
443
444   delete runLoader;
445
446   AliInfo(Form("Execution time: R:%.2fs C:%.2fs",
447            stopwatch.RealTime(),stopwatch.CpuTime()));
448
449   return kTRUE;
450 }
451
452
453 //_____________________________________________________________________________
454 Bool_t AliSimulation::RunDigitization(const char* detectors, 
455                                       const char* excludeDetectors)
456 {
457 // run the digitization and produce digits from sdigits
458
459   TStopwatch stopwatch;
460   stopwatch.Start();
461
462   while (AliRunLoader::GetRunLoader()) delete AliRunLoader::GetRunLoader();
463   if (gAlice) delete gAlice;
464   gAlice = NULL;
465
466   Int_t nStreams = 1;
467   if (fBkgrdFileNames) nStreams = fBkgrdFileNames->GetEntriesFast() + 1;
468   Int_t signalPerBkgrd = GetNSignalPerBkgrd();
469   AliRunDigitizer* manager = new AliRunDigitizer(nStreams, signalPerBkgrd);
470   manager->SetInputStream(0, fGAliceFileName.Data());
471   for (Int_t iStream = 1; iStream < nStreams; iStream++) {
472     const char* fileName = ((TObjString*)
473                             (fBkgrdFileNames->At(iStream-1)))->GetName();
474     manager->SetInputStream(iStream, fileName);
475   }
476
477   TString detStr = detectors;
478   TString detExcl = excludeDetectors;
479   manager->GetInputStream(0)->ImportgAlice();
480   AliRunLoader* runLoader = 
481     AliRunLoader::GetRunLoader(manager->GetInputStream(0)->GetFolderName());
482   TObjArray* detArray = runLoader->GetAliRun()->Detectors();
483   for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
484     AliModule* det = (AliModule*) detArray->At(iDet);
485     if (!det || !det->IsActive()) continue;
486     if (IsSelected(det->GetName(), detStr) && 
487         !IsSelected(det->GetName(), detExcl)) {
488       AliDigitizer* digitizer = det->CreateDigitizer(manager);
489       if (!digitizer) {
490         AliError(Form("no digitizer for %s", det->GetName()));
491         if (fStopOnError) return kFALSE;
492       } else {
493         digitizer->SetRegionOfInterest(fRegionOfInterest);
494       }
495     }
496   }
497
498   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
499     AliError(Form("the following detectors were not found: %s", 
500                   detStr.Data()));
501     if (fStopOnError) return kFALSE;
502   }
503
504   if (!manager->GetListOfTasks()->IsEmpty()) {
505     AliInfo("executing digitization");
506     manager->Exec("");
507   }
508
509   delete manager;
510
511   AliInfo(Form("Execution time: R:%.2fs C:%.2fs",
512                stopwatch.RealTime(),stopwatch.CpuTime()));
513   
514   return kTRUE;
515 }
516
517 //_____________________________________________________________________________
518 Bool_t AliSimulation::RunHitsDigitization(const char* detectors)
519 {
520 // run the digitization and produce digits from hits
521
522   TStopwatch stopwatch;
523   stopwatch.Start();
524
525   AliRunLoader* runLoader = LoadRun("READ");
526   if (!runLoader) return kFALSE;
527
528   TString detStr = detectors;
529   TObjArray* detArray = runLoader->GetAliRun()->Detectors();
530   for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
531     AliModule* det = (AliModule*) detArray->At(iDet);
532     if (!det || !det->IsActive()) continue;
533     if (IsSelected(det->GetName(), detStr)) {
534       AliInfo(Form("creating digits from hits for %s", det->GetName()));
535       det->Hits2Digits();
536     }
537   }
538
539   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
540     AliError(Form("the following detectors were not found: %s", 
541                   detStr.Data()));
542     if (fStopOnError) return kFALSE;
543   }
544
545   delete runLoader;
546   //PH Temporary fix to avoid interference with the PHOS loder/getter
547   //PH The problem has to be solved in more general way 09/06/05
548
549   AliInfo(Form("Execution time: R:%.2fs C:%.2fs",
550                stopwatch.RealTime(),stopwatch.CpuTime()));
551
552   return kTRUE;
553 }
554
555 //_____________________________________________________________________________
556 Bool_t AliSimulation::WriteRawData(const char* detectors, 
557                                    const char* fileName,
558                                    Bool_t deleteIntermediateFiles)
559 {
560 // convert the digits to raw data
561 // First DDL raw data files for the given detectors are created.
562 // If a file name is given, the DDL files are then converted to a DATE file.
563 // If deleteIntermediateFiles is true, the DDL raw files are deleted 
564 // afterwards.
565 // If the file name has the extension ".root", the DATE file is converted
566 // to a root file.
567 // If deleteIntermediateFiles is true, the DATE file is deleted afterwards.
568
569   TStopwatch stopwatch;
570   stopwatch.Start();
571
572   if (!WriteRawFiles(detectors)) {
573     if (fStopOnError) return kFALSE;
574   }
575
576   TString dateFileName(fileName);
577   if (!dateFileName.IsNull()) {
578     Bool_t rootOutput = dateFileName.EndsWith(".root");
579     if (rootOutput) dateFileName += ".date";
580     if (!ConvertRawFilesToDate(dateFileName)) {
581       if (fStopOnError) return kFALSE;
582     }
583     if (deleteIntermediateFiles) {
584       AliRunLoader* runLoader = LoadRun("READ");
585       if (runLoader) for (Int_t iEvent = 0; 
586                           iEvent < runLoader->GetNumberOfEvents(); iEvent++) {
587         char command[256];
588         sprintf(command, "rm -r raw%d", iEvent);
589         gSystem->Exec(command);
590       }
591     }
592
593     if (rootOutput) {
594       if (!ConvertDateToRoot(dateFileName, fileName)) {
595         if (fStopOnError) return kFALSE;
596       }
597       if (deleteIntermediateFiles) {
598         gSystem->Unlink(dateFileName);
599       }
600     }
601   }
602
603   AliInfo(Form("Execution time: R:%.2fs C:%.2fs",
604                stopwatch.RealTime(),stopwatch.CpuTime()));
605
606   return kTRUE;
607 }
608
609 //_____________________________________________________________________________
610 Bool_t AliSimulation::WriteRawFiles(const char* detectors)
611 {
612 // convert the digits to raw data DDL files
613
614   AliRunLoader* runLoader = LoadRun("READ");
615   if (!runLoader) return kFALSE;
616
617   // write raw data to DDL files
618   for (Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); iEvent++) {
619     AliInfo(Form("processing event %d", iEvent));
620     runLoader->GetEvent(iEvent);
621     TString baseDir = gSystem->WorkingDirectory();
622     char dirName[256];
623     sprintf(dirName, "raw%d", iEvent);
624     gSystem->MakeDirectory(dirName);
625     if (!gSystem->ChangeDirectory(dirName)) {
626       AliError(Form("couldn't change to directory %s", dirName));
627       if (fStopOnError) return kFALSE; else continue;
628     }
629
630     TString detStr = detectors;
631     TObjArray* detArray = runLoader->GetAliRun()->Detectors();
632     for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
633       AliModule* det = (AliModule*) detArray->At(iDet);
634       if (!det || !det->IsActive()) continue;
635       if (IsSelected(det->GetName(), detStr)) {
636         AliInfo(Form("creating raw data from digits for %s", det->GetName()));
637         det->Digits2Raw();
638       }
639     }
640
641     gSystem->ChangeDirectory(baseDir);
642     if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
643       AliError(Form("the following detectors were not found: %s", 
644                     detStr.Data()));
645       if (fStopOnError) return kFALSE;
646     }
647   }
648
649   delete runLoader;
650   return kTRUE;
651 }
652
653 //_____________________________________________________________________________
654 Bool_t AliSimulation::ConvertRawFilesToDate(const char* dateFileName)
655 {
656 // convert raw data DDL files to a DATE file with the program "dateStream"
657
658   // DATE setup
659   const Int_t kNDetectors = 17;
660   const char* kDetectors[kNDetectors] = {"TPC", "ITSSPD", "ITSSDD", "ITSSSD", 
661                                          "TRD", "TOF", "PHOS", "RICH", 
662                                          "EMCAL", "MUON", "MUTR", "ZDC", 
663                                          "PMD", "START", "VZERO", "CRT",
664                                          "FMD"};
665   const Int_t kDetectorDDLs[kNDetectors]   = {216, 20, 12, 16, 
666                                               18, 72, 20, 20, 
667                                               22, 20, 2, 1, 
668                                               6, 1, 1, 1,
669                                               3};
670   const Float_t kDetectorLDCs[kNDetectors] = {46, 2, 2, 1, 
671                                               4, 2, 1, 2, 
672                                               1, 2, 1, 1,
673                                               1, 0.5, 0.5, 1,
674                                               1};
675
676   char* path = gSystem->Which(gSystem->Getenv("PATH"), "dateStream");
677   if (!path) {
678     AliError("the program dateStream was not found");
679     if (fStopOnError) return kFALSE;
680   } else {
681     delete[] path;
682   }
683
684   AliRunLoader* runLoader = LoadRun("READ");
685   if (!runLoader) return kFALSE;
686
687   AliInfo(Form("converting raw data DDL files to DATE file %s", dateFileName));
688   char command[256];
689   sprintf(command, "dateStream -o %s -# %d -C", 
690           dateFileName, runLoader->GetNumberOfEvents());
691   FILE* pipe = gSystem->OpenPipe(command, "w");
692
693   for (Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); iEvent++) {
694     fprintf(pipe, "GDC\n");
695     Float_t ldc = 0;
696     Int_t prevLDC = -1;
697
698     // loop over detectors and DDLs
699     for (Int_t iDet = 0; iDet < kNDetectors; iDet++) {
700       for (Int_t iDDL = 0; iDDL < kDetectorDDLs[iDet]; iDDL++) {
701
702         Int_t ddlID = 0x100*iDet + iDDL;
703         Int_t ldcID = Int_t(ldc + 0.0001);
704         ldc += kDetectorLDCs[iDet] / kDetectorDDLs[iDet];
705
706         char rawFileName[256];
707         sprintf(rawFileName, "raw%d/%s_%d.ddl", 
708                 iEvent, kDetectors[iDet], ddlID);
709
710         // check existence and size of raw data file
711         FILE* file = fopen(rawFileName, "rb");
712         if (!file) continue;
713         fseek(file, 0, SEEK_END);
714         unsigned long size = ftell(file);
715         fclose(file);
716         if (!size) continue;
717
718         if (ldcID != prevLDC) {
719           fprintf(pipe, " LDC Id %d\n", ldcID);
720           prevLDC = ldcID;
721         }
722         fprintf(pipe, "  Equipment Id %d Payload %s\n", ddlID, rawFileName);
723       }
724     }
725   }
726
727   Int_t result = gSystem->ClosePipe(pipe);
728
729   delete runLoader;
730   return (result == 0);
731 }
732
733 //_____________________________________________________________________________
734 Bool_t AliSimulation::ConvertDateToRoot(const char* dateFileName,
735                                         const char* rootFileName)
736 {
737 // convert a DATE file to a root file with the program "alimdc"
738
739   // ALIMDC setup
740   const Int_t kDBSize = 1000000000;
741   const Int_t kTagDBSize = 1000000000;
742   const Bool_t kFilter = kFALSE;
743   const Int_t kCompression = 1;
744
745   char* path = gSystem->Which(gSystem->Getenv("PATH"), "alimdc");
746   if (!path) {
747     AliError("the program alimdc was not found");
748     if (fStopOnError) return kFALSE;
749   } else {
750     delete[] path;
751   }
752
753   AliInfo(Form("converting DATE file %s to root file %s", 
754                dateFileName, rootFileName));
755
756   gSystem->Exec("rm -rf /tmp/mdc1");
757   gSystem->Exec("rm -rf /tmp/mdc2");
758
759   gSystem->Exec("mkdir /tmp/mdc1");
760   gSystem->Exec("mkdir /tmp/mdc2");
761
762   char command[256];
763   sprintf(command, "alimdc %d %d %d %d %s", 
764           kDBSize, kTagDBSize, kFilter, kCompression, dateFileName);
765   Int_t result = gSystem->Exec(command);
766   sprintf(command, "mv /tmp/mdc1/*.root %s", rootFileName);
767   gSystem->Exec(command);
768   gSystem->Exec("rm -rf /tmp/mdc1");
769   gSystem->Exec("rm -rf /tmp/mdc2");
770
771   return (result == 0);
772 }
773
774
775 //_____________________________________________________________________________
776 AliRunLoader* AliSimulation::LoadRun(const char* mode) const
777 {
778 // delete existing run loaders, open a new one and load gAlice
779
780   while (AliRunLoader::GetRunLoader()) delete AliRunLoader::GetRunLoader();
781   AliRunLoader* runLoader = 
782     AliRunLoader::Open(fGAliceFileName.Data(), 
783                        AliConfig::GetDefaultEventFolderName(), mode);
784   if (!runLoader) {
785     AliError(Form("no run loader found in file %s", fGAliceFileName.Data()));
786     return NULL;
787   }
788   runLoader->LoadgAlice();
789   gAlice = runLoader->GetAliRun();
790   if (!gAlice) {
791     AliError(Form("no gAlice object found in file %s", 
792                   fGAliceFileName.Data()));
793     return NULL;
794   }
795   return runLoader;
796 }
797
798 //_____________________________________________________________________________
799 Int_t AliSimulation::GetNSignalPerBkgrd(Int_t nEvents) const
800 {
801 // get or calculate the number of signal events per background event
802
803   if (!fBkgrdFileNames) return 1;
804   Int_t nBkgrdFiles = fBkgrdFileNames->GetEntriesFast();
805   if (nBkgrdFiles == 0) return 1;
806
807   // get the number of signal events
808   if (nEvents <= 0) {
809     AliRunLoader* runLoader = 
810       AliRunLoader::Open(fGAliceFileName.Data(), "SIGNAL");
811     if (!runLoader) return 1;
812     nEvents = runLoader->GetNumberOfEvents();
813     delete runLoader;
814   }
815
816   Int_t result = 0;
817   for (Int_t iBkgrdFile = 0; iBkgrdFile < nBkgrdFiles; iBkgrdFile++) {
818     // get the number of background events
819     const char* fileName = ((TObjString*)
820                             (fBkgrdFileNames->At(iBkgrdFile)))->GetName();
821     AliRunLoader* runLoader = 
822       AliRunLoader::Open(fileName, "BKGRD");
823     if (!runLoader) continue;
824     Int_t nBkgrdEvents = runLoader->GetNumberOfEvents();
825     delete runLoader;
826
827     // get or calculate the number of signal per background events
828     Int_t nSignalPerBkgrd = fBkgrdFileNames->At(iBkgrdFile)->GetUniqueID();
829     if (nSignalPerBkgrd <= 0) {
830       nSignalPerBkgrd = (nEvents-1) / nBkgrdEvents + 1;
831     } else if (result && (result != nSignalPerBkgrd)) {
832       AliInfo(Form("the number of signal events per background event "
833                    "will be changed from %d to %d for stream %d", 
834                    nSignalPerBkgrd, result, iBkgrdFile+1));
835       nSignalPerBkgrd = result;
836     }
837
838     if (!result) result = nSignalPerBkgrd;
839     if (nSignalPerBkgrd * nBkgrdEvents < nEvents) {
840       AliWarning(Form("not enough background events (%d) for %d signal events "
841                       "using %d signal per background events for stream %d",
842                       nBkgrdEvents, nEvents, nSignalPerBkgrd, iBkgrdFile+1));
843     }
844   }
845
846   return result;
847 }
848
849 //_____________________________________________________________________________
850 Bool_t AliSimulation::IsSelected(TString detName, TString& detectors) const
851 {
852 // check whether detName is contained in detectors
853 // if yes, it is removed from detectors
854
855   // check if all detectors are selected
856   if ((detectors.CompareTo("ALL") == 0) ||
857       detectors.BeginsWith("ALL ") ||
858       detectors.EndsWith(" ALL") ||
859       detectors.Contains(" ALL ")) {
860     detectors = "ALL";
861     return kTRUE;
862   }
863
864   // search for the given detector
865   Bool_t result = kFALSE;
866   if ((detectors.CompareTo(detName) == 0) ||
867       detectors.BeginsWith(detName+" ") ||
868       detectors.EndsWith(" "+detName) ||
869       detectors.Contains(" "+detName+" ")) {
870     detectors.ReplaceAll(detName, "");
871     result = kTRUE;
872   }
873
874   // clean up the detectors string
875   while (detectors.Contains("  ")) detectors.ReplaceAll("  ", " ");
876   while (detectors.BeginsWith(" ")) detectors.Remove(0, 1);
877   while (detectors.EndsWith(" ")) detectors.Remove(detectors.Length()-1, 1);
878
879   return result;
880 }