1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 ///////////////////////////////////////////////////////////////////////////////
20 // class for running generation, simulation and digitization //
22 // Hits, sdigits and digits are created for all detectors by typing: //
24 // AliSimulation sim; //
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 //
31 // sim.SetNumberOfEvents(n); //
33 // The name of the configuration file can be passed as argument to the //
34 // AliSimulation constructor or can be specified by //
36 // sim.SetConfigFile("..."); //
38 // The generation of particles and the simulation of detector hits can be //
39 // switched on or off by //
41 // sim.SetRunGeneration(kTRUE); // generation of primary particles //
42 // sim.SetRunSimulation(kFALSE); // but no tracking //
44 // For which detectors sdigits and digits will be created, can be steered //
47 // sim.SetMakeSDigits("ALL"); // make sdigits for all detectors //
48 // sim.SetMakeDigits("ITS TPC"); // make digits only for ITS and TPC //
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. //
55 // The creation of digits from hits instead of from sdigits can be selected //
58 // sim.SetMakeDigitsFromHits("TRD"); //
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. //
64 // Background events can be merged by calling //
66 // sim.MergeWith("background/galice.root", 2); //
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. //
75 // The methods RunSimulation, RunSDigitization, RunDigitization and //
76 // RunHitsDigitization can be used to run only parts of the full simulation //
79 ///////////////////////////////////////////////////////////////////////////////
82 #include "AliSimulation.h"
83 #include "AliRunLoader.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>
93 ClassImp(AliSimulation)
96 //_____________________________________________________________________________
97 AliSimulation::AliSimulation(const char* configFileName,
98 const char* name, const char* title) :
101 fRunGeneration(kTRUE),
102 fRunSimulation(kTRUE),
105 fMakeDigitsFromHits(""),
106 fStopOnError(kFALSE),
109 fConfigFileName(configFileName),
110 fGAliceFileName("galice.root"),
111 fBkgrdFileNames(NULL),
112 fUseBkgrdVertex(kTRUE),
113 fRegionOfInterest(kTRUE)
115 // create simulation object with default parameters
119 //_____________________________________________________________________________
120 AliSimulation::AliSimulation(const AliSimulation& sim) :
123 fRunGeneration(sim.fRunGeneration),
124 fRunSimulation(sim.fRunSimulation),
125 fMakeSDigits(sim.fMakeSDigits),
126 fMakeDigits(sim.fMakeDigits),
127 fMakeDigitsFromHits(sim.fMakeDigitsFromHits),
128 fStopOnError(sim.fStopOnError),
130 fNEvents(sim.fNEvents),
131 fConfigFileName(sim.fConfigFileName),
132 fGAliceFileName(sim.fGAliceFileName),
133 fBkgrdFileNames(NULL),
134 fUseBkgrdVertex(sim.fUseBkgrdVertex),
135 fRegionOfInterest(sim.fRegionOfInterest)
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());
146 //_____________________________________________________________________________
147 AliSimulation& AliSimulation::operator = (const AliSimulation& sim)
149 // assignment operator
151 this->~AliSimulation();
152 new(this) AliSimulation(sim);
156 //_____________________________________________________________________________
157 AliSimulation::~AliSimulation()
161 if (fBkgrdFileNames) {
162 fBkgrdFileNames->Delete();
163 delete fBkgrdFileNames;
168 //_____________________________________________________________________________
169 void AliSimulation::SetNumberOfEvents(Int_t nEvents)
171 // set the number of events for one run
176 //_____________________________________________________________________________
177 void AliSimulation::SetConfigFile(const char* fileName)
179 // set the name of the config file
181 fConfigFileName = fileName;
184 //_____________________________________________________________________________
185 void AliSimulation::MergeWith(const char* fileName, Int_t nSignalPerBkgrd)
187 // add a file with background events for merging
189 TObjString* fileNameStr = new TObjString(fileName);
190 fileNameStr->SetUniqueID(nSignalPerBkgrd);
191 if (!fBkgrdFileNames) fBkgrdFileNames = new TObjArray;
192 fBkgrdFileNames->Add(fileNameStr);
196 //_____________________________________________________________________________
197 Bool_t AliSimulation::Run(Int_t nEvents)
199 // run the generation, simulation and digitization
201 if (nEvents > 0) fNEvents = nEvents;
203 // generation and simulation -> hits
204 if (fRunGeneration) {
205 if (!RunSimulation()) if (fStopOnError) return kFALSE;
208 // hits -> summable digits
209 if (!fMakeSDigits.IsNull()) {
210 if (!RunSDigitization(fMakeSDigits)) if (fStopOnError) return kFALSE;
213 // summable digits -> digits
214 if (!fMakeDigits.IsNull()) {
215 if (!RunDigitization(fMakeDigits, fMakeDigitsFromHits)) {
216 if (fStopOnError) return kFALSE;
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());
228 if (!RunHitsDigitization(fMakeDigitsFromHits)) {
229 if (fStopOnError) return kFALSE;
236 //_____________________________________________________________________________
237 Bool_t AliSimulation::RunSimulation(Int_t nEvents)
239 // run the generation and simulation
241 TStopwatch stopwatch;
245 Error("RunSimulation", "no gAlice object. Restart aliroot and try again.");
248 if (gAlice->Modules()->GetEntries() > 0) {
249 Error("RunSimulation",
250 "gAlice was already run. Restart aliroot and try again.");
254 Info("RunSimulation", "initializing gAlice with config file %s",
255 fConfigFileName.Data());
256 gAlice->Init(fConfigFileName.Data());
257 AliRunLoader* runLoader = gAlice->GetRunLoader();
259 Error("RunSimulation", "gAlice has no run loader object. "
260 "Check your config file: %s", fConfigFileName.Data());
263 fGAliceFileName = runLoader->GetFileName();
265 if (!gAlice->Generator()) {
266 Error("RunSimulation", "gAlice has no generator object. "
267 "Check your config file: %s", fConfigFileName.Data());
270 if (nEvents <= 0) nEvents = fNEvents;
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);
285 if (!fRunSimulation) {
286 gAlice->Generator()->SetTrackingFlag(0);
289 Info("RunSimulation", "running gAlice");
290 gAlice->Run(nEvents);
294 Info("RunSimulation", "execution time:");
300 //_____________________________________________________________________________
301 Bool_t AliSimulation::RunSDigitization(const char* detectors)
303 // run the digitization and produce summable digits
305 TStopwatch stopwatch;
308 AliRunLoader* runLoader = LoadRun();
309 if (!runLoader) return kFALSE;
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",
319 TStopwatch stopwatchDet;
320 stopwatchDet.Start();
322 Info("RunSDigitization", "execution time for %s:", det->GetName());
323 stopwatchDet.Print();
327 if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
328 Error("RunSDigitization", "the following detectors were not found: %s",
330 if (fStopOnError) return kFALSE;
335 Info("RunSDigitization", "execution time:");
342 //_____________________________________________________________________________
343 Bool_t AliSimulation::RunDigitization(const char* detectors,
344 const char* excludeDetectors)
346 // run the digitization and produce digits from sdigits
348 TStopwatch stopwatch;
351 while (AliRunLoader::GetRunLoader()) delete AliRunLoader::GetRunLoader();
352 if (gAlice) delete gAlice;
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);
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);
379 Error("RunDigitization", "no digitizer for %s", det->GetName());
380 if (fStopOnError) return kFALSE;
382 digitizer->SetRegionOfInterest(fRegionOfInterest);
387 if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
388 Error("RunDigitization", "the following detectors were not found: %s",
390 if (fStopOnError) return kFALSE;
393 if (!manager->GetListOfTasks()->IsEmpty()) {
394 Info("RunDigitization", "executing digitization");
400 Info("RunDigitization", "execution time:");
406 //_____________________________________________________________________________
407 Bool_t AliSimulation::RunHitsDigitization(const char* detectors)
409 // run the digitization and produce digits from hits
411 TStopwatch stopwatch;
414 AliRunLoader* runLoader = LoadRun();
415 if (!runLoader) return kFALSE;
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",
429 if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
430 Error("RunHitsDigitization", "the following detectors were not found: %s",
432 if (fStopOnError) return kFALSE;
437 Info("RunHitsDigitization", "execution time:");
444 //_____________________________________________________________________________
445 AliRunLoader* AliSimulation::LoadRun() const
447 // delete existing run loaders, open a new one and load gAlice
449 while (AliRunLoader::GetRunLoader()) delete AliRunLoader::GetRunLoader();
450 AliRunLoader* runLoader =
451 AliRunLoader::Open(fGAliceFileName.Data(),
452 AliConfig::fgkDefaultEventFolderName, "UPDATE");
454 Error("LoadRun", "no run loader found in file %s",
455 fGAliceFileName.Data());
458 runLoader->LoadgAlice();
459 gAlice = runLoader->GetAliRun();
461 Error("LoadRun", "no gAlice object found in file %s",
462 fGAliceFileName.Data());
468 //_____________________________________________________________________________
469 Int_t AliSimulation::GetNSignalPerBkgrd(Int_t nEvents) const
471 // get or calculate the number of signal events per background event
473 if (!fBkgrdFileNames) return 1;
474 Int_t nBkgrdFiles = fBkgrdFileNames->GetEntriesFast();
475 if (nBkgrdFiles == 0) return 1;
477 // get the number of signal events
479 AliRunLoader* runLoader =
480 AliRunLoader::Open(fGAliceFileName.Data(), "SIGNAL");
481 if (!runLoader) return 1;
482 nEvents = runLoader->GetNumberOfEvents();
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();
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;
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 "
513 nBkgrdEvents, nEvents, nSignalPerBkgrd, iBkgrdFile+1);
520 //_____________________________________________________________________________
521 Bool_t AliSimulation::IsSelected(TString detName, TString& detectors) const
523 // check whether detName is contained in detectors
524 // if yes, it is removed from detectors
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 ")) {
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, "");
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);