From 9f29bd461a3e7ea76249d117d0da5ccecdae9c58 Mon Sep 17 00:00:00 2001
From: Andre Sailer <andre.philippe.sailer@cern.ch>
Date: Tue, 18 Jul 2023 18:48:01 +0200
Subject: [PATCH] DDG4: add propagating of run parameters from input files to
 output files

---
 DDG4/hepmc/HepMC3FileReader.cpp       | 29 +++++++++++++++++++++++++++
 DDG4/include/DDG4/Geant4InputAction.h |  3 +++
 DDG4/src/Geant4InputAction.cpp        |  1 +
 3 files changed, 33 insertions(+)

diff --git a/DDG4/hepmc/HepMC3FileReader.cpp b/DDG4/hepmc/HepMC3FileReader.cpp
index 72d644541..5bbbf6e67 100644
--- a/DDG4/hepmc/HepMC3FileReader.cpp
+++ b/DDG4/hepmc/HepMC3FileReader.cpp
@@ -27,6 +27,7 @@
 #include "HepMC3EventReader.h"
 
 #include "DDG4/EventParameters.h"
+#include "DDG4/RunParameters.h"
 
 #include <HepMC3/ReaderFactory.h>
 
@@ -68,6 +69,22 @@ namespace dd4hep  {
       }
     }
 
+    template <class T=HepMC3::GenRunInfo> void RunParameters::ingestParameters(T const& runInfo) {
+      // This attributes is not the same return type as for GenEvent!
+      for(auto const& attr: runInfo.attributes()){
+        std::stringstream strstr;
+        if(auto int_attr = std::dynamic_pointer_cast<HepMC3::IntAttribute>(attr.second)) {
+          m_intValues[attr.first] = {int_attr->value()};
+        } else if(auto flt_attr = std::dynamic_pointer_cast<HepMC3::FloatAttribute>(attr.second)) {
+          m_fltValues[attr.first] = {flt_attr->value()};
+        } else if(auto dbl_attr = std::dynamic_pointer_cast<HepMC3::DoubleAttribute>(attr.second)) {
+          m_dblValues[attr.first] = {dbl_attr->value()};
+        } else { // anything else
+          m_strValues[attr.first] = {attr.second->unparsed_string()};
+        }
+      }
+    }
+
     /// Base class to read hepmc3 event files
     /**
      *  \version 1.0
@@ -89,6 +106,9 @@ namespace dd4hep  {
       virtual EventReaderStatus moveToEvent(int event_number);
       //virtual EventReaderStatus skipEvent() { return EVENT_READER_OK; }
       virtual EventReaderStatus setParameters(std::map< std::string, std::string >& parameters);
+      /// register the run parameters into an extension for the run context
+      virtual void registerRunParameters();
+
     };
   }
 }
@@ -111,6 +131,15 @@ HEPMC3FileReader::HEPMC3FileReader(const std::string& nam)
   m_directAccess = false;
 }
 
+void HEPMC3FileReader::registerRunParameters() {
+  try {
+    auto *parameters = new RunParameters();
+    parameters->ingestParameters(*(m_reader->run_info()));
+    context()->run().addExtension<RunParameters>(parameters);
+  } catch(std::exception &) {
+  }
+}
+
 /// moveToSpecifiedEvent, a.k.a. skipNEvents
 Geant4EventReader::EventReaderStatus
 HEPMC3FileReader::moveToEvent(int event_number) {
diff --git a/DDG4/include/DDG4/Geant4InputAction.h b/DDG4/include/DDG4/Geant4InputAction.h
index e6b07a045..16de07720 100644
--- a/DDG4/include/DDG4/Geant4InputAction.h
+++ b/DDG4/include/DDG4/Geant4InputAction.h
@@ -137,6 +137,9 @@ namespace dd4hep  {
 
       /// make sure that all parameters have been processed, otherwise throw exceptions
       virtual void checkParameters( std::map< std::string, std::string >& );
+
+      /// Register Run Parameters
+      virtual void registerRunParameters() {}
     };
 
     /// Generic input action capable of using the Geant4EventReader class.
diff --git a/DDG4/src/Geant4InputAction.cpp b/DDG4/src/Geant4InputAction.cpp
index 999962518..aab1eafb3 100644
--- a/DDG4/src/Geant4InputAction.cpp
+++ b/DDG4/src/Geant4InputAction.cpp
@@ -165,6 +165,7 @@ int Geant4InputAction::readParticles(int evt_number,
       m_reader->setParameters( m_parameters );
       m_reader->checkParameters( m_parameters );
       m_reader->setInputAction( this );
+      m_reader->registerRunParameters();
     }
     catch(const exception& e)  {
       err = e.what();
-- 
GitLab