]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - STEER/AliSimulation.cxx
Splitting of TRD library (T.Kuhr)
[u/mrichter/AliRoot.git] / STEER / AliSimulation.cxx
index 54440d3702bfeaa8345b9d98c4eeaed8cb866fa0..0aca64ef70308fd8ebdda8afb6a2068a5b9f9299 100644 (file)
@@ -30,7 +30,8 @@
 //                                                                           //
 //   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;
 }
 
 //_____________________________________________________________________________
@@ -134,28 +166,10 @@ AliSimulation::~AliSimulation()
 {
 // 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;
+  }
 }
 
 
@@ -175,6 +189,21 @@ void AliSimulation::SetConfigFile(const char* fileName)
   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)
 {
@@ -182,6 +211,7 @@ 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);
 }
 
@@ -195,33 +225,9 @@ Bool_t AliSimulation::Run(Int_t nEvents)
 
   // 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;
@@ -236,7 +242,7 @@ Bool_t AliSimulation::Run(Int_t nEvents)
 
   // 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",
@@ -247,54 +253,104 @@ Bool_t AliSimulation::Run(Int_t nEvents)
     }
   }
 
+  // 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();
     }
   }
 
@@ -304,19 +360,31 @@ Bool_t AliSimulation::RunSDigitization(const TString& detectors)
     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++) {
@@ -327,15 +395,21 @@ Bool_t AliSimulation::RunDigitization(const TString& detectors,
 
   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);
       }
     }
   }
@@ -350,18 +424,28 @@ Bool_t AliSimulation::RunDigitization(const TString& detectors,
     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;
@@ -378,10 +462,142 @@ Bool_t AliSimulation::RunHitsDigitization(const TString& detectors)
     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
 {