X-Git-Url: http://git.uio.no/git/?p=u%2Fmrichter%2FAliRoot.git;a=blobdiff_plain;f=STEER%2FAliSimulation.cxx;h=f7a3a0cc27c29b60e5fa2ba4d3c63a2677337f9a;hp=5058133dba1ce2ea17a757776e4247ee5011c68c;hb=caf9c464f513368898dc62e8382ebdb833e42603;hpb=389c9f66e7b54d28b8cdef82833f93890018e1a3 diff --git a/STEER/AliSimulation.cxx b/STEER/AliSimulation.cxx index 5058133dba1..f7a3a0cc27c 100644 --- a/STEER/AliSimulation.cxx +++ b/STEER/AliSimulation.cxx @@ -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("..."); // // // @@ -60,64 +61,166 @@ // 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 default output format of the raw data are DDL files. They are // +// converted to a DATE file, if a file name is given as second argument. // +// For this conversion the program "dateStream" is required. If the file // +// name has the extension ".root", the DATE file is converted to a root // +// file. The program "alimdc" is used for this purpose. For the conversion // +// to DATE and root format the two conversion programs have to be installed. // +// Only the raw data in the final format is kept if the third argument is // +// kTRUE. // +// // +// The methods RunSimulation, RunSDigitization, RunDigitization, // +// RunHitsDigitization and WriteRawData can be used to run only parts of // +// the full simulation chain. The creation of raw data DDL files and their // +// conversion to the DATE or root format can be run directly by calling // +// the methods WriteRawFiles, ConvertRawFilesToDate and ConvertDateToRoot. // +// // +// The default number of events per file, which is usually set in the // +// config file, can be changed for individual detectors and data types // +// by calling // +// // +// sim.SetEventsPerFile("PHOS", "Reconstructed Points", 3); // +// // +// The first argument is the detector, the second one the data type and the // +// last one the number of events per file. Valid data types are "Hits", // +// "Summable Digits", "Digits", "Reconstructed Points" and "Tracks". // +// The number of events per file has to be set before the simulation of // +// hits. Otherwise it has no effect. // // // /////////////////////////////////////////////////////////////////////////////// - -#include "AliSimulation.h" -#include "AliRunLoader.h" -#include "AliRun.h" -#include "AliModule.h" +#include +#include +#include +#include +#include +#include + +#include "AliCDBStorage.h" +#include "AliCDBEntry.h" +#include "AliCDBManager.h" +#include "AliGeomManager.h" +#include "AliAlignObj.h" +#include "AliCentralTrigger.h" +#include "AliDAQ.h" +#include "AliDigitizer.h" #include "AliGenerator.h" +#include "AliLog.h" +#include "AliModule.h" +#include "AliRun.h" #include "AliRunDigitizer.h" -#include "AliDigitizer.h" -#include - +#include "AliRunLoader.h" +#include "AliSimulation.h" +#include "AliVertexGenFile.h" +#include "AliCentralTrigger.h" +#include "AliCTPRawData.h" +#include "AliRawReaderFile.h" +#include "AliESD.h" +#include "AliHeader.h" +#include "AliGenEventHeader.h" +#include "AliMC.h" ClassImp(AliSimulation) +AliSimulation *AliSimulation::fgInstance = 0; //_____________________________________________________________________________ -AliSimulation::AliSimulation(const char* name, const char* title) : - TNamed(name, title) +AliSimulation::AliSimulation(const char* configFileName, const char* cdbUri, + const char* name, const char* title) : + TNamed(name, title), + + fRunGeneration(kTRUE), + fRunSimulation(kTRUE), + fLoadAlignFromCDB(kTRUE), + fLoadAlObjsListOfDets("ALL"), + fMakeSDigits("ALL"), + fMakeDigits("ALL"), + fMakeTrigger(""), + fMakeDigitsFromHits(""), + fWriteRawData(""), + fRawDataFileName(""), + fDeleteIntermediateFiles(kFALSE), + fStopOnError(kFALSE), + + fNEvents(1), + fConfigFileName(configFileName), + fGAliceFileName("galice.root"), + fEventsPerFile(), + fBkgrdFileNames(NULL), + fAlignObjArray(NULL), + fUseBkgrdVertex(kTRUE), + fRegionOfInterest(kFALSE), + fCDBUri(cdbUri), + fSpecCDBUri(), + fEmbeddingFlag(kFALSE) { // create simulation object with default parameters - - Init(); + fgInstance = this; + SetGAliceFile("galice.root"); } //_____________________________________________________________________________ AliSimulation::AliSimulation(const AliSimulation& sim) : - TNamed(sim) + TNamed(sim), + + fRunGeneration(sim.fRunGeneration), + fRunSimulation(sim.fRunSimulation), + fLoadAlignFromCDB(sim.fLoadAlignFromCDB), + fLoadAlObjsListOfDets(sim.fLoadAlObjsListOfDets), + fMakeSDigits(sim.fMakeSDigits), + fMakeDigits(sim.fMakeDigits), + fMakeTrigger(sim.fMakeTrigger), + fMakeDigitsFromHits(sim.fMakeDigitsFromHits), + fWriteRawData(sim.fWriteRawData), + fRawDataFileName(""), + fDeleteIntermediateFiles(kFALSE), + fStopOnError(sim.fStopOnError), + + fNEvents(sim.fNEvents), + fConfigFileName(sim.fConfigFileName), + fGAliceFileName(sim.fGAliceFileName), + fEventsPerFile(), + fBkgrdFileNames(NULL), + fAlignObjArray(NULL), + fUseBkgrdVertex(sim.fUseBkgrdVertex), + fRegionOfInterest(sim.fRegionOfInterest), + fCDBUri(sim.fCDBUri), + fSpecCDBUri(), + fEmbeddingFlag(sim.fEmbeddingFlag) { // copy constructor - fRunGeneration = sim.fRunGeneration; - fRunSimulation = sim.fRunSimulation; - fMakeSDigits = sim.fMakeSDigits; - fMakeDigits = sim.fMakeDigits; - fMakeDigitsFromHits = sim.fMakeDigitsFromHits; - fStopOnError = sim.fStopOnError; + for (Int_t i = 0; i < sim.fEventsPerFile.GetEntriesFast(); i++) { + if (!sim.fEventsPerFile[i]) continue; + fEventsPerFile.Add(sim.fEventsPerFile[i]->Clone()); + } - 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; + for (Int_t i = 0; i < sim.fSpecCDBUri.GetEntriesFast(); i++) { + if (sim.fSpecCDBUri[i]) fSpecCDBUri.Add(sim.fSpecCDBUri[i]->Clone()); + } + fgInstance = this; } //_____________________________________________________________________________ @@ -135,29 +238,17 @@ AliSimulation::~AliSimulation() { // clean up - fBkgrdFileNames->Delete(); - delete fBkgrdFileNames; -} + fEventsPerFile.Delete(); +// if(fAlignObjArray) fAlignObjArray->Delete(); // fAlignObjArray->RemoveAll() ??? +// delete fAlignObjArray; fAlignObjArray=0; -//_____________________________________________________________________________ -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; - fRegionOfInterest = kTRUE; + if (fBkgrdFileNames) { + fBkgrdFileNames->Delete(); + delete fBkgrdFileNames; + } - fRunLoader = NULL; + fSpecCDBUri.Delete(); + if (fgInstance==this) fgInstance = 0; } @@ -169,6 +260,67 @@ void AliSimulation::SetNumberOfEvents(Int_t nEvents) fNEvents = nEvents; } +//_____________________________________________________________________________ +void AliSimulation::InitCDBStorage() +{ +// activate a default CDB storage +// First check if we have any CDB storage set, because it is used +// to retrieve the calibration and alignment constants + + AliCDBManager* man = AliCDBManager::Instance(); + if (man->IsDefaultStorageSet()) + { + AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + AliWarning("Default CDB storage has been already set !"); + AliWarning(Form("Ignoring the default storage declared in AliReconstruction: %s",fCDBUri.Data())); + AliWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + fCDBUri = ""; + } + else { + AliDebug(2,"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + AliDebug(2, Form("Default CDB storage is set to: %s",fCDBUri.Data())); + AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + man->SetDefaultStorage(fCDBUri); + } + + // Now activate the detector specific CDB storage locations + for (Int_t i = 0; i < fSpecCDBUri.GetEntriesFast(); i++) { + TObject* obj = fSpecCDBUri[i]; + if (!obj) continue; + AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + AliDebug(2, Form("Specific CDB storage for %s is set to: %s",obj->GetName(),obj->GetTitle())); + AliDebug(2, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + man->SetSpecificStorage(obj->GetName(), obj->GetTitle()); + } + man->Print(); +} + +//_____________________________________________________________________________ +void AliSimulation::SetDefaultStorage(const char* uri) { +// Store the desired default CDB storage location +// Activate it later within the Run() method + + fCDBUri = uri; + +} + +//_____________________________________________________________________________ +void AliSimulation::SetSpecificStorage(const char* calibType, const char* uri) { +// Store a detector-specific CDB storage location +// Activate it later within the Run() method + + AliCDBPath aPath(calibType); + if(!aPath.IsValid()){ + AliError(Form("Not a valid path: %s", calibType)); + return; + } + + TObject* obj = fSpecCDBUri.FindObject(calibType); + if (obj) fSpecCDBUri.Remove(obj); + fSpecCDBUri.Add(new TNamed(calibType, uri)); + +} + //_____________________________________________________________________________ void AliSimulation::SetConfigFile(const char* fileName) { @@ -177,6 +329,134 @@ 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; + } + + AliDebug(2, Form("galice file name set to %s", fileName)); +} + +//_____________________________________________________________________________ +void AliSimulation::SetEventsPerFile(const char* detector, const char* type, + Int_t nEvents) +{ +// set the number of events per file for the given detector and data type +// ("Hits", "Summable Digits", "Digits", "Reconstructed Points" or "Tracks") + + TNamed* obj = new TNamed(detector, type); + obj->SetUniqueID(nEvents); + fEventsPerFile.Add(obj); +} + +//_____________________________________________________________________________ +Bool_t AliSimulation::MisalignGeometry(AliRunLoader *runLoader) +{ + // Read the alignment objects from CDB. + // Each detector is supposed to have the + // alignment objects in DET/Align/Data CDB path. + // All the detector objects are then collected, + // sorted by geometry level (starting from ALIC) and + // then applied to the TGeo geometry. + // Finally an overlaps check is performed. + + Bool_t delRunLoader = kFALSE; + if (!runLoader) { + runLoader = LoadRun("READ"); + if (!runLoader) return kFALSE; + delRunLoader = kTRUE; + } + + // Export ideal geometry + if (gGeoManager) gGeoManager->Export("geometry.root"); + + // Load alignment data from CDB and apply to geometry through AliGeomManager + if(fLoadAlignFromCDB){ + + TString detStr = fLoadAlObjsListOfDets; + TString loadAlObjsListOfDets = ""; + + 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)) { + //add det to list of dets to be aligned from CDB + loadAlObjsListOfDets += det->GetName(); + loadAlObjsListOfDets += " "; + } + } // end loop over detectors + (AliGeomManager::Instance())->ApplyAlignObjsFromCDB(loadAlObjsListOfDets.Data()); + }else{ + // Check if the array with alignment objects was + // provided by the user. If yes, apply the objects + // to the present TGeo geometry + if (fAlignObjArray) { + if (gGeoManager && gGeoManager->IsClosed()) { + if ((AliGeomManager::Instance())->ApplyAlignObjsToGeom(fAlignObjArray) == kFALSE) { + AliError("The misalignment of one or more volumes failed!" + "Compare the list of simulated detectors and the list of detector alignment data!"); + if (delRunLoader) delete runLoader; + return kFALSE; + } + } + else { + AliError("Can't apply the misalignment! gGeoManager doesn't exist or it is still opened!"); + if (delRunLoader) delete runLoader; + return kFALSE; + } + } + } + + // Update the internal geometry of modules (ITS needs it) + TString detStr = fLoadAlObjsListOfDets; + 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)) { + det->UpdateInternalGeometry(); + } + } // end loop over detectors + + + if (delRunLoader) delete runLoader; + + // Update the TGeoPhysicalNodes + gGeoManager->RefreshPhysicalNodes(); + + return kTRUE; +} + + +//_____________________________________________________________________________ +Bool_t AliSimulation::SetRunNumber() +{ + // Set the CDB manager run number + // The run number is retrieved from gAlice + + if(AliCDBManager::Instance()->GetRun() < 0) { + AliRunLoader* runLoader = LoadRun("READ"); + if (!runLoader) return kFALSE; + else { + AliCDBManager::Instance()->SetRun(runLoader->GetAliRun()->GetRunNumber()); + AliInfo(Form("Run number: %d",AliCDBManager::Instance()->GetRun())); + delete runLoader; + } + } + return kTRUE; +} + //_____________________________________________________________________________ void AliSimulation::MergeWith(const char* fileName, Int_t nSignalPerBkgrd) { @@ -184,44 +464,40 @@ 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); } +void AliSimulation::EmbedInto(const char* fileName, Int_t nSignalPerBkgrd) +{ +// add a file with background events for embeddin + MergeWith(fileName, nSignalPerBkgrd); + fEmbeddingFlag = kTRUE; +} //_____________________________________________________________________________ Bool_t AliSimulation::Run(Int_t nEvents) { // run the generation, simulation and digitization + InitCDBStorage(); + if (nEvents > 0) fNEvents = 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(),AliConfig::fgkDefaultEventFolderName,"UPDATE"); - if (!fRunLoader) { - Error("Run", "no run loader found in file %s", - fGAliceFileName.Data()); - return kFALSE; - } - fRunLoader->LoadgAlice(); - gAlice = fRunLoader->GetAliRun(); - if (!gAlice) { - Error("Run", "no gAlice object found in file %s", - fGAliceFileName.Data()); - return kFALSE; + // Set run number in CDBManager (if it is not already set in RunSimulation) + if (!SetRunNumber()) if (fStopOnError) return kFALSE; + + // If RunSimulation was not called, load the geometry and misalign it + if (!gGeoManager) { + TGeoManager::Import("geometry.root"); + if (!gGeoManager) if (fStopOnError) return kFALSE; + // Initialize the geometry manager (if not already done) + if(!MisalignGeometry()) if (fStopOnError) return kFALSE; } // hits -> summable digits @@ -238,103 +514,272 @@ Bool_t AliSimulation::Run(Int_t nEvents) // hits -> digits if (!fMakeDigitsFromHits.IsNull()) { - if (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", - fMakeDigitsFromHits.Data()); + if (fBkgrdFileNames && (fBkgrdFileNames->GetEntriesFast() > 0)) { + AliWarning(Form("Merging and direct creation of digits from hits " + "was selected for some detectors. " + "No merging will be done for the following detectors: %s", + fMakeDigitsFromHits.Data())); } if (!RunHitsDigitization(fMakeDigitsFromHits)) { if (fStopOnError) return kFALSE; } } + // digits -> trigger + if (!RunTrigger(fMakeTrigger)) { + if (fStopOnError) return kFALSE; + } + + // digits -> raw data + if (!fWriteRawData.IsNull()) { + if (!WriteRawData(fWriteRawData, fRawDataFileName, + fDeleteIntermediateFiles)) { + if (fStopOnError) return kFALSE; + } + } + + return kTRUE; +} + +//_____________________________________________________________________________ +Bool_t AliSimulation::RunTrigger(const char* descriptors) +{ + // run the trigger + + TStopwatch stopwatch; + stopwatch.Start(); + + AliRunLoader* runLoader = LoadRun("READ"); + if (!runLoader) return kFALSE; + TString des = descriptors; + + if (des.IsNull()) { + if (gAlice->GetTriggerDescriptor() != "") { + des = gAlice->GetTriggerDescriptor(); + } + else { + AliWarning("No trigger descriptor is specified. Skipping the trigger simulation..."); + return kTRUE; + } + } + + runLoader->MakeTree( "GG" ); + AliCentralTrigger* aCTP = runLoader->GetTrigger(); + // Load Descriptors + aCTP->LoadDescriptor( des ); + + // digits -> trigger + if( !aCTP->RunTrigger( runLoader ) ) { + if (fStopOnError) { + // delete aCTP; + return kFALSE; + } + } + + AliInfo(Form("Execution time: R:%.2fs C:%.2fs", + stopwatch.RealTime(),stopwatch.CpuTime())); + + delete runLoader; + + return kTRUE; +} + +//_____________________________________________________________________________ +Bool_t AliSimulation::WriteTriggerRawData() +{ + // Writes the CTP (trigger) DDL raw data + // Details of the format are given in the + // trigger TDR - pages 134 and 135. + AliCTPRawData writer; + writer.RawData(); + return kTRUE; } //_____________________________________________________________________________ -Bool_t AliSimulation::RunSimulation() +Bool_t AliSimulation::RunSimulation(Int_t nEvents) { // run the generation and simulation TStopwatch stopwatch; stopwatch.Start(); - Info("RunSimulation", "initializing gAlice with config file %s", - fConfigFileName.Data()); - gAlice->Init(fConfigFileName.Data()); - fRunLoader = gAlice->GetRunLoader(); - if (!fRunLoader) { - Error("RunSimulation", "gAlice has no run loader object. " - "Check your config file: %s", fConfigFileName.Data()); + if (!gAlice) { + AliError("no gAlice object. Restart aliroot and try again."); + return kFALSE; + } + if (gAlice->Modules()->GetEntries() > 0) { + AliError("gAlice was already run. Restart aliroot and try again."); + return kFALSE; + } + + AliInfo(Form("initializing gAlice with config file %s", + fConfigFileName.Data())); + StdoutToAliInfo(StderrToAliError( + gAlice->Init(fConfigFileName.Data()); + );); + + // Get the trigger descriptor string + // Either from AliSimulation or from + // gAlice + if (fMakeTrigger.IsNull()) { + if (gAlice->GetTriggerDescriptor() != "") + fMakeTrigger = gAlice->GetTriggerDescriptor(); + } + else + gAlice->SetTriggerDescriptor(fMakeTrigger.Data()); + + // Set run number in CDBManager + AliCDBManager::Instance()->SetRun(gAlice->GetRunNumber()); + AliInfo(Form("Run number: %d",AliCDBManager::Instance()->GetRun())); + + AliRunLoader* runLoader = gAlice->GetRunLoader(); + if (!runLoader) { + AliError(Form("gAlice has no run loader object. " + "Check your config file: %s", fConfigFileName.Data())); + return kFALSE; + } + SetGAliceFile(runLoader->GetFileName()); + + // Misalign geometry +#if ROOT_VERSION_CODE < 331527 + MisalignGeometry(runLoader); +#endif + + // Export (mis)aligned geometry + if (gGeoManager) gGeoManager->Export("misaligned_geometry.root"); + +// AliRunLoader* runLoader = gAlice->GetRunLoader(); +// if (!runLoader) { +// AliError(Form("gAlice has no run loader object. " +// "Check your config file: %s", fConfigFileName.Data())); +// return kFALSE; +// } +// SetGAliceFile(runLoader->GetFileName()); + + if (!gAlice->Generator()) { + AliError(Form("gAlice has no generator object. " + "Check your config file: %s", fConfigFileName.Data())); return kFALSE; } - fGAliceFileName = fRunLoader->GetFileName(); + 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(); + AliInfo(Form("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("RunSimulation", "running gAlice"); - gAlice->Run(fNEvents); + // set the number of events per file for given detectors and data types + for (Int_t i = 0; i < fEventsPerFile.GetEntriesFast(); i++) { + if (!fEventsPerFile[i]) continue; + const char* detName = fEventsPerFile[i]->GetName(); + const char* typeName = fEventsPerFile[i]->GetTitle(); + TString loaderName(detName); + loaderName += "Loader"; + AliLoader* loader = runLoader->GetLoader(loaderName); + if (!loader) { + AliError(Form("RunSimulation", "no loader for %s found\n" + "Number of events per file not set for %s %s", + detName, typeName, detName)); + continue; + } + AliDataLoader* dataLoader = + loader->GetDataLoader(typeName); + if (!dataLoader) { + AliError(Form("no data loader for %s found\n" + "Number of events per file not set for %s %s", + typeName, detName, typeName)); + continue; + } + dataLoader->SetNumberOfEventsPerFile(fEventsPerFile[i]->GetUniqueID()); + AliDebug(1, Form("number of events per file set to %d for %s %s", + fEventsPerFile[i]->GetUniqueID(), detName, typeName)); + } + + AliInfo("running gAlice"); + StdoutToAliInfo(StderrToAliError( + gAlice->Run(nEvents); + );); - Info("RunSimulation", "execution time:"); - stopwatch.Print(); + delete runLoader; + + AliInfo(Form("Execution time: R:%.2fs C:%.2fs", + stopwatch.RealTime(),stopwatch.CpuTime())); 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()); + AliInfo(Form("creating summable digits for %s", det->GetName())); + TStopwatch stopwatchDet; + stopwatchDet.Start(); det->Hits2SDigits(); + AliInfo(Form("Execution time for %s: R:%.2fs C:%.2fs", + det->GetName(),stopwatchDet.RealTime(),stopwatchDet.CpuTime())); } } if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) { - Error("RunSDigitization", "the following detectors were not found: %s", - detStr.Data()); + AliError(Form("the following detectors were not found: %s", + detStr.Data())); if (fStopOnError) return kFALSE; } - Info("RunSDigitization", "execution time:"); - stopwatch.Print(); + delete runLoader; + + AliInfo(Form("Execution time: R:%.2fs C:%.2fs", + stopwatch.RealTime(),stopwatch.CpuTime())); 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 TStopwatch stopwatch; stopwatch.Start(); - Int_t nStreams = fBkgrdFileNames->GetEntriesFast() + 1; - Int_t signalPerBkgrd = 1; - if (nStreams > 1) signalPerBkgrd = fBkgrdFileNames->At(0)->GetUniqueID(); + 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->SetEmbeddingFlag(fEmbeddingFlag); manager->SetInputStream(0, fGAliceFileName.Data()); for (Int_t iStream = 1; iStream < nStreams; iStream++) { const char* fileName = ((TObjString*) @@ -344,15 +789,19 @@ 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)) { AliDigitizer* digitizer = det->CreateDigitizer(manager); + if (!digitizer) { - Error("RunDigitization", "no digitizer for %s", det->GetName()); + AliError(Form("no digitizer for %s", det->GetName())); if (fStopOnError) return kFALSE; } else { digitizer->SetRegionOfInterest(fRegionOfInterest); @@ -361,57 +810,355 @@ Bool_t AliSimulation::RunDigitization(const TString& detectors, } if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) { - Error("RunDigitization", "the following detectors were not found: %s", - detStr.Data()); + AliError(Form("the following detectors were not found: %s", + detStr.Data())); if (fStopOnError) return kFALSE; } if (!manager->GetListOfTasks()->IsEmpty()) { - delete fRunLoader; - fRunLoader = NULL; - Info("RunDigitization", "executing digitization"); + AliInfo("executing digitization"); manager->Exec(""); } - delete manager; - Info("RunDigitization", "execution time:"); - stopwatch.Print(); + delete manager; + AliInfo(Form("Execution time: R:%.2fs C:%.2fs", + stopwatch.RealTime(),stopwatch.CpuTime())); + 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("READ"); + 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("RunHitsDigitization", "creating digits from hits for %s", - det->GetName()); + AliInfo(Form("creating digits from hits for %s", det->GetName())); det->Hits2Digits(); } } if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) { - Error("RunHitsDigitization", "the following detectors were not found: %s", - detStr.Data()); + AliError(Form("the following detectors were not found: %s", + detStr.Data())); if (fStopOnError) return kFALSE; } - Info("RunHitsDigitization", "execution time:"); - stopwatch.Print(); + delete runLoader; + //PH Temporary fix to avoid interference with the PHOS loder/getter + //PH The problem has to be solved in more general way 09/06/05 + + AliInfo(Form("Execution time: R:%.2fs C:%.2fs", + stopwatch.RealTime(),stopwatch.CpuTime())); return kTRUE; } +//_____________________________________________________________________________ +Bool_t AliSimulation::WriteRawData(const char* detectors, + const char* fileName, + Bool_t deleteIntermediateFiles) +{ +// convert the digits to raw data +// First DDL raw data files for the given detectors are created. +// If a file name is given, the DDL files are then converted to a DATE file. +// If deleteIntermediateFiles is true, the DDL raw files are deleted +// afterwards. +// If the file name has the extension ".root", the DATE file is converted +// to a root file. +// If deleteIntermediateFiles is true, the DATE file is deleted afterwards. + + TStopwatch stopwatch; + stopwatch.Start(); + + if (!WriteRawFiles(detectors)) { + if (fStopOnError) return kFALSE; + } + + TString dateFileName(fileName); + if (!dateFileName.IsNull()) { + Bool_t rootOutput = dateFileName.EndsWith(".root"); + if (rootOutput) dateFileName += ".date"; + if (!ConvertRawFilesToDate(dateFileName)) { + if (fStopOnError) return kFALSE; + } + if (deleteIntermediateFiles) { + AliRunLoader* runLoader = LoadRun("READ"); + if (runLoader) for (Int_t iEvent = 0; + iEvent < runLoader->GetNumberOfEvents(); iEvent++) { + char command[256]; + sprintf(command, "rm -r raw%d", iEvent); + gSystem->Exec(command); + } + } + + if (rootOutput) { + if (!ConvertDateToRoot(dateFileName, fileName)) { + if (fStopOnError) return kFALSE; + } + if (deleteIntermediateFiles) { + gSystem->Unlink(dateFileName); + } + } + } + + AliInfo(Form("Execution time: R:%.2fs C:%.2fs", + stopwatch.RealTime(),stopwatch.CpuTime())); + + return kTRUE; +} + +//_____________________________________________________________________________ +Bool_t AliSimulation::WriteRawFiles(const char* detectors) +{ +// convert the digits to raw data DDL files + + AliRunLoader* runLoader = LoadRun("READ"); + if (!runLoader) return kFALSE; + + // write raw data to DDL files + for (Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); iEvent++) { + AliInfo(Form("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)) { + AliError(Form("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)) { + AliInfo(Form("creating raw data from digits for %s", det->GetName())); + det->Digits2Raw(); + } + } + + if (!WriteTriggerRawData()) + if (fStopOnError) return kFALSE; + + gSystem->ChangeDirectory(baseDir); + if ((detStr.CompareTo("ALL") != 0) && !detStr.IsNull()) { + AliError(Form("the following detectors were not found: %s", + detStr.Data())); + if (fStopOnError) return kFALSE; + } + } + + delete runLoader; + return kTRUE; +} + +//_____________________________________________________________________________ +Bool_t AliSimulation::ConvertRawFilesToDate(const char* dateFileName) +{ +// convert raw data DDL files to a DATE file with the program "dateStream" + + char* path = gSystem->Which(gSystem->Getenv("PATH"), "dateStream"); + if (!path) { + AliError("the program dateStream was not found"); + if (fStopOnError) return kFALSE; + } else { + delete[] path; + } + + AliRunLoader* runLoader = LoadRun("READ"); + if (!runLoader) return kFALSE; + + AliInfo(Form("converting raw data DDL files to DATE file %s", dateFileName)); + char command[256]; + // Note the option -s. It is used in order to avoid + // the generation of SOR/EOR events. + sprintf(command, "dateStream -s -D -o %s -# %d -C", + dateFileName, runLoader->GetNumberOfEvents()); + FILE* pipe = gSystem->OpenPipe(command, "w"); + + for (Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); iEvent++) { + fprintf(pipe, "GDC\n"); + Float_t ldc = 0; + Int_t prevLDC = -1; + + // loop over detectors and DDLs + for (Int_t iDet = 0; iDet < AliDAQ::kNDetectors; iDet++) { + for (Int_t iDDL = 0; iDDL < AliDAQ::NumberOfDdls(iDet); iDDL++) { + + Int_t ddlID = AliDAQ::DdlID(iDet,iDDL); + Int_t ldcID = Int_t(ldc + 0.0001); + ldc += AliDAQ::NumberOfLdcs(iDet) / AliDAQ::NumberOfDdls(iDet); + + char rawFileName[256]; + sprintf(rawFileName, "raw%d/%s", + iEvent, AliDAQ::DdlFileName(iDet,iDDL)); + + // check existence and size of raw data file + FILE* file = fopen(rawFileName, "rb"); + if (!file) continue; + fseek(file, 0, SEEK_END); + unsigned long size = ftell(file); + fclose(file); + if (!size) continue; + + if (ldcID != prevLDC) { + fprintf(pipe, " LDC Id %d\n", ldcID); + prevLDC = ldcID; + } + fprintf(pipe, " Equipment Id %d Payload %s\n", ddlID, rawFileName); + } + } + } + + Int_t result = gSystem->ClosePipe(pipe); + + delete runLoader; + return (result == 0); +} + +//_____________________________________________________________________________ +Bool_t AliSimulation::ConvertDateToRoot(const char* dateFileName, + const char* rootFileName) +{ +// convert a DATE file to a root file with the program "alimdc" + + // ALIMDC setup + const Int_t kDBSize = 2000000000; + const Int_t kTagDBSize = 1000000000; + const Bool_t kFilter = kFALSE; + const Int_t kCompression = 0; + + char* path = gSystem->Which(gSystem->Getenv("PATH"), "alimdc"); + if (!path) { + AliError("the program alimdc was not found"); + if (fStopOnError) return kFALSE; + } else { + delete[] path; + } + + AliInfo(Form("converting DATE file %s to root file %s", + dateFileName, rootFileName)); + + const char* rawDBFS[2] = { "/tmp/mdc1", "/tmp/mdc2" }; + const char* tagDBFS = "/tmp/mdc1/tags"; + + // User defined file system locations + if (gSystem->Getenv("ALIMDC_RAWDB1")) + rawDBFS[0] = gSystem->Getenv("ALIMDC_RAWDB1"); + if (gSystem->Getenv("ALIMDC_RAWDB2")) + rawDBFS[1] = gSystem->Getenv("ALIMDC_RAWDB2"); + if (gSystem->Getenv("ALIMDC_TAGDB")) + tagDBFS = gSystem->Getenv("ALIMDC_TAGDB"); + + gSystem->Exec(Form("rm -rf %s",rawDBFS[0])); + gSystem->Exec(Form("rm -rf %s",rawDBFS[1])); + gSystem->Exec(Form("rm -rf %s",tagDBFS)); + + gSystem->Exec(Form("mkdir %s",rawDBFS[0])); + gSystem->Exec(Form("mkdir %s",rawDBFS[1])); + gSystem->Exec(Form("mkdir %s",tagDBFS)); + + Int_t result = gSystem->Exec(Form("alimdc %d %d %d %d %s", + kDBSize, kTagDBSize, kFilter, kCompression, dateFileName)); + gSystem->Exec(Form("mv %s/*.root %s", rawDBFS[0], rootFileName)); + + gSystem->Exec(Form("rm -rf %s",rawDBFS[0])); + gSystem->Exec(Form("rm -rf %s",rawDBFS[1])); + gSystem->Exec(Form("rm -rf %s",tagDBFS)); + + return (result == 0); +} + + +//_____________________________________________________________________________ +AliRunLoader* AliSimulation::LoadRun(const char* mode) 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(), mode); + if (!runLoader) { + AliError(Form("no run loader found in file %s", fGAliceFileName.Data())); + return NULL; + } + runLoader->LoadgAlice(); + gAlice = runLoader->GetAliRun(); + if (!gAlice) { + AliError(Form("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)) { + AliInfo(Form("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) { + AliWarning(Form("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 @@ -445,3 +1192,104 @@ Bool_t AliSimulation::IsSelected(TString detName, TString& detectors) const return result; } + +Bool_t AliSimulation::ConvertRaw2SDigits(const char* rawDirectory, const char* esdFileName) +{ +// +// Steering routine to convert raw data in directory rawDirectory/ to fake SDigits. +// These can be used for embedding of MC tracks into RAW data using the standard +// merging procedure. +// +// If an ESD file is given the reconstructed vertex is taken from it and stored in the event header. +// + if (!gAlice) { + AliError("no gAlice object. Restart aliroot and try again."); + return kFALSE; + } + if (gAlice->Modules()->GetEntries() > 0) { + AliError("gAlice was already run. Restart aliroot and try again."); + return kFALSE; + } + + AliInfo(Form("initializing gAlice with config file %s",fConfigFileName.Data())); + StdoutToAliInfo(StderrToAliError(gAlice->Init(fConfigFileName.Data()););); +// +// Initialize CDB + InitCDBStorage(); + AliCDBManager* man = AliCDBManager::Instance(); + man->SetRun(0); // Should this come from rawdata header ? + + Int_t iDet; + // + // Get the runloader + AliRunLoader* runLoader = gAlice->GetRunLoader(); + // + // Open esd file if available + TFile* esdFile = TFile::Open(esdFileName); + Bool_t esdOK = (esdFile != 0); + AliESD* esd = new AliESD; + TTree* treeESD = 0; + if (esdOK) { + treeESD = (TTree*) esdFile->Get("esdTree"); + if (!treeESD) { + AliWarning("No ESD tree found"); + esdOK = kFALSE; + } else { + treeESD->SetBranchAddress("ESD", &esd); + } + } + // + // Create the RawReader + AliRawReaderFile* rawReader = new AliRawReaderFile(rawDirectory); + // + // Get list of detectors + TObjArray* detArray = runLoader->GetAliRun()->Detectors(); + // + // Get Header + AliHeader* header = runLoader->GetHeader(); + // + // Event loop + Int_t nev = 0; + while(kTRUE) { + if (!(rawReader->NextEvent())) break; + // + // Detector loop + for (iDet = 0; iDet < detArray->GetEntriesFast(); iDet++) { + AliModule* det = (AliModule*) detArray->At(iDet); + AliInfo(Form("Calling Raw2SDigits for %s\n", det->GetName())); + det->Raw2SDigits(rawReader); + rawReader->Reset(); + } // detectors + + // + // If ESD information available obtain reconstructed vertex and store in header. + if (esdOK) { + treeESD->GetEvent(nev); + const AliESDVertex* esdVertex = esd->GetPrimaryVertex(); + Double_t position[3]; + esdVertex->GetXYZ(position); + AliGenEventHeader* mcHeader = new AliGenEventHeader("ESD"); + TArrayF mcV; + mcV.Set(3); + for (Int_t i = 0; i < 3; i++) mcV[i] = position[i]; + mcHeader->SetPrimaryVertex(mcV); + header->Reset(0,nev); + header->SetGenEventHeader(mcHeader); + printf("***** Saved vertex %f %f %f \n", position[0], position[1], position[2]); + } + nev++; +// +// Finish the event + runLoader->TreeE()->Fill(); + runLoader->SetNextEvent(); + } // events + + delete rawReader; +// +// Finish the run + runLoader->CdGAFile(); + runLoader->WriteHeader("OVERWRITE"); + runLoader->WriteRunLoader(); + + return kTRUE; +}