diff --git a/DDG4/include/DDG4/Geant4InputAction.h b/DDG4/include/DDG4/Geant4InputAction.h index 16de077205f8b737c2407894725d04e114a14bef..b8a0a5bc4f78a6cda04c702e02f484042aa7d945 100644 --- a/DDG4/include/DDG4/Geant4InputAction.h +++ b/DDG4/include/DDG4/Geant4InputAction.h @@ -36,6 +36,7 @@ // Forward declarations class G4Event; +class G4Run; /// Namespace for the AIDA detector description toolkit namespace dd4hep { @@ -177,6 +178,11 @@ namespace dd4hep { /// Property: named parameters to configure file readers or input actions std::map< std::string, std::string> m_parameters; + /// Perform some actions before the run starts, like opening the event inputs + void beginRun(const G4Run*); + + /// Create the input reader + void createReader(); public: /// Read an event and return a LCCollectionVec of MCParticles. int readParticles(int event_number, diff --git a/DDG4/src/Geant4InputAction.cpp b/DDG4/src/Geant4InputAction.cpp index aab1eafb31723a72b21599480a4f417e7ca01ae4..05dfd7b5d49b830e00c49e2ec60dcee73a85edc1 100644 --- a/DDG4/src/Geant4InputAction.cpp +++ b/DDG4/src/Geant4InputAction.cpp @@ -19,6 +19,7 @@ #include "DDG4/Geant4Context.h" #include "DDG4/Geant4Kernel.h" #include "DDG4/Geant4InputAction.h" +#include "DDG4/Geant4RunAction.h" #include "G4Event.hh" @@ -127,12 +128,50 @@ Geant4InputAction::Geant4InputAction(Geant4Context* ctxt, const string& nam) declareProperty("HaveAbort", m_abort = true); declareProperty("Parameters", m_parameters = {}); m_needsControl = true; + + runAction().callAtBegin(this, &Geant4InputAction::beginRun); } /// Default destructor Geant4InputAction::~Geant4InputAction() { } +///Intialize the event reader before the run starts +void Geant4InputAction::beginRun(const G4Run*) { + createReader(); +} + +void Geant4InputAction::createReader() { + if(m_reader) { + return; + } + if ( m_input.empty() ) { + except("InputAction: No input file declared!"); + } + string err; + TypeName tn = TypeName::split(m_input,"|"); + try { + m_reader = PluginService::Create<Geant4EventReader*>(tn.first,tn.second); + if ( 0 == m_reader ) { + PluginDebug dbg; + m_reader = PluginService::Create<Geant4EventReader*>(tn.first,tn.second); + abortRun("Error creating reader plugin.", + "Failed to create file reader of type %s. Cannot open dataset %s", + tn.first.c_str(),tn.second.c_str()); + } + m_reader->setParameters( m_parameters ); + m_reader->checkParameters( m_parameters ); + m_reader->setInputAction( this ); + m_reader->registerRunParameters(); + } catch(const exception& e) { + err = e.what(); + } + if ( !err.empty() ) { + abortRun(err,"Error when creating reader for file %s",m_input.c_str()); + } +} + + /// helper to report Geant4 exceptions string Geant4InputAction::issue(int i) const { stringstream str; @@ -145,36 +184,9 @@ int Geant4InputAction::readParticles(int evt_number, Vertices& vertices, std::vector<Particle*>& particles) { + //in case readParticles is called diractly outside of having a run, we make sure a reader exists + createReader(); int evid = evt_number + m_firstEvent; - if ( 0 == m_reader ) { - if ( m_input.empty() ) { - except("InputAction: No input file declared!"); - } - string err; - TypeName tn = TypeName::split(m_input,"|"); - try { - m_reader = PluginService::Create<Geant4EventReader*>(tn.first,tn.second); - if ( 0 == m_reader ) { - PluginDebug dbg; - m_reader = PluginService::Create<Geant4EventReader*>(tn.first,tn.second); - abortRun(issue(evid)+"Error creating reader plugin.", - "Failed to create file reader of type %s. Cannot open dataset %s", - tn.first.c_str(),tn.second.c_str()); - return Geant4EventReader::EVENT_READER_NO_FACTORY; - } - m_reader->setParameters( m_parameters ); - m_reader->checkParameters( m_parameters ); - m_reader->setInputAction( this ); - m_reader->registerRunParameters(); - } - catch(const exception& e) { - err = e.what(); - } - if ( !err.empty() ) { - abortRun(issue(evid)+err,"Error when creating reader for file %s",m_input.c_str()); - return Geant4EventReader::EVENT_READER_NO_FACTORY; - } - } int status = m_reader->moveToEvent(evid); if(status == Geant4EventReader::EVENT_READER_EOF ) { long nEvents = context()->kernel().property("NumEvents").value<long>();