File indexing completed on 2025-11-08 09:19:16
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "ActsExamples/Io/EDM4hep/EDM4hepUtil.hpp"
0010
0011 #include "Acts/Definitions/Common.hpp"
0012 #include "Acts/Definitions/Units.hpp"
0013 #include "Acts/EventData/MultiTrajectoryHelpers.hpp"
0014 #include "Acts/Geometry/GeometryContext.hpp"
0015 #include "ActsExamples/Digitization/MeasurementCreation.hpp"
0016 #include "ActsExamples/EventData/Index.hpp"
0017 #include "ActsExamples/EventData/Measurement.hpp"
0018 #include "ActsExamples/Validation/TrackClassification.hpp"
0019 #include "ActsPlugins/EDM4hep/EDM4hepUtil.hpp"
0020
0021 #include "edm4hep/TrackState.h"
0022
0023 using namespace Acts::UnitLiterals;
0024
0025 namespace ActsExamples {
0026
0027 SimParticle EDM4hepUtil::readParticle(const edm4hep::MCParticle& from,
0028 const MapParticleIdFrom& particleMapper) {
0029 ActsFatras::Barcode particleId = particleMapper(from);
0030
0031 SimParticle to(particleId, static_cast<Acts::PdgParticle>(from.getPDG()),
0032 from.getCharge() * Acts::UnitConstants::e,
0033 from.getMass() * Acts::UnitConstants::GeV);
0034
0035
0036
0037
0038 to.initialState().setPosition4(from.getVertex()[0] * Acts::UnitConstants::mm,
0039 from.getVertex()[1] * Acts::UnitConstants::mm,
0040 from.getVertex()[2] * Acts::UnitConstants::mm,
0041 from.getTime() * Acts::UnitConstants::ns);
0042
0043
0044 Acts::Vector3 momentum = {from.getMomentum()[0], from.getMomentum()[1],
0045 from.getMomentum()[2]};
0046 to.initialState().setDirection(momentum.normalized());
0047
0048 to.initialState().setAbsoluteMomentum(momentum.norm() * 1_GeV);
0049
0050 return to;
0051 }
0052
0053 void EDM4hepUtil::writeParticle(const SimParticle& from,
0054 edm4hep::MutableMCParticle to) {
0055
0056
0057 to.setPDG(from.pdg());
0058 to.setCharge(from.charge() / Acts::UnitConstants::e);
0059 to.setMass(from.mass() / Acts::UnitConstants::GeV);
0060 to.setVertex({from.position().x(), from.position().y(), from.position().z()});
0061 to.setMomentum({static_cast<float>(from.fourMomentum().x()),
0062 static_cast<float>(from.fourMomentum().y()),
0063 static_cast<float>(from.fourMomentum().z())});
0064 to.setMomentumAtEndpoint(
0065 {static_cast<float>(from.finalState().fourMomentum().x()),
0066 static_cast<float>(from.finalState().fourMomentum().y()),
0067 static_cast<float>(from.finalState().fourMomentum().z())});
0068 }
0069
0070 ActsFatras::Hit EDM4hepUtil::readSimHit(
0071 const edm4hep::SimTrackerHit& from, const MapParticleIdFrom& particleMapper,
0072 const MapGeometryIdFrom& geometryMapper) {
0073 auto particle = ActsPlugins::EDM4hepUtil::getParticle(from);
0074 ActsFatras::Barcode particleId = particleMapper(particle);
0075
0076 const auto mass = particle.getMass() * 1_GeV;
0077 const Acts::Vector3 momentum{
0078 from.getMomentum().x * 1_GeV,
0079 from.getMomentum().y * 1_GeV,
0080 from.getMomentum().z * 1_GeV,
0081 };
0082 const auto energy = std::hypot(momentum.norm(), mass);
0083
0084 Acts::Vector4 pos4{
0085 from.getPosition().x * 1_mm,
0086 from.getPosition().y * 1_mm,
0087 from.getPosition().z * 1_mm,
0088 from.getTime() * 1_ns,
0089 };
0090
0091 Acts::Vector4 mom4{
0092 momentum.x(),
0093 momentum.y(),
0094 momentum.z(),
0095 energy,
0096 };
0097
0098 Acts::Vector4 delta4 = Acts::Vector4::Zero();
0099 delta4[Acts::eEnergy] = -from.getEDep() * Acts::UnitConstants::GeV;
0100
0101 Acts::GeometryIdentifier geometryId = geometryMapper(from.getCellID());
0102
0103
0104
0105 std::int32_t index = -1;
0106
0107 return ActsFatras::Hit(geometryId, particleId, pos4, mom4, mom4 + delta4,
0108 index);
0109 }
0110
0111 void EDM4hepUtil::writeSimHit(const ActsFatras::Hit& from,
0112 edm4hep::MutableSimTrackerHit to,
0113 const MapParticleIdTo& particleMapper,
0114 const MapGeometryIdTo& geometryMapper) {
0115 const Acts::Vector4& globalPos4 = from.fourPosition();
0116 const Acts::Vector4& momentum4Before = from.momentum4Before();
0117 const auto delta4 = from.momentum4After() - momentum4Before;
0118
0119 if (particleMapper) {
0120 ActsPlugins::EDM4hepUtil::setParticle(to,
0121 particleMapper(from.particleId()));
0122 }
0123
0124 if (geometryMapper) {
0125
0126 to.setCellID(geometryMapper(from.geometryId()));
0127 }
0128
0129 to.setTime(globalPos4[Acts::eTime] / Acts::UnitConstants::ns);
0130
0131 to.setPosition({
0132 globalPos4[Acts::ePos0] / Acts::UnitConstants::mm,
0133 globalPos4[Acts::ePos1] / Acts::UnitConstants::mm,
0134 globalPos4[Acts::ePos2] / Acts::UnitConstants::mm,
0135 });
0136
0137 to.setMomentum({
0138 static_cast<float>(momentum4Before[Acts::eMom0] /
0139 Acts::UnitConstants::GeV),
0140 static_cast<float>(momentum4Before[Acts::eMom1] /
0141 Acts::UnitConstants::GeV),
0142 static_cast<float>(momentum4Before[Acts::eMom2] /
0143 Acts::UnitConstants::GeV),
0144 });
0145
0146 to.setEDep(-delta4[Acts::eEnergy] / Acts::UnitConstants::GeV);
0147 }
0148
0149 VariableBoundMeasurementProxy EDM4hepUtil::readMeasurement(
0150 MeasurementContainer& container, const edm4hep::TrackerHitPlane& from,
0151 const edm4hep::TrackerHit3DCollection* ,
0152 Cluster* , const MapGeometryIdFrom& geometryMapper) {
0153
0154 Acts::GeometryIdentifier geometryId = geometryMapper(from.getCellID());
0155
0156 auto pos = from.getPosition();
0157 auto cov = from.getCovMatrix();
0158
0159 DigitizedParameters dParameters;
0160
0161 dParameters.indices.push_back(Acts::eBoundLoc0);
0162 dParameters.values.push_back(pos.x);
0163 dParameters.variances.push_back(cov[0]);
0164
0165
0166 dParameters.indices.push_back(Acts::eBoundLoc1);
0167 dParameters.values.push_back(pos.y);
0168 dParameters.variances.push_back(cov[2]);
0169
0170 dParameters.indices.push_back(Acts::eBoundTime);
0171 dParameters.values.push_back(pos.z);
0172 dParameters.variances.push_back(cov[5]);
0173
0174 auto to = createMeasurement(container, geometryId, dParameters);
0175
0176
0177
0178 return to;
0179 }
0180
0181 void EDM4hepUtil::writeMeasurement(
0182 const ConstVariableBoundMeasurementProxy& from,
0183 edm4hep::MutableTrackerHitPlane to, const Cluster* ,
0184 edm4hep::TrackerHit3DCollection& ,
0185 const MapGeometryIdTo& geometryMapper) {
0186 Acts::GeometryIdentifier geoId = from.geometryId();
0187
0188 if (geometryMapper) {
0189
0190 to.setCellID(geometryMapper(geoId));
0191 }
0192
0193 const auto& parameters = from.fullParameters();
0194 const auto& covariance = from.fullCovariance();
0195
0196 to.setTime(parameters[Acts::eBoundTime] / Acts::UnitConstants::ns);
0197
0198 to.setType(ActsPlugins::EDM4hepUtil::EDM4HEP_ACTS_POSITION_TYPE);
0199
0200 to.setPosition({parameters[Acts::eBoundLoc0], parameters[Acts::eBoundLoc1],
0201 parameters[Acts::eBoundTime]});
0202
0203 to.setCovMatrix({
0204 static_cast<float>(covariance(Acts::eBoundLoc0, Acts::eBoundLoc0)),
0205 static_cast<float>(covariance(Acts::eBoundLoc1, Acts::eBoundLoc0)),
0206 static_cast<float>(covariance(Acts::eBoundLoc1, Acts::eBoundLoc1)),
0207 0,
0208 0,
0209 0,
0210 });
0211
0212
0213 }
0214
0215 void EDM4hepUtil::writeTrajectory(
0216 const Acts::GeometryContext& gctx, double Bz, const Trajectories& from,
0217 edm4hep::MutableTrack to, std::size_t fromIndex,
0218 const Acts::ParticleHypothesis& particleHypothesis,
0219 const IndexMultimap<ActsFatras::Barcode>& hitParticlesMap) {
0220 const auto& multiTrajectory = from.multiTrajectory();
0221 auto trajectoryState =
0222 Acts::MultiTrajectoryHelpers::trajectoryState(multiTrajectory, fromIndex);
0223
0224 std::vector<ParticleHitCount> particleHitCount;
0225 identifyContributingParticles(hitParticlesMap, from, fromIndex,
0226 particleHitCount);
0227
0228
0229
0230
0231
0232 to.setChi2(trajectoryState.chi2Sum / trajectoryState.NDF);
0233 to.setNdf(trajectoryState.NDF);
0234
0235 multiTrajectory.visitBackwards(fromIndex, [&](const auto& state) {
0236
0237 auto typeFlags = state.typeFlags();
0238 if (!typeFlags.test(Acts::TrackStateFlag::MeasurementFlag)) {
0239 return true;
0240 }
0241
0242 edm4hep::TrackState trackState;
0243
0244 Acts::BoundTrackParameters parObj{state.referenceSurface().getSharedPtr(),
0245 state.parameters(), state.covariance(),
0246 particleHypothesis};
0247
0248
0249
0250
0251 ActsPlugins::EDM4hepUtil::detail::Parameters converted =
0252 ActsPlugins::EDM4hepUtil::detail::convertTrackParametersToEdm4hep(
0253 gctx, Bz, parObj);
0254
0255 trackState.D0 = converted.values[0];
0256 trackState.Z0 = converted.values[1];
0257 trackState.phi = converted.values[2];
0258 trackState.tanLambda = converted.values[3];
0259 trackState.omega = converted.values[4];
0260 trackState.time = converted.values[5];
0261
0262
0263
0264 auto center = converted.surface->center(gctx);
0265 trackState.referencePoint.x = center.x();
0266 trackState.referencePoint.y = center.y();
0267 trackState.referencePoint.z = center.z();
0268
0269 if (converted.covariance) {
0270 auto c = [&](std::size_t row, std::size_t col) {
0271 return static_cast<float>(converted.covariance.value()(row, col));
0272 };
0273
0274
0275 trackState.covMatrix = {c(0, 0),
0276 c(1, 0), c(1, 1),
0277 c(2, 0), c(2, 1), c(2, 2),
0278 c(3, 0), c(3, 1), c(3, 2), c(3, 3),
0279 c(4, 0), c(4, 1), c(4, 2), c(4, 3), c(4, 4),
0280 c(5, 0), c(5, 1), c(5, 2), c(5, 3), c(5, 4), c(5, 5)};
0281
0282 }
0283
0284 to.addToTrackStates(trackState);
0285
0286 return true;
0287 });
0288 }
0289
0290 }