From 8b959084cc5ce564422d3285d19f506751f89884 Mon Sep 17 00:00:00 2001 From: Florian Uhlig <f.uhlig@gsi.de> Date: Thu, 17 Feb 2022 18:41:31 +0100 Subject: [PATCH] Don't transport more events as available in input In #2421 a crash was reported when the number of events requested to be transported is larger than the number of events in the input. Add protection against such a crash in the transport class. The number of events to be transported is set to the minimum number of events in any of the connected inputs. --- .../generators/CbmPlutoGenerator.cxx | 34 +++--------------- sim/transport/generators/CbmPlutoGenerator.h | 31 +++++++++------- .../generators/CbmUnigenGenerator.cxx | 24 ++----------- sim/transport/generators/CbmUnigenGenerator.h | 36 +++++++++++-------- sim/transport/steer/CMakeLists.txt | 2 ++ sim/transport/steer/CbmTransport.cxx | 31 +++++++++++++++- 6 files changed, 78 insertions(+), 80 deletions(-) diff --git a/sim/transport/generators/CbmPlutoGenerator.cxx b/sim/transport/generators/CbmPlutoGenerator.cxx index f3d944df0c..4e92dbbff9 100644 --- a/sim/transport/generators/CbmPlutoGenerator.cxx +++ b/sim/transport/generators/CbmPlutoGenerator.cxx @@ -34,29 +34,11 @@ #include <sys/stat.h> // ----- Default constructor ------------------------------------------ -CbmPlutoGenerator::CbmPlutoGenerator() - : FairGenerator() - , fdata(makeStaticData()) - , fbase(makeDataBase()) - , iEvent(0) - , fFileName(nullptr) - , fInputChain(nullptr) - , fParticles(nullptr) - , fPDGmanual(0) -{ -} +CbmPlutoGenerator::CbmPlutoGenerator() : FairGenerator() {} // ------------------------------------------------------------------------ // ----- Standard constructor ----------------------------------------- -CbmPlutoGenerator::CbmPlutoGenerator(const Char_t* fileName) - : FairGenerator() - , fdata(makeStaticData()) - , fbase(makeDataBase()) - , iEvent(0) - , fFileName(fileName) - , fInputChain(nullptr) - , fParticles(new TClonesArray("PParticle", 100)) - , fPDGmanual(0) +CbmPlutoGenerator::CbmPlutoGenerator(const Char_t* fileName) : FairGenerator(), fFileName(fileName) { fInputChain = new TChain("data"); @@ -68,19 +50,12 @@ CbmPlutoGenerator::CbmPlutoGenerator(const Char_t* fileName) else { LOG(fatal) << "Problem opening file " << fileName; } + fAvailableEvents = fInputChain->GetEntries(); } // ------------------------------------------------------------------------ // ----- Constructor with file list ----------------------------------------- -CbmPlutoGenerator::CbmPlutoGenerator(std::vector<std::string> fileNames) - : FairGenerator() - , fdata(makeStaticData()) - , fbase(makeDataBase()) - , iEvent(0) - , fFileName() - , fInputChain(nullptr) - , fParticles(new TClonesArray("PParticle", 100)) - , fPDGmanual(0) +CbmPlutoGenerator::CbmPlutoGenerator(std::vector<std::string> fileNames) : FairGenerator() { fInputChain = new TChain("data"); for (const auto& name : fileNames) { @@ -94,6 +69,7 @@ CbmPlutoGenerator::CbmPlutoGenerator(std::vector<std::string> fileNames) } fInputChain->SetBranchAddress("Particles", &fParticles); + fAvailableEvents = fInputChain->GetEntries(); } diff --git a/sim/transport/generators/CbmPlutoGenerator.h b/sim/transport/generators/CbmPlutoGenerator.h index c8585c4c15..5650523e4b 100644 --- a/sim/transport/generators/CbmPlutoGenerator.h +++ b/sim/transport/generators/CbmPlutoGenerator.h @@ -22,19 +22,19 @@ #include "FairGenerator.h" // for FairGenerator -#include "Rtypes.h" // for Char_t, etc +#include "Rtypes.h" // for Char_t, etc +#include "TClonesArray.h" // for TClonesArray #include <string> #include <vector> +#include "PParticle.h" // for PParticle +#include "PStaticData.h" // for PStaticData + class FairPrimaryGenerator; -class TClonesArray; class TChain; -class PStaticData; -class PDataBase; - class CbmPlutoGenerator : public FairGenerator { public: @@ -66,22 +66,27 @@ public: virtual Bool_t ReadEvent(FairPrimaryGenerator* primGen); void SetManualPDG(Int_t pdg) { fPDGmanual = pdg; } + /** @brief Get the maximum number of events available in the input file + ** @return number of available ebvents + */ + Int_t GetNumAvailableEvents() { return fAvailableEvents; } private: - PStaticData* fdata; //! pluto static data - PDataBase* fbase; //! pluto data base + PStaticData* fdata {makeStaticData()}; //! pluto static data + PDataBase* fbase {makeDataBase()}; //! pluto data base - Int_t iEvent; //! Event number - const Char_t* fFileName; //! Input file name - TChain* fInputChain; //! Pointer to input file - TClonesArray* fParticles; //! Particle array from PLUTO - Int_t fPDGmanual; //! forced pdg value for undefined pluto codes + Int_t iEvent {0}; //! Event number + const Char_t* fFileName {""}; //! Input file name + TChain* fInputChain {nullptr}; //! Pointer to input file + TClonesArray* fParticles {new TClonesArray("PParticle", 100)}; //! Particle array from PLUTO + Int_t fPDGmanual {0}; //! forced pdg value for undefined pluto codes + Int_t fAvailableEvents {0}; //! Maximum number of events in the input file /** Private method CloseInput. Just for convenience. Closes the ** input file properly. Called from destructor and from ReadEvent. **/ void CloseInput(); - ClassDef(CbmPlutoGenerator, 4); + ClassDef(CbmPlutoGenerator, 5); }; #endif diff --git a/sim/transport/generators/CbmUnigenGenerator.cxx b/sim/transport/generators/CbmUnigenGenerator.cxx index 3a4be378ea..212d618263 100644 --- a/sim/transport/generators/CbmUnigenGenerator.cxx +++ b/sim/transport/generators/CbmUnigenGenerator.cxx @@ -35,17 +35,6 @@ CbmUnigenGenerator::CbmUnigenGenerator(const char* fileName, EMode mode) : FairGenerator("UnigenGenerator", "CBM generator") , fFileName(fileName) , fMode(mode) - , fPhi(0.) - , fIsInit(kFALSE) - , fFile(nullptr) - , fTree(nullptr) - , fCurrentEntry(-1) - , fEvent(new UEvent()) - , fNofPrimaries(0) - , fNofEvents(0) - , fBetaCM(0.) - , fGammaCM(1.) - , fIonMap() { LOG(debug) << GetName() << ": Constructor"; if (mode == kRotateFixed) @@ -63,16 +52,6 @@ CbmUnigenGenerator::CbmUnigenGenerator(const char* fileName, EMode mode, Double_ , fFileName(fileName) , fMode(mode) , fPhi(phi) - , fIsInit(kFALSE) - , fFile(nullptr) - , fTree(nullptr) - , fCurrentEntry(-1) - , fEvent(new UEvent()) - , fNofPrimaries(0) - , fNofEvents(0) - , fBetaCM(0.) - , fGammaCM(1.) - , fIonMap() { LOG(debug) << GetName() << ": Constructor"; if (fileName[0] == '\0') return; @@ -207,7 +186,8 @@ Bool_t CbmUnigenGenerator::Init() return kFALSE; } fTree->SetBranchAddress("event", &fEvent); - LOG(info) << GetName() << ": " << fTree->GetEntries() << " events in input tree"; + fAvailableEvents = fTree->GetEntriesFast(); + LOG(info) << GetName() << ": " << fAvailableEvents << " events in input tree"; // --- Register ions found in the input file Int_t nIons = RegisterIons(); diff --git a/sim/transport/generators/CbmUnigenGenerator.h b/sim/transport/generators/CbmUnigenGenerator.h index 8af033e84a..bd34df29df 100644 --- a/sim/transport/generators/CbmUnigenGenerator.h +++ b/sim/transport/generators/CbmUnigenGenerator.h @@ -19,9 +19,10 @@ #include <map> +#include "UEvent.h" + class TFile; class TTree; -class UEvent; class UParticle; class FairIon; class FairPrimaryGenerator; @@ -93,21 +94,26 @@ public: **/ virtual Bool_t ReadEvent(FairPrimaryGenerator* primGen); + /** @brief Get the maximum number of events available in the input file + ** @return number of available ebvents + */ + Int_t GetNumAvailableEvents() { return fAvailableEvents; } private: - TString fFileName; ///< Input file name - EMode fMode; ///< Rotation mode - Double_t fPhi; ///< Event plane rotation angle - Bool_t fIsInit; ///< Flag whether generator is initialised - TFile* fFile; //!< Input ROOT file - TTree* fTree; //!< Input ROOT tree - Int_t fCurrentEntry; ///< Current entry number - UEvent* fEvent; //!< Current input event - Int_t fNofPrimaries; //!< Number of primaries registered in current event - Int_t fNofEvents; ///< Number of processed events - Double_t fBetaCM; ///< CM velocity in the lab frame - Double_t fGammaCM; ///< Gamma factor of CM in lab frame - std::map<TString, FairIon*> fIonMap; //!< Map from ion name to FairIon + TString fFileName = ""; ///< Input file name + EMode fMode = kStandard; ///< Rotation mode + Double_t fPhi = 0.; ///< Event plane rotation angle + Bool_t fIsInit = kFALSE; ///< Flag whether generator is initialised + TFile* fFile = nullptr; //!< Input ROOT file + TTree* fTree = nullptr; //!< Input ROOT tree + Int_t fCurrentEntry = -1; ///< Current entry number + UEvent* fEvent = new UEvent(); //!< Current input event + Int_t fNofPrimaries = 0; //!< Number of primaries registered in current event + Int_t fNofEvents = 0; ///< Number of processed events + Double_t fBetaCM = 0; ///< CM velocity in the lab frame + Double_t fGammaCM = 0; ///< Gamma factor of CM in lab frame + Int_t fAvailableEvents = 0; ///< Maximum number of events in the input file + std::map<TString, FairIon*> fIonMap {}; //!< Map from ion name to FairIon // Constants for decimal decomposition of ion PDG. // For ions the PDG code is +-10LZZZAAAI, with L = number of Lambdas, @@ -204,7 +210,7 @@ private: CbmUnigenGenerator& operator=(const CbmUnigenGenerator&) = delete; - ClassDef(CbmUnigenGenerator, 4); + ClassDef(CbmUnigenGenerator, 5); }; #endif diff --git a/sim/transport/steer/CMakeLists.txt b/sim/transport/steer/CMakeLists.txt index d119b821f1..2b4e797c65 100644 --- a/sim/transport/steer/CMakeLists.txt +++ b/sim/transport/steer/CMakeLists.txt @@ -31,6 +31,8 @@ ${CBMROOT_SOURCE_DIR}/sim ${CBMROOT_SOURCE_DIR}/sim/transport ${CBMROOT_SOURCE_DIR}/sim/transport/base ${CBMROOT_SOURCE_DIR}/sim/transport/generators +${CBMROOT_SOURCE_DIR}/sim/transport/generators/unigen +${CBMROOT_SOURCE_DIR}/sim/transport/generators/pluto ${CBMROOT_SOURCE_DIR}/sim/transport/steer ${CBMROOT_SOURCE_DIR}/sim/transport/geosetup ${CBMDATA_DIR} diff --git a/sim/transport/steer/CbmTransport.cxx b/sim/transport/steer/CbmTransport.cxx index 87676b0b8c..cb7bee6ab6 100644 --- a/sim/transport/steer/CbmTransport.cxx +++ b/sim/transport/steer/CbmTransport.cxx @@ -49,6 +49,7 @@ #include <array> #include <cassert> +#include <climits> #include <iostream> #include <sstream> #include <string> @@ -468,6 +469,35 @@ void CbmTransport::PiAndEtaDecay(TVirtualMC* vmc) void CbmTransport::Run(Int_t nEvents) { + // Get the minimum number of events from all file based generators + // Set the number of events to process to this minimum number of events + Int_t numAvailEvents {0}; + Int_t numMinAvailEvents {INT_MAX}; + TObjArray* genList = fEventGen->GetListOfGenerators(); + for (Int_t i = 0; i < genList->GetEntries(); i++) { + CbmUnigenGenerator* gen = dynamic_cast<CbmUnigenGenerator*>(genList->At(i)); + if (gen) { + numAvailEvents = gen->GetNumAvailableEvents(); + if (nEvents > numAvailEvents) { + if (numAvailEvents < numMinAvailEvents) { numMinAvailEvents = numAvailEvents; } + } + } + CbmPlutoGenerator* pgen = dynamic_cast<CbmPlutoGenerator*>(genList->At(i)); + if (pgen) { + numAvailEvents = pgen->GetNumAvailableEvents(); + if (nEvents > numAvailEvents) { + if (numAvailEvents < numMinAvailEvents) { numMinAvailEvents = numAvailEvents; } + } + } + } + if (nEvents > numMinAvailEvents) { + LOG(warning) << ""; + LOG(warning) << "The number of requested events (" << nEvents << ") is larger than the number of available events (" + << numMinAvailEvents << ")"; + LOG(warning) << "Set the number of events to process to " << numMinAvailEvents; + LOG(warning) << ""; + } + // --- Timer TStopwatch timer; @@ -525,7 +555,6 @@ void CbmTransport::Run(Int_t nEvents) // --- Initialise the event generator InitEventGenerator(); - // --- Trigger generation of run info fRun->SetGenerateRunInfo(fGenerateRunInfo); -- GitLab