// //
// sim.SetNumberOfEvents(n); //
// //
-// The name of the configuration file can be specified by //
+// The name of the configuration file can be passed as argument to the //
+// AliSimulation constructor or can be specified by //
// //
// sim.SetConfigFile("..."); //
// //
// this feature is not available for all detectors and that merging is not //
// possible, when digits are created directly from hits. //
// //
-// Backgound events can be merged by calling //
+// Background events can be merged by calling //
// //
// sim.MergeWith("background/galice.root", 2); //
// //
// The first argument is the file name of the background galice file. The //
// second argument is the number of signal events per background event. //
-// The default value for this is 1. MergeWith can be called several times //
-// to merge more than two event streams. It is assumed that the sdigits //
-// were already produced for the background events. //
+// By default this number is calculated from the number of available //
+// background events. MergeWith can be called several times to merge more //
+// than two event streams. It is assumed that the sdigits were already //
+// produced for the background events. //
+// //
+// The output of raw data can be switched on by calling //
+// //
+// sim.SetWriteRawData("MUON"); // write raw data for MUON //
+// //
+// The methods RunSimulation, RunSDigitization, RunDigitization, //
+// RunHitsDigitization and WriteRawData can be used to run only parts of //
+// the full simulation chain. //
// //
///////////////////////////////////////////////////////////////////////////////
+#include <TObjString.h>
+#include <TStopwatch.h>
+#include <TSystem.h>
-#include "AliSimulation.h"
-#include "AliRunLoader.h"
-#include "AliRun.h"
-#include "AliModule.h"
+#include "AliDigitizer.h"
#include "AliGenerator.h"
+#include "AliModule.h"
+#include "AliRun.h"
#include "AliRunDigitizer.h"
-#include <TObjString.h>
-
+#include "AliRunLoader.h"
+#include "AliSimulation.h"
+#include "AliVertexGenFile.h"
ClassImp(AliSimulation)
//_____________________________________________________________________________
-AliSimulation::AliSimulation(const char* name, const char* title) :
- TNamed(name, title)
+AliSimulation::AliSimulation(const char* configFileName,
+ const char* name, const char* title) :
+ TNamed(name, title),
+
+ fRunGeneration(kTRUE),
+ fRunSimulation(kTRUE),
+ fMakeSDigits("ALL"),
+ fMakeDigits("ALL"),
+ fMakeDigitsFromHits(""),
+ fWriteRawData(""),
+ fStopOnError(kFALSE),
+
+ fNEvents(1),
+ fConfigFileName(configFileName),
+ fGAliceFileName("galice.root"),
+ fBkgrdFileNames(NULL),
+ fUseBkgrdVertex(kTRUE),
+ fRegionOfInterest(kTRUE)
{
// create simulation object with default parameters
- Init();
+ SetGAliceFile("galice.root");
}
//_____________________________________________________________________________
AliSimulation::AliSimulation(const AliSimulation& sim) :
- TNamed(sim)
+ TNamed(sim),
+
+ fRunGeneration(sim.fRunGeneration),
+ fRunSimulation(sim.fRunSimulation),
+ fMakeSDigits(sim.fMakeSDigits),
+ fMakeDigits(sim.fMakeDigits),
+ fMakeDigitsFromHits(sim.fMakeDigitsFromHits),
+ fWriteRawData(sim.fWriteRawData),
+ fStopOnError(sim.fStopOnError),
+
+ fNEvents(sim.fNEvents),
+ fConfigFileName(sim.fConfigFileName),
+ fGAliceFileName(sim.fGAliceFileName),
+ fBkgrdFileNames(NULL),
+ fUseBkgrdVertex(sim.fUseBkgrdVertex),
+ fRegionOfInterest(sim.fRegionOfInterest)
{
// copy constructor
- fRunGeneration = sim.fRunGeneration;
- fRunSimulation = sim.fRunSimulation;
- fMakeSDigits = sim.fMakeSDigits;
- fMakeDigits = sim.fMakeDigits;
- fMakeDigitsFromHits = sim.fMakeDigitsFromHits;
- fStopOnError = sim.fStopOnError;
-
- fNEvents = sim.fNEvents;
- fConfigFileName = sim.fConfigFileName;
- fGAliceFileName = sim.fGAliceFileName;
fBkgrdFileNames = new TObjArray;
for (Int_t i = 0; i < sim.fBkgrdFileNames->GetEntriesFast(); i++) {
if (!sim.fBkgrdFileNames->At(i)) continue;
fBkgrdFileNames->Add(sim.fBkgrdFileNames->At(i)->Clone());
}
-
- fRunLoader = NULL;
}
//_____________________________________________________________________________
{
// clean up
- fBkgrdFileNames->Delete();
- delete fBkgrdFileNames;
-}
-
-//_____________________________________________________________________________
-void AliSimulation::Init()
-{
-// set default parameters
-
- fRunGeneration = kTRUE;
- fRunSimulation = kTRUE;
- fMakeSDigits = "ALL";
- fMakeDigits = "ALL";
- fMakeDigitsFromHits = "";
- fStopOnError = kFALSE;
-
- fNEvents = 1;
- fConfigFileName = "Config.C";
- fGAliceFileName = "galice.root";
- fBkgrdFileNames = new TObjArray;
-
- fRunLoader = NULL;
+ if (fBkgrdFileNames) {
+ fBkgrdFileNames->Delete();
+ delete fBkgrdFileNames;
+ }
}
fConfigFileName = fileName;
}
+//_____________________________________________________________________________
+void AliSimulation::SetGAliceFile(const char* fileName)
+{
+// set the name of the galice file
+// the path is converted to an absolute one if it is relative
+
+ fGAliceFileName = fileName;
+ if (!gSystem->IsAbsoluteFileName(fGAliceFileName)) {
+ char* absFileName = gSystem->ConcatFileName(gSystem->WorkingDirectory(),
+ fGAliceFileName);
+ fGAliceFileName = absFileName;
+ delete[] absFileName;
+ }
+}
+
//_____________________________________________________________________________
void AliSimulation::MergeWith(const char* fileName, Int_t nSignalPerBkgrd)
{
TObjString* fileNameStr = new TObjString(fileName);
fileNameStr->SetUniqueID(nSignalPerBkgrd);
+ if (!fBkgrdFileNames) fBkgrdFileNames = new TObjArray;
fBkgrdFileNames->Add(fileNameStr);
}
// generation and simulation -> hits
if (fRunGeneration) {
- if (!gAlice) {
- Error("Run", "no gAlice object. Restart aliroot and try again.");
- return kFALSE;
- }
- if (gAlice->Modules()->GetEntries() > 0) {
- Error("Run", "gAlice was already run. Restart aliroot and try again.");
- return kFALSE;
- }
if (!RunSimulation()) if (fStopOnError) return kFALSE;
}
- // reopen the run loader
- if (fRunLoader) delete fRunLoader;
- fRunLoader = AliRunLoader::Open(fGAliceFileName.Data());
- if (!fRunLoader) {
- Error("Run", "no run loader found in file %s",
- fGAliceFileName.Data());
- return kFALSE;
- }
- fRunLoader->LoadgAlice();
- gAlice = fRunLoader->GetAliRun();
- if (!gAlice) {
- Error("GetLoadersAndDetectors", "no gAlice object found in file %s",
- fGAliceFileName.Data());
- return kFALSE;
- }
-
// hits -> summable digits
if (!fMakeSDigits.IsNull()) {
if (!RunSDigitization(fMakeSDigits)) if (fStopOnError) return kFALSE;
// hits -> digits
if (!fMakeDigitsFromHits.IsNull()) {
- if (fBkgrdFileNames->GetEntriesFast() > 0) {
+ if (fBkgrdFileNames && (fBkgrdFileNames->GetEntriesFast() > 0)) {
Warning("Run", "Merging and direct creation of digits from hits "
"was selected for some detectors. "
"No merging will be done for the following detectors: %s",
}
}
+ // digits -> raw data
+ if (!fWriteRawData.IsNull()) {
+ if (!WriteRawData(fWriteRawData)) {
+ if (fStopOnError) return kFALSE;
+ }
+ }
+
return kTRUE;
}
//_____________________________________________________________________________
-Bool_t AliSimulation::RunSimulation()
+Bool_t AliSimulation::RunSimulation(Int_t nEvents)
{
// run the generation and simulation
+ TStopwatch stopwatch;
+ stopwatch.Start();
+
+ if (!gAlice) {
+ Error("RunSimulation", "no gAlice object. Restart aliroot and try again.");
+ return kFALSE;
+ }
+ if (gAlice->Modules()->GetEntries() > 0) {
+ Error("RunSimulation",
+ "gAlice was already run. Restart aliroot and try again.");
+ return kFALSE;
+ }
+
Info("RunSimulation", "initializing gAlice with config file %s",
fConfigFileName.Data());
gAlice->Init(fConfigFileName.Data());
- fRunLoader = gAlice->GetRunLoader();
- if (!fRunLoader) {
+ AliRunLoader* runLoader = gAlice->GetRunLoader();
+ if (!runLoader) {
Error("RunSimulation", "gAlice has no run loader object. "
"Check your config file: %s", fConfigFileName.Data());
return kFALSE;
}
- fGAliceFileName = fRunLoader->GetFileName();
+ SetGAliceFile(runLoader->GetFileName());
+
+ if (!gAlice->Generator()) {
+ Error("RunSimulation", "gAlice has no generator object. "
+ "Check your config file: %s", fConfigFileName.Data());
+ return kFALSE;
+ }
+ if (nEvents <= 0) nEvents = fNEvents;
+
+ // get vertex from background file in case of merging
+ if (fUseBkgrdVertex &&
+ fBkgrdFileNames && (fBkgrdFileNames->GetEntriesFast() > 0)) {
+ Int_t signalPerBkgrd = GetNSignalPerBkgrd(nEvents);
+ const char* fileName = ((TObjString*)
+ (fBkgrdFileNames->At(0)))->GetName();
+ Info("RunSimulation", "The vertex will be taken from the background "
+ "file %s with nSignalPerBackground = %d",
+ fileName, signalPerBkgrd);
+ AliVertexGenFile* vtxGen = new AliVertexGenFile(fileName, signalPerBkgrd);
+ gAlice->Generator()->SetVertexGenerator(vtxGen);
+ }
if (!fRunSimulation) {
- if (!gAlice->Generator()) {
- Error("RunSimulation", "gAlice has no generator object. "
- "Check your config file: %s", fConfigFileName.Data());
- return kFALSE;
- }
gAlice->Generator()->SetTrackingFlag(0);
}
- Info("Run", "running gAlice");
- gAlice->Run(fNEvents);
+ Info("RunSimulation", "running gAlice");
+ gAlice->Run(nEvents);
+
+ delete runLoader;
+
+ Info("RunSimulation", "execution time:");
+ stopwatch.Print();
return kTRUE;
}
//_____________________________________________________________________________
-Bool_t AliSimulation::RunSDigitization(const TString& detectors)
+Bool_t AliSimulation::RunSDigitization(const char* detectors)
{
// run the digitization and produce summable digits
+ TStopwatch stopwatch;
+ stopwatch.Start();
+
+ AliRunLoader* runLoader = LoadRun();
+ if (!runLoader) return kFALSE;
+
TString detStr = detectors;
- TObjArray* detArray = gAlice->Detectors();
+ TObjArray* detArray = runLoader->GetAliRun()->Detectors();
for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
AliModule* det = (AliModule*) detArray->At(iDet);
if (!det || !det->IsActive()) continue;
if (IsSelected(det->GetName(), detStr)) {
Info("RunSDigitization", "creating summable digits for %s",
det->GetName());
+ TStopwatch stopwatchDet;
+ stopwatchDet.Start();
det->Hits2SDigits();
+ Info("RunSDigitization", "execution time for %s:", det->GetName());
+ stopwatchDet.Print();
}
}
if (fStopOnError) return kFALSE;
}
+ delete runLoader;
+
+ Info("RunSDigitization", "execution time:");
+ stopwatch.Print();
+
return kTRUE;
}
//_____________________________________________________________________________
-Bool_t AliSimulation::RunDigitization(const TString& detectors,
- const TString& excludeDetectors)
+Bool_t AliSimulation::RunDigitization(const char* detectors,
+ const char* excludeDetectors)
{
// run the digitization and produce digits from sdigits
- Int_t nStreams = fBkgrdFileNames->GetEntriesFast() + 1;
- Int_t signalPerBkgrd = 1;
- if (nStreams > 1) signalPerBkgrd = fBkgrdFileNames->At(0)->GetUniqueID();
+ TStopwatch stopwatch;
+ stopwatch.Start();
+
+ while (AliRunLoader::GetRunLoader()) delete AliRunLoader::GetRunLoader();
+ if (gAlice) delete gAlice;
+ gAlice = NULL;
+
+ Int_t nStreams = 1;
+ if (fBkgrdFileNames) nStreams = fBkgrdFileNames->GetEntriesFast() + 1;
+ Int_t signalPerBkgrd = GetNSignalPerBkgrd();
AliRunDigitizer* manager = new AliRunDigitizer(nStreams, signalPerBkgrd);
manager->SetInputStream(0, fGAliceFileName.Data());
for (Int_t iStream = 1; iStream < nStreams; iStream++) {
TString detStr = detectors;
TString detExcl = excludeDetectors;
- TObjArray* detArray = gAlice->Detectors();
+ manager->GetInputStream(0)->ImportgAlice();
+ AliRunLoader* runLoader =
+ AliRunLoader::GetRunLoader(manager->GetInputStream(0)->GetFolderName());
+ TObjArray* detArray = runLoader->GetAliRun()->Detectors();
for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
AliModule* det = (AliModule*) detArray->At(iDet);
if (!det || !det->IsActive()) continue;
if (IsSelected(det->GetName(), detStr) &&
!IsSelected(det->GetName(), detExcl)) {
- if (!det->CreateDigitizer(manager)) {
+ AliDigitizer* digitizer = det->CreateDigitizer(manager);
+ if (!digitizer) {
Error("RunDigitization", "no digitizer for %s", det->GetName());
if (fStopOnError) return kFALSE;
+ } else {
+ digitizer->SetRegionOfInterest(fRegionOfInterest);
}
}
}
Info("RunDigitization", "executing digitization");
manager->Exec("");
}
+
delete manager;
+ Info("RunDigitization", "execution time:");
+ stopwatch.Print();
+
return kTRUE;
}
//_____________________________________________________________________________
-Bool_t AliSimulation::RunHitsDigitization(const TString& detectors)
+Bool_t AliSimulation::RunHitsDigitization(const char* detectors)
{
// run the digitization and produce digits from hits
+ TStopwatch stopwatch;
+ stopwatch.Start();
+
+ AliRunLoader* runLoader = LoadRun();
+ if (!runLoader) return kFALSE;
+
TString detStr = detectors;
- TObjArray* detArray = gAlice->Detectors();
+ TObjArray* detArray = runLoader->GetAliRun()->Detectors();
for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
AliModule* det = (AliModule*) detArray->At(iDet);
if (!det || !det->IsActive()) continue;
if (fStopOnError) return kFALSE;
}
+ delete runLoader;
+
+ Info("RunHitsDigitization", "execution time:");
+ stopwatch.Print();
+
+ return kTRUE;
+}
+
+//_____________________________________________________________________________
+Bool_t AliSimulation::WriteRawData(const char* detectors)
+{
+// convert the digits to raw data
+
+ TStopwatch stopwatch;
+ stopwatch.Start();
+
+ AliRunLoader* runLoader = LoadRun();
+ if (!runLoader) return kFALSE;
+
+ for (Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); iEvent++) {
+ Info("WriteRawData", "processing event %d", iEvent);
+ runLoader->GetEvent(iEvent);
+ TString baseDir = gSystem->WorkingDirectory();
+ char dirName[256];
+ sprintf(dirName, "raw%d", iEvent);
+ gSystem->MakeDirectory(dirName);
+ if (!gSystem->ChangeDirectory(dirName)) {
+ Error("WriteRawData", "couldn't change to directory %s", dirName);
+ if (fStopOnError) return kFALSE; else continue;
+ }
+
+ TString detStr = detectors;
+ TObjArray* detArray = runLoader->GetAliRun()->Detectors();
+ for (Int_t iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) {
+ AliModule* det = (AliModule*) detArray->At(iDet);
+ if (!det || !det->IsActive()) continue;
+ if (IsSelected(det->GetName(), detStr)) {
+ Info("WriteRawData", "creating raw data from digits for %s",
+ det->GetName());
+ det->Digits2Raw();
+ }
+ }
+
+ gSystem->ChangeDirectory(baseDir);
+ if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) {
+ Error("WriteRawData", "the following detectors were not found: %s",
+ detStr.Data());
+ if (fStopOnError) return kFALSE;
+ }
+ }
+
+ delete runLoader;
+
+ Info("WriteRawData", "execution time:");
+ stopwatch.Print();
+
return kTRUE;
}
+//_____________________________________________________________________________
+AliRunLoader* AliSimulation::LoadRun() const
+{
+// delete existing run loaders, open a new one and load gAlice
+
+ while (AliRunLoader::GetRunLoader()) delete AliRunLoader::GetRunLoader();
+ AliRunLoader* runLoader =
+ AliRunLoader::Open(fGAliceFileName.Data(),
+ AliConfig::GetDefaultEventFolderName(), "UPDATE");
+ if (!runLoader) {
+ Error("LoadRun", "no run loader found in file %s",
+ fGAliceFileName.Data());
+ return NULL;
+ }
+ runLoader->LoadgAlice();
+ gAlice = runLoader->GetAliRun();
+ if (!gAlice) {
+ Error("LoadRun", "no gAlice object found in file %s",
+ fGAliceFileName.Data());
+ return NULL;
+ }
+ return runLoader;
+}
+
+//_____________________________________________________________________________
+Int_t AliSimulation::GetNSignalPerBkgrd(Int_t nEvents) const
+{
+// get or calculate the number of signal events per background event
+
+ if (!fBkgrdFileNames) return 1;
+ Int_t nBkgrdFiles = fBkgrdFileNames->GetEntriesFast();
+ if (nBkgrdFiles == 0) return 1;
+
+ // get the number of signal events
+ if (nEvents <= 0) {
+ AliRunLoader* runLoader =
+ AliRunLoader::Open(fGAliceFileName.Data(), "SIGNAL");
+ if (!runLoader) return 1;
+ nEvents = runLoader->GetNumberOfEvents();
+ delete runLoader;
+ }
+
+ Int_t result = 0;
+ for (Int_t iBkgrdFile = 0; iBkgrdFile < nBkgrdFiles; iBkgrdFile++) {
+ // get the number of background events
+ const char* fileName = ((TObjString*)
+ (fBkgrdFileNames->At(iBkgrdFile)))->GetName();
+ AliRunLoader* runLoader =
+ AliRunLoader::Open(fileName, "BKGRD");
+ if (!runLoader) continue;
+ Int_t nBkgrdEvents = runLoader->GetNumberOfEvents();
+ delete runLoader;
+
+ // get or calculate the number of signal per background events
+ Int_t nSignalPerBkgrd = fBkgrdFileNames->At(iBkgrdFile)->GetUniqueID();
+ if (nSignalPerBkgrd <= 0) {
+ nSignalPerBkgrd = (nEvents-1) / nBkgrdEvents + 1;
+ } else if (result && (result != nSignalPerBkgrd)) {
+ Info("GetNSignalPerBkgrd", "the number of signal events per "
+ "background event will be changed from %d to %d for stream %d",
+ nSignalPerBkgrd, result, iBkgrdFile+1);
+ nSignalPerBkgrd = result;
+ }
+
+ if (!result) result = nSignalPerBkgrd;
+ if (nSignalPerBkgrd * nBkgrdEvents < nEvents) {
+ Warning("GetNSignalPerBkgrd", "not enough background events (%d) for "
+ "%d signal events using %d signal per background events for "
+ "stream %d",
+ nBkgrdEvents, nEvents, nSignalPerBkgrd, iBkgrdFile+1);
+ }
+ }
+
+ return result;
+}
+
//_____________________________________________________________________________
Bool_t AliSimulation::IsSelected(TString detName, TString& detectors) const
{