diff --git a/DDG4/CMakeLists.txt b/DDG4/CMakeLists.txt index 0a341469d..a4006137d 100644 --- a/DDG4/CMakeLists.txt +++ b/DDG4/CMakeLists.txt @@ -104,12 +104,22 @@ ENDIF() IF(TARGET EDM4HEP::edm4hep) dd4hep_add_plugin(DDG4EDM4HEP - SOURCES edm4hep/*.cpp + SOURCES edm4hep/Geant4Output2EDM4hep.cpp USES DD4hep::DDG4 EDM4HEP::edm4hep EDM4HEP::edm4hepDict podio::podio podio::podioDict podio::podioRootIO ) install(TARGETS DDG4EDM4HEP EXPORT DD4hep LIBRARY DESTINATION lib) set_target_properties(DDG4EDM4HEP PROPERTIES VERSION ${DD4hep_VERSION} SOVERSION ${DD4hep_SOVERSION}) - + if(TARGET podio::podioIO) + dd4hep_add_plugin(DDG4EDM4HEPReader + SOURCES edm4hep/EDM4hepFileReader.cpp + USES DD4hep::DDG4 EDM4HEP::edm4hep EDM4HEP::edm4hepDict podio::podio podio::podioDict podio::podioIO + ) + install(TARGETS DDG4EDM4HEPReader EXPORT DD4hep LIBRARY DESTINATION lib) + set_target_properties(DDG4EDM4HEPReader PROPERTIES VERSION ${DD4hep_VERSION} SOVERSION ${DD4hep_SOVERSION}) + MESSAGE(STATUS "EDM4hepFileReader enabled") + else() + MESSAGE(STATUS "EDM4hepFileReader requires at least PODIO 1.0, disabled") + endif() ENDIF() IF(DD4HEP_USE_HEPMC3) diff --git a/DDG4/edm4hep/EDM4hepFileReader.cpp b/DDG4/edm4hep/EDM4hepFileReader.cpp new file mode 100644 index 000000000..8e7181d00 --- /dev/null +++ b/DDG4/edm4hep/EDM4hepFileReader.cpp @@ -0,0 +1,332 @@ +//========================================================================== +// AIDA Detector description implementation +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : A.Sailer +// +//========================================================================== + +/** \addtogroup Geant4EventReader + * + @{ + \package EDM4hepFileReader + * \brief Plugin to read EDM4hep files + * + * + @} +*/ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +typedef dd4hep::detail::ReferenceBitMask PropertyMask; + + +namespace dd4hep::sim { + + // we use the index of the objectID to identify particles + // we will not support MCParticles from different collections + using MCPARTICLE_MAP=std::map; + + /// get the parameters from the GenericParameters of the input EDM4hep frame and store them in the EventParameters + /// extension + template void EventParameters::ingestParameters(T const& source) { + for(auto const& key: source.template getKeys()) { + m_intValues[key] = source.template get>(key).value(); + } + for(auto const& key: source.template getKeys()) { + m_fltValues[key] = source.template get>(key).value(); + } + for(auto const& key: source.template getKeys()) { + m_dblValues[key] = source.template get>(key).value(); + } + for(auto const& key: source.template getKeys()) { + m_strValues[key] = source.template get>(key).value(); + } + } + + /// get the parameters from the GenericParameters of the input EDM4hep run frame and store them in the RunParameters + /// extension + template void RunParameters::ingestParameters(T const& source) { + for(auto const& key: source.template getKeys()) { + m_intValues[key] = source.template get>(key).value(); + } + for(auto const& key: source.template getKeys()) { + m_fltValues[key] = source.template get>(key).value(); + } + for(auto const& key: source.template getKeys()) { + m_dblValues[key] = source.template get>(key).value(); + } + for(auto const& key: source.template getKeys()) { + m_strValues[key] = source.template get>(key).value(); + } + } + + template void FileParameters::ingestParameters(T const& source) { + for(auto const& key: source.template getKeys()) { + m_intValues[key] = source.template get>(key).value(); + } + for(auto const& key: source.template getKeys()) { + m_fltValues[key] = source.template get>(key).value(); + } + for(auto const& key: source.template getKeys()) { + m_dblValues[key] = source.template get>(key).value(); + } + for(auto const& key: source.template getKeys()) { + m_strValues[key] = source.template get>(key).value(); + } + } + + /// Class to read EDM4hep files + /** + * \version 1.0 + * \ingroup DD4HEP_SIMULATION + */ + class EDM4hepFileReader : public Geant4EventReader { + protected: + /// Reference to reader object + podio::Reader m_reader; + /// Name of the MCParticle collection to read + std::string m_collectionName; + /// Name of the EventHeader collection to read + std::string m_eventHeaderCollectionName; + + public: + /// Initializing constructor + EDM4hepFileReader(const std::string& nam); + + /// Read parameters set for this action + virtual EventReaderStatus setParameters(std::map< std::string, std::string >& parameters); + + /// Read an event and fill a vector of MCParticles. + virtual EventReaderStatus readParticles(int event_number, Vertices& vertices, std::vector& particles); + /// Call to register the run parameters + void registerRunParameters(); + + }; + + /// Initializing constructor + dd4hep::sim::EDM4hepFileReader::EDM4hepFileReader(const std::string& nam) + : Geant4EventReader(nam) + , m_reader(podio::makeReader(nam)) + , m_collectionName("MCParticles") + , m_eventHeaderCollectionName("EventHeader") + { + printout(INFO,"EDM4hepFileReader","Created file reader. Try to open input %s",nam.c_str()); + m_directAccess = true; + } + + void EDM4hepFileReader::registerRunParameters() { + try { + auto *parameters = new RunParameters(); + try { + podio::Frame runFrame = m_reader.readFrame("runs", 0); + parameters->ingestParameters(runFrame.getParameters()); + } catch (std::runtime_error& e) { + // we ignore if we do not have runs information + } catch(std::invalid_argument&) { + // we ignore if we do not have runs information + } + context()->run().addExtension(parameters); + } catch(std::exception &e) { + printout(ERROR,"EDM4hepFileReader::registerRunParameters","Failed to register run parameters: %s", e.what()); + } + + try { + auto *fileParameters = new FileParameters(); + try { + podio::Frame metaFrame = m_reader.readFrame("metadata", 0); + fileParameters->ingestParameters(metaFrame.getParameters()); + } catch (std::runtime_error& e) { + // we ignore if we do not have metadata information + } catch(std::invalid_argument&) { + // we ignore if we do not have metadata information + } + context()->run().addExtension(fileParameters); + } catch(std::exception &e) { + printout(ERROR,"EDM4hepFileReader::registerRunParameters","Failed to register file parameters: %s", e.what()); + } + } + + namespace { + /// Helper function to look up MCParticles from mapping + inline int GET_ENTRY(MCPARTICLE_MAP const& mcparts, int partID) { + MCPARTICLE_MAP::const_iterator ip = mcparts.find(partID); + if ( ip == mcparts.end() ) { + throw std::runtime_error("Unknown particle identifier look-up!"); + } + return (*ip).second; + } + } + + /// Read an event and fill a vector of MCParticles + EDM4hepFileReader::EventReaderStatus + EDM4hepFileReader::readParticles(int event_number, Vertices& vertices, std::vector& particles) { + m_currEvent = event_number; + podio::Frame frame = m_reader.readFrame("events", event_number); + const auto& primaries = frame.get(m_collectionName); + int eventNumber = event_number, runNumber = 0; + if (primaries.isValid()) { + //Read the event header collection and add it to the context as an extension + const auto& eventHeaderCollection = frame.get(m_eventHeaderCollectionName); + if(eventHeaderCollection.isValid() && eventHeaderCollection.size() == 1){ + const auto& eh = eventHeaderCollection.at(0); + eventNumber = eh.getEventNumber(); + runNumber = eh.getRunNumber(); + try { + Geant4Context* ctx = context(); + ctx->event().addExtension(new edm4hep::MutableEventHeader(eh.clone())); + } catch(std::exception& ) {} + // Create input event parameters context + try { + Geant4Context* ctx = context(); + EventParameters *parameters = new EventParameters(); + parameters->setRunNumber(runNumber); + parameters->setEventNumber(eventNumber); + parameters->ingestParameters(frame.getParameters()); + ctx->event().addExtension(parameters); + } catch(std::exception &) {} + } else { + printout(WARNING,"EDM4hepFileReader","No EventHeader collection found or too many event headers!"); + try { + Geant4Context* ctx = context(); + EventParameters *parameters = new EventParameters(); + parameters->setRunNumber(0); + parameters->setEventNumber(event_number); + parameters->ingestParameters(frame.getParameters()); + ctx->event().addExtension(parameters); + } catch(std::exception &) {} + } + printout(INFO,"EDM4hepFileReader","read collection %s from event %d in run %d ", + m_collectionName.c_str(), eventNumber, runNumber); + + } else { + return EVENT_READER_EOF; + } + + printout(INFO,"EDM4hepFileReader", "We read the particle collection"); + int NHEP = primaries.size(); + // check if there is at least one particle + if ( NHEP == 0 ) { + printout(WARNING,"EDM4hepFileReader", "We have no particles"); + return EVENT_READER_NO_PRIMARIES; + } + + MCPARTICLE_MAP mcparts; + std::vector mcpcoll; + mcpcoll.resize(NHEP); + for(int i=0; ipdgID = pdg; + p->charge = int(mcp.getCharge()*3.0); + p->psx = mom[0]*CLHEP::GeV; + p->psy = mom[1]*CLHEP::GeV; + p->psz = mom[2]*CLHEP::GeV; + p->time = mcp.getTime()*CLHEP::ns; + p->properTime = mcp.getTime()*CLHEP::ns; + p->vsx = vsx[0]*CLHEP::mm; + p->vsy = vsx[1]*CLHEP::mm; + p->vsz = vsx[2]*CLHEP::mm; + p->vex = vex[0]*CLHEP::mm; + p->vey = vex[1]*CLHEP::mm; + p->vez = vex[2]*CLHEP::mm; + p->process = 0; + p->spin[0] = spin[0]; + p->spin[1] = spin[1]; + p->spin[2] = spin[2]; + p->colorFlow[0] = 0; + p->colorFlow[1] = 0; + p->mass = mcp.getMass()*CLHEP::GeV; + const auto par = mcp.getParents(), &dau=mcp.getDaughters(); + for(int num=dau.size(),k=0; kdaughters.insert(GET_ENTRY(mcparts,dau_k.getObjectID().index)); + } + for(int num=par.size(),k=0; kparents.insert(GET_ENTRY(mcparts, par_k.getObjectID().index)); + } + + PropertyMask status(p->status); + int genStatus = mcp.getGeneratorStatus(); + // Copy raw generator status + p->genStatus = genStatus&G4PARTICLE_GEN_STATUS_MASK; + if(m_inputAction) { + // in some tests we do not set up the inputAction + m_inputAction->setGeneratorStatus(genStatus, status); + } + + //fg: we simply add all particles without parents as with their own vertex. + // This might include the incoming beam particles, e.g. in + // the case of lcio files written with Whizard2, which is slightly odd, + // however should be treated correctly in Geant4InputHandling.cpp. + // We no longer make an attempt to identify the incoming particles + // based on the generator status, as this varies widely with different + // generators. + + if ( p->parents.size() == 0 ) { + + Geant4Vertex* vtx = new Geant4Vertex ; + vertices.emplace_back( vtx ); + vtx->x = p->vsx; + vtx->y = p->vsy; + vtx->z = p->vsz; + vtx->time = p->time; + + vtx->out.insert(p->id) ; + } + + if ( mcp.isCreatedInSimulation() ) status.set(G4PARTICLE_SIM_CREATED); + if ( mcp.isBackscatter() ) status.set(G4PARTICLE_SIM_BACKSCATTER); + if ( mcp.vertexIsNotEndpointOfParent() ) status.set(G4PARTICLE_SIM_PARENT_RADIATED); + if ( mcp.isDecayedInTracker() ) status.set(G4PARTICLE_SIM_DECAY_TRACKER); + if ( mcp.isDecayedInCalorimeter() ) status.set(G4PARTICLE_SIM_DECAY_CALO); + if ( mcp.hasLeftDetector() ) status.set(G4PARTICLE_SIM_LEFT_DETECTOR); + if ( mcp.isStopped() ) status.set(G4PARTICLE_SIM_STOPPED); + if ( mcp.isOverlay() ) status.set(G4PARTICLE_SIM_OVERLAY); + particles.emplace_back(p); + } + return EVENT_READER_OK; + } + + /// Set the parameters for the class, in particular the name of the MCParticle + /// list + Geant4EventReader::EventReaderStatus + dd4hep::sim::EDM4hepFileReader::setParameters( std::map< std::string, std::string > & parameters ) { + _getParameterValue(parameters, "MCParticleCollectionName", m_collectionName, m_collectionName); + _getParameterValue(parameters, "EventHeaderCollectionName", m_eventHeaderCollectionName, m_eventHeaderCollectionName); + return EVENT_READER_OK; + } + +} //end dd4hep::sim + +DECLARE_GEANT4_EVENT_READER_NS(dd4hep::sim,EDM4hepFileReader) diff --git a/DDG4/edm4hep/Geant4Output2EDM4hep.cpp b/DDG4/edm4hep/Geant4Output2EDM4hep.cpp index 9d4d2613f..bd68c468b 100644 --- a/DDG4/edm4hep/Geant4Output2EDM4hep.cpp +++ b/DDG4/edm4hep/Geant4Output2EDM4hep.cpp @@ -16,6 +16,7 @@ /// Framework include files #include #include +#include #include #include @@ -25,13 +26,10 @@ #include #include #include -#if EDM4HEP_BUILD_VERSION <= EDM4HEP_VERSION(0, 10, 2) - constexpr const char* CellIDEncoding = "CellIDEncoding"; -#elif EDM4HEP_BUILD_VERSION < EDM4HEP_VERSION(0, 99, 0) - #include +#include +#if EDM4HEP_BUILD_VERSION < EDM4HEP_VERSION(0, 99, 0) using edm4hep::CellIDEncoding; #else - #include using edm4hep::labels::CellIDEncoding; #endif /// podio include files @@ -137,13 +135,11 @@ namespace dd4hep { printout(DEBUG, "Geant4OutputEDM4hep", "Saving event parameter: %s", p.first.c_str()); frame.putParameter(p.first, p.second); } -#if PODIO_BUILD_VERSION > PODIO_VERSION(0, 16, 2) // This functionality is only present in podio > 0.16.2 for (auto const& p: this->dblParameters()) { printout(DEBUG, "Geant4OutputEDM4hep", "Saving event parameter: %s", p.first.c_str()); frame.putParameter(p.first, p.second); } -#endif } template <> void RunParameters::extractParameters(podio::Frame& frame) { @@ -159,13 +155,30 @@ namespace dd4hep { printout(DEBUG, "Geant4OutputEDM4hep", "Saving run parameter: %s", p.first.c_str()); frame.putParameter(p.first, p.second); } -#if PODIO_BUILD_VERSION > PODIO_VERSION(0, 16, 2) // This functionality is only present in podio > 0.16.2 for (auto const& p: this->dblParameters()) { printout(DEBUG, "Geant4OutputEDM4hep", "Saving run parameter: %s", p.first.c_str()); frame.putParameter(p.first, p.second); } -#endif + } + template <> void FileParameters::extractParameters(podio::Frame& frame) { + for(auto const& p: this->intParameters()) { + printout(DEBUG, "Geant4OutputEDM4hep", "Saving meta parameter: %s", p.first.c_str()); + frame.putParameter(p.first, p.second); + } + for(auto const& p: this->fltParameters()) { + printout(DEBUG, "Geant4OutputEDM4hep", "Saving meta parameter: %s", p.first.c_str()); + frame.putParameter(p.first, p.second); + } + for(auto const& p: this->strParameters()) { + printout(DEBUG, "Geant4OutputEDM4hep", "Saving meta parameter: %s", p.first.c_str()); + frame.putParameter(p.first, p.second); + } + // This functionality is only present in podio > 0.16.2 + for (auto const& p: this->dblParameters()) { + printout(DEBUG, "Geant4OutputEDM4hep", "Saving meta parameter: %s", p.first.c_str()); + frame.putParameter(p.first, p.second); + } } } // End namespace sim @@ -311,7 +324,7 @@ void Geant4Output2EDM4hep::saveRun(const G4Run* run) { // --- write an edm4hep::RunHeader --------- // Runs are just Frames with different contents in EDM4hep / podio. We simply // store everything as parameters for now - podio::Frame runHeader {}; + podio::Frame runHeader {}; for (const auto& [key, value] : m_runHeader) runHeader.putParameter(key, value); @@ -320,13 +333,21 @@ void Geant4Output2EDM4hep::saveRun(const G4Run* run) { runHeader.putParameter("GEANT4Version", G4Version); runHeader.putParameter("DD4hepVersion", versionString()); runHeader.putParameter("detectorName", context()->detectorDescription().header().name()); - - RunParameters* parameters = context()->run().extension(false); - if ( parameters ) { - parameters->extractParameters(runHeader); + { + RunParameters* parameters = context()->run().extension(false); + if ( parameters ) { + parameters->extractParameters(runHeader); + } + m_file->writeFrame(runHeader, "runs"); + } + { + podio::Frame metaFrame {}; + FileParameters* parameters = context()->run().extension(false); + if ( parameters ) { + parameters->extractParameters(metaFrame); + } + m_file->writeFrame(metaFrame, "meta"); } - - m_file->writeFrame(runHeader, "runs"); } void Geant4Output2EDM4hep::begin(const G4Event* event) { @@ -451,13 +472,10 @@ void Geant4Output2EDM4hep::saveEvent(OutputContext& ctxt) { runNumber = parameters->runNumber() + runNumberOffset; eventNumber = parameters->eventNumber() + eventNumberOffset; parameters->extractParameters(m_frame); -#if PODIO_BUILD_VERSION > PODIO_VERSION(0, 16, 2) - // This functionality is only present in podio > 0.16.2 #if PODIO_BUILD_VERSION > PODIO_VERSION(0, 99, 0) eventWeight = m_frame.getParameter("EventWeights").value_or(0.0); #else eventWeight = m_frame.getParameter("EventWeights"); -#endif #endif } else { // ... or from DD4hep framework runNumber = m_runNo + runNumberOffset; @@ -467,14 +485,26 @@ void Geant4Output2EDM4hep::saveEvent(OutputContext& ctxt) { // this does not compile as create() is we only get a const ref - need to review PODIO EventStore API edm4hep::EventHeaderCollection header_collection; + auto header = header_collection.create(); header.setRunNumber(runNumber); header.setEventNumber(eventNumber); header.setWeight(eventWeight); //not implemented in EDM4hep ? header.setDetectorName(context()->detectorDescription().header().name()); - header.setTimeStamp( std::time(nullptr) ) ; - m_frame.put( std::move(header_collection), "EventHeader"); + header.setTimeStamp(std::time(nullptr)); + + // extract event header, in case we come from edm4hep input + auto* meh = context()->event().extension(false); + if(meh) { + header.setTimeStamp(meh->getTimeStamp()); +#if EDM4HEP_BUILD_VERSION >= EDM4HEP_VERSION(0, 99, 0) + for (auto const& weight: meh->getWeights()) { + header.addToWeights(weight); + } +#endif + } + m_frame.put(std::move(header_collection), "EventHeader"); saveEventParameters(m_eventParametersInt); saveEventParameters(m_eventParametersFloat); saveEventParameters(m_eventParametersString); diff --git a/DDG4/include/DDG4/EventParameters.h b/DDG4/include/DDG4/EventParameters.h index ee1d08649..8b02490b5 100644 --- a/DDG4/include/DDG4/EventParameters.h +++ b/DDG4/include/DDG4/EventParameters.h @@ -12,10 +12,7 @@ #ifndef DDG4_EVENTPARAMETERS_H #define DDG4_EVENTPARAMETERS_H -#include -#include -#include - +#include /// Namespace for the AIDA detector description toolkit namespace dd4hep { @@ -28,21 +25,12 @@ namespace dd4hep { * \version 1.0 * \ingroup DD4HEP_SIMULATION */ - class EventParameters { + class EventParameters : public ExtensionParameters { protected: - int m_runNumber = -1; - int m_eventNumber = -1; - std::map> m_intValues {}; - std::map> m_fltValues {}; - std::map> m_strValues {}; - std::map> m_dblValues {}; + int m_runNumber = -1; + int m_eventNumber = -1; public: - /// Initializing constructor - EventParameters() = default; - /// Default destructor - ~EventParameters() = default; - /// Set the event parameters void setRunNumber(int runNumber); void setEventNumber(int eventNumber); @@ -50,21 +38,10 @@ namespace dd4hep { int runNumber() const { return m_runNumber; } /// Get the event number int eventNumber() const { return m_eventNumber; } - /// Copy the parameters from source template void ingestParameters(T const& source); /// Put parameters into destination template void extractParameters(T& destination); - - /// Get the int event parameters - auto const& intParameters() const { return m_intValues; } - /// Get the float event parameters - auto const& fltParameters() const { return m_fltValues; } - /// Get the string event parameters - auto const& strParameters() const { return m_strValues; } - /// Get the double event parameters - auto const& dblParameters() const { return m_dblValues; } - }; } /* End namespace sim */ diff --git a/DDG4/include/DDG4/ExtensionParameters.h b/DDG4/include/DDG4/ExtensionParameters.h new file mode 100644 index 000000000..cd9108e3c --- /dev/null +++ b/DDG4/include/DDG4/ExtensionParameters.h @@ -0,0 +1,52 @@ +//========================================================================== +// AIDA Detector description implementation +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// +//========================================================================== +#ifndef DDG4_EXTENSIONPARAMETERS_H +#define DDG4_EXTENSIONPARAMETERS_H + +#include +#include +#include + + +/// Namespace for the AIDA detector description toolkit +namespace dd4hep { + + /// Namespace for the Geant4 based simulation part of the AIDA detector description toolkit + namespace sim { + + /// Extension to pass input data to output data + /** + * \version 1.0 + * \ingroup DD4HEP_SIMULATION + */ + class ExtensionParameters { + protected: + std::map> m_intValues {}; + std::map> m_fltValues {}; + std::map> m_strValues {}; + std::map> m_dblValues {}; + + public: + /// Get the int parameters + auto const& intParameters() const { return m_intValues; } + /// Get the float parameters + auto const& fltParameters() const { return m_fltValues; } + /// Get the string parameters + auto const& strParameters() const { return m_strValues; } + /// Get the double parameters + auto const& dblParameters() const { return m_dblValues; } + + }; + + } /* End namespace sim */ +} /* End namespace dd4hep */ +#endif // DDG4_EXTENSIONPARAMETERS_H diff --git a/DDG4/include/DDG4/FileParameters.h b/DDG4/include/DDG4/FileParameters.h new file mode 100644 index 000000000..4cfb12d7d --- /dev/null +++ b/DDG4/include/DDG4/FileParameters.h @@ -0,0 +1,38 @@ +//========================================================================== +// AIDA Detector description implementation +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// +//========================================================================== +#ifndef DDG4_FILEPARAMETERS_H +#define DDG4_FILEPARAMETERS_H + +#include + +/// Namespace for the AIDA detector description toolkit +namespace dd4hep { + + /// Namespace for the Geant4 based simulation part of the AIDA detector description toolkit + namespace sim { + + /// Extension to pass input run data to output run data + /** + * \version 1.0 + * \ingroup DD4HEP_SIMULATION + */ + class FileParameters: public ExtensionParameters { + public: + /// Copy the parameters from source + template void ingestParameters(T const& source); + /// Put parameters into destination + template void extractParameters(T& destination); + }; + + } /* End namespace sim */ +} /* End namespace dd4hep */ +#endif // DDG4_FILEPARAMETERS_H diff --git a/DDG4/include/DDG4/RunParameters.h b/DDG4/include/DDG4/RunParameters.h index 05557f18e..c6d8ea891 100644 --- a/DDG4/include/DDG4/RunParameters.h +++ b/DDG4/include/DDG4/RunParameters.h @@ -12,10 +12,7 @@ #ifndef DDG4_RUNPARAMETERS_H #define DDG4_RUNPARAMETERS_H -#include -#include -#include - +#include /// Namespace for the AIDA detector description toolkit namespace dd4hep { @@ -28,39 +25,19 @@ namespace dd4hep { * \version 1.0 * \ingroup DD4HEP_SIMULATION */ - class RunParameters { + class RunParameters: ExtensionParameters { protected: - std::map> m_intValues {}; - std::map> m_fltValues {}; - std::map> m_strValues {}; - std::map> m_dblValues {}; - int m_runNumber = -1; + int m_runNumber = -1; public: - /// Initializing constructor - RunParameters() = default; - /// Default destructor - ~RunParameters() = default; - /// Set the Run parameters void setRunNumber(int runNumber); /// Get the run number int runNumber() const { return m_runNumber; } - /// Copy the parameters from source template void ingestParameters(T const& source); /// Put parameters into destination template void extractParameters(T& destination); - - /// Get the int Run parameters - auto const& intParameters() const { return m_intValues; } - /// Get the float Run parameters - auto const& fltParameters() const { return m_fltValues; } - /// Get the string Run parameters - auto const& strParameters() const { return m_strValues; } - /// Get the double Run parameters - auto const& dblParameters() const { return m_dblValues; } - }; } /* End namespace sim */ diff --git a/DDG4/lcio/LCIOEventReader.cpp b/DDG4/lcio/LCIOEventReader.cpp index e919ab9d1..4b0bc2b7a 100644 --- a/DDG4/lcio/LCIOEventReader.cpp +++ b/DDG4/lcio/LCIOEventReader.cpp @@ -121,7 +121,10 @@ LCIOEventReader::readParticles(int event_number, int genStatus = mcp->getGeneratorStatus(); // Copy raw generator status p->genStatus = genStatus&G4PARTICLE_GEN_STATUS_MASK; - m_inputAction->setGeneratorStatus(genStatus, status); + if(m_inputAction) { + // in some tests we do not set up the inputAction + m_inputAction->setGeneratorStatus(genStatus, status); + } //fg: we simply add all particles without parents as with their own vertex. // This might include the incoming beam particles, e.g. in diff --git a/DDG4/python/DDSim/DD4hepSimulation.py b/DDG4/python/DDSim/DD4hepSimulation.py index f037833f8..28cd3e421 100644 --- a/DDG4/python/DDSim/DD4hepSimulation.py +++ b/DDG4/python/DDSim/DD4hepSimulation.py @@ -45,11 +45,17 @@ ".hepmc3", ".hepmc3.gz", ".hepmc3.xz", ".hepmc3.bz2", ".hepmc3.tree.root", ] +EDM4HEP_INPUT_EXTENSIONS = [ + ".root", + ".sio", + ] POSSIBLEINPUTFILES = [ ".stdhep", ".slcio", ".HEPEvt", ".hepevt", ".pairs", ".hepmc", - ] + HEPMC3_SUPPORTED_EXTENSIONS + ] +POSSIBLEINPUTFILES += HEPMC3_SUPPORTED_EXTENSIONS +POSSIBLEINPUTFILES += EDM4HEP_INPUT_EXTENSIONS class DD4hepSimulation(object): @@ -445,6 +451,10 @@ def run(self): gen = DDG4.GeneratorAction(kernel, "Geant4InputAction/GuineaPig%d" % index) gen.Input = "Geant4EventReaderGuineaPig|" + inputFile gen.Parameters = self.guineapig.getParameters() + elif inputFile.endswith(tuple(EDM4HEP_INPUT_EXTENSIONS)): + # EDM4HEP must come after HEPMC3 because of .root also part of hepmc3 extensions + gen = DDG4.GeneratorAction(kernel, "Geant4InputAction/EDM4hep%d" % index) + gen.Input = "EDM4hepFileReader|" + inputFile else: # this should never happen because we already check at the top, but in case of some LogicError... raise RuntimeError("Unknown input file type: %s" % inputFile) diff --git a/DDTest/CMakeLists.txt b/DDTest/CMakeLists.txt index de36d1fd5..182852e89 100644 --- a/DDTest/CMakeLists.txt +++ b/DDTest/CMakeLists.txt @@ -109,6 +109,9 @@ if (DD4HEP_USE_GEANT4) if(DD4HEP_USE_HEPMC3) target_compile_definitions(${TEST_NAME} PRIVATE DD4HEP_USE_HEPMC3) endif() + if(DD4HEP_USE_EDM4HEP) + target_compile_definitions(${TEST_NAME} PRIVATE DD4HEP_USE_EDM4HEP) + endif() if(DD4HEP_USE_LCIO) target_compile_definitions(${TEST_NAME} PRIVATE DD4HEP_USE_LCIO) endif() @@ -161,6 +164,15 @@ if (DD4HEP_USE_GEANT4) PASS_REGULAR_EXPRESSION "Deleting object StepActionCLI1" ) + if(DD4HEP_USE_EDM4HEP AND TARGET podio::podioIO) + add_test( t_ddsimEDM4hepPlugins "${CMAKE_INSTALL_PREFIX}/bin/run_test.sh" + ddsim --compactFile=${CMAKE_INSTALL_PREFIX}/DDDetectors/compact/SiD.xml --runType=batch -N=3 + --outputFile=ddsim_edm4hep_ZH.root + --inputFiles=${CMAKE_CURRENT_SOURCE_DIR}/inputFiles/ZH250_ISR.edm4hep.root + --part.userParticleHandler= + ) + endif() + endif() install(DIRECTORY include/DD4hep DESTINATION include) diff --git a/DDTest/inputFiles/ZH250_ISR.edm4hep.root b/DDTest/inputFiles/ZH250_ISR.edm4hep.root new file mode 100644 index 000000000..2b6b92e4e Binary files /dev/null and b/DDTest/inputFiles/ZH250_ISR.edm4hep.root differ diff --git a/DDTest/src/test_EventReaders.cc b/DDTest/src/test_EventReaders.cc index d48985884..2384402ed 100644 --- a/DDTest/src/test_EventReaders.cc +++ b/DDTest/src/test_EventReaders.cc @@ -46,6 +46,9 @@ int main(int argc, char** argv ){ tests.push_back( TestTuple( "HEPMC3FileReader", "g4pythia.hepmc", /*skipEOF= */ true) ); tests.push_back( TestTuple( "HEPMC3FileReader", "Pythia_output.hepmc", /*skipEOF= */ true) ); #endif + #ifdef DD4HEP_USE_EDM4HEP + tests.push_back( TestTuple( "EDM4hepFileReader", "ZH250_ISR.edm4hep.root", /*skipEOF= */ true) ); + #endif try{ for(std::vector::const_iterator it = tests.begin(); it != tests.end(); ++it) { @@ -61,29 +64,27 @@ int main(int argc, char** argv ){ continue; } test( thisReader->currentEventNumber() == 0 , readerType + std::string("Initial Event Number") ); - thisReader->moveToEvent(1); - test( thisReader->currentEventNumber() == 1 , readerType + std::string("Event Number after Skip") ); + if (!thisReader->hasDirectAccess()) { + thisReader->moveToEvent(1); + test( thisReader->currentEventNumber() == 1 , readerType + std::string("Event Number after Skip") ); + } std::vector particles; std::vector vertices ; - - dd4hep::sim::Geant4EventReader::EventReaderStatus sc = thisReader->readParticles(3,vertices,particles); + dd4hep::sim::Geant4EventReader::EventReaderStatus sc = thisReader->readParticles(2,vertices,particles); std::for_each(particles.begin(),particles.end(),dd4hep::detail::deleteObject); test( thisReader->currentEventNumber() == 2 && sc == dd4hep::sim::Geant4EventReader::EVENT_READER_OK, readerType + std::string("Event Number Read") ); - //Reset Reader to check what happens if moving to far in the file + //Reset Reader to check what happens if moving too far in the file if (not skipEOF) { thisReader = dd4hep::PluginService::Create(readerType, std::move(inputFile)); sc = thisReader->moveToEvent(1000000); test( sc != dd4hep::sim::Geant4EventReader::EVENT_READER_OK , readerType + std::string("EventReader False") ); } } - } catch( std::exception &e ){ - //} catch( ... ){ - - test.log( e.what() ); - test.error( "exception occurred" ); + test.error("Exception occurred:"); + test.log(e.what()); } return 0; }