]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliSimulation.cxx
Auto-defining the number of signal events merged with each underlying event (T.Kuhr)
[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 methods RunSimulation, RunSDigitization, RunDigitization and          //
76 // RunHitsDigitization can be used to run only parts of the full simulation  //
77 // chain.                                                                    //
78 //                                                                           //
79 ///////////////////////////////////////////////////////////////////////////////
80
81
82 #include "AliSimulation.h"
83 #include "AliRunLoader.h"
84 #include "AliRun.h"
85 #include "AliModule.h"
86 #include "AliGenerator.h"
87 #include "AliVertexGenFile.h"
88 #include "AliRunDigitizer.h"
89 #include "AliDigitizer.h"
90 #include <TObjString.h>
91
92
93 ClassImp(AliSimulation)
94
95
96 //_____________________________________________________________________________
97 AliSimulation::AliSimulation(const char* configFileName,
98                              const char* name, const char* title) :
99   TNamed(name, title),
100
101   fRunGeneration(kTRUE),
102   fRunSimulation(kTRUE),
103   fMakeSDigits("ALL"),
104   fMakeDigits("ALL"),
105   fMakeDigitsFromHits(""),
106   fStopOnError(kFALSE),
107
108   fNEvents(1),
109   fConfigFileName(configFileName),
110   fGAliceFileName("galice.root"),
111   fBkgrdFileNames(NULL),
112   fUseBkgrdVertex(kTRUE),
113   fRegionOfInterest(kTRUE)
114 {
115 // create simulation object with default parameters
116
117 }
118
119 //_____________________________________________________________________________
120 AliSimulation::AliSimulation(const AliSimulation& sim) :
121   TNamed(sim),
122
123   fRunGeneration(sim.fRunGeneration),
124   fRunSimulation(sim.fRunSimulation),
125   fMakeSDigits(sim.fMakeSDigits),
126   fMakeDigits(sim.fMakeDigits),
127   fMakeDigitsFromHits(sim.fMakeDigitsFromHits),
128   fStopOnError(sim.fStopOnError),
129
130   fNEvents(sim.fNEvents),
131   fConfigFileName(sim.fConfigFileName),
132   fGAliceFileName(sim.fGAliceFileName),
133   fBkgrdFileNames(NULL),
134   fUseBkgrdVertex(sim.fUseBkgrdVertex),
135   fRegionOfInterest(sim.fRegionOfInterest)
136 {
137 // copy constructor
138
139   fBkgrdFileNames = new TObjArray;
140   for (Int_t i = 0; i < sim.fBkgrdFileNames->GetEntriesFast(); i++) {
141     if (!sim.fBkgrdFileNames->At(i)) continue;
142     fBkgrdFileNames->Add(sim.fBkgrdFileNames->At(i)->Clone());
143   }
144 }
145
146 //_____________________________________________________________________________
147 AliSimulation& AliSimulation::operator = (const AliSimulation& sim)
148 {
149 // assignment operator
150
151   this->~AliSimulation();
152   new(this) AliSimulation(sim);
153   return *this;
154 }
155
156 //_____________________________________________________________________________
157 AliSimulation::~AliSimulation()
158 {
159 // clean up
160
161   if (fBkgrdFileNames) {
162     fBkgrdFileNames->Delete();
163     delete fBkgrdFileNames;
164   }
165 }
166
167
168 //_____________________________________________________________________________
169 void AliSimulation::SetNumberOfEvents(Int_t nEvents)
170 {
171 // set the number of events for one run
172
173   fNEvents = nEvents;
174 }
175
176 //_____________________________________________________________________________
177 void AliSimulation::SetConfigFile(const char* fileName)
178 {
179 // set the name of the config file
180
181   fConfigFileName = fileName;
182 }
183
184 //_____________________________________________________________________________
185 void AliSimulation::MergeWith(const char* fileName, Int_t nSignalPerBkgrd)
186 {
187 // add a file with background events for merging
188
189   TObjString* fileNameStr = new TObjString(fileName);
190   fileNameStr->SetUniqueID(nSignalPerBkgrd);
191   if (!fBkgrdFileNames) fBkgrdFileNames = new TObjArray;
192   fBkgrdFileNames->Add(fileNameStr);
193 }
194
195
196 //_____________________________________________________________________________
197 Bool_t AliSimulation::Run(Int_t nEvents)
198 {
199 // run the generation, simulation and digitization
200
201   if (nEvents > 0) fNEvents = nEvents;
202
203   // generation and simulation -> hits
204   if (fRunGeneration) {
205     if (!RunSimulation()) if (fStopOnError) return kFALSE;
206   }
207
208   // hits -> summable digits
209   if (!fMakeSDigits.IsNull()) {
210     if (!RunSDigitization(fMakeSDigits)) if (fStopOnError) return kFALSE;
211   }
212
213   // summable digits -> digits
214   if (!fMakeDigits.IsNull()) {
215     if (!RunDigitization(fMakeDigits, fMakeDigitsFromHits)) {
216       if (fStopOnError) return kFALSE;
217     }
218   }
219
220   // hits -> digits
221   if (!fMakeDigitsFromHits.IsNull()) {
222     if (fBkgrdFileNames && (fBkgrdFileNames->GetEntriesFast() > 0)) {
223       Warning("Run", "Merging and direct creation of digits from hits " 
224               "was selected for some detectors. "
225               "No merging will be done for the following detectors: %s",
226               fMakeDigitsFromHits.Data());
227     }
228     if (!RunHitsDigitization(fMakeDigitsFromHits)) {
229       if (fStopOnError) return kFALSE;
230     }
231   }
232
233   return kTRUE;
234 }
235
236 //_____________________________________________________________________________
237 Bool_t AliSimulation::RunSimulation(Int_t nEvents)
238 {
239 // run the generation and simulation
240
241   TStopwatch stopwatch;
242   stopwatch.Start();
243
244   if (!gAlice) {
245     Error("RunSimulation", "no gAlice object. Restart aliroot and try again.");
246     return kFALSE;
247   }
248   if (gAlice->Modules()->GetEntries() > 0) {
249     Error("RunSimulation", 
250           "gAlice was already run. Restart aliroot and try again.");
251     return kFALSE;
252   }
253
254   Info("RunSimulation", "initializing gAlice with config file %s",
255        fConfigFileName.Data());
256   gAlice->Init(fConfigFileName.Data());
257   AliRunLoader* runLoader = gAlice->GetRunLoader();
258   if (!runLoader) {
259     Error("RunSimulation", "gAlice has no run loader object. "
260           "Check your config file: %s", fConfigFileName.Data());
261     return kFALSE;
262   }
263   fGAliceFileName = runLoader->GetFileName();
264
265   if (!gAlice->Generator()) {
266     Error("RunSimulation", "gAlice has no generator object. "
267           "Check your config file: %s", fConfigFileName.Data());
268     return kFALSE;
269   }
270   if (nEvents <= 0) nEvents = fNEvents;
271
272   // get vertex from background file in case of merging
273   if (fUseBkgrdVertex &&
274       fBkgrdFileNames && (fBkgrdFileNames->GetEntriesFast() > 0)) {
275     Int_t signalPerBkgrd = GetNSignalPerBkgrd(nEvents);
276     const char* fileName = ((TObjString*)
277                             (fBkgrdFileNames->At(0)))->GetName();
278     Info("RunSimulation", "The vertex will be taken from the background "
279          "file %s with nSignalPerBackground = %d", 
280          fileName, signalPerBkgrd);
281     AliVertexGenFile* vtxGen = new AliVertexGenFile(fileName, signalPerBkgrd);
282     gAlice->Generator()->SetVertexGenerator(vtxGen);
283   }
284
285   if (!fRunSimulation) {
286     gAlice->Generator()->SetTrackingFlag(0);
287   }
288
289   Info("RunSimulation", "running gAlice");
290   gAlice->Run(nEvents);
291
292   delete runLoader;
293
294   Info("RunSimulation", "execution time:");
295   stopwatch.Print();
296
297   return kTRUE;
298 }
299
300 //_____________________________________________________________________________
301 Bool_t AliSimulation::RunSDigitization(const char* detectors)
302 {
303 // run the digitization and produce summable digits
304
305   TStopwatch stopwatch;
306   stopwatch.Start();
307
308   AliRunLoader* runLoader = LoadRun();
309   if (!runLoader) return kFALSE;
310
311   TString detStr = detectors;
312   TObjArray* detArray = runLoader->GetAliRun()->Detectors();
313   for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
314     AliModule* det = (AliModule*) detArray->At(iDet);
315     if (!det || !det->IsActive()) continue;
316     if (IsSelected(det->GetName(), detStr)) {
317       Info("RunSDigitization", "creating summable digits for %s", 
318            det->GetName());
319       TStopwatch stopwatchDet;
320       stopwatchDet.Start();
321       det->Hits2SDigits();
322       Info("RunSDigitization", "execution time for %s:", det->GetName());
323       stopwatchDet.Print();
324     }
325   }
326
327   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
328     Error("RunSDigitization", "the following detectors were not found: %s", 
329           detStr.Data());
330     if (fStopOnError) return kFALSE;
331   }
332
333   delete runLoader;
334
335   Info("RunSDigitization", "execution time:");
336   stopwatch.Print();
337
338   return kTRUE;
339 }
340
341
342 //_____________________________________________________________________________
343 Bool_t AliSimulation::RunDigitization(const char* detectors, 
344                                       const char* excludeDetectors)
345 {
346 // run the digitization and produce digits from sdigits
347
348   TStopwatch stopwatch;
349   stopwatch.Start();
350
351   while (AliRunLoader::GetRunLoader()) delete AliRunLoader::GetRunLoader();
352   if (gAlice) delete gAlice;
353   gAlice = NULL;
354
355   Int_t nStreams = 1;
356   if (fBkgrdFileNames) nStreams = fBkgrdFileNames->GetEntriesFast() + 1;
357   Int_t signalPerBkgrd = GetNSignalPerBkgrd();
358   AliRunDigitizer* manager = new AliRunDigitizer(nStreams, signalPerBkgrd);
359   manager->SetInputStream(0, fGAliceFileName.Data());
360   for (Int_t iStream = 1; iStream < nStreams; iStream++) {
361     const char* fileName = ((TObjString*)
362                             (fBkgrdFileNames->At(iStream-1)))->GetName();
363     manager->SetInputStream(iStream, fileName);
364   }
365
366   TString detStr = detectors;
367   TString detExcl = excludeDetectors;
368   manager->GetInputStream(0)->ImportgAlice();
369   AliRunLoader* runLoader = 
370     AliRunLoader::GetRunLoader(manager->GetInputStream(0)->GetFolderName());
371   TObjArray* detArray = runLoader->GetAliRun()->Detectors();
372   for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
373     AliModule* det = (AliModule*) detArray->At(iDet);
374     if (!det || !det->IsActive()) continue;
375     if (IsSelected(det->GetName(), detStr) && 
376         !IsSelected(det->GetName(), detExcl)) {
377       AliDigitizer* digitizer = det->CreateDigitizer(manager);
378       if (!digitizer) {
379         Error("RunDigitization", "no digitizer for %s", det->GetName());
380         if (fStopOnError) return kFALSE;
381       } else {
382         digitizer->SetRegionOfInterest(fRegionOfInterest);
383       }
384     }
385   }
386
387   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
388     Error("RunDigitization", "the following detectors were not found: %s", 
389           detStr.Data());
390     if (fStopOnError) return kFALSE;
391   }
392
393   if (!manager->GetListOfTasks()->IsEmpty()) {
394     Info("RunDigitization", "executing digitization");
395     manager->Exec("");
396   }
397
398   delete manager;
399
400   Info("RunDigitization", "execution time:");
401   stopwatch.Print();
402
403   return kTRUE;
404 }
405
406 //_____________________________________________________________________________
407 Bool_t AliSimulation::RunHitsDigitization(const char* detectors)
408 {
409 // run the digitization and produce digits from hits
410
411   TStopwatch stopwatch;
412   stopwatch.Start();
413
414   AliRunLoader* runLoader = LoadRun();
415   if (!runLoader) return kFALSE;
416
417   TString detStr = detectors;
418   TObjArray* detArray = runLoader->GetAliRun()->Detectors();
419   for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
420     AliModule* det = (AliModule*) detArray->At(iDet);
421     if (!det || !det->IsActive()) continue;
422     if (IsSelected(det->GetName(), detStr)) {
423       Info("RunHitsDigitization", "creating digits from hits for %s", 
424            det->GetName());
425       det->Hits2Digits();
426     }
427   }
428
429   if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
430     Error("RunHitsDigitization", "the following detectors were not found: %s", 
431           detStr.Data());
432     if (fStopOnError) return kFALSE;
433   }
434
435   delete runLoader;
436
437   Info("RunHitsDigitization", "execution time:");
438   stopwatch.Print();
439
440   return kTRUE;
441 }
442
443
444 //_____________________________________________________________________________
445 AliRunLoader* AliSimulation::LoadRun() const
446 {
447 // delete existing run loaders, open a new one and load gAlice
448
449   while (AliRunLoader::GetRunLoader()) delete AliRunLoader::GetRunLoader();
450   AliRunLoader* runLoader = 
451     AliRunLoader::Open(fGAliceFileName.Data(), 
452                        AliConfig::fgkDefaultEventFolderName, "UPDATE");
453   if (!runLoader) {
454     Error("LoadRun", "no run loader found in file %s", 
455           fGAliceFileName.Data());
456     return NULL;
457   }
458   runLoader->LoadgAlice();
459   gAlice = runLoader->GetAliRun();
460   if (!gAlice) {
461     Error("LoadRun", "no gAlice object found in file %s", 
462           fGAliceFileName.Data());
463     return NULL;
464   }
465   return runLoader;
466 }
467
468 //_____________________________________________________________________________
469 Int_t AliSimulation::GetNSignalPerBkgrd(Int_t nEvents) const
470 {
471 // get or calculate the number of signal events per background event
472
473   if (!fBkgrdFileNames) return 1;
474   Int_t nBkgrdFiles = fBkgrdFileNames->GetEntriesFast();
475   if (nBkgrdFiles == 0) return 1;
476
477   // get the number of signal events
478   if (nEvents <= 0) {
479     AliRunLoader* runLoader = 
480       AliRunLoader::Open(fGAliceFileName.Data(), "SIGNAL");
481     if (!runLoader) return 1;
482     nEvents = runLoader->GetNumberOfEvents();
483     delete runLoader;
484   }
485
486   Int_t result = 0;
487   for (Int_t iBkgrdFile = 0; iBkgrdFile < nBkgrdFiles; iBkgrdFile++) {
488     // get the number of background events
489     const char* fileName = ((TObjString*)
490                             (fBkgrdFileNames->At(iBkgrdFile)))->GetName();
491     AliRunLoader* runLoader = 
492       AliRunLoader::Open(fileName, "BKGRD");
493     if (!runLoader) continue;
494     Int_t nBkgrdEvents = runLoader->GetNumberOfEvents();
495     delete runLoader;
496
497     // get or calculate the number of signal per background events
498     Int_t nSignalPerBkgrd = fBkgrdFileNames->At(iBkgrdFile)->GetUniqueID();
499     if (nSignalPerBkgrd <= 0) {
500       nSignalPerBkgrd = (nEvents-1) / nBkgrdEvents + 1;
501     } else if (result && (result != nSignalPerBkgrd)) {
502       Info("GetNSignalPerBkgrd", "the number of signal events per "
503            "background event will be changed from %d to %d for stream %d", 
504            nSignalPerBkgrd, result, iBkgrdFile+1);
505       nSignalPerBkgrd = result;
506     }
507
508     if (!result) result = nSignalPerBkgrd;
509     if (nSignalPerBkgrd * nBkgrdEvents < nEvents) {
510       Warning("GetNSignalPerBkgrd", "not enough background events (%d) for "
511               "%d signal events using %d signal per background events for "
512               "stream %d", 
513               nBkgrdEvents, nEvents, nSignalPerBkgrd, iBkgrdFile+1);
514     }
515   }
516
517   return result;
518 }
519
520 //_____________________________________________________________________________
521 Bool_t AliSimulation::IsSelected(TString detName, TString& detectors) const
522 {
523 // check whether detName is contained in detectors
524 // if yes, it is removed from detectors
525
526   // check if all detectors are selected
527   if ((detectors.CompareTo("ALL") == 0) ||
528       detectors.BeginsWith("ALL ") ||
529       detectors.EndsWith(" ALL") ||
530       detectors.Contains(" ALL ")) {
531     detectors = "ALL";
532     return kTRUE;
533   }
534
535   // search for the given detector
536   Bool_t result = kFALSE;
537   if ((detectors.CompareTo(detName) == 0) ||
538       detectors.BeginsWith(detName+" ") ||
539       detectors.EndsWith(" "+detName) ||
540       detectors.Contains(" "+detName+" ")) {
541     detectors.ReplaceAll(detName, "");
542     result = kTRUE;
543   }
544
545   // clean up the detectors string
546   while (detectors.Contains("  ")) detectors.ReplaceAll("  ", " ");
547   while (detectors.BeginsWith(" ")) detectors.Remove(0, 1);
548   while (detectors.EndsWith(" ")) detectors.Remove(detectors.Length()-1, 1);
549
550   return result;
551 }