Warning, /eic-spack/packages/dd4hep/revert-Geant4Output2EDM4hep-dd4hep-1-25-1-to-1-23.patch is written in an unsupported language. File is not indexed.
0001 diff --git a/DDG4/edm4hep/Geant4Output2EDM4hep.cpp b/DDG4/edm4hep/Geant4Output2EDM4hep.cpp
0002 --- a/DDG4/edm4hep/Geant4Output2EDM4hep.cpp
0003 +++ b/DDG4/edm4hep/Geant4Output2EDM4hep.cpp
0004 @@ -10,19 +10,40 @@
0005 // Author : F.Gaede, DESY
0006 //
0007 //==========================================================================
0008 +
0009 #ifndef DD4HEP_DDG4_GEANT4OUTPUT2EDM4hep_H
0010 #define DD4HEP_DDG4_GEANT4OUTPUT2EDM4hep_H
0011
0012 -/// Framework include files
0013 -#include <DD4hep/Detector.h>
0014 -#include <DDG4/EventParameters.h>
0015 -#include <DDG4/Geant4OutputAction.h>
0016 -
0017 -/// edm4hep include files
0018 -#include <edm4hep/MCParticleCollection.h>
0019 -/// podio include files
0020 -#include <podio/Frame.h>
0021 -#include <podio/ROOTFrameWriter.h>
0022 +// Framework include files
0023 +#include "DD4hep/Detector.h"
0024 +#include "DD4hep/VolumeManager.h"
0025 +#include "DDG4/Geant4HitCollection.h"
0026 +#include "DDG4/Geant4OutputAction.h"
0027 +#include "DDG4/Geant4SensDetAction.h"
0028 +#include "DDG4/Geant4DataConversion.h"
0029 +#include "DDG4/EventParameters.h"
0030 +
0031 +// Geant4 headers
0032 +#include "G4Threading.hh"
0033 +#include "G4AutoLock.hh"
0034 +#include "G4Version.hh"
0035 +
0036 +// use the Geant4 units in namespace CLHEP
0037 +#include "CLHEP/Units/SystemOfUnits.h"
0038 +
0039 +// edm4hep include files
0040 +#include "edm4hep/EventHeaderCollection.h"
0041 +#include "edm4hep/MCParticleCollection.h"
0042 +#include "edm4hep/SimTrackerHitCollection.h"
0043 +#include "edm4hep/CaloHitContributionCollection.h"
0044 +#include "edm4hep/SimCalorimeterHitCollection.h"
0045 +#include "podio/EventStore.h"
0046 +#include "podio/ROOTWriter.h"
0047 +
0048 +#include <typeinfo>
0049 +#include <iostream>
0050 +#include <ctime>
0051 +#include <unordered_map>
0052 #include <podio/podioVersion.h>
0053
0054 /// Namespace for the AIDA detector description toolkit
0055 @@ -33,6 +54,20 @@ namespace dd4hep {
0056 /// Namespace for the Geant4 based simulation part of the AIDA detector description toolkit
0057 namespace sim {
0058
0059 + template <class T=podio::EventStore> void EventParameters::extractParameters(T& event){
0060 + auto& lcparameters = event.getEventMetaData();
0061 +
0062 + for(auto const& ival: this->intParameters()) {
0063 + lcparameters.setValue(ival.first, ival.second);
0064 + }
0065 + for(auto const& ival: this->fltParameters()) {
0066 + lcparameters.setValue(ival.first, ival.second);
0067 + }
0068 + for(auto const& ival: this->strParameters()) {
0069 + lcparameters.setValue(ival.first, ival.second);
0070 + }
0071 + }
0072 +
0073 class Geant4ParticleMap;
0074
0075 /// Base class to output Geant4 event data to EDM4hep
0076 @@ -43,22 +78,19 @@ namespace dd4hep {
0077 */
0078 class Geant4Output2EDM4hep : public Geant4OutputAction {
0079 protected:
0080 - using writer_t = podio::ROOTFrameWriter;
0081 - using stringmap_t = std::map< std::string, std::string >;
0082 - std::unique_ptr<writer_t> m_file { };
0083 - podio::Frame m_frame { };
0084 - edm4hep::MCParticleCollection m_particles { };
0085 - stringmap_t m_runHeader;
0086 - stringmap_t m_eventParametersInt;
0087 - stringmap_t m_eventParametersFloat;
0088 - stringmap_t m_eventParametersString;
0089 - std::string m_section_name { "events" };
0090 - int m_runNo { 0 };
0091 - int m_runNumberOffset { 0 };
0092 - int m_eventNo { 0 };
0093 - int m_eventNumberOffset { 0 };
0094 - bool m_filesByRun { false };
0095 -
0096 + podio::EventStore* m_store;
0097 + podio::ROOTWriter* m_file;
0098 + int m_runNo;
0099 + int m_runNumberOffset;
0100 + int m_eventNumberOffset;
0101 + std::map< std::string, std::string > m_runHeader;
0102 + std::map< std::string, std::string > m_eventParametersInt;
0103 + std::map< std::string, std::string > m_eventParametersFloat;
0104 + std::map< std::string, std::string > m_eventParametersString;
0105 + bool m_FirstEvent = true ;
0106 +
0107 + std::unordered_map<std::string, podio::CollectionBase*> m_collections;
0108 +
0109 /// create the podio collections for the particles and hits
0110 void createCollections(OutputContext<G4Event>& ctxt) ;
0111 /// Data conversion interface for MC particles to EDM4hep format
0112 @@ -87,35 +119,33 @@ namespace dd4hep {
0113 protected:
0114 /// Fill event parameters in EDM4hep event
0115 template <typename T>
0116 - void saveEventParameters(const std::map<std::string, std::string >& parameters) {
0117 - for(const auto& p : parameters) {
0118 - info("Saving event parameter: %-32s = %s", p.first.c_str(), p.second.c_str());
0119 - m_frame.putParameter(p.first, p.second);
0120 - }
0121 - }
0122 + void saveEventParameters(const std::map<std::string, std::string >& parameters);
0123 };
0124
0125 - template <> void EventParameters::extractParameters(podio::Frame& frame) {
0126 - for(auto const& p: this->intParameters()) {
0127 - printout(DEBUG, "Geant4OutputEDM4hep", "Saving event parameter: %s", p.first.c_str());
0128 - frame.putParameter(p.first, p.second);
0129 - }
0130 - for(auto const& p: this->fltParameters()) {
0131 - printout(DEBUG, "Geant4OutputEDM4hep", "Saving event parameter: %s", p.first.c_str());
0132 - frame.putParameter(p.first, p.second);
0133 - }
0134 - for(auto const& p: this->strParameters()) {
0135 - printout(DEBUG, "Geant4OutputEDM4hep", "Saving event parameter: %s", p.first.c_str());
0136 - frame.putParameter(p.first, p.second);
0137 + /// Fill event parameters in EDM4hep event
0138 + template <typename T>
0139 + inline void Geant4Output2EDM4hep::saveEventParameters(const std::map<std::string, std::string >& parameters) {
0140 + for(std::map<std::string, std::string >::const_iterator iter = parameters.begin(), endIter = parameters.end() ; iter != endIter ; ++iter) {
0141 + T parameter;
0142 + std::istringstream iss(iter->second);
0143 + if ( (iss >> parameter).fail() ) {
0144 + printout(FATAL,"saveEventParameters","+++ Event parameter %s: FAILED to convert to type :%s",iter->first.c_str(),typeid(T).name());
0145 + continue;
0146 + }
0147 + auto& evtMD = m_store->getEventMetaData();
0148 + evtMD.setValue(iter->first,parameter);
0149 }
0150 -#if podio_VERSION_MAJOR > 0 || podio_VERSION_MINOR > 16 || podio_VERSION_PATCH > 2
0151 - // This functionality is only present in podio > 0.16.2
0152 - for (auto const& p: this->dblParameters()) {
0153 - printout(DEBUG, "Geant4OutputEDM4hep", "Saving event parameter: %s", p.first.c_str());
0154 - frame.putParameter(p.first, p.second);
0155 + }
0156 +
0157 + /// Fill event parameters in EDM4hep event - std::string specialization
0158 + template <>
0159 + inline void Geant4Output2EDM4hep::saveEventParameters<std::string>(const std::map<std::string, std::string >& parameters) {
0160 + for(std::map<std::string, std::string >::const_iterator iter = parameters.begin(), endIter = parameters.end() ; iter != endIter ; ++iter) {
0161 + auto& evtMD = m_store->getEventMetaData();
0162 + evtMD.setValue(iter->first,iter->second);
0163 }
0164 -#endif
0165 }
0166 +
0167 } // End namespace sim
0168 } // End namespace dd4hep
0169 #endif // DD4HEP_DDG4_GEANT4OUTPUT2EDM4hep_H
0170 @@ -133,38 +163,26 @@ namespace dd4hep {
0171 //
0172 //==========================================================================
0173
0174 -/// Framework include files
0175 -#include <DD4hep/InstanceCount.h>
0176 -#include <DD4hep/VolumeManager.h>
0177 -
0178 -#include <DDG4/Geant4HitCollection.h>
0179 -#include <DDG4/Geant4DataConversion.h>
0180 -#include <DDG4/Geant4SensDetAction.h>
0181 -#include <DDG4/Geant4Context.h>
0182 -#include <DDG4/Geant4Particle.h>
0183 -#include <DDG4/Geant4Data.h>
0184 -
0185 -///#include <DDG4/Geant4Output2EDM4hep.h>
0186 -/// Geant4 headers
0187 -#include <G4Threading.hh>
0188 -#include <G4AutoLock.hh>
0189 -#include <G4Version.hh>
0190 -#include <G4ParticleDefinition.hh>
0191 -#include <G4VProcess.hh>
0192 -#include <G4Event.hh>
0193 -#include <G4Run.hh>
0194 -/// use the Geant4 units in namespace CLHEP
0195 -#include <CLHEP/Units/SystemOfUnits.h>
0196 -
0197 -/// edm4hep include files
0198 -#include <edm4hep/EventHeaderCollection.h>
0199 -#include <edm4hep/SimTrackerHitCollection.h>
0200 -#include <edm4hep/CaloHitContributionCollection.h>
0201 -#include <edm4hep/SimCalorimeterHitCollection.h>
0202 +// Framework include files
0203 +#include "DD4hep/InstanceCount.h"
0204 +#include "DD4hep/Detector.h"
0205 +#include "DDG4/Geant4HitCollection.h"
0206 +#include "DDG4/Geant4DataConversion.h"
0207 +#include "DDG4/Geant4Context.h"
0208 +#include "DDG4/Geant4Particle.h"
0209 +#include "DDG4/Geant4Data.h"
0210 +#include "DDG4/Geant4Action.h"
0211 +
0212 +//#include "DDG4/Geant4Output2EDM4hep.h"
0213 +#include "G4ParticleDefinition.hh"
0214 +#include "G4VProcess.hh"
0215 +#include "G4Event.hh"
0216 +#include "G4Run.hh"
0217 +
0218
0219 using namespace dd4hep::sim;
0220 using namespace dd4hep;
0221 -
0222 +using namespace std;
0223 namespace {
0224 G4Mutex action_mutex=G4MUTEX_INITIALIZER;
0225 }
0226 @@ -173,65 +191,55 @@ namespace {
0227 DECLARE_GEANT4ACTION(Geant4Output2EDM4hep)
0228
0229 /// Standard constructor
0230 -Geant4Output2EDM4hep::Geant4Output2EDM4hep(Geant4Context* ctxt, const std::string& nam)
0231 -: Geant4OutputAction(ctxt,nam), m_runNo(0), m_runNumberOffset(0), m_eventNumberOffset(0)
0232 +Geant4Output2EDM4hep::Geant4Output2EDM4hep(Geant4Context* ctxt, const string& nam)
0233 +: Geant4OutputAction(ctxt,nam), m_store(0), m_file(0), m_runNo(0), m_runNumberOffset(0), m_eventNumberOffset(0)
0234 {
0235 declareProperty("RunHeader", m_runHeader);
0236 declareProperty("EventParametersInt", m_eventParametersInt);
0237 declareProperty("EventParametersFloat", m_eventParametersFloat);
0238 declareProperty("EventParametersString", m_eventParametersString);
0239 - declareProperty("RunNumberOffset", m_runNumberOffset);
0240 - declareProperty("EventNumberOffset", m_eventNumberOffset);
0241 - declareProperty("SectionName", m_section_name);
0242 - declareProperty("FilesByRun", m_filesByRun);
0243 - info("Writer is now instantiated ..." );
0244 + declareProperty("RunNumberOffset", m_runNumberOffset);
0245 + declareProperty("EventNumberOffset", m_eventNumberOffset);
0246 + printout( INFO, "Geant4Output2EDM4hep" ," instantiated ..." ) ;
0247 InstanceCount::increment(this);
0248 }
0249
0250 /// Default destructor
0251 Geant4Output2EDM4hep::~Geant4Output2EDM4hep() {
0252 G4AutoLock protection_lock(&action_mutex);
0253 - m_file.reset();
0254 + if ( m_file ) {
0255 + m_file->finish();
0256 + detail::deletePtr(m_file);
0257 + }
0258 + if (nullptr != m_store) {
0259 + delete m_store;
0260 + }
0261 InstanceCount::decrement(this);
0262 }
0263
0264 // Callback to store the Geant4 run information
0265 void Geant4Output2EDM4hep::beginRun(const G4Run* run) {
0266 G4AutoLock protection_lock(&action_mutex);
0267 - std::string fname = m_output;
0268 - m_runNo = run->GetRunID();
0269 - if ( m_filesByRun ) {
0270 - std::size_t idx = m_output.rfind(".");
0271 - if ( idx != std::string::npos ) {
0272 - fname = m_output.substr(0, idx) + _toString(m_runNo, ".run%08d") + m_output.substr(idx);
0273 - }
0274 - }
0275 - if ( !m_file && !fname.empty() ) {
0276 - m_file = std::make_unique<podio::ROOTFrameWriter>(fname);
0277 - if ( !m_file ) {
0278 - fatal("+++ Failed to open output file: %s", fname.c_str());
0279 - }
0280 - printout( INFO, "Geant4Output2EDM4hep" ,"Opened %s for output", fname.c_str() ) ;
0281 + if ( 0 == m_file && !m_output.empty() ) {
0282 + m_store = new podio::EventStore ;
0283 + m_file = new podio::ROOTWriter(m_output, m_store);
0284 +
0285 + printout( INFO, "Geant4Output2EDM4hep" ," opened %s for output", m_output.c_str() ) ;
0286 }
0287 +
0288 + saveRun(run);
0289 }
0290
0291 /// Callback to store the Geant4 run information
0292 -void Geant4Output2EDM4hep::endRun(const G4Run* run) {
0293 - saveRun(run);
0294 - if ( m_file ) {
0295 - m_file->finish();
0296 - m_file.reset();
0297 - }
0298 +void Geant4Output2EDM4hep::endRun(const G4Run* /*run*/) {
0299 }
0300
0301 /// Commit data at end of filling procedure
0302 void Geant4Output2EDM4hep::commit( OutputContext<G4Event>& /* ctxt */) {
0303 if ( m_file ) {
0304 G4AutoLock protection_lock(&action_mutex);
0305 - m_frame.put( std::move(m_particles), "MCParticles");
0306 - m_file->writeFrame(m_frame, m_section_name);
0307 - m_particles.clear();
0308 - m_frame = {};
0309 + m_file->writeEvent();
0310 + m_store->clearCollections();
0311 return;
0312 }
0313 except("+++ Failed to write output file. [Stream is not open]");
0314 @@ -239,31 +247,12 @@ void Geant4Output2EDM4hep::commit( OutputContext<G4Event>& /* ctxt */) {
0315
0316 /// Callback to store the Geant4 run information
0317 void Geant4Output2EDM4hep::saveRun(const G4Run* run) {
0318 - G4AutoLock protection_lock(&action_mutex);
0319 - // --- write an edm4hep::RunHeader ---------
0320 - // Runs are just Frames with different contents in EDM4hep / podio. We simply
0321 - // store everything as parameters for now
0322 - auto runHeader = podio::Frame();
0323 -
0324 - for (const auto& [key, value] : m_runHeader) {
0325 - runHeader.putParameter(key, value);
0326 - }
0327 + //G4AutoLock protection_lock(&action_mutex);
0328
0329 - m_runNo = m_runNumberOffset > 0 ? m_runNumberOffset + run->GetRunID() : run->GetRunID();
0330 - runHeader.putParameter("runNumber", m_runNo);
0331 - runHeader.putParameter("GEANT4Version", G4Version);
0332 - runHeader.putParameter("DD4hepVersion", versionString());
0333 - runHeader.putParameter("detectorName", context()->detectorDescription().header().name());
0334 -
0335 - m_file->writeFrame(runHeader, "runs");
0336 + warning("saveRun: RunHeader not implemented in EDM4hep, nothing written for run: %d", run->GetRunID());
0337 }
0338
0339 -void Geant4Output2EDM4hep::begin(const G4Event* event) {
0340 - /// Create event frame object
0341 - m_eventNo = event->GetEventID();
0342 - m_particles.clear();
0343 - m_particles = {};
0344 - m_frame = {};
0345 +void Geant4Output2EDM4hep::begin(const G4Event* /* event */) {
0346 }
0347
0348 /// Data conversion interface for MC particles to EDM4hep format
0349 @@ -271,13 +260,13 @@ void Geant4Output2EDM4hep::saveParticles(Geant4ParticleMap* particles) {
0350 typedef detail::ReferenceBitMask<const int> PropertyMask;
0351 typedef Geant4ParticleMap::ParticleMap ParticleMap;
0352 const ParticleMap& pm = particles->particleMap;
0353 + auto mcpc = static_cast<edm4hep::MCParticleCollection*>(m_collections["MCParticles"]);
0354
0355 - m_particles.clear();
0356 if ( pm.size() > 0 ) {
0357 size_t cnt = 0;
0358 // Mapping of ids in the ParticleMap to indices in the MCParticle collection
0359 - std::map<int,int> p_ids;
0360 - std::vector<const Geant4Particle*> p_part;
0361 + map<int,int> p_ids;
0362 + vector<const Geant4Particle*> p_part;
0363 p_part.reserve(pm.size());
0364 // First create the particles
0365 for (const auto& iParticle : pm) {
0366 @@ -286,7 +275,7 @@ void Geant4Output2EDM4hep::saveParticles(Geant4ParticleMap* particles) {
0367 PropertyMask mask(p->status);
0368 // std::cout << " ********** mcp status : 0x" << std::hex << p->status << ", mask.isSet(G4PARTICLE_GEN_STABLE) x" << std::dec << mask.isSet(G4PARTICLE_GEN_STABLE) <<std::endl ;
0369 const G4ParticleDefinition* def = p.definition();
0370 - auto mcp = m_particles.create();
0371 + auto mcp = mcpc->create();
0372 mcp.setPDG(p->pdgID);
0373
0374 float ps_fa[3] = {float(p->psx/CLHEP::GeV),float(p->psy/CLHEP::GeV),float(p->psz/CLHEP::GeV)};
0375 @@ -308,13 +297,13 @@ void Geant4Output2EDM4hep::saveParticles(Geant4ParticleMap* particles) {
0376 // Set generator status
0377 mcp.setGeneratorStatus(0);
0378 if( p->genStatus ) {
0379 - mcp.setGeneratorStatus( p->genStatus ) ;
0380 + mcp.setGeneratorStatus( p->genStatus ) ;
0381 } else {
0382 - if ( mask.isSet(G4PARTICLE_GEN_STABLE) ) mcp.setGeneratorStatus(1);
0383 - else if ( mask.isSet(G4PARTICLE_GEN_DECAYED) ) mcp.setGeneratorStatus(2);
0384 - else if ( mask.isSet(G4PARTICLE_GEN_DOCUMENTATION) ) mcp.setGeneratorStatus(3);
0385 - else if ( mask.isSet(G4PARTICLE_GEN_BEAM) ) mcp.setGeneratorStatus(4);
0386 - else if ( mask.isSet(G4PARTICLE_GEN_OTHER) ) mcp.setGeneratorStatus(9);
0387 + if ( mask.isSet(G4PARTICLE_GEN_STABLE) ) mcp.setGeneratorStatus(1);
0388 + else if ( mask.isSet(G4PARTICLE_GEN_DECAYED) ) mcp.setGeneratorStatus(2);
0389 + else if ( mask.isSet(G4PARTICLE_GEN_DOCUMENTATION) ) mcp.setGeneratorStatus(3);
0390 + else if ( mask.isSet(G4PARTICLE_GEN_BEAM) ) mcp.setGeneratorStatus(4);
0391 + else if ( mask.isSet(G4PARTICLE_GEN_OTHER) ) mcp.setGeneratorStatus(9);
0392 }
0393
0394 // Set simulation status
0395 @@ -329,7 +318,7 @@ void Geant4Output2EDM4hep::saveParticles(Geant4ParticleMap* particles) {
0396
0397 //fg: if simstatus !=0 we have to set the generator status to 0:
0398 if( mcp.isCreatedInSimulation() )
0399 - mcp.setGeneratorStatus( 0 ) ;
0400 + mcp.setGeneratorStatus( 0 ) ;
0401
0402 mcp.setSpin(p->spin);
0403 mcp.setColorFlow(p->colorFlow);
0404 @@ -341,30 +330,30 @@ void Geant4Output2EDM4hep::saveParticles(Geant4ParticleMap* particles) {
0405 // Now establish parent-daughter relationships
0406 for(size_t i=0; i < p_ids.size(); ++i) {
0407 const Geant4Particle* p = p_part[i];
0408 - auto q = m_particles[i];
0409 + auto q = (*mcpc)[i];
0410
0411 for (const auto& idau : p->daughters) {
0412 - const auto k = p_ids.find(idau);
0413 - if (k == p_ids.end()) {
0414 - fatal("+++ Particle %d: FAILED to find daughter with ID:%d",p->id,idau);
0415 - continue;
0416 - }
0417 - int iqdau = (*k).second;
0418 - auto qdau = m_particles[iqdau];
0419 - q.addToDaughters(qdau);
0420 + const auto k = p_ids.find(idau);
0421 + if (k == p_ids.end()) {
0422 + printout(FATAL,"Geant4Conversion","+++ Particle %d: FAILED to find daughter with ID:%d",p->id,idau);
0423 + continue;
0424 + }
0425 + int iqdau = (*k).second;
0426 + auto qdau = (*mcpc)[iqdau];
0427 + q.addToDaughters(qdau);
0428 }
0429
0430 for (const auto& ipar : p->parents) {
0431 - if (ipar >= 0) { // A parent ID of -1 means NO parent, because a base of 0 is perfectly legal
0432 - const auto k = p_ids.find(ipar);
0433 - if (k == p_ids.end()) {
0434 - fatal("+++ Particle %d: FAILED to find parent with ID:%d",p->id,ipar);
0435 - continue;
0436 - }
0437 - int iqpar = (*k).second;
0438 - auto qpar = m_particles[iqpar];
0439 - q.addToParents(qpar);
0440 - }
0441 + if (ipar >= 0) { // A parent ID of -1 means NO parent, because a base of 0 is perfectly legal
0442 + const auto k = p_ids.find(ipar);
0443 + if (k == p_ids.end()) {
0444 + printout(FATAL,"Geant4Conversion","+++ Particle %d: FAILED to find parent with ID:%d",p->id,ipar);
0445 + continue;
0446 + }
0447 + int iqpar = (*k).second;
0448 + auto qpar = (*mcpc)[iqpar];
0449 + q.addToParents(qpar);
0450 + }
0451 }
0452 }
0453 }
0454 @@ -372,6 +361,12 @@ void Geant4Output2EDM4hep::saveParticles(Geant4ParticleMap* particles) {
0455
0456 /// Callback to store the Geant4 event
0457 void Geant4Output2EDM4hep::saveEvent(OutputContext<G4Event>& ctxt) {
0458 +
0459 + if( m_FirstEvent ){
0460 + createCollections( ctxt ) ;
0461 + m_FirstEvent = false ;
0462 + }
0463 +
0464 EventParameters* parameters = context()->event().extension<EventParameters>(false);
0465 int runNumber(0), eventNumber(0);
0466 const int eventNumberOffset(m_eventNumberOffset > 0 ? m_eventNumberOffset : 0);
0467 @@ -381,11 +376,7 @@ void Geant4Output2EDM4hep::saveEvent(OutputContext<G4Event>& ctxt) {
0468 if ( parameters ) {
0469 runNumber = parameters->runNumber() + runNumberOffset;
0470 eventNumber = parameters->eventNumber() + eventNumberOffset;
0471 - parameters->extractParameters(m_frame);
0472 -#if podio_VERSION_MAJOR > 0 || podio_VERSION_MINOR > 16 || podio_VERSION_PATCH > 2
0473 - // This functionality is only present in podio > 0.16.2
0474 - eventWeight = m_frame.getParameter<double>("EventWeights");
0475 -#endif
0476 + parameters->extractParameters(*m_store);
0477 } else { // ... or from DD4hep framework
0478 runNumber = m_runNo + runNumberOffset;
0479 eventNumber = ctxt.context->GetEventID() + eventNumberOffset;
0480 @@ -393,14 +384,15 @@ void Geant4Output2EDM4hep::saveEvent(OutputContext<G4Event>& ctxt) {
0481 printout(INFO,"Geant4Output2EDM4hep","+++ Saving EDM4hep event %d run %d.", eventNumber, runNumber);
0482
0483 // this does not compile as create() is we only get a const ref - need to review PODIO EventStore API
0484 - edm4hep::EventHeaderCollection header_collection;
0485 - auto header = header_collection.create();
0486 - header.setRunNumber(runNumber);
0487 - header.setEventNumber(eventNumber);
0488 - header.setWeight(eventWeight);
0489 - //not implemented in EDM4hep ? header.setDetectorName(context()->detectorDescription().header().name());
0490 - header.setTimeStamp( std::time(nullptr) ) ;
0491 - m_frame.put( std::move(header_collection), "EventHeader");
0492 + // auto& evtHCol = m_store->get<edm4hep::EventHeaderCollection>("EventHeader") ;
0493 +// auto evtHdr = evtHCol.create() ;
0494 + auto* evtHCol = static_cast<edm4hep::EventHeaderCollection*>(m_collections["EventHeader"]);
0495 + auto evtHdr = evtHCol->create() ;
0496 +
0497 + evtHdr.setRunNumber(runNumber);
0498 + evtHdr.setEventNumber(eventNumber);
0499 +//not implemented in EDM4hep ? evtHdr.setDetectorName(context()->detectorDescription().header().name());
0500 + evtHdr.setTimeStamp( std::time(nullptr) ) ;
0501
0502 saveEventParameters<int>(m_eventParametersInt);
0503 saveEventParameters<float>(m_eventParametersFloat);
0504 @@ -417,34 +409,49 @@ void Geant4Output2EDM4hep::saveEvent(OutputContext<G4Event>& ctxt) {
0505
0506 /// Callback to store each Geant4 hit collection
0507 void Geant4Output2EDM4hep::saveCollection(OutputContext<G4Event>& /*ctxt*/, G4VHitsCollection* collection) {
0508 - Geant4HitCollection* coll = dynamic_cast<Geant4HitCollection*>(collection);
0509 +
0510 + size_t nhits = collection->GetSize();
0511 std::string colName = collection->GetName();
0512 +
0513 + printout(DEBUG,"Geant4Output2EDM4hep","+++ Saving EDM4hep collection %s with %d entries.",
0514 + colName.c_str(),int(nhits));
0515 +
0516 + Geant4HitCollection* coll = dynamic_cast<Geant4HitCollection*>(collection);
0517 if( coll == nullptr ){
0518 - error(" no Geant4HitCollection: %s ", colName.c_str());
0519 + printout(ERROR, "Geant4Output2EDM4hep" , " no Geant4HitCollection: %s ", colName.c_str() );
0520 return ;
0521 }
0522 - size_t nhits = collection->GetSize();
0523 +
0524 Geant4ParticleMap* pm = context()->event().extension<Geant4ParticleMap>(false);
0525 - debug("+++ Saving EDM4hep collection %s with %d entries.", colName.c_str(), int(nhits));
0526 +
0527 + auto* mcpc = static_cast<edm4hep::MCParticleCollection*>(m_collections["MCParticles"]);
0528 +
0529 //-------------------------------------------------------------------
0530 if( typeid( Geant4Tracker::Hit ) == coll->type().type() ){
0531 - edm4hep::SimTrackerHitCollection sthc;
0532 +
0533 + auto* sthc = static_cast<edm4hep::SimTrackerHitCollection*>(m_collections[colName]);
0534 +
0535 for(unsigned i=0 ; i < nhits ; ++i){
0536 - auto sth = sthc->create();
0537 + auto sth = sthc->create() ;
0538 +
0539 const Geant4Tracker::Hit* hit = coll->hit(i);
0540 const Geant4Tracker::Hit::Contribution& t = hit->truth;
0541 - int trackID = pm->particleID(t.trackID);
0542 - auto mcp = m_particles.at(trackID);
0543 - const auto& mom = hit->momentum;
0544 - const auto& pos = hit->position;
0545 - edm4hep::Vector3f();
0546 + int trackID = pm->particleID(t.trackID);
0547 +
0548 + auto mcp = mcpc->at(trackID);
0549 +
0550 sth.setCellID( hit->cellID ) ;
0551 sth.setEDep(hit->energyDeposit/CLHEP::GeV);
0552 sth.setPathLength(hit->length/CLHEP::mm);
0553 sth.setTime(hit->truth.time/CLHEP::ns);
0554 sth.setMCParticle(mcp);
0555 - sth.setPosition( {pos.x()/CLHEP::mm, pos.y()/CLHEP::mm, pos.z()/CLHEP::mm} );
0556 - sth.setMomentum( {float(mom.x()/CLHEP::GeV),float(mom.y()/CLHEP::GeV),float(mom.z()/CLHEP::GeV)} );
0557 + sth.setPosition({hit->position.x()/CLHEP::mm,
0558 + hit->position.y()/CLHEP::mm,
0559 + hit->position.z()/CLHEP::mm});
0560 + sth.setMomentum(edm4hep::Vector3f(hit->momentum.x()/CLHEP::GeV,
0561 + hit->momentum.y()/CLHEP::GeV,
0562 + hit->momentum.z()/CLHEP::GeV ));
0563 +
0564 auto particleIt = pm->particles().find(trackID);
0565 if( ( particleIt != pm->particles().end()) ){
0566 // if the original track ID of the particle is not the same as the
0567 @@ -453,49 +460,139 @@ void Geant4Output2EDM4hep::saveCollection(OutputContext<G4Event>& /*ctxt*/, G4VH
0568 sth.setProducedBySecondary( (particleIt->second->originalG4ID != t.trackID) );
0569 }
0570 }
0571 - m_frame.put(std::move(sthc), colName);
0572 - //-------------------------------------------------------------------
0573 + //-------------------------------------------------------------------
0574 }
0575 else if( typeid( Geant4Calorimeter::Hit ) == coll->type().type() ){
0576 - Geant4Sensitive* sd = coll->sensitive();
0577 +
0578 + Geant4Sensitive* sd = coll->sensitive();
0579 int hit_creation_mode = sd->hitCreationMode();
0580
0581 - edm4hep::SimCalorimeterHitCollection sCaloHitColl;
0582 - edm4hep::CaloHitContributionCollection sCaloHitContColl;
0583 + auto* sCaloHitColl = static_cast<edm4hep::SimCalorimeterHitCollection*>(m_collections[colName]);
0584 +
0585 + colName += "Contributions" ;
0586 +
0587 + auto* sCaloHitContColl = static_cast<edm4hep::CaloHitContributionCollection*>(m_collections[colName]);
0588 +
0589 +
0590 for(unsigned i=0 ; i < nhits ; ++i){
0591 auto sch = sCaloHitColl->create() ;
0592 +
0593 const Geant4Calorimeter::Hit* hit = coll->hit(i);
0594 - const auto& pos = hit->position;
0595 +
0596 sch.setCellID( hit->cellID );
0597 - sch.setPosition({float(pos.x()/CLHEP::mm), float(pos.y()/CLHEP::mm), float(pos.z()/CLHEP::mm)});
0598 + sch.setPosition({
0599 + float(hit->position.x()/CLHEP::mm),
0600 + float(hit->position.y()/CLHEP::mm),
0601 + float(hit->position.z()/CLHEP::mm)});
0602 sch.setEnergy( hit->energyDeposit/CLHEP::GeV );
0603
0604 -
0605 // now add the individual step contributions
0606 - for(auto ci=hit->truth.begin(); ci != hit->truth.end(); ++ci){
0607 + for(Geant4HitData::Contributions::const_iterator ci=hit->truth.begin();
0608 + ci!=hit->truth.end(); ++ci){
0609
0610 auto sCaloHitCont = sCaloHitContColl->create();
0611 sch.addToContributions( sCaloHitCont );
0612
0613 const Geant4HitData::Contribution& c = *ci;
0614 int trackID = pm->particleID(c.trackID);
0615 - auto mcp = m_particles.at(trackID);
0616 + auto mcp = mcpc->at(trackID);
0617 +
0618 sCaloHitCont.setEnergy( c.deposit/CLHEP::GeV );
0619 sCaloHitCont.setTime( c.time/CLHEP::ns );
0620 sCaloHitCont.setParticle( mcp );
0621
0622 if ( hit_creation_mode == Geant4Sensitive::DETAILED_MODE ) {
0623 - edm4hep::Vector3f p(c.x/CLHEP::mm, c.y/CLHEP::mm, c.z/CLHEP::mm);
0624 sCaloHitCont.setPDG( c.pdgID );
0625 - sCaloHitCont.setStepPosition( p );
0626 + sCaloHitCont.setStepPosition( edm4hep::Vector3f(
0627 + c.x/CLHEP::mm,
0628 + c.y/CLHEP::mm,
0629 + c.z/CLHEP::mm) );
0630 }
0631 }
0632 }
0633 - m_frame.put(std::move(sCaloHitColl), colName);
0634 - m_frame.put(std::move(sCaloHitContColl), colName + "Contributions");
0635 - //-------------------------------------------------------------------
0636 + //-------------------------------------------------------------------
0637 } else {
0638 - error("+++ unknown type in Geant4HitCollection %s ", coll->type().type().name());
0639 +
0640 + printout(ERROR, "Geant4Output2EDM4hep" , " unknown type in Geant4HitCollection %s ",
0641 + coll->type().type().name() );
0642 }
0643 }
0644
0645 +void Geant4Output2EDM4hep::createCollections(OutputContext<G4Event>& ctxt){
0646 +
0647 + auto* mcColl = new edm4hep::MCParticleCollection();
0648 + m_collections.emplace("MCParticles", mcColl);
0649 + m_store->registerCollection("MCParticles", mcColl);
0650 + m_file->registerForWrite("MCParticles");
0651 + printout(DEBUG,"Geant4Output2EDM4hep","+++ created collection MCParticles" );
0652 +
0653 + auto* evtHeader = new edm4hep::EventHeaderCollection();
0654 + m_collections.emplace("EventHeader", evtHeader);
0655 + m_store->registerCollection("EventHeader", evtHeader);
0656 + m_file->registerForWrite("EventHeader");
0657 + printout(DEBUG,"Geant4Output2EDM4hep","+++ created collection EventHeader" );
0658 +
0659 +
0660 + const G4Event* evt = ctxt.context ;
0661 + G4HCofThisEvent* hce = evt->GetHCofThisEvent();
0662 + int nCol = hce->GetNumberOfCollections();
0663 +
0664 + for (int i = 0; i < nCol; ++i) {
0665 + G4VHitsCollection* hc = hce->GetHC(i);
0666 + std::string colName = hc->GetName() ;
0667 + Geant4HitCollection* coll = dynamic_cast<Geant4HitCollection*>(hc);
0668 + if( coll == nullptr ){
0669 + printout(WARNING, "Geant4Output2EDM4hep" , " no Geant4HitCollection: %s ", colName.c_str() );
0670 + continue ;
0671 + }
0672 +
0673 + Geant4Sensitive* sd = coll->sensitive();
0674 + string sd_enc = dd4hep::sim::Geant4ConversionHelper::encoding(sd->sensitiveDetector());
0675 +
0676 + if( typeid( Geant4Tracker::Hit ) == coll->type().type() ){
0677 +
0678 + auto* sthc = new edm4hep::SimTrackerHitCollection();
0679 + auto pairColCheck = m_collections.emplace(colName, sthc);
0680 + if ( pairColCheck.second ) {
0681 + m_store->registerCollection(colName, sthc);
0682 + m_file->registerForWrite(colName);
0683 + auto& sthc_md = m_store->getCollectionMetaData( sthc->getID() );
0684 + sthc_md.setValue("CellIDEncodingString", sd_enc);
0685 + printout(DEBUG,"Geant4Output2EDM4hep","+++ created collection %s",colName.c_str() );
0686 + } else {
0687 + delete sthc;
0688 + }
0689 + printout(DEBUG,"Geant4Output2EDM4hep","+++ re-using collection %s",colName.c_str() );
0690 +
0691 + }
0692 + else if( typeid( Geant4Calorimeter::Hit ) == coll->type().type() ){
0693 +
0694 + auto* schc = new edm4hep::SimCalorimeterHitCollection();
0695 + auto pairColCheck = m_collections.emplace(colName, schc);
0696 + if ( pairColCheck.second ) {
0697 + m_store->registerCollection(colName, schc);
0698 + m_file->registerForWrite(colName);
0699 + auto& schc_md = m_store->getCollectionMetaData( schc->getID() );
0700 + schc_md.setValue("CellIDEncodingString", sd_enc);
0701 + printout(DEBUG,"Geant4Output2EDM4hep","+++ created collection %s",colName.c_str() );
0702 +
0703 + colName += "Contributions" ;
0704 + auto* chContribColl = new edm4hep::CaloHitContributionCollection();
0705 + m_collections.emplace(colName, chContribColl);
0706 + m_store->registerCollection(colName, chContribColl);
0707 + m_file->registerForWrite(colName);
0708 + printout(DEBUG,"Geant4Output2EDM4hep","+++ created collection %s",colName.c_str() );
0709 + } else {
0710 + delete schc;
0711 + printout(DEBUG,"Geant4Output2EDM4hep","+++ re-using collection %s",colName.c_str() );
0712 + }
0713 +
0714 + } else {
0715 +
0716 + printout(WARNING, "Geant4Output2EDM4hep" ,
0717 + " unknown type in Geant4HitCollection %s ", coll->type().type().name() );
0718 + }
0719 + }
0720 +
0721 +
0722 +}