File indexing completed on 2025-08-06 08:10:48
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/Charge.hpp"
0014 #include "Acts/EventData/MultiTrajectory.hpp"
0015 #include "Acts/EventData/MultiTrajectoryHelpers.hpp"
0016 #include "Acts/Geometry/GeometryContext.hpp"
0017 #include "Acts/Plugins/EDM4hep/EDM4hepUtil.hpp"
0018 #include "ActsExamples/Digitization/MeasurementCreation.hpp"
0019 #include "ActsExamples/EventData/Index.hpp"
0020 #include "ActsExamples/EventData/IndexSourceLink.hpp"
0021 #include "ActsExamples/EventData/SimHit.hpp"
0022 #include "ActsExamples/Validation/TrackClassification.hpp"
0023
0024 #include "edm4hep/TrackState.h"
0025
0026 using namespace Acts::UnitLiterals;
0027
0028 namespace ActsExamples {
0029
0030 ActsFatras::Particle EDM4hepUtil::readParticle(
0031 const edm4hep::MCParticle& from, const MapParticleIdFrom& particleMapper) {
0032 ActsFatras::Barcode particleId = particleMapper(from);
0033
0034 ActsFatras::Particle to(particleId,
0035 static_cast<Acts::PdgParticle>(from.getPDG()),
0036 from.getCharge() * Acts::UnitConstants::e,
0037 from.getMass() * Acts::UnitConstants::GeV);
0038
0039
0040
0041
0042 to.setPosition4(from.getVertex()[0] * Acts::UnitConstants::mm,
0043 from.getVertex()[1] * Acts::UnitConstants::mm,
0044 from.getVertex()[2] * Acts::UnitConstants::mm,
0045 from.getTime() * Acts::UnitConstants::ns);
0046
0047
0048 Acts::Vector3 momentum = {from.getMomentum()[0], from.getMomentum()[1],
0049 from.getMomentum()[2]};
0050 to.setDirection(momentum.normalized());
0051
0052 to.setAbsoluteMomentum(momentum.norm() * 1_GeV);
0053
0054 return to;
0055 }
0056
0057 void EDM4hepUtil::writeParticle(const ActsFatras::Particle& from,
0058 edm4hep::MutableMCParticle to) {
0059
0060
0061 to.setPDG(from.pdg());
0062 to.setCharge(from.charge() / Acts::UnitConstants::e);
0063 to.setMass(from.mass() / Acts::UnitConstants::GeV);
0064 to.setVertex({from.position().x(), from.position().y(), from.position().z()});
0065 to.setMomentum({static_cast<float>(from.fourMomentum().x()),
0066 static_cast<float>(from.fourMomentum().y()),
0067 static_cast<float>(from.fourMomentum().z())});
0068 }
0069
0070 ActsFatras::Hit EDM4hepUtil::readSimHit(
0071 const edm4hep::SimTrackerHit& from, const MapParticleIdFrom& particleMapper,
0072 const MapGeometryIdFrom& geometryMapper) {
0073 ActsFatras::Barcode particleId = particleMapper(from.getMCParticle());
0074
0075 const auto mass = from.getMCParticle().getMass() * 1_GeV;
0076 const Acts::Vector3 momentum{
0077 from.getMomentum().x * 1_GeV,
0078 from.getMomentum().y * 1_GeV,
0079 from.getMomentum().z * 1_GeV,
0080 };
0081 const auto energy = std::hypot(momentum.norm(), mass);
0082
0083 Acts::Vector4 pos4{
0084 from.getPosition().x * 1_mm,
0085 from.getPosition().y * 1_mm,
0086 from.getPosition().z * 1_mm,
0087 from.getTime() * 1_ns,
0088 };
0089
0090 Acts::Vector4 mom4{
0091 momentum.x(),
0092 momentum.y(),
0093 momentum.z(),
0094 energy,
0095 };
0096
0097 Acts::Vector4 delta4 = Acts::Vector4::Zero();
0098 delta4[Acts::eEnergy] = -from.getEDep() * Acts::UnitConstants::GeV;
0099
0100 Acts::GeometryIdentifier geometryId = geometryMapper(from.getCellID());
0101
0102
0103
0104 int32_t index = -1;
0105
0106 return ActsFatras::Hit(geometryId, particleId, pos4, mom4, mom4 + delta4,
0107 index);
0108 }
0109
0110 void EDM4hepUtil::writeSimHit(const ActsFatras::Hit& from,
0111 edm4hep::MutableSimTrackerHit to,
0112 const MapParticleIdTo& particleMapper,
0113 const MapGeometryIdTo& geometryMapper) {
0114 const Acts::Vector4& globalPos4 = from.fourPosition();
0115 const Acts::Vector4& momentum4Before = from.momentum4Before();
0116 const auto delta4 = from.momentum4After() - momentum4Before;
0117
0118 if (particleMapper) {
0119 to.setMCParticle(particleMapper(from.particleId()));
0120 }
0121
0122 if (geometryMapper) {
0123
0124 to.setCellID(geometryMapper(from.geometryId()));
0125 }
0126
0127 to.setTime(globalPos4[Acts::eTime] / Acts::UnitConstants::ns);
0128
0129 to.setPosition({
0130 globalPos4[Acts::ePos0] / Acts::UnitConstants::mm,
0131 globalPos4[Acts::ePos1] / Acts::UnitConstants::mm,
0132 globalPos4[Acts::ePos2] / Acts::UnitConstants::mm,
0133 });
0134
0135 to.setMomentum({
0136 static_cast<float>(momentum4Before[Acts::eMom0] /
0137 Acts::UnitConstants::GeV),
0138 static_cast<float>(momentum4Before[Acts::eMom1] /
0139 Acts::UnitConstants::GeV),
0140 static_cast<float>(momentum4Before[Acts::eMom2] /
0141 Acts::UnitConstants::GeV),
0142 });
0143
0144 to.setEDep(-delta4[Acts::eEnergy] / Acts::UnitConstants::GeV);
0145 }
0146
0147 Measurement EDM4hepUtil::readMeasurement(
0148 const edm4hep::TrackerHitPlane& from,
0149 const edm4hep::TrackerHitCollection* fromClusters, Cluster* toCluster,
0150 const MapGeometryIdFrom& geometryMapper) {
0151
0152 Acts::GeometryIdentifier geometryId = geometryMapper(from.getCellID());
0153
0154 IndexSourceLink sourceLink{
0155 geometryId, static_cast<Index>(podioObjectIDToInteger(from.id()))};
0156
0157 auto pos = from.getPosition();
0158 auto cov = from.getCovMatrix();
0159
0160 DigitizedParameters dParameters;
0161
0162 dParameters.indices.push_back(Acts::eBoundLoc0);
0163 dParameters.values.push_back(pos.x);
0164 dParameters.variances.push_back(cov[0]);
0165
0166
0167 dParameters.indices.push_back(Acts::eBoundLoc1);
0168 dParameters.values.push_back(pos.y);
0169 dParameters.variances.push_back(cov[2]);
0170
0171 dParameters.indices.push_back(Acts::eBoundTime);
0172 dParameters.values.push_back(pos.z);
0173 dParameters.variances.push_back(cov[5]);
0174
0175 auto to = createMeasurement(dParameters, sourceLink);
0176
0177 if (fromClusters != nullptr) {
0178 for (const auto objectId : from.getRawHits()) {
0179 const auto& c = fromClusters->at(objectId.index);
0180
0181
0182
0183
0184 ActsFatras::Segmentizer::Bin2D bin{
0185 static_cast<unsigned int>(c.getType()),
0186 static_cast<unsigned int>(c.getQuality())};
0187 ActsFatras::Segmentizer::Segment2D path2D{
0188 {Acts::Vector2::Zero(), Acts::Vector2::Zero()}};
0189 double activation = c.getTime();
0190 ActsFatras::Segmentizer::ChannelSegment cell{bin, path2D, activation};
0191
0192 toCluster->channels.push_back(cell);
0193 }
0194 }
0195
0196 return to;
0197 }
0198
0199 void EDM4hepUtil::writeMeasurement(const Measurement& from,
0200 edm4hep::MutableTrackerHitPlane to,
0201 const Cluster* fromCluster,
0202 edm4hep::TrackerHitCollection& toClusters,
0203 const MapGeometryIdTo& geometryMapper) {
0204 std::visit(
0205 [&](const auto& m) {
0206 Acts::GeometryIdentifier geoId =
0207 m.sourceLink().template get<IndexSourceLink>().geometryId();
0208
0209 if (geometryMapper) {
0210
0211 to.setCellID(geometryMapper(geoId));
0212 }
0213
0214 auto parameters = (m.expander() * m.parameters()).eval();
0215
0216 to.setTime(parameters[Acts::eBoundTime] / Acts::UnitConstants::ns);
0217
0218 to.setType(Acts::EDM4hepUtil::EDM4HEP_ACTS_POSITION_TYPE);
0219
0220 to.setPosition({parameters[Acts::eBoundLoc0],
0221 parameters[Acts::eBoundLoc1],
0222 parameters[Acts::eBoundTime]});
0223
0224 auto covariance =
0225 (m.expander() * m.covariance() * m.expander().transpose()).eval();
0226 to.setCovMatrix({
0227 static_cast<float>(covariance(Acts::eBoundLoc0, Acts::eBoundLoc0)),
0228 static_cast<float>(covariance(Acts::eBoundLoc1, Acts::eBoundLoc0)),
0229 static_cast<float>(covariance(Acts::eBoundLoc1, Acts::eBoundLoc1)),
0230 0,
0231 0,
0232 0,
0233 });
0234
0235 if (fromCluster) {
0236 for (const auto& c : fromCluster->channels) {
0237 auto toChannel = toClusters.create();
0238 to.addToRawHits(toChannel.getObjectID());
0239
0240
0241
0242
0243
0244
0245 toChannel.setType(c.bin[0]);
0246 toChannel.setQuality(c.bin[1]);
0247 toChannel.setTime(c.activation);
0248 }
0249 }
0250 },
0251 from);
0252 }
0253
0254 void EDM4hepUtil::writeTrajectory(
0255 const Acts::GeometryContext& gctx, double Bz, const Trajectories& from,
0256 edm4hep::MutableTrack to, std::size_t fromIndex,
0257 const Acts::ParticleHypothesis& particleHypothesis,
0258 const IndexMultimap<ActsFatras::Barcode>& hitParticlesMap) {
0259 const auto& multiTrajectory = from.multiTrajectory();
0260 auto trajectoryState =
0261 Acts::MultiTrajectoryHelpers::trajectoryState(multiTrajectory, fromIndex);
0262
0263 std::vector<ParticleHitCount> particleHitCount;
0264 identifyContributingParticles(hitParticlesMap, from, fromIndex,
0265 particleHitCount);
0266
0267
0268
0269
0270
0271 to.setChi2(trajectoryState.chi2Sum / trajectoryState.NDF);
0272 to.setNdf(trajectoryState.NDF);
0273
0274 multiTrajectory.visitBackwards(fromIndex, [&](const auto& state) {
0275
0276 auto typeFlags = state.typeFlags();
0277 if (!typeFlags.test(Acts::TrackStateFlag::MeasurementFlag)) {
0278 return true;
0279 }
0280
0281 edm4hep::TrackState trackState;
0282
0283 Acts::BoundTrackParameters parObj{state.referenceSurface().getSharedPtr(),
0284 state.parameters(), state.covariance(),
0285 particleHypothesis};
0286
0287
0288
0289
0290 Acts::EDM4hepUtil::detail::Parameters converted =
0291 Acts::EDM4hepUtil::detail::convertTrackParametersToEdm4hep(gctx, Bz,
0292 parObj);
0293
0294 trackState.D0 = converted.values[0];
0295 trackState.Z0 = converted.values[1];
0296 trackState.phi = converted.values[2];
0297 trackState.tanLambda = converted.values[3];
0298 trackState.omega = converted.values[4];
0299 trackState.time = converted.values[5];
0300
0301
0302
0303 auto center = converted.surface->center(gctx);
0304 trackState.referencePoint.x = center.x();
0305 trackState.referencePoint.y = center.y();
0306 trackState.referencePoint.z = center.z();
0307
0308 if (converted.covariance) {
0309 const auto& c = converted.covariance.value();
0310
0311 trackState.covMatrix = {
0312 static_cast<float>(c(0, 0)), static_cast<float>(c(1, 0)),
0313 static_cast<float>(c(1, 1)), static_cast<float>(c(2, 0)),
0314 static_cast<float>(c(2, 1)), static_cast<float>(c(2, 2)),
0315 static_cast<float>(c(3, 0)), static_cast<float>(c(3, 1)),
0316 static_cast<float>(c(3, 2)), static_cast<float>(c(3, 3)),
0317 static_cast<float>(c(4, 0)), static_cast<float>(c(4, 1)),
0318 static_cast<float>(c(4, 2)), static_cast<float>(c(4, 3)),
0319 static_cast<float>(c(4, 4))};
0320 }
0321
0322 to.addToTrackStates(trackState);
0323
0324 return true;
0325 });
0326 }
0327
0328 }