File indexing completed on 2026-09-08 08:23:11
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <DD4hep/Primitives.h>
0016 #include <DD4hep/Printout.h>
0017 #include "DigiIO.h"
0018
0019
0020
0021 #include <limits>
0022
0023
0024
0025
0026 #ifdef DD4HEP_USE_EDM4HEP
0027
0028
0029 #include <edm4hep/SimTrackerHit.h>
0030 #include <edm4hep/MCParticle.h>
0031 #include <edm4hep/MCParticleCollection.h>
0032 #if __has_include("edm4hep/TrackerHitCollection.h")
0033 #include <edm4hep/TrackerHitCollection.h>
0034 namespace edm4hep {
0035 using TrackerHit3DCollection = edm4hep::TrackerHitCollection;
0036 }
0037 #else
0038 #include <edm4hep/TrackerHit3DCollection.h>
0039 #endif
0040 #include <edm4hep/SimTrackerHitCollection.h>
0041 #include <edm4hep/CalorimeterHitCollection.h>
0042 #include <edm4hep/SimCalorimeterHitCollection.h>
0043 #include <edm4hep/EventHeaderCollection.h>
0044 #include <edm4hep/EDM4hepVersion.h>
0045 #include <podio/GenericParameters.h>
0046
0047
0048 namespace dd4hep {
0049
0050
0051 namespace digi {
0052
0053 struct bla {
0054 class my_part;
0055 typedef my_part particle_type;
0056 };
0057
0058 edm4hep::Vector3d _toVectorD(const Position& ep);
0059 edm4hep::Vector3f _toVectorF(const Position& ep);
0060
0061
0062
0063
0064
0065
0066
0067
0068 struct digi_input {
0069 typedef Particle particle_type;
0070 struct input_trackerhit_type {};
0071 struct input_calorimeterhit_type {};
0072 };
0073
0074
0075
0076
0077
0078
0079
0080
0081 struct edm4hep_input {
0082 typedef edm4hep::MutableMCParticle particle_type;
0083 struct input_trackerhit_type {};
0084 struct input_calorimeterhit_type {};
0085 };
0086
0087
0088
0089
0090
0091
0092
0093
0094 struct ddg4_input {
0095 typedef sim::Geant4Particle particle_type;
0096 struct input_trackerhit_type {};
0097 struct input_calorimeterhit_type {};
0098 };
0099
0100 template <typename T> struct data_input {
0101 using particle_t = typename T::particle_type;
0102 using trackerhit_t = typename T::input_trackerhit_type;
0103 using calorimeterhit_t = typename T::input_calorimeterhit_type;
0104 using pwrap_t = std::shared_ptr<particle_t>;
0105 using twrap_t = std::shared_ptr<trackerhit_t>;
0106 using cwrap_t = std::shared_ptr<calorimeterhit_t>;
0107 };
0108
0109 edm4hep::Vector3d _toVectorD(const dd4hep::Position& ep) {
0110 return { ep.x(), ep.y(), ep.z() };
0111 }
0112
0113 edm4hep::Vector3f _toVectorF(const dd4hep::Position& ep) {
0114 return { float(ep.x()), float(ep.y()), float(ep.z()) };
0115 }
0116
0117 template <typename POSITION> Position _toPosition(const POSITION& pos) {
0118 return { pos.x, pos.y, pos.z };
0119 }
0120
0121 namespace {
0122 template <typename DATA> bool internal_can_handle(const DATA&, const std::type_info&) {
0123 return true;
0124 }
0125 template <> bool internal_can_handle(const ParticleMapping::value_type& data, const std::type_info& info) {
0126 return (data.second.source.type() == info);
0127 }
0128 }
0129
0130 template <typename INPUT, typename DATA>
0131 static bool _can_handle(const INPUT& , const DATA& data) {
0132 return internal_can_handle(data, typeid(typename data_input<INPUT>::pwrap_t));
0133 }
0134
0135 template <typename CONT>
0136 void _pre_create(CONT* coll, std::size_t n) {
0137
0138 for ( std::size_t i=0; i<n; ++i ) {
0139 coll->create();
0140 }
0141 }
0142
0143 template <typename INPUT, typename CONT>
0144 std::vector<const typename INPUT::particle_t*> _to_vector(const INPUT&, const CONT& cont) {
0145 std::vector<const typename INPUT::particle_t*> vec;
0146 vec.reserve(cont.size());
0147 for ( const auto& part : cont ) {
0148 const auto& p = part.second;
0149 if ( p.source.type() == typeid(typename INPUT::pwrap_t) ) {
0150 const auto* ptr = std::any_cast<typename INPUT::pwrap_t>(&p.source);
0151 vec.emplace_back(ptr->get());
0152 }
0153 }
0154 if ( cont.size() != vec.size() ) {
0155 except("data_io","_to_vector: Containers of mixed origin are not supported!");
0156 }
0157 return vec;
0158 }
0159
0160 template <typename T> template <typename FIRST, typename SECOND>
0161 void data_io<T>::_to_edm4hep(const FIRST&, SECOND) {
0162 except("data_io::_to_edm4hep","(%s&, %s): Implementation not present!",
0163 typeName(typeid(FIRST)).c_str(), typeName(typeid(SECOND)).c_str());
0164 }
0165
0166
0167 template <> template <>
0168 void data_io<digi_input>::_to_edm4hep(const Particle& p,
0169 edm4hep::MutableMCParticle mcp) {
0170 mcp.setPDG(p.pdgID);
0171 mcp.setTime(p.time);
0172 mcp.setMass(p.mass);
0173 mcp.setCharge(3.0*p.charge);
0174 mcp.setVertex( _toVectorD(p.start_position) );
0175 mcp.setEndpoint( _toVectorD(p.end_position) );
0176 #if EDM4HEP_BUILD_VERSION < EDM4HEP_VERSION(0, 99, 0)
0177 mcp.setMomentum( _toVectorF(p.momentum) );
0178 mcp.setMomentumAtEndpoint( _toVectorF(p.momentum) );
0179 #else
0180 mcp.setMomentum( _toVectorD(p.momentum) );
0181 mcp.setMomentumAtEndpoint( _toVectorD(p.momentum) );
0182 #endif
0183 }
0184
0185 template <> template <>
0186 void data_io<digi_input>::_to_edm4hep(const std::vector<const Particle*>& cont,
0187 edm4hep::MCParticleCollection* coll) {
0188 std::size_t i, n = cont.size();
0189 _pre_create(coll, n);
0190
0191 for ( i=0; i<n; ++i) {
0192 _to_edm4hep(*cont[i], coll->at(i));
0193 }
0194 }
0195
0196
0197 template <> template <>
0198 void data_io<edm4hep_input>::_to_edm4hep(const edm4hep::MCParticle& p,
0199 edm4hep::MutableMCParticle mcp)
0200 {
0201 mcp.setPDG( p.getPDG() );
0202 mcp.setMomentum( p.getMomentum() );
0203 mcp.setMomentumAtEndpoint( p.getMomentumAtEndpoint() );
0204 mcp.setVertex( p.getVertex() );
0205 mcp.setEndpoint( p.getEndpoint() );
0206 mcp.setTime( p.getTime() );
0207 mcp.setMass( p.getMass() );
0208 mcp.setCharge( p.getCharge() );
0209 mcp.setGeneratorStatus( p.getGeneratorStatus() );
0210 mcp.setSimulatorStatus( p.getSimulatorStatus() );
0211 #ifdef EDM4HEP_MCPARTICLE_HAS_HELICITY
0212 mcp.setHelicity(p.getHelicity());
0213 #else
0214 mcp.setSpin(p.getSpin());
0215 #endif
0216 }
0217
0218 template <> template <>
0219 void data_io<edm4hep_input>::_to_edm4hep(const std::vector<const edm4hep::MCParticle*>& cont,
0220 edm4hep::MCParticleCollection* coll)
0221 {
0222 std::size_t i, n = cont.size();
0223 _pre_create(coll, n);
0224
0225 for ( i=0; i<n; ++i) {
0226 const auto* p = cont[i];
0227 auto mcp = coll->at(i);
0228 _to_edm4hep(*p, mcp);
0229 #if 0
0230
0231 for (std::size_t idau = 0; idau < p->daughters_size(); ++idau) {
0232 mcp.addToDaughters(coll->at(idau));
0233 }
0234 for (auto ipar : p->parents) {
0235 mcp.addToParents(coll->at(ipar));
0236 }
0237 #endif
0238 }
0239 }
0240
0241 template <> template <>
0242 void data_io<edm4hep_input>::_to_edm4hep(const std::pair<const CellID, EnergyDeposit>& dep,
0243 const std::array<float, 6>& covMat,
0244 edm4hep::TrackerHit3DCollection& collection,
0245 int hit_type)
0246
0247 {
0248 const EnergyDeposit& de = dep.second;
0249 auto hit = collection.create();
0250 double dep_error = de.depositError;
0251 if ( dep_error < -std::numeric_limits<double>::epsilon() ) {
0252 dep_error = 0e0;
0253 }
0254 hit.setType( hit_type );
0255 hit.setTime( de.time );
0256 hit.setCovMatrix( covMat );
0257 hit.setCellID( dep.first );
0258 hit.setEDep( de.deposit );
0259 hit.setEDepError( dep_error );
0260
0261 hit.setPosition( _toVectorD(de.position) );
0262 }
0263
0264 template <> template <>
0265 void data_io<edm4hep_input>::_to_edm4hep(const std::pair<const CellID, EnergyDeposit>& dep,
0266 edm4hep::CalorimeterHitCollection& collection,
0267 int hit_type)
0268 {
0269 const EnergyDeposit& de = dep.second;
0270 auto hit = collection.create();
0271 double dep_error = de.depositError;
0272 if ( dep_error < -std::numeric_limits<double>::epsilon() ) {
0273 dep_error = 0e0;
0274 }
0275 hit.setType( hit_type );
0276 hit.setTime( de.time );
0277 hit.setCellID( dep.first );
0278 hit.setEnergy( de.deposit );
0279 hit.setEnergyError( dep_error );
0280 hit.setPosition( _toVectorF(de.position) );
0281 }
0282
0283 template <> template <>
0284 void data_io<edm4hep_input>::_to_digi(Key key,
0285 const edm4hep::MCParticleCollection& input,
0286 ParticleMapping& particles)
0287 {
0288 Key mkey = key;
0289 for( std::size_t i=0, n=input.size(); i<n; ++i ) {
0290 Particle part {};
0291 edm4hep::MCParticle p = input.at(i);
0292 part.start_position = _toPosition(p.getVertex());
0293 part.end_position = _toPosition(p.getEndpoint());
0294 part.momentum = _toPosition(p.getMomentum());
0295 part.pdgID = p.getPDG();
0296 part.charge = 3.0*p.getCharge();
0297 part.mass = p.getMass();
0298 part.time = p.getTime();
0299 mkey.set_item(particles.size());
0300 part.source = std::make_any<edm4hep::MCParticle>(std::move(p));
0301 particles.push(mkey, std::move(part));
0302 }
0303 }
0304
0305 template <> template <>
0306 bool DepositPredicate<EnergyCut>::operator()(edm4hep::SimTrackerHit h) const {
0307 return h.getEDep() > data.cutoff;
0308 }
0309
0310 template <> template <>
0311 void data_io<edm4hep_input>::_to_digi_if(const edm4hep::SimTrackerHitCollection& input,
0312 std::map<CellID, edm4hep::SimTrackerHit>& hits,
0313 const DepositPredicate<EnergyCut>& predicate) {
0314 for( std::size_t i=0, n=input.size(); i<n; ++i ) {
0315 auto p = input.at(i);
0316 if ( predicate(p) ) {
0317 CellID cell = p.getCellID();
0318 hits.emplace(cell, std::move(p));
0319 }
0320 }
0321 }
0322
0323
0324 template <> template <>
0325 void data_io<edm4hep_input>::_to_digi(Key key,
0326 const std::map<CellID, edm4hep::SimTrackerHit>& hits,
0327 DepositVector& out) {
0328 out.data_type = SegmentEntry::CALORIMETER_HITS;
0329 for( const auto& depo : hits ) {
0330 Key history_key;
0331 EnergyDeposit dep { };
0332 const auto& h = depo.second;
0333 dep.flag = h.getQuality();
0334 dep.time = h.getTime();
0335 dep.length = h.getPathLength();
0336 dep.deposit = h.getEDep();
0337 dep.position = _toPosition(h.getPosition());
0338 dep.momentum = _toPosition(h.getMomentum());
0339 history_key.set_mask(key.mask());
0340 history_key.set_item(out.size());
0341 history_key.set_segment(key.segment());
0342 dep.history.hits.emplace_back(history_key, dep.deposit);
0343
0344 out.emplace(depo.first, std::move(dep));
0345 }
0346 }
0347
0348
0349 template <> template <>
0350 void data_io<edm4hep_input>::_to_digi(Key ,
0351 const edm4hep::EventHeaderCollection& headers,
0352 dd4hep::digi::DataParameters& params) {
0353 for( unsigned int i=0, n=headers.size(); i < n; ++i) {
0354 const auto& hdr = headers[i];
0355 params.setRunNumber(hdr.getRunNumber());
0356 params.setEventNumber(hdr.getEventNumber());
0357 params.setTimeStamp(hdr.getTimeStamp());
0358 params.setWeight(hdr.getWeight());
0359 break;
0360 }
0361 }
0362
0363
0364 template <> template <>
0365 void data_io<edm4hep_input>::_to_digi(Key ,
0366 const podio::GenericParameters& inputparams,
0367 dd4hep::digi::DataParameters& parameters) {
0368
0369 parameters.data->stringParams = inputparams.getMap<std::string>();
0370 parameters.data->floatParams = inputparams.getMap<float>();
0371 parameters.data->intParams = inputparams.getMap<int>();
0372 }
0373
0374 template <> template <>
0375 bool DepositPredicate<EnergyCut>::operator()(edm4hep::SimCalorimeterHit h) const {
0376 return h.getEnergy() > data.cutoff;
0377 }
0378
0379 template <> template <>
0380 void data_io<edm4hep_input>::_to_digi_if(const edm4hep::SimCalorimeterHitCollection& input,
0381 std::map<CellID, edm4hep::SimCalorimeterHit>& hits,
0382 const DepositPredicate<EnergyCut>& predicate) {
0383 for( std::size_t i=0, n=input.size(); i<n; ++i ) {
0384 auto p = input.at(i);
0385 if ( predicate(p) ) {
0386 CellID cell = p.getCellID();
0387 hits.emplace(cell, std::move(p));
0388 }
0389 }
0390 }
0391
0392 template <> template <>
0393 void data_io<edm4hep_input>::_to_digi(Key key,
0394 const std::map<CellID, edm4hep::SimCalorimeterHit>& hits,
0395 DepositVector& out) {
0396 out.data_type = SegmentEntry::CALORIMETER_HITS;
0397 for( const auto& depo : hits ) {
0398 Key history_key;
0399 EnergyDeposit dep { };
0400 const auto& h = depo.second;
0401 dep.flag = 0;
0402
0403 dep.deposit = h.getEnergy();
0404 dep.position = _toPosition(h.getPosition());
0405 history_key.set_mask(key.mask());
0406 history_key.set_item(out.size());
0407 history_key.set_segment(key.segment());
0408 dep.history.hits.emplace_back(history_key, dep.deposit);
0409
0410 out.emplace(depo.first, std::move(dep));
0411 }
0412 }
0413
0414 }
0415 }
0416 #endif
0417
0418
0419
0420
0421 #if defined(DD4HEP_USE_DDG4)
0422
0423 #include <DDG4/Geant4Data.h>
0424 #include <DDG4/Geant4Particle.h>
0425
0426
0427 namespace dd4hep {
0428
0429
0430 namespace digi {
0431
0432 using PropertyMask = dd4hep::detail::ReferenceBitMask<int>;
0433
0434 template <> template <>
0435 bool DepositPredicate<EnergyCut>::operator()(sim::Geant4Tracker::Hit* h) const {
0436 return h->energyDeposit > data.cutoff;
0437 }
0438
0439 template <> template <>
0440 bool DepositPredicate<EnergyCut>::operator()(sim::Geant4Calorimeter::Hit* h) const {
0441 return h->energyDeposit > data.cutoff;
0442 }
0443
0444 void add_particle_history(const sim::Geant4Calorimeter::Hit* hit, Key key, History& hist) {
0445 for( const auto& truth : hit->truth ) {
0446 key.set_item(truth.trackID);
0447 hist.particles.emplace_back(key, truth.deposit);
0448 }
0449 }
0450
0451 void add_particle_history(const sim::Geant4Tracker::Hit* hit, Key key, History& hist) {
0452 key.set_item(hit->truth.trackID);
0453 hist.particles.emplace_back(key, hit->truth.deposit);
0454 }
0455
0456 template <> template <>
0457 void data_io<ddg4_input>::_to_digi_if(const std::vector<sim::Geant4Tracker::Hit*>& data,
0458 std::map<CellID, std::shared_ptr<sim::Geant4Tracker::Hit> >& hits,
0459 const DepositPredicate<EnergyCut>& predicate) {
0460 for( auto* p : data ) {
0461 std::shared_ptr<sim::Geant4Tracker::Hit> ptr(p);
0462 if ( predicate(p) ) {
0463 CellID cell = ptr->cellID;
0464 hits.emplace(cell, std::move(ptr));
0465 }
0466 }
0467 }
0468
0469 template <> template <>
0470 void data_io<ddg4_input>::_to_digi_if(const std::vector<sim::Geant4Calorimeter::Hit*>& data,
0471 std::map<CellID, std::shared_ptr<sim::Geant4Calorimeter::Hit> >& hits,
0472 const DepositPredicate<EnergyCut>& predicate) {
0473 for( auto* p : data ) {
0474 std::shared_ptr<sim::Geant4Calorimeter::Hit> ptr(p);
0475 if ( predicate(p) ) {
0476 CellID cell = ptr->cellID;
0477 hits.emplace(cell, std::move(ptr));
0478 }
0479 }
0480 }
0481
0482 template <> template <>
0483 void data_io<ddg4_input>::_to_digi(Key key,
0484 const std::vector<sim::Geant4Particle*>& input,
0485 ParticleMapping& particles)
0486 {
0487 Key mkey = std::move(key);
0488 for( auto* part_ptr : input ) {
0489 std::shared_ptr<sim::Geant4Particle> p(part_ptr);
0490 Particle part;
0491 part.start_position = Position(p->vsx, p->vsy, p->vsz);
0492 part.end_position = Position(p->vex, p->vey, p->vez);
0493 part.momentum = Direction(p->psx,p->psy, p->psz);
0494 part.pdgID = p->pdgID;
0495 part.charge = p->charge;
0496 part.mass = p->mass;
0497 part.time = p->time;
0498 mkey.set_item(particles.size());
0499 part.source = std::make_any<std::shared_ptr<sim::Geant4Particle> >(std::move(p));
0500 particles.push(mkey, std::move(part));
0501 }
0502 }
0503
0504 template <typename T>
0505 static void ddg4_cnv_to_digi(Key key,
0506 const std::pair<const CellID, std::shared_ptr<T> >& depo,
0507 DepositVector& out) {
0508 Key history_key;
0509 EnergyDeposit dep { };
0510 const auto* h = depo.second.get();
0511
0512 dep.flag = h->flag;
0513 dep.deposit = h->energyDeposit;
0514 dep.position = (h->position / dd4hep::mm);
0515
0516 history_key.set_mask(key.mask());
0517 history_key.set_item(out.size());
0518 history_key.set_segment(key.segment());
0519 dep.history.hits.emplace_back(history_key, dep.deposit);
0520 add_particle_history(h, std::move(history_key), dep.history);
0521 out.emplace(depo.first, std::move(dep));
0522 }
0523
0524 template <> template <>
0525 void data_io<ddg4_input>::_to_digi(Key key,
0526 const std::map<CellID, std::shared_ptr<sim::Geant4Calorimeter::Hit> >& hits,
0527 DepositVector& out) {
0528 out.data_type = SegmentEntry::CALORIMETER_HITS;
0529 for( const auto& p : hits )
0530 ddg4_cnv_to_digi(key, p, out);
0531 }
0532
0533 template <> template <>
0534 void data_io<ddg4_input>::_to_digi(Key key,
0535 const std::map<CellID, std::shared_ptr<sim::Geant4Tracker::Hit> >& hits,
0536 DepositVector& out) {
0537 out.data_type = SegmentEntry::TRACKER_HITS;
0538 for( const auto& p : hits )
0539 ddg4_cnv_to_digi(key, p, out);
0540 }
0541 }
0542 }
0543 #endif
0544
0545
0546
0547
0548 #if defined(DD4HEP_USE_DDG4) && defined(DD4HEP_USE_EDM4HEP)
0549
0550
0551 namespace dd4hep {
0552
0553
0554 namespace digi {
0555
0556
0557 template <> template <>
0558 void data_io<ddg4_input>::_to_edm4hep(const sim::Geant4Particle& p,
0559 edm4hep::MutableMCParticle mcp)
0560 {
0561 auto status = p.status;
0562 const PropertyMask mask(status);
0563 mcp.setPDG(p.pdgID);
0564
0565 #if EDM4HEP_BUILD_VERSION < EDM4HEP_VERSION(0, 99, 0)
0566 mcp.setMomentum( _toVectorF( { p.psx, p.psy, p.psz } ) );
0567 mcp.setMomentumAtEndpoint( _toVectorF( {p.pex, p.pey, p.pez} ) );
0568 #else
0569 mcp.setMomentum( _toVectorD( { p.psx, p.psy, p.psz } ) );
0570 mcp.setMomentumAtEndpoint( _toVectorD( {p.pex, p.pey, p.pez} ) );
0571 #endif
0572 mcp.setVertex( _toVectorD( { p.vsx, p.vsy, p.vsz } ) );
0573 mcp.setEndpoint( _toVectorD( { p.vex, p.vey, p.vez } ) );
0574
0575 mcp.setTime(p.time);
0576 mcp.setMass(p.mass);
0577 mcp.setCharge(3.0*float(p.charge));
0578
0579
0580 mcp.setGeneratorStatus(0);
0581 if( p.genStatus ) {
0582 mcp.setGeneratorStatus( p.genStatus ) ;
0583 } else {
0584 if ( mask.isSet(sim::G4PARTICLE_GEN_STABLE) ) mcp.setGeneratorStatus(1);
0585 else if ( mask.isSet(sim::G4PARTICLE_GEN_DECAYED) ) mcp.setGeneratorStatus(2);
0586 else if ( mask.isSet(sim::G4PARTICLE_GEN_DOCUMENTATION) ) mcp.setGeneratorStatus(3);
0587 else if ( mask.isSet(sim::G4PARTICLE_GEN_BEAM) ) mcp.setGeneratorStatus(4);
0588 else if ( mask.isSet(sim::G4PARTICLE_GEN_OTHER) ) mcp.setGeneratorStatus(9);
0589 }
0590
0591
0592 mcp.setCreatedInSimulation( mask.isSet(sim::G4PARTICLE_SIM_CREATED) );
0593 mcp.setBackscatter( mask.isSet(sim::G4PARTICLE_SIM_BACKSCATTER) );
0594 mcp.setVertexIsNotEndpointOfParent( mask.isSet(sim::G4PARTICLE_SIM_PARENT_RADIATED) );
0595 mcp.setDecayedInTracker( mask.isSet(sim::G4PARTICLE_SIM_DECAY_TRACKER) );
0596 mcp.setDecayedInCalorimeter( mask.isSet(sim::G4PARTICLE_SIM_DECAY_CALO) );
0597 mcp.setHasLeftDetector( mask.isSet(sim::G4PARTICLE_SIM_LEFT_DETECTOR) );
0598 mcp.setStopped( mask.isSet(sim::G4PARTICLE_SIM_STOPPED) );
0599 mcp.setOverlay( false );
0600
0601
0602 if( mcp.isCreatedInSimulation() )
0603 mcp.setGeneratorStatus( 0 );
0604
0605 #ifdef EDM4HEP_MCPARTICLE_HAS_HELICITY
0606 mcp.setHelicity(p.spin[2]);
0607 #else
0608 mcp.setSpin(p.spin);
0609 #endif
0610 }
0611
0612 template <> template <>
0613 void data_io<ddg4_input>::_to_edm4hep(const std::vector<const sim::Geant4Particle*>& cont,
0614 edm4hep::MCParticleCollection* coll)
0615 {
0616
0617 std::size_t i, n = cont.size();
0618 _pre_create(coll, n);
0619
0620 for ( i=0; i<n; ++i) {
0621 const auto* p = cont[i];
0622 auto mcp = coll->at(i);
0623 _to_edm4hep(*p, mcp);
0624
0625 for (auto idau : p->daughters)
0626 mcp.addToDaughters(coll->at(idau));
0627 for (auto ipar : p->parents)
0628 mcp.addToParents(coll->at(ipar));
0629 }
0630 }
0631 }
0632 }
0633 #endif
0634
0635
0636
0637
0638 #ifdef DD4HEP_USE_EDM4HEP
0639
0640 namespace dd4hep {
0641
0642
0643 namespace digi {
0644
0645 template <> template <>
0646 void data_io<edm4hep_input>::_to_edm4hep(const ParticleMapping& cont,
0647 edm4hep::MCParticleCollection* coll)
0648 {
0649 if ( cont.empty() ) {
0650 return;
0651 }
0652 else if ( _can_handle(edm4hep_input(), *cont.begin()) ) {
0653 auto vec = _to_vector(data_input<edm4hep_input>(), cont);
0654 if ( !vec.empty() ) {
0655 data_io<edm4hep_input>::_to_edm4hep(vec, coll);
0656 }
0657 }
0658 else if ( _can_handle(ddg4_input(), *cont.begin()) ) {
0659 auto vec = _to_vector(data_input<ddg4_input>(), cont);
0660 if ( !vec.empty() ) {
0661 data_io<ddg4_input>::_to_edm4hep(vec, coll);
0662 }
0663 }
0664 else {
0665
0666 auto vec = _to_vector(data_input<digi_input>(), cont);
0667 if ( !vec.empty() ) {
0668 data_io<digi_input>::_to_edm4hep(vec, coll);
0669 }
0670 }
0671 }
0672 }
0673 }
0674 #endif