File indexing completed on 2026-05-27 07:26:06
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 #include <CLHEP/Units/SystemOfUnits.h>
0025
0026 #include <DDG4/EventParameters.h>
0027 #include <DDG4/Factories.h>
0028 #include <DDG4/FileParameters.h>
0029 #include <DDG4/Geant4InputAction.h>
0030 #include <DDG4/RunParameters.h>
0031
0032 #include <edm4hep/Constants.h>
0033 #include <edm4hep/EventHeaderCollection.h>
0034 #include <edm4hep/MCParticleCollection.h>
0035 #include <edm4hep/EDM4hepVersion.h>
0036 #if EDM4HEP_BUILD_VERSION >= EDM4HEP_VERSION(0, 99, 3)
0037 #include <edm4hep/GeneratorEventParametersCollection.h>
0038 #endif
0039
0040 #include <podio/Frame.h>
0041 #include <podio/Reader.h>
0042
0043 typedef dd4hep::detail::ReferenceBitMask<int> PropertyMask;
0044
0045
0046 namespace dd4hep::sim {
0047
0048
0049
0050 using MCPARTICLE_MAP=std::map<int, int>;
0051
0052
0053
0054 template <class T=podio::GenericParameters> void EventParameters::ingestParameters(T const& source) {
0055 for(auto const& key: source.template getKeys<int>()) {
0056 m_intValues[key] = source.template get<std::vector<int>>(key).value();
0057 }
0058 for(auto const& key: source.template getKeys<float>()) {
0059 m_fltValues[key] = source.template get<std::vector<float>>(key).value();
0060 }
0061 for(auto const& key: source.template getKeys<double>()) {
0062 m_dblValues[key] = source.template get<std::vector<double>>(key).value();
0063 }
0064 for(auto const& key: source.template getKeys<std::string>()) {
0065 m_strValues[key] = source.template get<std::vector<std::string>>(key).value();
0066 }
0067 }
0068
0069
0070
0071 template <class T=podio::GenericParameters> void RunParameters::ingestParameters(T const& source) {
0072 for(auto const& key: source.template getKeys<int>()) {
0073 m_intValues[key] = source.template get<std::vector<int>>(key).value();
0074 }
0075 for(auto const& key: source.template getKeys<float>()) {
0076 m_fltValues[key] = source.template get<std::vector<float>>(key).value();
0077 }
0078 for(auto const& key: source.template getKeys<double>()) {
0079 m_dblValues[key] = source.template get<std::vector<double>>(key).value();
0080 }
0081 for(auto const& key: source.template getKeys<std::string>()) {
0082 m_strValues[key] = source.template get<std::vector<std::string>>(key).value();
0083 }
0084 }
0085
0086 template <class T=podio::GenericParameters> void FileParameters::ingestParameters(T const& source) {
0087 for(auto const& key: source.template getKeys<int>()) {
0088 m_intValues[key] = source.template get<std::vector<int>>(key).value();
0089 }
0090 for(auto const& key: source.template getKeys<float>()) {
0091 m_fltValues[key] = source.template get<std::vector<float>>(key).value();
0092 }
0093 for(auto const& key: source.template getKeys<double>()) {
0094 m_dblValues[key] = source.template get<std::vector<double>>(key).value();
0095 }
0096 for(auto const& key: source.template getKeys<std::string>()) {
0097 m_strValues[key] = source.template get<std::vector<std::string>>(key).value();
0098 }
0099 }
0100
0101
0102
0103
0104
0105
0106 class EDM4hepFileReader : public Geant4EventReader {
0107 protected:
0108
0109 podio::Reader m_reader;
0110
0111 std::string m_collectionName;
0112
0113 std::string m_eventHeaderCollectionName;
0114
0115 public:
0116
0117 EDM4hepFileReader(const std::string& nam);
0118
0119
0120 virtual EventReaderStatus setParameters(std::map< std::string, std::string >& parameters);
0121
0122
0123 virtual EventReaderStatus readParticles(int event_number, Vertices& vertices, std::vector<Particle*>& particles);
0124
0125 void registerRunParameters();
0126
0127 };
0128
0129
0130 dd4hep::sim::EDM4hepFileReader::EDM4hepFileReader(const std::string& nam)
0131 : Geant4EventReader(nam)
0132 , m_reader(podio::makeReader(nam))
0133 , m_collectionName("MCParticles")
0134 , m_eventHeaderCollectionName("EventHeader")
0135 {
0136 printout(INFO,"EDM4hepFileReader","Created file reader. Try to open input %s",nam.c_str());
0137 m_directAccess = true;
0138 }
0139
0140 void EDM4hepFileReader::registerRunParameters() {
0141 try {
0142
0143 auto* parameters = context()->run().extension<RunParameters>(false);
0144 if (!parameters) {
0145 parameters = new RunParameters();
0146 context()->run().addExtension<RunParameters>(parameters);
0147 }
0148 try {
0149 podio::Frame runFrame = m_reader.readFrame("runs", 0);
0150 parameters->ingestParameters(runFrame.getParameters());
0151 } catch (std::runtime_error& e) {
0152
0153 } catch(std::invalid_argument&) {
0154
0155 }
0156 } catch(std::exception &e) {
0157 printout(ERROR,"EDM4hepFileReader::registerRunParameters","Failed to register run parameters: %s", e.what());
0158 }
0159
0160 try {
0161 auto *fileParameters = new FileParameters();
0162 try {
0163 podio::Frame metaFrame = m_reader.readFrame("metadata", 0);
0164 fileParameters->ingestParameters(metaFrame.getParameters());
0165 } catch (std::runtime_error& e) {
0166
0167 } catch(std::invalid_argument&) {
0168
0169 }
0170 context()->run().addExtension<FileParameters>(fileParameters);
0171 } catch(std::exception &e) {
0172 printout(ERROR,"EDM4hepFileReader::registerRunParameters","Failed to register file parameters: %s", e.what());
0173 }
0174 }
0175
0176 namespace {
0177
0178 inline int GET_ENTRY(MCPARTICLE_MAP const& mcparts, int partID) {
0179 MCPARTICLE_MAP::const_iterator ip = mcparts.find(partID);
0180 if ( ip == mcparts.end() ) {
0181 throw std::runtime_error("Unknown particle identifier look-up!");
0182 }
0183 return (*ip).second;
0184 }
0185 }
0186
0187
0188 EDM4hepFileReader::EventReaderStatus
0189 EDM4hepFileReader::readParticles(int event_number, Vertices& vertices, std::vector<Particle*>& particles) {
0190 m_currEvent = event_number;
0191 podio::Frame frame = m_reader.readFrame("events", event_number);
0192 const auto& primaries = frame.get<edm4hep::MCParticleCollection>(m_collectionName);
0193 const auto& availableCollections = frame.getAvailableCollections();
0194 int eventNumber = event_number, runNumber = 0;
0195 #if PODIO_BUILD_VERSION >= PODIO_VERSION(1, 6, 0)
0196 if (primaries.hasID()) {
0197 #else
0198 if (primaries.isValid()) {
0199 #endif
0200
0201 if (std::find(availableCollections.begin(), availableCollections.end(), m_eventHeaderCollectionName) != availableCollections.end()) {
0202 const auto& eventHeaderCollection = frame.get<edm4hep::EventHeaderCollection>(m_eventHeaderCollectionName);
0203 if(eventHeaderCollection.size() == 1){
0204 const auto& eh = eventHeaderCollection.at(0);
0205 eventNumber = eh.getEventNumber();
0206 runNumber = eh.getRunNumber();
0207 try {
0208 Geant4Context* ctx = context();
0209 ctx->event().addExtension<edm4hep::MutableEventHeader>(new edm4hep::MutableEventHeader(eh.clone()));
0210 } catch(std::exception& ) {}
0211 } else {
0212 printout(WARNING,"EDM4hepFileReader","Too many EventHeader objects found");
0213 }
0214 }
0215 else {
0216 printout(WARNING,"EDM4hepFileReader","No EventHeader collection found!");
0217 }
0218
0219 try {
0220 Geant4Context* ctx = context();
0221 EventParameters *parameters = new EventParameters();
0222 parameters->setRunNumber(runNumber);
0223 parameters->setEventNumber(event_number);
0224 parameters->ingestParameters(frame.getParameters());
0225 ctx->event().addExtension<EventParameters>(parameters);
0226 } catch(std::exception &) {}
0227 #if EDM4HEP_BUILD_VERSION >= EDM4HEP_VERSION(0, 99, 3)
0228 if (std::find(availableCollections.begin(), availableCollections.end(), edm4hep::labels::GeneratorEventParameters) != availableCollections.end()) {
0229 const auto& genEvtParameters =
0230 frame.get<edm4hep::GeneratorEventParametersCollection>(edm4hep::labels::GeneratorEventParameters);
0231 if (genEvtParameters.size() >= 1) {
0232 const auto genParams = genEvtParameters[0];
0233 try {
0234 auto *ctx = context();
0235 ctx->event().addExtension(new edm4hep::MutableGeneratorEventParameters(genParams.clone()));
0236 } catch (std::exception &) {}
0237 }
0238 if (genEvtParameters.size() > 1) {
0239 printout(WARNING, "EDM4hepFileReader", "Multiple GeneratorEventParameters found in input file. Ignoring all but the first one!");
0240 }
0241 } else {
0242 printout(DEBUG, "EDM4hepFileReader", "No GeneratorEventParameters found in input file");
0243 }
0244 #endif
0245 printout(INFO,"EDM4hepFileReader","read collection %s from event %d in run %d ",
0246 m_collectionName.c_str(), eventNumber, runNumber);
0247
0248 } else {
0249 return EVENT_READER_EOF;
0250 }
0251
0252 printout(INFO,"EDM4hepFileReader", "We read the particle collection");
0253 int NHEP = primaries.size();
0254
0255 if ( NHEP == 0 ) {
0256 printout(WARNING,"EDM4hepFileReader", "We have no particles");
0257 return EVENT_READER_NO_PRIMARIES;
0258 }
0259
0260 MCPARTICLE_MAP mcparts;
0261 std::vector<int> mcpcoll;
0262 mcpcoll.resize(NHEP);
0263 for(int i=0; i<NHEP; ++i ) {
0264 edm4hep::MCParticle p = primaries.at(i);
0265 mcparts[p.getObjectID().index] = i;
0266 mcpcoll[i] = p.getObjectID().index;
0267 }
0268
0269
0270 for(int i=0; i<NHEP; ++i ) {
0271 const auto& mcp = primaries.at(i);
0272 Geant4ParticleHandle p(new Particle(i));
0273 const auto mom = mcp.getMomentum();
0274 const auto vsx = mcp.getVertex();
0275 const auto vex = mcp.getEndpoint();
0276 const int pdg = mcp.getPDG();
0277 #ifdef EDM4HEP_MCPARTICLE_HAS_HELICITY
0278 p->spin[0] = 0;
0279 p->spin[1] = 0;
0280 p->spin[2] = mcp.getHelicity();
0281 #else
0282 const auto spin = mcp.getSpin();
0283 p->spin[0] = spin[0];
0284 p->spin[1] = spin[1];
0285 p->spin[2] = spin[2];
0286 #endif
0287 p->pdgID = pdg;
0288 p->charge = int(mcp.getCharge()*3.0);
0289 p->psx = mom[0]*CLHEP::GeV;
0290 p->psy = mom[1]*CLHEP::GeV;
0291 p->psz = mom[2]*CLHEP::GeV;
0292 p->time = mcp.getTime()*CLHEP::ns;
0293 p->properTime = mcp.getTime()*CLHEP::ns;
0294 p->vsx = vsx[0]*CLHEP::mm;
0295 p->vsy = vsx[1]*CLHEP::mm;
0296 p->vsz = vsx[2]*CLHEP::mm;
0297 p->vex = vex[0]*CLHEP::mm;
0298 p->vey = vex[1]*CLHEP::mm;
0299 p->vez = vex[2]*CLHEP::mm;
0300 p->process = 0;
0301 p->colorFlow[0] = 0;
0302 p->colorFlow[1] = 0;
0303 p->mass = mcp.getMass()*CLHEP::GeV;
0304 const auto par = mcp.getParents(), &dau=mcp.getDaughters();
0305 for(int num=dau.size(),k=0; k<num; ++k) {
0306 edm4hep::MCParticle dau_k = dau[k];
0307 p->daughters.insert(GET_ENTRY(mcparts,dau_k.getObjectID().index));
0308 }
0309 for(int num=par.size(),k=0; k<num; ++k) {
0310 auto par_k = par[k];
0311 p->parents.insert(GET_ENTRY(mcparts, par_k.getObjectID().index));
0312 }
0313
0314 PropertyMask status(p->status);
0315 int genStatus = mcp.getGeneratorStatus();
0316
0317 p->genStatus = genStatus&G4PARTICLE_GEN_STATUS_MASK;
0318 if(m_inputAction) {
0319
0320 m_inputAction->setGeneratorStatus(genStatus, status);
0321 }
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331 if ( p->parents.size() == 0 ) {
0332
0333 Geant4Vertex* vtx = new Geant4Vertex ;
0334 vertices.emplace_back( vtx );
0335 vtx->x = p->vsx;
0336 vtx->y = p->vsy;
0337 vtx->z = p->vsz;
0338 vtx->time = p->time;
0339
0340 vtx->out.insert(p->id) ;
0341 }
0342
0343 if ( mcp.isCreatedInSimulation() ) status.set(G4PARTICLE_SIM_CREATED);
0344 if ( mcp.isBackscatter() ) status.set(G4PARTICLE_SIM_BACKSCATTER);
0345 if ( mcp.vertexIsNotEndpointOfParent() ) status.set(G4PARTICLE_SIM_PARENT_RADIATED);
0346 if ( mcp.isDecayedInTracker() ) status.set(G4PARTICLE_SIM_DECAY_TRACKER);
0347 if ( mcp.isDecayedInCalorimeter() ) status.set(G4PARTICLE_SIM_DECAY_CALO);
0348 if ( mcp.hasLeftDetector() ) status.set(G4PARTICLE_SIM_LEFT_DETECTOR);
0349 if ( mcp.isStopped() ) status.set(G4PARTICLE_SIM_STOPPED);
0350 if ( mcp.isOverlay() ) status.set(G4PARTICLE_SIM_OVERLAY);
0351 particles.emplace_back(p);
0352 }
0353 return EVENT_READER_OK;
0354 }
0355
0356
0357
0358 Geant4EventReader::EventReaderStatus
0359 dd4hep::sim::EDM4hepFileReader::setParameters( std::map< std::string, std::string > & parameters ) {
0360 _getParameterValue(parameters, "MCParticleCollectionName", m_collectionName, m_collectionName);
0361 _getParameterValue(parameters, "EventHeaderCollectionName", m_eventHeaderCollectionName, m_eventHeaderCollectionName);
0362 return EVENT_READER_OK;
0363 }
0364
0365 }
0366
0367 DECLARE_GEANT4_EVENT_READER_NS(dd4hep::sim,EDM4hepFileReader)