8b8cddf1abfc4d6de9c6de115ab3b0e2fc53ce88
[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 specified by                    //
34 //                                                                           //
35 //   sim.SetConfigFile("...");                                               //
36 //                                                                           //
37 // The generation of particles and the simulation of detector hits can be    //
38 // switched on or off by                                                     //
39 //                                                                           //
40 //   sim.SetRunGeneration(kTRUE);   // generation of primary particles       //
41 //   sim.SetRunSimulation(kFALSE);  // but no tracking                       //
42 //                                                                           //
43 // For which detectors sdigits and digits will be created, can be steered    //
44 // by                                                                        //
45 //                                                                           //
46 //   sim.SetMakeSDigits("ALL");     // make sdigits for all detectors        //
47 //   sim.SetMakeDigits("ITS TPC");  // make digits only for ITS and TPC      //
48 //                                                                           //
49 // The argument is a (case sensitive) string with the names of the           //
50 // detectors separated by a space. An empty string ("") can be used to       //
51 // disable the creation of sdigits or digits. The special string "ALL"       //
52 // selects all available detectors. This is the default.                     //
53 //                                                                           //
54 // The creation of digits from hits instead of from sdigits can be selected  //
55 // by                                                                        //
56 //                                                                           //
57 //   sim.SetMakeDigitsFromHits("TRD");                                       //
58 //                                                                           //
59 // The argument is again a string with the selected detectors. Be aware that //
60 // this feature is not available for all detectors and that merging is not   //
61 // possible, when digits are created directly from hits.                     //
62 //                                                                           //
63 // Backgound events can be merged by calling                                 //
64 //                                                                           //
65 //   sim.MergeWith("background/galice.root", 2);                             //
66 //                                                                           //
67 // The first argument is the file name of the background galice file. The    //
68 // second argument is the number of signal events per background event.      //
69 // The default value for this is 1. MergeWith can be called several times    //
70 // to merge more than two event streams. It is assumed that the sdigits      //
71 // were already produced for the background events.                          //
72 //                                                                           //
73 ///////////////////////////////////////////////////////////////////////////////
74
75
76 #include "AliSimulation.h"
77 #include "AliRunLoader.h"
78 #include "AliRun.h"
79 #include "AliModule.h"
80 #include "AliGenerator.h"
81 #include "AliRunDigitizer.h"
82 #include "AliDigitizer.h"
83 #include <TObjString.h>
84
85
86 ClassImp(AliSimulation)
87
88
89 //_____________________________________________________________________________
90 AliSimulation::AliSimulation(const char* name, const char* title) :
91   TNamed(name, title)
92 {
93 // create simulation object with default parameters
94
95   Init();
96 }
97
98 //_____________________________________________________________________________
99 AliSimulation::AliSimulation(const AliSimulation& sim) :
100   TNamed(sim)
101 {
102 // copy constructor
103
104   fRunGeneration = sim.fRunGeneration;
105   fRunSimulation = sim.fRunSimulation;
106   fMakeSDigits = sim.fMakeSDigits;
107   fMakeDigits = sim.fMakeDigits;
108   fMakeDigitsFromHits = sim.fMakeDigitsFromHits;
109   fStopOnError = sim.fStopOnError;
110
111   fNEvents = sim.fNEvents;
112   fConfigFileName = sim.fConfigFileName;
113   fGAliceFileName = sim.fGAliceFileName;
114   fBkgrdFileNames = new TObjArray;
115   for (Int_t i = 0; i < sim.fBkgrdFileNames->GetEntriesFast(); i++) {
116     if (!sim.fBkgrdFileNames->At(i)) continue;
117     fBkgrdFileNames->Add(sim.fBkgrdFileNames->At(i)->Clone());
118   }
119
120   fRunLoader = NULL;
121 }
122
123 //_____________________________________________________________________________
124 AliSimulation& AliSimulation::operator = (const AliSimulation& sim)
125 {
126 // assignment operator
127
128   this->~AliSimulation();
129   new(this) AliSimulation(sim);
130   return *this;
131 }
132
133 //_____________________________________________________________________________
134 AliSimulation::~AliSimulation()
135 {
136 // clean up
137
138   fBkgrdFileNames->Delete();
139   delete fBkgrdFileNames;
140 }
141
142 //_____________________________________________________________________________
143 void AliSimulation::Init()
144 {
145 // set default parameters
146
147   fRunGeneration = kTRUE;
148   fRunSimulation = kTRUE;
149   fMakeSDigits = "ALL";
150   fMakeDigits = "ALL";
151   fMakeDigitsFromHits = "";
152   fStopOnError = kFALSE;
153
154   fNEvents = 1;
155   fConfigFileName = "Config.C";
156   fGAliceFileName = "galice.root";
157   fBkgrdFileNames = new TObjArray;
158   fRegionOfInterest = kTRUE;
159
160   fRunLoader = NULL;
161 }
162
163
164 //_____________________________________________________________________________
165 void AliSimulation::SetNumberOfEvents(Int_t nEvents)
166 {
167 // set the number of events for one run
168
169   fNEvents = nEvents;
170 }
171
172 //_____________________________________________________________________________
173 void AliSimulation::SetConfigFile(const char* fileName)
174 {
175 // set the name of the config file
176
177   fConfigFileName = fileName;
178 }
179
180 //_____________________________________________________________________________
181 void AliSimulation::MergeWith(const char* fileName, Int_t nSignalPerBkgrd)
182 {
183 // add a file with background events for merging
184
185   TObjString* fileNameStr = new TObjString(fileName);
186   fileNameStr->SetUniqueID(nSignalPerBkgrd);
187   fBkgrdFileNames->Add(fileNameStr);
188 }
189
190
191 //_____________________________________________________________________________
192 Bool_t AliSimulation::Run(Int_t nEvents)
193 {
194 // run the generation, simulation and digitization
195
196   if (nEvents > 0) fNEvents = nEvents;
197
198   // generation and simulation -> hits
199   if (fRunGeneration) {
200     if (!gAlice) {
201       Error("Run", "no gAlice object. Restart aliroot and try again.");
202       return kFALSE;
203     }
204     if (gAlice->Modules()->GetEntries() > 0) {
205       Error("Run", "gAlice was already run. Restart aliroot and try again.");
206       return kFALSE;
207     }
208     if (!RunSimulation()) if (fStopOnError) return kFALSE;
209   }
210
211   // reopen the run loader
212   if (fRunLoader) delete fRunLoader;
213   fRunLoader = AliRunLoader::Open(fGAliceFileName.Data(),AliConfig::fgkDefaultEventFolderName,"UPDATE");
214   if (!fRunLoader) {
215     Error("Run", "no run loader found in file %s", 
216           fGAliceFileName.Data());
217     return kFALSE;
218   }
219   fRunLoader->LoadgAlice();
220   gAlice = fRunLoader->GetAliRun();
221   if (!gAlice) {
222     Error("Run", "no gAlice object found in file %s", 
223           fGAliceFileName.Data());
224     return kFALSE;
225   }
226
227   // hits -> summable digits
228   if (!fMakeSDigits.IsNull()) {
229     if (!RunSDigitization(fMakeSDigits)) if (fStopOnError) return kFALSE;
230   }
231
232   // summable digits -> digits
233   if (!fMakeDigits.IsNull()) {
234     if (!RunDigitization(fMakeDigits, fMakeDigitsFromHits)) {
235       if (fStopOnError) return kFALSE;
236     }
237   }
238
239   // hits -> digits
240   if (!fMakeDigitsFromHits.IsNull()) {
241     if (fBkgrdFileNames->GetEntriesFast() > 0) {
242       Warning("Run", "Merging and direct creation of digits from hits " 
243               "was selected for some detectors. "
244               "No merging will be done for the following detectors: %s",
245               fMakeDigitsFromHits.Data());
246     }
247     if (!RunHitsDigitization(fMakeDigitsFromHits)) {
248       if (fStopOnError) return kFALSE;
249     }
250   }
251
252   return kTRUE;
253 }
254
255 //_____________________________________________________________________________
256 Bool_t AliSimulation::RunSimulation()
257 {
258 // run the generation and simulation
259
260   TStopwatch stopwatch;
261   stopwatch.Start();
262
263   Info("RunSimulation", "initializing gAlice with config file %s",
264        fConfigFileName.Data());
265   gAlice->Init(fConfigFileName.Data());
266   fRunLoader = gAlice->GetRunLoader();
267   if (!fRunLoader) {
268     Error("RunSimulation", "gAlice has no run loader object. "
269           "Check your config file: %s", fConfigFileName.Data());
270     return kFALSE;
271   }
272   fGAliceFileName = fRunLoader->GetFileName();
273
274   if (!fRunSimulation) {
275     if (!gAlice->Generator()) {
276       Error("RunSimulation", "gAlice has no generator object. "
277             "Check your config file: %s", fConfigFileName.Data());
278       return kFALSE;
279     }
280     gAlice->Generator()->SetTrackingFlag(0);
281   }
282
283   Info("RunSimulation", "running gAlice");
284   gAlice->Run(fNEvents);
285
286   Info("RunSimulation", "execution time:");
287   stopwatch.Print();
288
289   return kTRUE;
290 }
291
292 //_____________________________________________________________________________
293 Bool_t AliSimulation::RunSDigitization(const TString& detectors)
294 {
295 // run the digitization and produce summable digits
296
297   TStopwatch stopwatch;
298   stopwatch.Start();
299
300   TString detStr = detectors;
301   TObjArray* detArray = gAlice->Detectors();
302   for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
303     AliModule* det = (AliModule*) detArray->At(iDet);
304     if (!det || !det->IsActive()) continue;
305     if (IsSelected(det->GetName(), detStr)) {
306       Info("RunSDigitization", "creating summable digits for %s", 
307            det->GetName());
308       det->Hits2SDigits();
309     }
310   }
311
312   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
313     Error("RunSDigitization", "the following detectors were not found: %s", 
314           detStr.Data());
315     if (fStopOnError) return kFALSE;
316   }
317
318   Info("RunSDigitization", "execution time:");
319   stopwatch.Print();
320
321   return kTRUE;
322 }
323
324
325 //_____________________________________________________________________________
326 Bool_t AliSimulation::RunDigitization(const TString& detectors, 
327                                       const TString& excludeDetectors)
328 {
329 // run the digitization and produce digits from sdigits
330
331   TStopwatch stopwatch;
332   stopwatch.Start();
333
334   Int_t nStreams = fBkgrdFileNames->GetEntriesFast() + 1;
335   Int_t signalPerBkgrd = 1;
336   if (nStreams > 1) signalPerBkgrd = fBkgrdFileNames->At(0)->GetUniqueID();
337   AliRunDigitizer* manager = new AliRunDigitizer(nStreams, signalPerBkgrd);
338   manager->SetInputStream(0, fGAliceFileName.Data());
339   for (Int_t iStream = 1; iStream < nStreams; iStream++) {
340     const char* fileName = ((TObjString*)
341                             (fBkgrdFileNames->At(iStream-1)))->GetName();
342     manager->SetInputStream(iStream, fileName);
343   }
344
345   TString detStr = detectors;
346   TString detExcl = excludeDetectors;
347   TObjArray* detArray = gAlice->Detectors();
348   for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
349     AliModule* det = (AliModule*) detArray->At(iDet);
350     if (!det || !det->IsActive()) continue;
351     if (IsSelected(det->GetName(), detStr) && 
352         !IsSelected(det->GetName(), detExcl)) {
353       AliDigitizer* digitizer = det->CreateDigitizer(manager);
354       if (!digitizer) {
355         Error("RunDigitization", "no digitizer for %s", det->GetName());
356         if (fStopOnError) return kFALSE;
357       } else {
358         digitizer->SetRegionOfInterest(fRegionOfInterest);
359       }
360     }
361   }
362
363   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
364     Error("RunDigitization", "the following detectors were not found: %s", 
365           detStr.Data());
366     if (fStopOnError) return kFALSE;
367   }
368
369   if (!manager->GetListOfTasks()->IsEmpty()) {
370     Info("RunDigitization", "executing digitization");
371     manager->Exec("");
372   }
373   delete manager;
374
375   Info("RunDigitization", "execution time:");
376   stopwatch.Print();
377
378   return kTRUE;
379 }
380
381 //_____________________________________________________________________________
382 Bool_t AliSimulation::RunHitsDigitization(const TString& detectors)
383 {
384 // run the digitization and produce digits from hits
385
386   TStopwatch stopwatch;
387   stopwatch.Start();
388
389   TString detStr = detectors;
390   TObjArray* detArray = gAlice->Detectors();
391   for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
392     AliModule* det = (AliModule*) detArray->At(iDet);
393     if (!det || !det->IsActive()) continue;
394     if (IsSelected(det->GetName(), detStr)) {
395       Info("RunHitsDigitization", "creating digits from hits for %s", 
396            det->GetName());
397       det->Hits2Digits();
398     }
399   }
400
401   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
402     Error("RunHitsDigitization", "the following detectors were not found: %s", 
403           detStr.Data());
404     if (fStopOnError) return kFALSE;
405   }
406
407   Info("RunHitsDigitization", "execution time:");
408   stopwatch.Print();
409
410   return kTRUE;
411 }
412
413
414 //_____________________________________________________________________________
415 Bool_t AliSimulation::IsSelected(TString detName, TString& detectors) const
416 {
417 // check whether detName is contained in detectors
418 // if yes, it is removed from detectors
419
420   // check if all detectors are selected
421   if ((detectors.CompareTo("ALL") == 0) ||
422       detectors.BeginsWith("ALL ") ||
423       detectors.EndsWith(" ALL") ||
424       detectors.Contains(" ALL ")) {
425     detectors = "ALL";
426     return kTRUE;
427   }
428
429   // search for the given detector
430   Bool_t result = kFALSE;
431   if ((detectors.CompareTo(detName) == 0) ||
432       detectors.BeginsWith(detName+" ") ||
433       detectors.EndsWith(" "+detName) ||
434       detectors.Contains(" "+detName+" ")) {
435     detectors.ReplaceAll(detName, "");
436     result = kTRUE;
437   }
438
439   // clean up the detectors string
440   while (detectors.Contains("  ")) detectors.ReplaceAll("  ", " ");
441   while (detectors.BeginsWith(" ")) detectors.Remove(0, 1);
442   while (detectors.EndsWith(" ")) detectors.Remove(detectors.Length()-1, 1);
443
444   return result;
445 }