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 // The default number of events per file, which is usually set in the //
84 // config file, can be changed for individual detectors and data types //
87 // sim.SetEventsPerFile("PHOS", "Reconstructed Points", 3); //
89 // The first argument is the detector, the second one the data type and the //
90 // last one the number of events per file. Valid data types are "Hits", //
91 // "Summable Digits", "Digits", "Reconstructed Points" and "Tracks". //
92 // The number of events per file has to be set before the simulation of //
93 // hits. Otherwise it has no effect. //
95 ///////////////////////////////////////////////////////////////////////////////
97 #include <TObjString.h>
98 #include <TStopwatch.h>
101 #include "AliDigitizer.h"
102 #include "AliGenerator.h"
103 #include "AliModule.h"
105 #include "AliRunDigitizer.h"
106 #include "AliRunLoader.h"
107 #include "AliSimulation.h"
108 #include "AliVertexGenFile.h"
110 ClassImp(AliSimulation)
113 //_____________________________________________________________________________
114 AliSimulation::AliSimulation(const char* configFileName,
115 const char* name, const char* title) :
118 fRunGeneration(kTRUE),
119 fRunSimulation(kTRUE),
122 fMakeDigitsFromHits(""),
124 fStopOnError(kFALSE),
127 fConfigFileName(configFileName),
128 fGAliceFileName("galice.root"),
130 fBkgrdFileNames(NULL),
131 fUseBkgrdVertex(kTRUE),
132 fRegionOfInterest(kTRUE)
134 // create simulation object with default parameters
136 SetGAliceFile("galice.root");
139 //_____________________________________________________________________________
140 AliSimulation::AliSimulation(const AliSimulation& sim) :
143 fRunGeneration(sim.fRunGeneration),
144 fRunSimulation(sim.fRunSimulation),
145 fMakeSDigits(sim.fMakeSDigits),
146 fMakeDigits(sim.fMakeDigits),
147 fMakeDigitsFromHits(sim.fMakeDigitsFromHits),
148 fWriteRawData(sim.fWriteRawData),
149 fStopOnError(sim.fStopOnError),
151 fNEvents(sim.fNEvents),
152 fConfigFileName(sim.fConfigFileName),
153 fGAliceFileName(sim.fGAliceFileName),
155 fBkgrdFileNames(NULL),
156 fUseBkgrdVertex(sim.fUseBkgrdVertex),
157 fRegionOfInterest(sim.fRegionOfInterest)
161 for (Int_t i = 0; i < sim.fEventsPerFile.GetEntriesFast(); i++) {
162 if (!sim.fEventsPerFile[i]) continue;
163 fEventsPerFile.Add(sim.fEventsPerFile[i]->Clone());
166 fBkgrdFileNames = new TObjArray;
167 for (Int_t i = 0; i < sim.fBkgrdFileNames->GetEntriesFast(); i++) {
168 if (!sim.fBkgrdFileNames->At(i)) continue;
169 fBkgrdFileNames->Add(sim.fBkgrdFileNames->At(i)->Clone());
173 //_____________________________________________________________________________
174 AliSimulation& AliSimulation::operator = (const AliSimulation& sim)
176 // assignment operator
178 this->~AliSimulation();
179 new(this) AliSimulation(sim);
183 //_____________________________________________________________________________
184 AliSimulation::~AliSimulation()
188 fEventsPerFile.Delete();
190 if (fBkgrdFileNames) {
191 fBkgrdFileNames->Delete();
192 delete fBkgrdFileNames;
197 //_____________________________________________________________________________
198 void AliSimulation::SetNumberOfEvents(Int_t nEvents)
200 // set the number of events for one run
205 //_____________________________________________________________________________
206 void AliSimulation::SetConfigFile(const char* fileName)
208 // set the name of the config file
210 fConfigFileName = fileName;
213 //_____________________________________________________________________________
214 void AliSimulation::SetGAliceFile(const char* fileName)
216 // set the name of the galice file
217 // the path is converted to an absolute one if it is relative
219 fGAliceFileName = fileName;
220 if (!gSystem->IsAbsoluteFileName(fGAliceFileName)) {
221 char* absFileName = gSystem->ConcatFileName(gSystem->WorkingDirectory(),
223 fGAliceFileName = absFileName;
224 delete[] absFileName;
228 //_____________________________________________________________________________
229 void AliSimulation::SetEventsPerFile(const char* detector, const char* type,
232 // set the number of events per file for the given detector and data type
233 // ("Hits", "Summable Digits", "Digits", "Reconstructed Points" or "Tracks")
235 TNamed* obj = new TNamed(detector, type);
236 obj->SetUniqueID(nEvents);
237 fEventsPerFile.Add(obj);
240 //_____________________________________________________________________________
241 void AliSimulation::MergeWith(const char* fileName, Int_t nSignalPerBkgrd)
243 // add a file with background events for merging
245 TObjString* fileNameStr = new TObjString(fileName);
246 fileNameStr->SetUniqueID(nSignalPerBkgrd);
247 if (!fBkgrdFileNames) fBkgrdFileNames = new TObjArray;
248 fBkgrdFileNames->Add(fileNameStr);
252 //_____________________________________________________________________________
253 Bool_t AliSimulation::Run(Int_t nEvents)
255 // run the generation, simulation and digitization
257 if (nEvents > 0) fNEvents = nEvents;
259 // generation and simulation -> hits
260 if (fRunGeneration) {
261 if (!RunSimulation()) if (fStopOnError) return kFALSE;
264 // hits -> summable digits
265 if (!fMakeSDigits.IsNull()) {
266 if (!RunSDigitization(fMakeSDigits)) if (fStopOnError) return kFALSE;
269 // summable digits -> digits
270 if (!fMakeDigits.IsNull()) {
271 if (!RunDigitization(fMakeDigits, fMakeDigitsFromHits)) {
272 if (fStopOnError) return kFALSE;
277 if (!fMakeDigitsFromHits.IsNull()) {
278 if (fBkgrdFileNames && (fBkgrdFileNames->GetEntriesFast() > 0)) {
279 Warning("Run", "Merging and direct creation of digits from hits "
280 "was selected for some detectors. "
281 "No merging will be done for the following detectors: %s",
282 fMakeDigitsFromHits.Data());
284 if (!RunHitsDigitization(fMakeDigitsFromHits)) {
285 if (fStopOnError) return kFALSE;
289 // digits -> raw data
290 if (!fWriteRawData.IsNull()) {
291 if (!WriteRawData(fWriteRawData)) {
292 if (fStopOnError) return kFALSE;
299 //_____________________________________________________________________________
300 Bool_t AliSimulation::RunSimulation(Int_t nEvents)
302 // run the generation and simulation
304 TStopwatch stopwatch;
308 Error("RunSimulation", "no gAlice object. Restart aliroot and try again.");
311 if (gAlice->Modules()->GetEntries() > 0) {
312 Error("RunSimulation",
313 "gAlice was already run. Restart aliroot and try again.");
317 Info("RunSimulation", "initializing gAlice with config file %s",
318 fConfigFileName.Data());
319 gAlice->Init(fConfigFileName.Data());
320 AliRunLoader* runLoader = gAlice->GetRunLoader();
322 Error("RunSimulation", "gAlice has no run loader object. "
323 "Check your config file: %s", fConfigFileName.Data());
326 SetGAliceFile(runLoader->GetFileName());
328 if (!gAlice->Generator()) {
329 Error("RunSimulation", "gAlice has no generator object. "
330 "Check your config file: %s", fConfigFileName.Data());
333 if (nEvents <= 0) nEvents = fNEvents;
335 // get vertex from background file in case of merging
336 if (fUseBkgrdVertex &&
337 fBkgrdFileNames && (fBkgrdFileNames->GetEntriesFast() > 0)) {
338 Int_t signalPerBkgrd = GetNSignalPerBkgrd(nEvents);
339 const char* fileName = ((TObjString*)
340 (fBkgrdFileNames->At(0)))->GetName();
341 Info("RunSimulation", "The vertex will be taken from the background "
342 "file %s with nSignalPerBackground = %d",
343 fileName, signalPerBkgrd);
344 AliVertexGenFile* vtxGen = new AliVertexGenFile(fileName, signalPerBkgrd);
345 gAlice->Generator()->SetVertexGenerator(vtxGen);
348 if (!fRunSimulation) {
349 gAlice->Generator()->SetTrackingFlag(0);
352 // set the number of events per file for given detectors and data types
353 for (Int_t i = 0; i < fEventsPerFile.GetEntriesFast(); i++) {
354 if (!fEventsPerFile[i]) continue;
355 const char* detName = fEventsPerFile[i]->GetName();
356 const char* typeName = fEventsPerFile[i]->GetTitle();
357 TString loaderName(detName);
358 loaderName += "Loader";
359 AliLoader* loader = runLoader->GetLoader(loaderName);
361 Error("RunSimulation", "no loader for %s found\n"
362 "Number of events per file not set for %s %s",
363 detName, typeName, detName);
366 AliDataLoader* dataLoader =
367 loader->GetDataLoader(typeName);
369 Error("RunSimulation", "no data loader for %s found\n"
370 "Number of events per file not set for %s %s",
371 typeName, detName, typeName);
374 dataLoader->SetNumberOfEventsPerFile(fEventsPerFile[i]->GetUniqueID());
375 Info("RunSimulation", "number of events per file set to %d for %s %s",
376 fEventsPerFile[i]->GetUniqueID(), detName, typeName);
379 Info("RunSimulation", "running gAlice");
380 gAlice->Run(nEvents);
384 Info("RunSimulation", "execution time:");
390 //_____________________________________________________________________________
391 Bool_t AliSimulation::RunSDigitization(const char* detectors)
393 // run the digitization and produce summable digits
395 TStopwatch stopwatch;
398 AliRunLoader* runLoader = LoadRun();
399 if (!runLoader) return kFALSE;
401 TString detStr = detectors;
402 TObjArray* detArray = runLoader->GetAliRun()->Detectors();
403 for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
404 AliModule* det = (AliModule*) detArray->At(iDet);
405 if (!det || !det->IsActive()) continue;
406 if (IsSelected(det->GetName(), detStr)) {
407 Info("RunSDigitization", "creating summable digits for %s",
409 TStopwatch stopwatchDet;
410 stopwatchDet.Start();
412 Info("RunSDigitization", "execution time for %s:", det->GetName());
413 stopwatchDet.Print();
417 if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
418 Error("RunSDigitization", "the following detectors were not found: %s",
420 if (fStopOnError) return kFALSE;
425 Info("RunSDigitization", "execution time:");
432 //_____________________________________________________________________________
433 Bool_t AliSimulation::RunDigitization(const char* detectors,
434 const char* excludeDetectors)
436 // run the digitization and produce digits from sdigits
438 TStopwatch stopwatch;
441 while (AliRunLoader::GetRunLoader()) delete AliRunLoader::GetRunLoader();
442 if (gAlice) delete gAlice;
446 if (fBkgrdFileNames) nStreams = fBkgrdFileNames->GetEntriesFast() + 1;
447 Int_t signalPerBkgrd = GetNSignalPerBkgrd();
448 AliRunDigitizer* manager = new AliRunDigitizer(nStreams, signalPerBkgrd);
449 manager->SetInputStream(0, fGAliceFileName.Data());
450 for (Int_t iStream = 1; iStream < nStreams; iStream++) {
451 const char* fileName = ((TObjString*)
452 (fBkgrdFileNames->At(iStream-1)))->GetName();
453 manager->SetInputStream(iStream, fileName);
456 TString detStr = detectors;
457 TString detExcl = excludeDetectors;
458 manager->GetInputStream(0)->ImportgAlice();
459 AliRunLoader* runLoader =
460 AliRunLoader::GetRunLoader(manager->GetInputStream(0)->GetFolderName());
461 TObjArray* detArray = runLoader->GetAliRun()->Detectors();
462 for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
463 AliModule* det = (AliModule*) detArray->At(iDet);
464 if (!det || !det->IsActive()) continue;
465 if (IsSelected(det->GetName(), detStr) &&
466 !IsSelected(det->GetName(), detExcl)) {
467 AliDigitizer* digitizer = det->CreateDigitizer(manager);
469 Error("RunDigitization", "no digitizer for %s", det->GetName());
470 if (fStopOnError) return kFALSE;
472 digitizer->SetRegionOfInterest(fRegionOfInterest);
477 if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
478 Error("RunDigitization", "the following detectors were not found: %s",
480 if (fStopOnError) return kFALSE;
483 if (!manager->GetListOfTasks()->IsEmpty()) {
484 Info("RunDigitization", "executing digitization");
490 Info("RunDigitization", "execution time:");
496 //_____________________________________________________________________________
497 Bool_t AliSimulation::RunHitsDigitization(const char* detectors)
499 // run the digitization and produce digits from hits
501 TStopwatch stopwatch;
504 AliRunLoader* runLoader = LoadRun();
505 if (!runLoader) return kFALSE;
507 TString detStr = detectors;
508 TObjArray* detArray = runLoader->GetAliRun()->Detectors();
509 for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
510 AliModule* det = (AliModule*) detArray->At(iDet);
511 if (!det || !det->IsActive()) continue;
512 if (IsSelected(det->GetName(), detStr)) {
513 Info("RunHitsDigitization", "creating digits from hits for %s",
519 if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
520 Error("RunHitsDigitization", "the following detectors were not found: %s",
522 if (fStopOnError) return kFALSE;
527 Info("RunHitsDigitization", "execution time:");
533 //_____________________________________________________________________________
534 Bool_t AliSimulation::WriteRawData(const char* detectors)
536 // convert the digits to raw data
538 TStopwatch stopwatch;
541 AliRunLoader* runLoader = LoadRun();
542 if (!runLoader) return kFALSE;
544 for (Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); iEvent++) {
545 Info("WriteRawData", "processing event %d", iEvent);
546 runLoader->GetEvent(iEvent);
547 TString baseDir = gSystem->WorkingDirectory();
549 sprintf(dirName, "raw%d", iEvent);
550 gSystem->MakeDirectory(dirName);
551 if (!gSystem->ChangeDirectory(dirName)) {
552 Error("WriteRawData", "couldn't change to directory %s", dirName);
553 if (fStopOnError) return kFALSE; else continue;
556 TString detStr = detectors;
557 TObjArray* detArray = runLoader->GetAliRun()->Detectors();
558 for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
559 AliModule* det = (AliModule*) detArray->At(iDet);
560 if (!det || !det->IsActive()) continue;
561 if (IsSelected(det->GetName(), detStr)) {
562 Info("WriteRawData", "creating raw data from digits for %s",
568 gSystem->ChangeDirectory(baseDir);
569 if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
570 Error("WriteRawData", "the following detectors were not found: %s",
572 if (fStopOnError) return kFALSE;
578 Info("WriteRawData", "execution time:");
585 //_____________________________________________________________________________
586 AliRunLoader* AliSimulation::LoadRun() const
588 // delete existing run loaders, open a new one and load gAlice
590 while (AliRunLoader::GetRunLoader()) delete AliRunLoader::GetRunLoader();
591 AliRunLoader* runLoader =
592 AliRunLoader::Open(fGAliceFileName.Data(),
593 AliConfig::GetDefaultEventFolderName(), "UPDATE");
595 Error("LoadRun", "no run loader found in file %s",
596 fGAliceFileName.Data());
599 runLoader->LoadgAlice();
600 gAlice = runLoader->GetAliRun();
602 Error("LoadRun", "no gAlice object found in file %s",
603 fGAliceFileName.Data());
609 //_____________________________________________________________________________
610 Int_t AliSimulation::GetNSignalPerBkgrd(Int_t nEvents) const
612 // get or calculate the number of signal events per background event
614 if (!fBkgrdFileNames) return 1;
615 Int_t nBkgrdFiles = fBkgrdFileNames->GetEntriesFast();
616 if (nBkgrdFiles == 0) return 1;
618 // get the number of signal events
620 AliRunLoader* runLoader =
621 AliRunLoader::Open(fGAliceFileName.Data(), "SIGNAL");
622 if (!runLoader) return 1;
623 nEvents = runLoader->GetNumberOfEvents();
628 for (Int_t iBkgrdFile = 0; iBkgrdFile < nBkgrdFiles; iBkgrdFile++) {
629 // get the number of background events
630 const char* fileName = ((TObjString*)
631 (fBkgrdFileNames->At(iBkgrdFile)))->GetName();
632 AliRunLoader* runLoader =
633 AliRunLoader::Open(fileName, "BKGRD");
634 if (!runLoader) continue;
635 Int_t nBkgrdEvents = runLoader->GetNumberOfEvents();
638 // get or calculate the number of signal per background events
639 Int_t nSignalPerBkgrd = fBkgrdFileNames->At(iBkgrdFile)->GetUniqueID();
640 if (nSignalPerBkgrd <= 0) {
641 nSignalPerBkgrd = (nEvents-1) / nBkgrdEvents + 1;
642 } else if (result && (result != nSignalPerBkgrd)) {
643 Info("GetNSignalPerBkgrd", "the number of signal events per "
644 "background event will be changed from %d to %d for stream %d",
645 nSignalPerBkgrd, result, iBkgrdFile+1);
646 nSignalPerBkgrd = result;
649 if (!result) result = nSignalPerBkgrd;
650 if (nSignalPerBkgrd * nBkgrdEvents < nEvents) {
651 Warning("GetNSignalPerBkgrd", "not enough background events (%d) for "
652 "%d signal events using %d signal per background events for "
654 nBkgrdEvents, nEvents, nSignalPerBkgrd, iBkgrdFile+1);
661 //_____________________________________________________________________________
662 Bool_t AliSimulation::IsSelected(TString detName, TString& detectors) const
664 // check whether detName is contained in detectors
665 // if yes, it is removed from detectors
667 // check if all detectors are selected
668 if ((detectors.CompareTo("ALL") == 0) ||
669 detectors.BeginsWith("ALL ") ||
670 detectors.EndsWith(" ALL") ||
671 detectors.Contains(" ALL ")) {
676 // search for the given detector
677 Bool_t result = kFALSE;
678 if ((detectors.CompareTo(detName) == 0) ||
679 detectors.BeginsWith(detName+" ") ||
680 detectors.EndsWith(" "+detName) ||
681 detectors.Contains(" "+detName+" ")) {
682 detectors.ReplaceAll(detName, "");
686 // clean up the detectors string
687 while (detectors.Contains(" ")) detectors.ReplaceAll(" ", " ");
688 while (detectors.BeginsWith(" ")) detectors.Remove(0, 1);
689 while (detectors.EndsWith(" ")) detectors.Remove(detectors.Length()-1, 1);