File indexing completed on 2025-07-01 07:55: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 mcp.setSpin(p.getSpin());
0212 }
0213
0214 template <> template <>
0215 void data_io<edm4hep_input>::_to_edm4hep(const std::vector<const edm4hep::MCParticle*>& cont,
0216 edm4hep::MCParticleCollection* coll)
0217 {
0218 std::size_t i, n = cont.size();
0219 _pre_create(coll, n);
0220
0221 for ( i=0; i<n; ++i) {
0222 const auto* p = cont[i];
0223 auto mcp = coll->at(i);
0224 _to_edm4hep(*p, mcp);
0225 #if 0
0226
0227 for (std::size_t idau = 0; idau < p->daughters_size(); ++idau) {
0228 mcp.addToDaughters(coll->at(idau));
0229 }
0230 for (auto ipar : p->parents) {
0231 mcp.addToParents(coll->at(ipar));
0232 }
0233 #endif
0234 }
0235 }
0236
0237 template <> template <>
0238 void data_io<edm4hep_input>::_to_edm4hep(const std::pair<const CellID, EnergyDeposit>& dep,
0239 const std::array<float, 6>& covMat,
0240 edm4hep::TrackerHit3DCollection& collection,
0241 int hit_type)
0242
0243 {
0244 const EnergyDeposit& de = dep.second;
0245 auto hit = collection.create();
0246 double dep_error = de.depositError;
0247 if ( dep_error < -std::numeric_limits<double>::epsilon() ) {
0248 dep_error = 0e0;
0249 }
0250 hit.setType( hit_type );
0251 hit.setTime( de.time );
0252 hit.setCovMatrix( covMat );
0253 hit.setCellID( dep.first );
0254 hit.setEDep( de.deposit );
0255 hit.setEDepError( dep_error );
0256
0257 hit.setPosition( _toVectorD(de.position) );
0258 }
0259
0260 template <> template <>
0261 void data_io<edm4hep_input>::_to_edm4hep(const std::pair<const CellID, EnergyDeposit>& dep,
0262 edm4hep::CalorimeterHitCollection& collection,
0263 int hit_type)
0264 {
0265 const EnergyDeposit& de = dep.second;
0266 auto hit = collection.create();
0267 double dep_error = de.depositError;
0268 if ( dep_error < -std::numeric_limits<double>::epsilon() ) {
0269 dep_error = 0e0;
0270 }
0271 hit.setType( hit_type );
0272 hit.setTime( de.time );
0273 hit.setCellID( dep.first );
0274 hit.setEnergy( de.deposit );
0275 hit.setEnergyError( dep_error );
0276 hit.setPosition( _toVectorF(de.position) );
0277 }
0278
0279 template <> template <>
0280 void data_io<edm4hep_input>::_to_digi(Key key,
0281 const edm4hep::MCParticleCollection& input,
0282 ParticleMapping& particles)
0283 {
0284 Key mkey = key;
0285 for( std::size_t i=0, n=input.size(); i<n; ++i ) {
0286 Particle part {};
0287 edm4hep::MCParticle p = input.at(i);
0288 part.start_position = _toPosition(p.getVertex());
0289 part.end_position = _toPosition(p.getEndpoint());
0290 part.momentum = _toPosition(p.getMomentum());
0291 part.pdgID = p.getPDG();
0292 part.charge = 3.0*p.getCharge();
0293 part.mass = p.getMass();
0294 part.time = p.getTime();
0295 mkey.set_item(particles.size());
0296 part.source = std::make_any<edm4hep::MCParticle>(std::move(p));
0297 particles.push(mkey, std::move(part));
0298 }
0299 }
0300
0301 template <> template <>
0302 bool DepositPredicate<EnergyCut>::operator()(edm4hep::SimTrackerHit h) const {
0303 return h.getEDep() > data.cutoff;
0304 }
0305
0306 template <> template <>
0307 void data_io<edm4hep_input>::_to_digi_if(const edm4hep::SimTrackerHitCollection& input,
0308 std::map<CellID, edm4hep::SimTrackerHit>& hits,
0309 const DepositPredicate<EnergyCut>& predicate) {
0310 for( std::size_t i=0, n=input.size(); i<n; ++i ) {
0311 auto p = input.at(i);
0312 if ( predicate(p) ) {
0313 CellID cell = p.getCellID();
0314 hits.emplace(cell, std::move(p));
0315 }
0316 }
0317 }
0318
0319
0320 template <> template <>
0321 void data_io<edm4hep_input>::_to_digi(Key key,
0322 const std::map<CellID, edm4hep::SimTrackerHit>& hits,
0323 DepositVector& out) {
0324 out.data_type = SegmentEntry::CALORIMETER_HITS;
0325 for( const auto& depo : hits ) {
0326 Key history_key;
0327 EnergyDeposit dep { };
0328 const auto& h = depo.second;
0329 dep.flag = h.getQuality();
0330 dep.time = h.getTime();
0331 dep.length = h.getPathLength();
0332 dep.deposit = h.getEDep();
0333 dep.position = _toPosition(h.getPosition());
0334 dep.momentum = _toPosition(h.getMomentum());
0335 history_key.set_mask(key.mask());
0336 history_key.set_item(out.size());
0337 history_key.set_segment(key.segment());
0338 dep.history.hits.emplace_back(history_key, dep.deposit);
0339
0340 out.emplace(depo.first, std::move(dep));
0341 }
0342 }
0343
0344
0345 template <> template <>
0346 void data_io<edm4hep_input>::_to_digi(Key ,
0347 const edm4hep::EventHeaderCollection& headers,
0348 dd4hep::digi::DataParameters& params) {
0349 for( unsigned int i=0, n=headers.size(); i < n; ++i) {
0350 const auto& hdr = headers[i];
0351 params.setRunNumber(hdr.getRunNumber());
0352 params.setEventNumber(hdr.getEventNumber());
0353 params.setTimeStamp(hdr.getTimeStamp());
0354 params.setWeight(hdr.getWeight());
0355 break;
0356 }
0357 }
0358
0359
0360 template <> template <>
0361 void data_io<edm4hep_input>::_to_digi(Key ,
0362 const podio::GenericParameters& inputparams,
0363 dd4hep::digi::DataParameters& parameters) {
0364
0365 parameters.data->stringParams = inputparams.getMap<std::string>();
0366 parameters.data->floatParams = inputparams.getMap<float>();
0367 parameters.data->intParams = inputparams.getMap<int>();
0368 }
0369
0370 template <> template <>
0371 bool DepositPredicate<EnergyCut>::operator()(edm4hep::SimCalorimeterHit h) const {
0372 return h.getEnergy() > data.cutoff;
0373 }
0374
0375 template <> template <>
0376 void data_io<edm4hep_input>::_to_digi_if(const edm4hep::SimCalorimeterHitCollection& input,
0377 std::map<CellID, edm4hep::SimCalorimeterHit>& hits,
0378 const DepositPredicate<EnergyCut>& predicate) {
0379 for( std::size_t i=0, n=input.size(); i<n; ++i ) {
0380 auto p = input.at(i);
0381 if ( predicate(p) ) {
0382 CellID cell = p.getCellID();
0383 hits.emplace(cell, std::move(p));
0384 }
0385 }
0386 }
0387
0388 template <> template <>
0389 void data_io<edm4hep_input>::_to_digi(Key key,
0390 const std::map<CellID, edm4hep::SimCalorimeterHit>& hits,
0391 DepositVector& out) {
0392 out.data_type = SegmentEntry::CALORIMETER_HITS;
0393 for( const auto& depo : hits ) {
0394 Key history_key;
0395 EnergyDeposit dep { };
0396 const auto& h = depo.second;
0397 dep.flag = 0;
0398
0399 dep.deposit = h.getEnergy();
0400 dep.position = _toPosition(h.getPosition());
0401 history_key.set_mask(key.mask());
0402 history_key.set_item(out.size());
0403 history_key.set_segment(key.segment());
0404 dep.history.hits.emplace_back(history_key, dep.deposit);
0405
0406 out.emplace(depo.first, std::move(dep));
0407 }
0408 }
0409
0410 }
0411 }
0412 #endif
0413
0414
0415
0416
0417 #if defined(DD4HEP_USE_DDG4)
0418
0419 #include <DDG4/Geant4Data.h>
0420 #include <DDG4/Geant4Particle.h>
0421
0422
0423 namespace dd4hep {
0424
0425
0426 namespace digi {
0427
0428 using PropertyMask = dd4hep::detail::ReferenceBitMask<int>;
0429
0430 template <> template <>
0431 bool DepositPredicate<EnergyCut>::operator()(sim::Geant4Tracker::Hit* h) const {
0432 return h->energyDeposit > data.cutoff;
0433 }
0434
0435 template <> template <>
0436 bool DepositPredicate<EnergyCut>::operator()(sim::Geant4Calorimeter::Hit* h) const {
0437 return h->energyDeposit > data.cutoff;
0438 }
0439
0440 void add_particle_history(const sim::Geant4Calorimeter::Hit* hit, Key key, History& hist) {
0441 for( const auto& truth : hit->truth ) {
0442 key.set_item(truth.trackID);
0443 hist.particles.emplace_back(key, truth.deposit);
0444 }
0445 }
0446
0447 void add_particle_history(const sim::Geant4Tracker::Hit* hit, Key key, History& hist) {
0448 key.set_item(hit->truth.trackID);
0449 hist.particles.emplace_back(key, hit->truth.deposit);
0450 }
0451
0452 template <> template <>
0453 void data_io<ddg4_input>::_to_digi_if(const std::vector<sim::Geant4Tracker::Hit*>& data,
0454 std::map<CellID, std::shared_ptr<sim::Geant4Tracker::Hit> >& hits,
0455 const DepositPredicate<EnergyCut>& predicate) {
0456 for( auto* p : data ) {
0457 std::shared_ptr<sim::Geant4Tracker::Hit> ptr(p);
0458 if ( predicate(p) ) {
0459 CellID cell = ptr->cellID;
0460 hits.emplace(cell, std::move(ptr));
0461 }
0462 }
0463 }
0464
0465 template <> template <>
0466 void data_io<ddg4_input>::_to_digi_if(const std::vector<sim::Geant4Calorimeter::Hit*>& data,
0467 std::map<CellID, std::shared_ptr<sim::Geant4Calorimeter::Hit> >& hits,
0468 const DepositPredicate<EnergyCut>& predicate) {
0469 for( auto* p : data ) {
0470 std::shared_ptr<sim::Geant4Calorimeter::Hit> ptr(p);
0471 if ( predicate(p) ) {
0472 CellID cell = ptr->cellID;
0473 hits.emplace(cell, std::move(ptr));
0474 }
0475 }
0476 }
0477
0478 template <> template <>
0479 void data_io<ddg4_input>::_to_digi(Key key,
0480 const std::vector<sim::Geant4Particle*>& input,
0481 ParticleMapping& particles)
0482 {
0483 Key mkey = std::move(key);
0484 for( auto* part_ptr : input ) {
0485 std::shared_ptr<sim::Geant4Particle> p(part_ptr);
0486 Particle part;
0487 part.start_position = Position(p->vsx, p->vsy, p->vsz);
0488 part.end_position = Position(p->vex, p->vey, p->vez);
0489 part.momentum = Direction(p->psx,p->psy, p->psz);
0490 part.pdgID = p->pdgID;
0491 part.charge = p->charge;
0492 part.mass = p->mass;
0493 part.time = p->time;
0494 mkey.set_item(particles.size());
0495 part.source = std::make_any<std::shared_ptr<sim::Geant4Particle> >(std::move(p));
0496 particles.push(mkey, std::move(part));
0497 }
0498 }
0499
0500 template <typename T>
0501 static void ddg4_cnv_to_digi(Key key,
0502 const std::pair<const CellID, std::shared_ptr<T> >& depo,
0503 DepositVector& out) {
0504 Key history_key;
0505 EnergyDeposit dep { };
0506 const auto* h = depo.second.get();
0507
0508 dep.flag = h->flag;
0509 dep.deposit = h->energyDeposit;
0510 dep.position = (h->position / dd4hep::mm);
0511
0512 history_key.set_mask(key.mask());
0513 history_key.set_item(out.size());
0514 history_key.set_segment(key.segment());
0515 dep.history.hits.emplace_back(history_key, dep.deposit);
0516 add_particle_history(h, std::move(history_key), dep.history);
0517 out.emplace(depo.first, std::move(dep));
0518 }
0519
0520 template <> template <>
0521 void data_io<ddg4_input>::_to_digi(Key key,
0522 const std::map<CellID, std::shared_ptr<sim::Geant4Calorimeter::Hit> >& hits,
0523 DepositVector& out) {
0524 out.data_type = SegmentEntry::CALORIMETER_HITS;
0525 for( const auto& p : hits )
0526 ddg4_cnv_to_digi(key, p, out);
0527 }
0528
0529 template <> template <>
0530 void data_io<ddg4_input>::_to_digi(Key key,
0531 const std::map<CellID, std::shared_ptr<sim::Geant4Tracker::Hit> >& hits,
0532 DepositVector& out) {
0533 out.data_type = SegmentEntry::TRACKER_HITS;
0534 for( const auto& p : hits )
0535 ddg4_cnv_to_digi(key, p, out);
0536 }
0537 }
0538 }
0539 #endif
0540
0541
0542
0543
0544 #if defined(DD4HEP_USE_DDG4) && defined(DD4HEP_USE_EDM4HEP)
0545
0546
0547 namespace dd4hep {
0548
0549
0550 namespace digi {
0551
0552
0553 template <> template <>
0554 void data_io<ddg4_input>::_to_edm4hep(const sim::Geant4Particle& p,
0555 edm4hep::MutableMCParticle mcp)
0556 {
0557 auto status = p.status;
0558 const PropertyMask mask(status);
0559 mcp.setPDG(p.pdgID);
0560
0561 #if EDM4HEP_BUILD_VERSION < EDM4HEP_VERSION(0, 99, 0)
0562 mcp.setMomentum( _toVectorF( { p.psx, p.psy, p.psz } ) );
0563 mcp.setMomentumAtEndpoint( _toVectorF( {p.pex, p.pey, p.pez} ) );
0564 #else
0565 mcp.setMomentum( _toVectorD( { p.psx, p.psy, p.psz } ) );
0566 mcp.setMomentumAtEndpoint( _toVectorD( {p.pex, p.pey, p.pez} ) );
0567 #endif
0568 mcp.setVertex( _toVectorD( { p.vsx, p.vsy, p.vsz } ) );
0569 mcp.setEndpoint( _toVectorD( { p.vex, p.vey, p.vez } ) );
0570
0571 mcp.setTime(p.time);
0572 mcp.setMass(p.mass);
0573 mcp.setCharge(3.0*float(p.charge));
0574
0575
0576 mcp.setGeneratorStatus(0);
0577 if( p.genStatus ) {
0578 mcp.setGeneratorStatus( p.genStatus ) ;
0579 } else {
0580 if ( mask.isSet(sim::G4PARTICLE_GEN_STABLE) ) mcp.setGeneratorStatus(1);
0581 else if ( mask.isSet(sim::G4PARTICLE_GEN_DECAYED) ) mcp.setGeneratorStatus(2);
0582 else if ( mask.isSet(sim::G4PARTICLE_GEN_DOCUMENTATION) ) mcp.setGeneratorStatus(3);
0583 else if ( mask.isSet(sim::G4PARTICLE_GEN_BEAM) ) mcp.setGeneratorStatus(4);
0584 else if ( mask.isSet(sim::G4PARTICLE_GEN_OTHER) ) mcp.setGeneratorStatus(9);
0585 }
0586
0587
0588 mcp.setCreatedInSimulation( mask.isSet(sim::G4PARTICLE_SIM_CREATED) );
0589 mcp.setBackscatter( mask.isSet(sim::G4PARTICLE_SIM_BACKSCATTER) );
0590 mcp.setVertexIsNotEndpointOfParent( mask.isSet(sim::G4PARTICLE_SIM_PARENT_RADIATED) );
0591 mcp.setDecayedInTracker( mask.isSet(sim::G4PARTICLE_SIM_DECAY_TRACKER) );
0592 mcp.setDecayedInCalorimeter( mask.isSet(sim::G4PARTICLE_SIM_DECAY_CALO) );
0593 mcp.setHasLeftDetector( mask.isSet(sim::G4PARTICLE_SIM_LEFT_DETECTOR) );
0594 mcp.setStopped( mask.isSet(sim::G4PARTICLE_SIM_STOPPED) );
0595 mcp.setOverlay( false );
0596
0597
0598 if( mcp.isCreatedInSimulation() )
0599 mcp.setGeneratorStatus( 0 );
0600
0601 mcp.setSpin(p.spin);
0602 }
0603
0604 template <> template <>
0605 void data_io<ddg4_input>::_to_edm4hep(const std::vector<const sim::Geant4Particle*>& cont,
0606 edm4hep::MCParticleCollection* coll)
0607 {
0608
0609 std::size_t i, n = cont.size();
0610 _pre_create(coll, n);
0611
0612 for ( i=0; i<n; ++i) {
0613 const auto* p = cont[i];
0614 auto mcp = coll->at(i);
0615 _to_edm4hep(*p, mcp);
0616
0617 for (auto idau : p->daughters)
0618 mcp.addToDaughters(coll->at(idau));
0619 for (auto ipar : p->parents)
0620 mcp.addToParents(coll->at(ipar));
0621 }
0622 }
0623 }
0624 }
0625 #endif
0626
0627
0628
0629
0630 #ifdef DD4HEP_USE_EDM4HEP
0631
0632 namespace dd4hep {
0633
0634
0635 namespace digi {
0636
0637 template <> template <>
0638 void data_io<edm4hep_input>::_to_edm4hep(const ParticleMapping& cont,
0639 edm4hep::MCParticleCollection* coll)
0640 {
0641 if ( cont.empty() ) {
0642 return;
0643 }
0644 else if ( _can_handle(edm4hep_input(), *cont.begin()) ) {
0645 auto vec = _to_vector(data_input<edm4hep_input>(), cont);
0646 if ( !vec.empty() ) {
0647 data_io<edm4hep_input>::_to_edm4hep(vec, coll);
0648 }
0649 }
0650 else if ( _can_handle(ddg4_input(), *cont.begin()) ) {
0651 auto vec = _to_vector(data_input<ddg4_input>(), cont);
0652 if ( !vec.empty() ) {
0653 data_io<ddg4_input>::_to_edm4hep(vec, coll);
0654 }
0655 }
0656 else {
0657
0658 auto vec = _to_vector(data_input<digi_input>(), cont);
0659 if ( !vec.empty() ) {
0660 data_io<digi_input>::_to_edm4hep(vec, coll);
0661 }
0662 }
0663 }
0664 }
0665 }
0666 #endif