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 output of raw data can be switched on by calling //
77 // sim.SetWriteRawData("MUON"); // write raw data for MUON //
79 // The methods RunSimulation, RunSDigitization, RunDigitization, //
80 // RunHitsDigitization and WriteRawData can be used to run only parts of //
81 // the full simulation chain. //
83 ///////////////////////////////////////////////////////////////////////////////
85 #include <TObjString.h>
86 #include <TStopwatch.h>
89 #include "AliDigitizer.h"
90 #include "AliGenerator.h"
91 #include "AliModule.h"
93 #include "AliRunDigitizer.h"
94 #include "AliRunLoader.h"
95 #include "AliSimulation.h"
96 #include "AliVertexGenFile.h"
98 ClassImp(AliSimulation)
101 //_____________________________________________________________________________
102 AliSimulation::AliSimulation(const char* configFileName,
103 const char* name, const char* title) :
106 fRunGeneration(kTRUE),
107 fRunSimulation(kTRUE),
110 fMakeDigitsFromHits(""),
112 fStopOnError(kFALSE),
115 fConfigFileName(configFileName),
116 fGAliceFileName("galice.root"),
117 fBkgrdFileNames(NULL),
118 fUseBkgrdVertex(kTRUE),
119 fRegionOfInterest(kTRUE)
121 // create simulation object with default parameters
123 SetGAliceFile("galice.root");
126 //_____________________________________________________________________________
127 AliSimulation::AliSimulation(const AliSimulation& sim) :
130 fRunGeneration(sim.fRunGeneration),
131 fRunSimulation(sim.fRunSimulation),
132 fMakeSDigits(sim.fMakeSDigits),
133 fMakeDigits(sim.fMakeDigits),
134 fMakeDigitsFromHits(sim.fMakeDigitsFromHits),
135 fWriteRawData(sim.fWriteRawData),
136 fStopOnError(sim.fStopOnError),
138 fNEvents(sim.fNEvents),
139 fConfigFileName(sim.fConfigFileName),
140 fGAliceFileName(sim.fGAliceFileName),
141 fBkgrdFileNames(NULL),
142 fUseBkgrdVertex(sim.fUseBkgrdVertex),
143 fRegionOfInterest(sim.fRegionOfInterest)
147 fBkgrdFileNames = new TObjArray;
148 for (Int_t i = 0; i < sim.fBkgrdFileNames->GetEntriesFast(); i++) {
149 if (!sim.fBkgrdFileNames->At(i)) continue;
150 fBkgrdFileNames->Add(sim.fBkgrdFileNames->At(i)->Clone());
154 //_____________________________________________________________________________
155 AliSimulation& AliSimulation::operator = (const AliSimulation& sim)
157 // assignment operator
159 this->~AliSimulation();
160 new(this) AliSimulation(sim);
164 //_____________________________________________________________________________
165 AliSimulation::~AliSimulation()
169 if (fBkgrdFileNames) {
170 fBkgrdFileNames->Delete();
171 delete fBkgrdFileNames;
176 //_____________________________________________________________________________
177 void AliSimulation::SetNumberOfEvents(Int_t nEvents)
179 // set the number of events for one run
184 //_____________________________________________________________________________
185 void AliSimulation::SetConfigFile(const char* fileName)
187 // set the name of the config file
189 fConfigFileName = fileName;
192 //_____________________________________________________________________________
193 void AliSimulation::SetGAliceFile(const char* fileName)
195 // set the name of the galice file
196 // the path is converted to an absolute one if it is relative
198 fGAliceFileName = fileName;
199 if (!gSystem->IsAbsoluteFileName(fGAliceFileName)) {
200 char* absFileName = gSystem->ConcatFileName(gSystem->WorkingDirectory(),
202 fGAliceFileName = absFileName;
203 delete[] absFileName;
207 //_____________________________________________________________________________
208 void AliSimulation::MergeWith(const char* fileName, Int_t nSignalPerBkgrd)
210 // add a file with background events for merging
212 TObjString* fileNameStr = new TObjString(fileName);
213 fileNameStr->SetUniqueID(nSignalPerBkgrd);
214 if (!fBkgrdFileNames) fBkgrdFileNames = new TObjArray;
215 fBkgrdFileNames->Add(fileNameStr);
219 //_____________________________________________________________________________
220 Bool_t AliSimulation::Run(Int_t nEvents)
222 // run the generation, simulation and digitization
224 if (nEvents > 0) fNEvents = nEvents;
226 // generation and simulation -> hits
227 if (fRunGeneration) {
228 if (!RunSimulation()) if (fStopOnError) return kFALSE;
231 // hits -> summable digits
232 if (!fMakeSDigits.IsNull()) {
233 if (!RunSDigitization(fMakeSDigits)) if (fStopOnError) return kFALSE;
236 // summable digits -> digits
237 if (!fMakeDigits.IsNull()) {
238 if (!RunDigitization(fMakeDigits, fMakeDigitsFromHits)) {
239 if (fStopOnError) return kFALSE;
244 if (!fMakeDigitsFromHits.IsNull()) {
245 if (fBkgrdFileNames && (fBkgrdFileNames->GetEntriesFast() > 0)) {
246 Warning("Run", "Merging and direct creation of digits from hits "
247 "was selected for some detectors. "
248 "No merging will be done for the following detectors: %s",
249 fMakeDigitsFromHits.Data());
251 if (!RunHitsDigitization(fMakeDigitsFromHits)) {
252 if (fStopOnError) return kFALSE;
256 // digits -> raw data
257 if (!fWriteRawData.IsNull()) {
258 if (!WriteRawData(fWriteRawData)) {
259 if (fStopOnError) return kFALSE;
266 //_____________________________________________________________________________
267 Bool_t AliSimulation::RunSimulation(Int_t nEvents)
269 // run the generation and simulation
271 TStopwatch stopwatch;
275 Error("RunSimulation", "no gAlice object. Restart aliroot and try again.");
278 if (gAlice->Modules()->GetEntries() > 0) {
279 Error("RunSimulation",
280 "gAlice was already run. Restart aliroot and try again.");
284 Info("RunSimulation", "initializing gAlice with config file %s",
285 fConfigFileName.Data());
286 gAlice->Init(fConfigFileName.Data());
287 AliRunLoader* runLoader = gAlice->GetRunLoader();
289 Error("RunSimulation", "gAlice has no run loader object. "
290 "Check your config file: %s", fConfigFileName.Data());
293 SetGAliceFile(runLoader->GetFileName());
295 if (!gAlice->Generator()) {
296 Error("RunSimulation", "gAlice has no generator object. "
297 "Check your config file: %s", fConfigFileName.Data());
300 if (nEvents <= 0) nEvents = fNEvents;
302 // get vertex from background file in case of merging
303 if (fUseBkgrdVertex &&
304 fBkgrdFileNames && (fBkgrdFileNames->GetEntriesFast() > 0)) {
305 Int_t signalPerBkgrd = GetNSignalPerBkgrd(nEvents);
306 const char* fileName = ((TObjString*)
307 (fBkgrdFileNames->At(0)))->GetName();
308 Info("RunSimulation", "The vertex will be taken from the background "
309 "file %s with nSignalPerBackground = %d",
310 fileName, signalPerBkgrd);
311 AliVertexGenFile* vtxGen = new AliVertexGenFile(fileName, signalPerBkgrd);
312 gAlice->Generator()->SetVertexGenerator(vtxGen);
315 if (!fRunSimulation) {
316 gAlice->Generator()->SetTrackingFlag(0);
319 Info("RunSimulation", "running gAlice");
320 gAlice->Run(nEvents);
324 Info("RunSimulation", "execution time:");
330 //_____________________________________________________________________________
331 Bool_t AliSimulation::RunSDigitization(const char* detectors)
333 // run the digitization and produce summable digits
335 TStopwatch stopwatch;
338 AliRunLoader* runLoader = LoadRun();
339 if (!runLoader) return kFALSE;
341 TString detStr = detectors;
342 TObjArray* detArray = runLoader->GetAliRun()->Detectors();
343 for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
344 AliModule* det = (AliModule*) detArray->At(iDet);
345 if (!det || !det->IsActive()) continue;
346 if (IsSelected(det->GetName(), detStr)) {
347 Info("RunSDigitization", "creating summable digits for %s",
349 TStopwatch stopwatchDet;
350 stopwatchDet.Start();
352 Info("RunSDigitization", "execution time for %s:", det->GetName());
353 stopwatchDet.Print();
357 if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
358 Error("RunSDigitization", "the following detectors were not found: %s",
360 if (fStopOnError) return kFALSE;
365 Info("RunSDigitization", "execution time:");
372 //_____________________________________________________________________________
373 Bool_t AliSimulation::RunDigitization(const char* detectors,
374 const char* excludeDetectors)
376 // run the digitization and produce digits from sdigits
378 TStopwatch stopwatch;
381 while (AliRunLoader::GetRunLoader()) delete AliRunLoader::GetRunLoader();
382 if (gAlice) delete gAlice;
386 if (fBkgrdFileNames) nStreams = fBkgrdFileNames->GetEntriesFast() + 1;
387 Int_t signalPerBkgrd = GetNSignalPerBkgrd();
388 AliRunDigitizer* manager = new AliRunDigitizer(nStreams, signalPerBkgrd);
389 manager->SetInputStream(0, fGAliceFileName.Data());
390 for (Int_t iStream = 1; iStream < nStreams; iStream++) {
391 const char* fileName = ((TObjString*)
392 (fBkgrdFileNames->At(iStream-1)))->GetName();
393 manager->SetInputStream(iStream, fileName);
396 TString detStr = detectors;
397 TString detExcl = excludeDetectors;
398 manager->GetInputStream(0)->ImportgAlice();
399 AliRunLoader* runLoader =
400 AliRunLoader::GetRunLoader(manager->GetInputStream(0)->GetFolderName());
401 TObjArray* detArray = runLoader->GetAliRun()->Detectors();
402 for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
403 AliModule* det = (AliModule*) detArray->At(iDet);
404 if (!det || !det->IsActive()) continue;
405 if (IsSelected(det->GetName(), detStr) &&
406 !IsSelected(det->GetName(), detExcl)) {
407 AliDigitizer* digitizer = det->CreateDigitizer(manager);
409 Error("RunDigitization", "no digitizer for %s", det->GetName());
410 if (fStopOnError) return kFALSE;
412 digitizer->SetRegionOfInterest(fRegionOfInterest);
417 if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
418 Error("RunDigitization", "the following detectors were not found: %s",
420 if (fStopOnError) return kFALSE;
423 if (!manager->GetListOfTasks()->IsEmpty()) {
424 Info("RunDigitization", "executing digitization");
430 Info("RunDigitization", "execution time:");
436 //_____________________________________________________________________________
437 Bool_t AliSimulation::RunHitsDigitization(const char* detectors)
439 // run the digitization and produce digits from hits
441 TStopwatch stopwatch;
444 AliRunLoader* runLoader = LoadRun();
445 if (!runLoader) return kFALSE;
447 TString detStr = detectors;
448 TObjArray* detArray = runLoader->GetAliRun()->Detectors();
449 for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
450 AliModule* det = (AliModule*) detArray->At(iDet);
451 if (!det || !det->IsActive()) continue;
452 if (IsSelected(det->GetName(), detStr)) {
453 Info("RunHitsDigitization", "creating digits from hits for %s",
459 if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
460 Error("RunHitsDigitization", "the following detectors were not found: %s",
462 if (fStopOnError) return kFALSE;
467 Info("RunHitsDigitization", "execution time:");
473 //_____________________________________________________________________________
474 Bool_t AliSimulation::WriteRawData(const char* detectors)
476 // convert the digits to raw data
478 TStopwatch stopwatch;
481 AliRunLoader* runLoader = LoadRun();
482 if (!runLoader) return kFALSE;
484 for (Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); iEvent++) {
485 Info("WriteRawData", "processing event %d", iEvent);
486 runLoader->GetEvent(iEvent);
487 TString baseDir = gSystem->WorkingDirectory();
489 sprintf(dirName, "raw%d", iEvent);
490 gSystem->MakeDirectory(dirName);
491 if (!gSystem->ChangeDirectory(dirName)) {
492 Error("WriteRawData", "couldn't change to directory %s", dirName);
493 if (fStopOnError) return kFALSE; else continue;
496 TString detStr = detectors;
497 TObjArray* detArray = runLoader->GetAliRun()->Detectors();
498 for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
499 AliModule* det = (AliModule*) detArray->At(iDet);
500 if (!det || !det->IsActive()) continue;
501 if (IsSelected(det->GetName(), detStr)) {
502 Info("WriteRawData", "creating raw data from digits for %s",
508 gSystem->ChangeDirectory(baseDir);
509 if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
510 Error("WriteRawData", "the following detectors were not found: %s",
512 if (fStopOnError) return kFALSE;
518 Info("WriteRawData", "execution time:");
525 //_____________________________________________________________________________
526 AliRunLoader* AliSimulation::LoadRun() const
528 // delete existing run loaders, open a new one and load gAlice
530 while (AliRunLoader::GetRunLoader()) delete AliRunLoader::GetRunLoader();
531 AliRunLoader* runLoader =
532 AliRunLoader::Open(fGAliceFileName.Data(),
533 AliConfig::GetDefaultEventFolderName(), "UPDATE");
535 Error("LoadRun", "no run loader found in file %s",
536 fGAliceFileName.Data());
539 runLoader->LoadgAlice();
540 gAlice = runLoader->GetAliRun();
542 Error("LoadRun", "no gAlice object found in file %s",
543 fGAliceFileName.Data());
549 //_____________________________________________________________________________
550 Int_t AliSimulation::GetNSignalPerBkgrd(Int_t nEvents) const
552 // get or calculate the number of signal events per background event
554 if (!fBkgrdFileNames) return 1;
555 Int_t nBkgrdFiles = fBkgrdFileNames->GetEntriesFast();
556 if (nBkgrdFiles == 0) return 1;
558 // get the number of signal events
560 AliRunLoader* runLoader =
561 AliRunLoader::Open(fGAliceFileName.Data(), "SIGNAL");
562 if (!runLoader) return 1;
563 nEvents = runLoader->GetNumberOfEvents();
568 for (Int_t iBkgrdFile = 0; iBkgrdFile < nBkgrdFiles; iBkgrdFile++) {
569 // get the number of background events
570 const char* fileName = ((TObjString*)
571 (fBkgrdFileNames->At(iBkgrdFile)))->GetName();
572 AliRunLoader* runLoader =
573 AliRunLoader::Open(fileName, "BKGRD");
574 if (!runLoader) continue;
575 Int_t nBkgrdEvents = runLoader->GetNumberOfEvents();
578 // get or calculate the number of signal per background events
579 Int_t nSignalPerBkgrd = fBkgrdFileNames->At(iBkgrdFile)->GetUniqueID();
580 if (nSignalPerBkgrd <= 0) {
581 nSignalPerBkgrd = (nEvents-1) / nBkgrdEvents + 1;
582 } else if (result && (result != nSignalPerBkgrd)) {
583 Info("GetNSignalPerBkgrd", "the number of signal events per "
584 "background event will be changed from %d to %d for stream %d",
585 nSignalPerBkgrd, result, iBkgrdFile+1);
586 nSignalPerBkgrd = result;
589 if (!result) result = nSignalPerBkgrd;
590 if (nSignalPerBkgrd * nBkgrdEvents < nEvents) {
591 Warning("GetNSignalPerBkgrd", "not enough background events (%d) for "
592 "%d signal events using %d signal per background events for "
594 nBkgrdEvents, nEvents, nSignalPerBkgrd, iBkgrdFile+1);
601 //_____________________________________________________________________________
602 Bool_t AliSimulation::IsSelected(TString detName, TString& detectors) const
604 // check whether detName is contained in detectors
605 // if yes, it is removed from detectors
607 // check if all detectors are selected
608 if ((detectors.CompareTo("ALL") == 0) ||
609 detectors.BeginsWith("ALL ") ||
610 detectors.EndsWith(" ALL") ||
611 detectors.Contains(" ALL ")) {
616 // search for the given detector
617 Bool_t result = kFALSE;
618 if ((detectors.CompareTo(detName) == 0) ||
619 detectors.BeginsWith(detName+" ") ||
620 detectors.EndsWith(" "+detName) ||
621 detectors.Contains(" "+detName+" ")) {
622 detectors.ReplaceAll(detName, "");
626 // clean up the detectors string
627 while (detectors.Contains(" ")) detectors.ReplaceAll(" ", " ");
628 while (detectors.BeginsWith(" ")) detectors.Remove(0, 1);
629 while (detectors.EndsWith(" ")) detectors.Remove(detectors.Length()-1, 1);