File indexing completed on 2025-07-15 08:15:00
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef DD4HEP_DDG4_GEANT4OUTPUT2EDM4hep_H
0014 #define DD4HEP_DDG4_GEANT4OUTPUT2EDM4hep_H
0015
0016
0017 #include <DD4hep/Detector.h>
0018 #include <DDG4/EventParameters.h>
0019 #include <DDG4/FileParameters.h>
0020 #include <DDG4/Geant4OutputAction.h>
0021 #include <DDG4/RunParameters.h>
0022
0023
0024 #include <edm4hep/MCParticleCollection.h>
0025 #include <edm4hep/SimTrackerHitCollection.h>
0026 #include <edm4hep/CaloHitContributionCollection.h>
0027 #include <edm4hep/SimCalorimeterHitCollection.h>
0028 #include <edm4hep/EDM4hepVersion.h>
0029 #include <edm4hep/Constants.h>
0030 #if EDM4HEP_BUILD_VERSION < EDM4HEP_VERSION(0, 99, 0)
0031 using edm4hep::CellIDEncoding;
0032 #else
0033 using edm4hep::labels::CellIDEncoding;
0034 #endif
0035
0036 #include <podio/CollectionBase.h>
0037 #include <podio/podioVersion.h>
0038 #include <podio/Frame.h>
0039 #include <podio/FrameCategories.h>
0040 #if PODIO_BUILD_VERSION >= PODIO_VERSION(0, 99, 0)
0041 #include <podio/ROOTWriter.h>
0042 #else
0043 #include <podio/ROOTFrameWriter.h>
0044 namespace podio {
0045 using ROOTWriter = podio::ROOTFrameWriter;
0046 }
0047 #endif
0048
0049 #include <atomic>
0050
0051
0052 namespace dd4hep {
0053
0054 class ComponentCast;
0055
0056
0057 namespace sim {
0058
0059 class Geant4ParticleMap;
0060
0061
0062
0063
0064
0065
0066
0067 class Geant4Output2EDM4hep : public Geant4OutputAction {
0068 protected:
0069 using writer_t = podio::ROOTWriter;
0070 using stringmap_t = std::map< std::string, std::string >;
0071 using trackermap_t = std::map< std::string, edm4hep::SimTrackerHitCollection >;
0072 using calorimeterpair_t = std::pair< edm4hep::SimCalorimeterHitCollection, edm4hep::CaloHitContributionCollection >;
0073 using calorimetermap_t = std::map< std::string, calorimeterpair_t >;
0074 std::unique_ptr<writer_t> m_file { };
0075 std::atomic_size_t m_fileUseCount { 0 };
0076 podio::Frame m_frame { };
0077 edm4hep::MCParticleCollection m_particles { };
0078 trackermap_t m_trackerHits;
0079 calorimetermap_t m_calorimeterHits;
0080 stringmap_t m_runHeader;
0081 stringmap_t m_eventParametersInt;
0082 stringmap_t m_eventParametersFloat;
0083 stringmap_t m_eventParametersString;
0084 stringmap_t m_cellIDEncodingStrings{};
0085 std::string m_section_name { "events" };
0086 int m_runNo { 0 };
0087 int m_runNumberOffset { 0 };
0088 int m_eventNo { 0 };
0089 int m_eventNumberOffset { 0 };
0090 bool m_filesByRun { false };
0091
0092
0093 void saveParticles(Geant4ParticleMap* particles);
0094
0095 void saveFileMetaData();
0096 public:
0097
0098 Geant4Output2EDM4hep(Geant4Context* ctxt, const std::string& nam);
0099
0100 virtual ~Geant4Output2EDM4hep();
0101
0102 virtual void beginRun(const G4Run* run);
0103
0104 virtual void endRun(const G4Run* run);
0105
0106
0107 virtual void saveRun(const G4Run* run);
0108
0109 virtual void saveEvent( OutputContext<G4Event>& ctxt);
0110
0111 virtual void saveCollection( OutputContext<G4Event>& ctxt, G4VHitsCollection* collection);
0112
0113 virtual void commit( OutputContext<G4Event>& ctxt);
0114
0115
0116 virtual void begin(const G4Event* event);
0117 protected:
0118
0119 template <typename T>
0120 void saveEventParameters(const std::map<std::string, std::string >& parameters) {
0121 for(const auto& p : parameters) {
0122 info("Saving event parameter: %-32s = %s", p.first.c_str(), p.second.c_str());
0123 m_frame.putParameter(p.first, p.second);
0124 }
0125 }
0126 };
0127
0128 template <> void EventParameters::extractParameters(podio::Frame& frame) {
0129 for(auto const& p: this->intParameters()) {
0130 printout(DEBUG, "Geant4OutputEDM4hep", "Saving event parameter: %s", p.first.c_str());
0131 frame.putParameter(p.first, p.second);
0132 }
0133 for(auto const& p: this->fltParameters()) {
0134 printout(DEBUG, "Geant4OutputEDM4hep", "Saving event parameter: %s", p.first.c_str());
0135 frame.putParameter(p.first, p.second);
0136 }
0137 for(auto const& p: this->strParameters()) {
0138 printout(DEBUG, "Geant4OutputEDM4hep", "Saving event parameter: %s", p.first.c_str());
0139 frame.putParameter(p.first, p.second);
0140 }
0141
0142 for (auto const& p: this->dblParameters()) {
0143 printout(DEBUG, "Geant4OutputEDM4hep", "Saving event parameter: %s", p.first.c_str());
0144 frame.putParameter(p.first, p.second);
0145 }
0146 }
0147
0148 template <> void RunParameters::extractParameters(podio::Frame& frame) {
0149 for(auto const& p: this->intParameters()) {
0150 printout(DEBUG, "Geant4OutputEDM4hep", "Saving run parameter: %s", p.first.c_str());
0151 frame.putParameter(p.first, p.second);
0152 }
0153 for(auto const& p: this->fltParameters()) {
0154 printout(DEBUG, "Geant4OutputEDM4hep", "Saving run parameter: %s", p.first.c_str());
0155 frame.putParameter(p.first, p.second);
0156 }
0157 for(auto const& p: this->strParameters()) {
0158 printout(DEBUG, "Geant4OutputEDM4hep", "Saving run parameter: %s", p.first.c_str());
0159 frame.putParameter(p.first, p.second);
0160 }
0161
0162 for (auto const& p: this->dblParameters()) {
0163 printout(DEBUG, "Geant4OutputEDM4hep", "Saving run parameter: %s", p.first.c_str());
0164 frame.putParameter(p.first, p.second);
0165 }
0166 }
0167 template <> void FileParameters::extractParameters(podio::Frame& frame) {
0168 for(auto const& p: this->intParameters()) {
0169 printout(DEBUG, "Geant4OutputEDM4hep", "Saving meta parameter: %s", p.first.c_str());
0170 frame.putParameter(p.first, p.second);
0171 }
0172 for(auto const& p: this->fltParameters()) {
0173 printout(DEBUG, "Geant4OutputEDM4hep", "Saving meta parameter: %s", p.first.c_str());
0174 frame.putParameter(p.first, p.second);
0175 }
0176 for(auto const& p: this->strParameters()) {
0177 printout(DEBUG, "Geant4OutputEDM4hep", "Saving meta parameter: %s", p.first.c_str());
0178 frame.putParameter(p.first, p.second);
0179 }
0180
0181 for (auto const& p: this->dblParameters()) {
0182 printout(DEBUG, "Geant4OutputEDM4hep", "Saving meta parameter: %s", p.first.c_str());
0183 frame.putParameter(p.first, p.second);
0184 }
0185 }
0186
0187 }
0188 }
0189 #endif
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205 #include <DD4hep/InstanceCount.h>
0206 #include <DD4hep/VolumeManager.h>
0207
0208 #include <DDG4/Geant4HitCollection.h>
0209 #include <DDG4/Geant4DataConversion.h>
0210 #include <DDG4/Geant4SensDetAction.h>
0211 #include <DDG4/Geant4Context.h>
0212 #include <DDG4/Geant4Particle.h>
0213 #include <DDG4/Geant4Data.h>
0214
0215
0216
0217 #include <G4Threading.hh>
0218 #include <G4AutoLock.hh>
0219 #include <G4Version.hh>
0220 #include <G4ParticleDefinition.hh>
0221 #include <G4VProcess.hh>
0222 #include <G4Event.hh>
0223 #include <G4Run.hh>
0224
0225 #include <CLHEP/Units/SystemOfUnits.h>
0226
0227
0228 #include <edm4hep/EventHeaderCollection.h>
0229
0230 using namespace dd4hep::sim;
0231 using namespace dd4hep;
0232
0233 namespace {
0234 G4Mutex action_mutex = G4MUTEX_INITIALIZER;
0235 }
0236
0237 #include <DDG4/Factories.h>
0238 DECLARE_GEANT4ACTION(Geant4Output2EDM4hep)
0239
0240
0241 Geant4Output2EDM4hep::Geant4Output2EDM4hep(Geant4Context* ctxt, const std::string& nam)
0242 : Geant4OutputAction(ctxt,nam), m_runNo(0), m_runNumberOffset(0), m_eventNumberOffset(0)
0243 {
0244 declareProperty("RunHeader", m_runHeader);
0245 declareProperty("EventParametersInt", m_eventParametersInt);
0246 declareProperty("EventParametersFloat", m_eventParametersFloat);
0247 declareProperty("EventParametersString", m_eventParametersString);
0248 declareProperty("RunNumberOffset", m_runNumberOffset);
0249 declareProperty("EventNumberOffset", m_eventNumberOffset);
0250 declareProperty("SectionName", m_section_name);
0251 declareProperty("FilesByRun", m_filesByRun);
0252 info("Writer is now instantiated ..." );
0253 InstanceCount::increment(this);
0254 }
0255
0256
0257 Geant4Output2EDM4hep::~Geant4Output2EDM4hep() {
0258 G4AutoLock protection_lock(&action_mutex);
0259 InstanceCount::decrement(this);
0260 }
0261
0262
0263 void Geant4Output2EDM4hep::beginRun(const G4Run* run) {
0264 G4AutoLock protection_lock(&action_mutex);
0265 std::string fname = m_output;
0266 m_runNo = run->GetRunID();
0267 if ( m_filesByRun ) {
0268 std::size_t idx = m_output.rfind(".");
0269 if ( idx != std::string::npos ) {
0270 fname = m_output.substr(0, idx) + _toString(m_runNo, ".run%08d") + m_output.substr(idx);
0271 }
0272 }
0273
0274 if ( !fname.empty() && !m_file ) {
0275 m_file = std::make_unique<podio::ROOTWriter>(fname);
0276 if ( !m_file ) {
0277 fatal("+++ Failed to open output file: %s", fname.c_str());
0278 }
0279 printout( INFO, "Geant4Output2EDM4hep" ,"Opened %s for output", fname.c_str() ) ;
0280 }
0281 m_fileUseCount++;
0282 }
0283
0284
0285 void Geant4Output2EDM4hep::endRun(const G4Run* run) {
0286 saveRun(run);
0287 saveFileMetaData();
0288
0289
0290
0291
0292 G4AutoLock protection_lock(&action_mutex);
0293 if ( m_file && m_fileUseCount == 1 ) {
0294 m_file->finish();
0295 m_file.reset();
0296 }
0297 m_fileUseCount--;
0298 }
0299
0300 void Geant4Output2EDM4hep::saveFileMetaData() {
0301 podio::Frame metaFrame{};
0302 for (const auto& [name, encodingStr] : m_cellIDEncodingStrings) {
0303 metaFrame.putParameter(podio::collMetadataParamName(name, CellIDEncoding), encodingStr);
0304 }
0305 G4AutoLock protection_lock(&action_mutex);
0306 m_file->writeFrame(metaFrame, "metadata");
0307 }
0308
0309
0310 void Geant4Output2EDM4hep::commit( OutputContext<G4Event>& ) {
0311 if ( m_file ) {
0312 G4AutoLock protection_lock(&action_mutex);
0313 m_frame.put( std::move(m_particles), "MCParticles");
0314 for (auto it = m_trackerHits.begin(); it != m_trackerHits.end(); ++it) {
0315 m_frame.put( std::move(it->second), it->first);
0316 }
0317 for (auto& [colName, calorimeterHits] : m_calorimeterHits) {
0318 m_frame.put( std::move(calorimeterHits.first), colName);
0319 m_frame.put( std::move(calorimeterHits.second), colName + "Contributions");
0320 }
0321 m_file->writeFrame(m_frame, m_section_name);
0322 m_particles = { };
0323 m_trackerHits.clear();
0324 m_calorimeterHits.clear();
0325 m_frame = {};
0326 return;
0327 }
0328 except("+++ Failed to write output file. [Stream is not open]");
0329 }
0330
0331
0332 void Geant4Output2EDM4hep::saveRun(const G4Run* run) {
0333 G4AutoLock protection_lock(&action_mutex);
0334
0335
0336
0337 podio::Frame runHeader {};
0338 for (const auto& [key, value] : m_runHeader)
0339 runHeader.putParameter(key, value);
0340
0341 m_runNo = m_runNumberOffset > 0 ? m_runNumberOffset + run->GetRunID() : run->GetRunID();
0342 runHeader.putParameter("runNumber", m_runNo);
0343 runHeader.putParameter("GEANT4Version", G4Version);
0344 runHeader.putParameter("DD4hepVersion", versionString());
0345 runHeader.putParameter("detectorName", context()->detectorDescription().header().name());
0346 {
0347
0348 if (context()->runPtr() != nullptr) {
0349 RunParameters* parameters = context()->run().extension<RunParameters>(false);
0350 if ( parameters ) {
0351 parameters->extractParameters(runHeader);
0352 }
0353 m_file->writeFrame(runHeader, "runs");
0354 }
0355 }
0356 {
0357
0358 if (context()->runPtr() != nullptr) {
0359 podio::Frame metaFrame {};
0360 FileParameters* parameters = context()->run().extension<FileParameters>(false);
0361 if ( parameters ) {
0362 parameters->extractParameters(metaFrame);
0363 }
0364 m_file->writeFrame(metaFrame, "meta");
0365 }
0366 }
0367 }
0368
0369 void Geant4Output2EDM4hep::begin(const G4Event* event) {
0370
0371 m_eventNo = event->GetEventID();
0372 m_frame = {};
0373 m_particles = {};
0374 m_trackerHits.clear();
0375 m_calorimeterHits.clear();
0376 }
0377
0378
0379 void Geant4Output2EDM4hep::saveParticles(Geant4ParticleMap* particles) {
0380 typedef detail::ReferenceBitMask<const int> PropertyMask;
0381 typedef Geant4ParticleMap::ParticleMap ParticleMap;
0382 const ParticleMap& pm = particles->particleMap;
0383
0384 m_particles.clear();
0385 if ( pm.size() > 0 ) {
0386 size_t cnt = 0;
0387
0388 std::map<int,int> p_ids;
0389 std::vector<const Geant4Particle*> p_part;
0390 p_part.reserve(pm.size());
0391
0392 for (const auto& iParticle : pm) {
0393 int id = iParticle.first;
0394 const Geant4ParticleHandle p = iParticle.second;
0395 PropertyMask mask(p->status);
0396
0397 const G4ParticleDefinition* def = p.definition();
0398 auto mcp = m_particles.create();
0399 mcp.setPDG(p->pdgID);
0400
0401 using MT = decltype(std::declval<edm4hep::MCParticle>().getMomentum().x);
0402 mcp.setMomentum( {MT(p->psx/CLHEP::GeV),MT(p->psy/CLHEP::GeV),MT(p->psz/CLHEP::GeV)} );
0403 mcp.setMomentumAtEndpoint( {MT(p->pex/CLHEP::GeV),MT(p->pey/CLHEP::GeV),MT(p->pez/CLHEP::GeV)} );
0404
0405 double vs_fa[3] = { p->vsx/CLHEP::mm, p->vsy/CLHEP::mm, p->vsz/CLHEP::mm } ;
0406 mcp.setVertex( vs_fa );
0407
0408 double ve_fa[3] = { p->vex/CLHEP::mm, p->vey/CLHEP::mm, p->vez/CLHEP::mm } ;
0409 mcp.setEndpoint( ve_fa );
0410
0411 mcp.setTime(p->time/CLHEP::ns);
0412 mcp.setMass(p->mass/CLHEP::GeV);
0413 mcp.setCharge(def ? def->GetPDGCharge() : 0);
0414
0415
0416 mcp.setGeneratorStatus(0);
0417 if( p->genStatus ) {
0418 mcp.setGeneratorStatus( p->genStatus ) ;
0419 } else {
0420 if ( mask.isSet(G4PARTICLE_GEN_STABLE) ) mcp.setGeneratorStatus(1);
0421 else if ( mask.isSet(G4PARTICLE_GEN_DECAYED) ) mcp.setGeneratorStatus(2);
0422 else if ( mask.isSet(G4PARTICLE_GEN_DOCUMENTATION) ) mcp.setGeneratorStatus(3);
0423 else if ( mask.isSet(G4PARTICLE_GEN_BEAM) ) mcp.setGeneratorStatus(4);
0424 else if ( mask.isSet(G4PARTICLE_GEN_OTHER) ) mcp.setGeneratorStatus(9);
0425 }
0426
0427
0428 mcp.setCreatedInSimulation( mask.isSet(G4PARTICLE_SIM_CREATED) );
0429 mcp.setBackscatter( mask.isSet(G4PARTICLE_SIM_BACKSCATTER) );
0430 mcp.setVertexIsNotEndpointOfParent( mask.isSet(G4PARTICLE_SIM_PARENT_RADIATED) );
0431 mcp.setDecayedInTracker( mask.isSet(G4PARTICLE_SIM_DECAY_TRACKER) );
0432 mcp.setDecayedInCalorimeter( mask.isSet(G4PARTICLE_SIM_DECAY_CALO) );
0433 mcp.setHasLeftDetector( mask.isSet(G4PARTICLE_SIM_LEFT_DETECTOR) );
0434 mcp.setStopped( mask.isSet(G4PARTICLE_SIM_STOPPED) );
0435 mcp.setOverlay( false );
0436
0437
0438 if( mcp.isCreatedInSimulation() )
0439 mcp.setGeneratorStatus( 0 ) ;
0440
0441 mcp.setSpin(p->spin);
0442
0443 p_ids[id] = cnt++;
0444 p_part.push_back(p);
0445 }
0446
0447
0448 for(size_t i=0; i < p_ids.size(); ++i) {
0449 const Geant4Particle* p = p_part[i];
0450 auto q = m_particles[i];
0451
0452 for (const auto& idau : p->daughters) {
0453 const auto k = p_ids.find(idau);
0454 if (k == p_ids.end()) {
0455 fatal("+++ Particle %d: FAILED to find daughter with ID:%d",p->id,idau);
0456 continue;
0457 }
0458 int iqdau = (*k).second;
0459 auto qdau = m_particles[iqdau];
0460 q.addToDaughters(qdau);
0461 }
0462
0463 for (const auto& ipar : p->parents) {
0464 if (ipar >= 0) {
0465 const auto k = p_ids.find(ipar);
0466 if (k == p_ids.end()) {
0467 fatal("+++ Particle %d: FAILED to find parent with ID:%d",p->id,ipar);
0468 continue;
0469 }
0470 int iqpar = (*k).second;
0471 auto qpar = m_particles[iqpar];
0472 q.addToParents(qpar);
0473 }
0474 }
0475 }
0476 }
0477 }
0478
0479
0480 void Geant4Output2EDM4hep::saveEvent(OutputContext<G4Event>& ctxt) {
0481 EventParameters* parameters = context()->event().extension<EventParameters>(false);
0482 int runNumber(0), eventNumber(0);
0483 const int eventNumberOffset(m_eventNumberOffset > 0 ? m_eventNumberOffset : 0);
0484 const int runNumberOffset(m_runNumberOffset > 0 ? m_runNumberOffset : 0);
0485 double eventWeight{0};
0486
0487 if ( parameters ) {
0488 runNumber = parameters->runNumber() + runNumberOffset;
0489 eventNumber = parameters->eventNumber() + eventNumberOffset;
0490 parameters->extractParameters(m_frame);
0491 #if PODIO_BUILD_VERSION > PODIO_VERSION(0, 99, 0)
0492 eventWeight = m_frame.getParameter<double>("EventWeights").value_or(0.0);
0493 #else
0494 eventWeight = m_frame.getParameter<double>("EventWeights");
0495 #endif
0496 } else {
0497 runNumber = m_runNo + runNumberOffset;
0498 eventNumber = ctxt.context->GetEventID() + eventNumberOffset;
0499 }
0500 printout(INFO,"Geant4Output2EDM4hep","+++ Saving EDM4hep event %d run %d.", eventNumber, runNumber);
0501
0502
0503 edm4hep::EventHeaderCollection header_collection;
0504
0505 auto header = header_collection.create();
0506 header.setRunNumber(runNumber);
0507 header.setEventNumber(eventNumber);
0508 header.setWeight(eventWeight);
0509
0510 header.setTimeStamp(std::time(nullptr));
0511
0512
0513 auto* meh = context()->event().extension<edm4hep::MutableEventHeader>(false);
0514 if(meh) {
0515 header.setTimeStamp(meh->getTimeStamp());
0516 #if EDM4HEP_BUILD_VERSION >= EDM4HEP_VERSION(0, 99, 0)
0517 for (auto const& weight: meh->getWeights()) {
0518 header.addToWeights(weight);
0519 }
0520 #endif
0521 }
0522
0523 m_frame.put(std::move(header_collection), "EventHeader");
0524 saveEventParameters<int>(m_eventParametersInt);
0525 saveEventParameters<float>(m_eventParametersFloat);
0526 saveEventParameters<std::string>(m_eventParametersString);
0527
0528 Geant4ParticleMap* part_map = context()->event().extension<Geant4ParticleMap>(false);
0529 if ( part_map ) {
0530 print("+++ Saving %d EDM4hep particles....",int(part_map->particleMap.size()));
0531 if ( part_map->particleMap.size() > 0 ) {
0532 saveParticles(part_map);
0533 }
0534 }
0535 }
0536
0537
0538
0539
0540
0541 struct LazyEncodingExtraction {
0542
0543
0544 LazyEncodingExtraction(Geant4HitCollection* coll) : m_coll(coll) {}
0545
0546
0547 operator std::string() const {
0548 const auto* sd = m_coll->sensitive();
0549 return dd4hep::sim::Geant4ConversionHelper::encoding(sd->sensitiveDetector());
0550 }
0551 private:
0552 Geant4HitCollection* m_coll{nullptr};
0553 };
0554
0555
0556
0557 void Geant4Output2EDM4hep::saveCollection(OutputContext<G4Event>& , G4VHitsCollection* collection) {
0558 Geant4HitCollection* coll = dynamic_cast<Geant4HitCollection*>(collection);
0559 std::string colName = collection->GetName();
0560 if( coll == nullptr ){
0561 error(" no Geant4HitCollection: %s ", colName.c_str());
0562 return ;
0563 }
0564 size_t nhits = collection->GetSize();
0565 Geant4ParticleMap* pm = context()->event().extension<Geant4ParticleMap>(false);
0566 debug("+++ Saving EDM4hep collection %s with %d entries.", colName.c_str(), int(nhits));
0567
0568
0569 m_cellIDEncodingStrings.try_emplace(colName, LazyEncodingExtraction{coll});
0570
0571
0572 if( typeid( Geant4Tracker::Hit ) == coll->type().type() ){
0573
0574 auto& hits = m_trackerHits[colName];
0575 for(unsigned i=0 ; i < nhits ; ++i){
0576 auto sth = hits->create();
0577 const Geant4Tracker::Hit* hit = coll->hit(i);
0578 const Geant4Tracker::Hit::Contribution& t = hit->truth;
0579 int trackID = pm->particleID(t.trackID);
0580 auto mcp = m_particles.at(trackID);
0581 const auto& mom = hit->momentum;
0582 const auto& pos = hit->position;
0583 edm4hep::Vector3f();
0584 sth.setCellID( hit->cellID ) ;
0585 sth.setEDep(hit->energyDeposit/CLHEP::GeV);
0586 sth.setPathLength(hit->length/CLHEP::mm);
0587 sth.setTime(hit->truth.time/CLHEP::ns);
0588 #if EDM4HEP_BUILD_VERSION >= EDM4HEP_VERSION(0, 10, 99)
0589 sth.setParticle(mcp);
0590 #else
0591 sth.setMCParticle(mcp);
0592 #endif
0593 sth.setPosition( {pos.x()/CLHEP::mm, pos.y()/CLHEP::mm, pos.z()/CLHEP::mm} );
0594 sth.setMomentum( {float(mom.x()/CLHEP::GeV),float(mom.y()/CLHEP::GeV),float(mom.z()/CLHEP::GeV)} );
0595 auto particleIt = pm->particles().find(trackID);
0596 if( ( particleIt != pm->particles().end()) ){
0597
0598
0599
0600 sth.setProducedBySecondary( (particleIt->second->originalG4ID != t.trackID) );
0601 }
0602 }
0603
0604 }
0605 else if( typeid( Geant4Calorimeter::Hit ) == coll->type().type() ){
0606 Geant4Sensitive* sd = coll->sensitive();
0607 int hit_creation_mode = sd->hitCreationMode();
0608
0609 auto& hits = m_calorimeterHits[colName];
0610 for(unsigned i=0 ; i < nhits ; ++i){
0611 auto sch = hits.first->create();
0612 const Geant4Calorimeter::Hit* hit = coll->hit(i);
0613 const auto& pos = hit->position;
0614 sch.setCellID( hit->cellID );
0615 sch.setPosition({float(pos.x()/CLHEP::mm), float(pos.y()/CLHEP::mm), float(pos.z()/CLHEP::mm)});
0616 sch.setEnergy( hit->energyDeposit/CLHEP::GeV );
0617
0618
0619
0620 for(auto ci=hit->truth.begin(); ci != hit->truth.end(); ++ci){
0621
0622 auto sCaloHitCont = hits.second->create();
0623 sch.addToContributions( sCaloHitCont );
0624
0625 const Geant4HitData::Contribution& c = *ci;
0626 int trackID = pm->particleID(c.trackID);
0627 auto mcp = m_particles.at(trackID);
0628 sCaloHitCont.setEnergy( c.deposit/CLHEP::GeV );
0629 sCaloHitCont.setTime( c.time/CLHEP::ns );
0630 sCaloHitCont.setParticle( mcp );
0631
0632 if ( hit_creation_mode == Geant4Sensitive::DETAILED_MODE ) {
0633 edm4hep::Vector3f p(c.x/CLHEP::mm, c.y/CLHEP::mm, c.z/CLHEP::mm);
0634 sCaloHitCont.setPDG( c.pdgID );
0635 sCaloHitCont.setStepPosition( p );
0636 }
0637 }
0638 }
0639
0640 } else {
0641 error("+++ unknown type in Geant4HitCollection %s ", coll->type().type().name());
0642 }
0643 }