From eb6a5f11df765261ac9f1b75e0eeb8f3e855eb59 Mon Sep 17 00:00:00 2001 From: Paul Gessinger Date: Fri, 29 Nov 2024 18:10:50 +0100 Subject: [PATCH] feat: compatibility for EDM4hep < `0.99` & >= `0.99` (#3921) This updates our code so it compiles with both EDM4hep versions below `0.99` and above/equal to `0.99`. Breaking changes are: - `TrackerHit` becomes `TrackerHit3D`. - `SimTrackerHit::getMCParticle` becomes `SimTrackerHit::getParticle`, with the original name being deprecated. I'm aliasing the new name `TrackerHit3D` and `TrackerHit3DCollection` to the old types, so that when we drop support for < `0.99` versions, they're already correct. ## Summary by CodeRabbit - **New Features** - Enhanced compatibility with different versions of the EDM4hep library for particle handling. - Introduced utility functions for retrieving and setting particle information in `SimTrackerHit` objects. - Added type aliases to streamline the handling of tracker hit collections. - **Bug Fixes** - Improved error handling in the `EDM4hepReader` for missing particles. - **Refactor** - Updated function signatures and internal logic to utilize new utility functions for better maintainability. - Streamlined the `EDM4hepMeasurementWriter` and `EDM4hepMeasurementReader` to accommodate new data structures. - Adjusted header inclusions and conditional compilation for better flexibility. - **Documentation** - Added comments to indicate changes in parameter handling for clarity. --- .../Io/EDM4hep/EDM4hepMeasurementWriter.hpp | 3 - .../ActsExamples/Io/EDM4hep/EDM4hepUtil.hpp | 21 +++--- .../EDM4hep/src/EDM4hepMeasurementReader.cpp | 5 +- .../EDM4hep/src/EDM4hepMeasurementWriter.cpp | 5 +- Examples/Io/EDM4hep/src/EDM4hepReader.cpp | 6 +- Examples/Io/EDM4hep/src/EDM4hepUtil.cpp | 73 ++++++------------- .../Acts/Plugins/EDM4hep/EDM4hepUtil.hpp | 12 ++- .../EDM4hep/TrackerHitCompatibility.hpp | 22 ++++++ Plugins/EDM4hep/src/EDM4hepUtil.cpp | 34 ++++++++- 9 files changed, 105 insertions(+), 76 deletions(-) create mode 100644 Plugins/EDM4hep/include/Acts/Plugins/EDM4hep/TrackerHitCompatibility.hpp diff --git a/Examples/Io/EDM4hep/include/ActsExamples/Io/EDM4hep/EDM4hepMeasurementWriter.hpp b/Examples/Io/EDM4hep/include/ActsExamples/Io/EDM4hep/EDM4hepMeasurementWriter.hpp index d559ee9a5e4..04cf8805df4 100644 --- a/Examples/Io/EDM4hep/include/ActsExamples/Io/EDM4hep/EDM4hepMeasurementWriter.hpp +++ b/Examples/Io/EDM4hep/include/ActsExamples/Io/EDM4hep/EDM4hepMeasurementWriter.hpp @@ -16,9 +16,6 @@ #include -#include -#include - namespace ActsExamples { /// Write out a measurement cluster collection to EDM4hep. diff --git a/Examples/Io/EDM4hep/include/ActsExamples/Io/EDM4hep/EDM4hepUtil.hpp b/Examples/Io/EDM4hep/include/ActsExamples/Io/EDM4hep/EDM4hepUtil.hpp index bdce08bc876..4973763a087 100644 --- a/Examples/Io/EDM4hep/include/ActsExamples/Io/EDM4hep/EDM4hepUtil.hpp +++ b/Examples/Io/EDM4hep/include/ActsExamples/Io/EDM4hep/EDM4hepUtil.hpp @@ -8,6 +8,7 @@ #pragma once #include "Acts/Geometry/GeometryContext.hpp" +#include "Acts/Plugins/EDM4hep/TrackerHitCompatibility.hpp" #include "ActsExamples/EventData/Cluster.hpp" #include "ActsExamples/EventData/Measurement.hpp" #include "ActsExamples/EventData/SimParticle.hpp" @@ -16,15 +17,13 @@ #include -#include "edm4hep/MCParticle.h" -#include "edm4hep/MutableMCParticle.h" -#include "edm4hep/MutableSimTrackerHit.h" -#include "edm4hep/MutableTrack.h" -#include "edm4hep/MutableTrackerHitPlane.h" -#include "edm4hep/SimTrackerHit.h" -#include "edm4hep/TrackerHit.h" -#include "edm4hep/TrackerHitCollection.h" -#include "edm4hep/TrackerHitPlane.h" +#include +#include +#include +#include +#include +#include +#include namespace ActsExamples::EDM4hepUtil { @@ -91,7 +90,7 @@ void writeSimHit(const ActsFatras::Hit& from, edm4hep::MutableSimTrackerHit to, /// - local 2D coordinates and time are read from position VariableBoundMeasurementProxy readMeasurement( MeasurementContainer& container, const edm4hep::TrackerHitPlane& from, - const edm4hep::TrackerHitCollection* fromClusters, Cluster* toCluster, + const edm4hep::TrackerHit3DCollection* fromClusters, Cluster* toCluster, const MapGeometryIdFrom& geometryMapper); /// Writes a measurement cluster to EDM4hep. @@ -107,7 +106,7 @@ VariableBoundMeasurementProxy readMeasurement( void writeMeasurement(const ConstVariableBoundMeasurementProxy& from, edm4hep::MutableTrackerHitPlane to, const Cluster* fromCluster, - edm4hep::TrackerHitCollection& toClusters, + edm4hep::TrackerHit3DCollection& toClusters, const MapGeometryIdTo& geometryMapper); /// Writes a trajectory to EDM4hep. diff --git a/Examples/Io/EDM4hep/src/EDM4hepMeasurementReader.cpp b/Examples/Io/EDM4hep/src/EDM4hepMeasurementReader.cpp index 237ff19e3b6..5299da121ca 100644 --- a/Examples/Io/EDM4hep/src/EDM4hepMeasurementReader.cpp +++ b/Examples/Io/EDM4hep/src/EDM4hepMeasurementReader.cpp @@ -9,6 +9,7 @@ #include "ActsExamples/Io/EDM4hep/EDM4hepMeasurementReader.hpp" #include "Acts/Definitions/Units.hpp" +#include "Acts/Plugins/EDM4hep/TrackerHitCompatibility.hpp" #include "Acts/Plugins/Podio/PodioUtil.hpp" #include "ActsExamples/EventData/Cluster.hpp" #include "ActsExamples/EventData/Measurement.hpp" @@ -18,8 +19,6 @@ #include #include -#include -#include #include #include @@ -60,7 +59,7 @@ ProcessCode EDM4hepMeasurementReader::read(const AlgorithmContext& ctx) { const auto& trackerHitPlaneCollection = frame.get("ActsTrackerHitsPlane"); const auto& trackerHitRawCollection = - frame.get("ActsTrackerHitsRaw"); + frame.get("ActsTrackerHitsRaw"); for (const auto& trackerHitPlane : trackerHitPlaneCollection) { Cluster cluster; diff --git a/Examples/Io/EDM4hep/src/EDM4hepMeasurementWriter.cpp b/Examples/Io/EDM4hep/src/EDM4hepMeasurementWriter.cpp index 0f9e9422d28..23e291cc2dd 100644 --- a/Examples/Io/EDM4hep/src/EDM4hepMeasurementWriter.cpp +++ b/Examples/Io/EDM4hep/src/EDM4hepMeasurementWriter.cpp @@ -9,6 +9,7 @@ #include "ActsExamples/Io/EDM4hep/EDM4hepMeasurementWriter.hpp" #include "Acts/Definitions/Units.hpp" +#include "Acts/Plugins/EDM4hep/TrackerHitCompatibility.hpp" #include "ActsExamples/EventData/Cluster.hpp" #include "ActsExamples/EventData/Measurement.hpp" #include "ActsExamples/Framework/WhiteBoard.hpp" @@ -16,6 +17,8 @@ #include +#include +#include #include namespace ActsExamples { @@ -44,7 +47,7 @@ ActsExamples::ProcessCode EDM4hepMeasurementWriter::writeT( podio::Frame frame; edm4hep::TrackerHitPlaneCollection hitsPlane; - edm4hep::TrackerHitCollection hits; + edm4hep::TrackerHit3DCollection hits; if (!m_cfg.inputClusters.empty()) { ACTS_VERBOSE("Fetch clusters for writing: " << m_cfg.inputClusters); diff --git a/Examples/Io/EDM4hep/src/EDM4hepReader.cpp b/Examples/Io/EDM4hep/src/EDM4hepReader.cpp index 4561bc61db0..0b82a20181b 100644 --- a/Examples/Io/EDM4hep/src/EDM4hepReader.cpp +++ b/Examples/Io/EDM4hep/src/EDM4hepReader.cpp @@ -10,6 +10,7 @@ #include "Acts/Definitions/Units.hpp" #include "Acts/Plugins/DD4hep/DD4hepDetectorElement.hpp" +#include "Acts/Plugins/EDM4hep/EDM4hepUtil.hpp" #include "ActsExamples/DD4hepDetector/DD4hepDetector.hpp" #include "ActsExamples/EventData/SimHit.hpp" #include "ActsExamples/EventData/SimParticle.hpp" @@ -305,8 +306,9 @@ ProcessCode EDM4hepReader::read(const AlgorithmContext& ctx) { auto simHit = EDM4hepUtil::readSimHit( hit, [&](const auto& inParticle) { - ACTS_VERBOSE("SimHit has source particle: " - << hit.getMCParticle().getObjectID().index); + ACTS_VERBOSE( + "SimHit has source particle: " + << Acts::EDM4hepUtil::getParticle(hit).getObjectID().index); auto it = edm4hepParticleMap.find(inParticle.getObjectID().index); if (it == edm4hepParticleMap.end()) { ACTS_ERROR( diff --git a/Examples/Io/EDM4hep/src/EDM4hepUtil.cpp b/Examples/Io/EDM4hep/src/EDM4hepUtil.cpp index 38e26038779..adb433891d9 100644 --- a/Examples/Io/EDM4hep/src/EDM4hepUtil.cpp +++ b/Examples/Io/EDM4hep/src/EDM4hepUtil.cpp @@ -70,9 +70,10 @@ void EDM4hepUtil::writeParticle(const SimParticle& from, ActsFatras::Hit EDM4hepUtil::readSimHit( const edm4hep::SimTrackerHit& from, const MapParticleIdFrom& particleMapper, const MapGeometryIdFrom& geometryMapper) { - ActsFatras::Barcode particleId = particleMapper(from.getMCParticle()); + auto particle = Acts::EDM4hepUtil::getParticle(from); + ActsFatras::Barcode particleId = particleMapper(particle); - const auto mass = from.getMCParticle().getMass() * 1_GeV; + const auto mass = particle.getMass() * 1_GeV; const Acts::Vector3 momentum{ from.getMomentum().x * 1_GeV, from.getMomentum().y * 1_GeV, @@ -116,7 +117,7 @@ void EDM4hepUtil::writeSimHit(const ActsFatras::Hit& from, const auto delta4 = from.momentum4After() - momentum4Before; if (particleMapper) { - to.setMCParticle(particleMapper(from.particleId())); + Acts::EDM4hepUtil::setParticle(to, particleMapper(from.particleId())); } if (geometryMapper) { @@ -146,8 +147,8 @@ void EDM4hepUtil::writeSimHit(const ActsFatras::Hit& from, VariableBoundMeasurementProxy EDM4hepUtil::readMeasurement( MeasurementContainer& container, const edm4hep::TrackerHitPlane& from, - const edm4hep::TrackerHitCollection* fromClusters, Cluster* toCluster, - const MapGeometryIdFrom& geometryMapper) { + const edm4hep::TrackerHit3DCollection* /*fromClusters*/, + Cluster* /*toCluster*/, const MapGeometryIdFrom& geometryMapper) { // no need for digitization as we only want to identify the sensor Acts::GeometryIdentifier geometryId = geometryMapper(from.getCellID()); @@ -171,32 +172,15 @@ VariableBoundMeasurementProxy EDM4hepUtil::readMeasurement( auto to = createMeasurement(container, geometryId, dParameters); - if (fromClusters != nullptr) { - for (const auto objectId : from.getRawHits()) { - const auto& c = fromClusters->at(objectId.index); - - // TODO get EDM4hep fixed - // misusing some fields to store ACTS specific information - // don't ask ... - ActsFatras::Segmentizer::Bin2D bin{ - static_cast(c.getType()), - static_cast(c.getQuality())}; - ActsFatras::Segmentizer::Segment2D path2D{ - {Acts::Vector2::Zero(), Acts::Vector2::Zero()}}; - double activation = c.getTime(); - ActsFatras::Segmentizer::ChannelSegment cell{bin, path2D, activation}; - - toCluster->channels.push_back(cell); - } - } + // @TODO: Figure out if cell information is accessible return to; } void EDM4hepUtil::writeMeasurement( const ConstVariableBoundMeasurementProxy& from, - edm4hep::MutableTrackerHitPlane to, const Cluster* fromCluster, - edm4hep::TrackerHitCollection& toClusters, + edm4hep::MutableTrackerHitPlane to, const Cluster* /*fromCluster*/, + edm4hep::TrackerHit3DCollection& /*toClusters*/, const MapGeometryIdTo& geometryMapper) { Acts::GeometryIdentifier geoId = from.geometryId(); @@ -224,21 +208,7 @@ void EDM4hepUtil::writeMeasurement( 0, }); - if (fromCluster != nullptr) { - for (const auto& c : fromCluster->channels) { - auto toChannel = toClusters.create(); - to.addToRawHits(toChannel.getObjectID()); - - // TODO digitization channel - - // TODO get EDM4hep fixed - // misusing some fields to store ACTS specific information - // don't ask ... - toChannel.setType(c.bin[0]); - toChannel.setQuality(c.bin[1]); - toChannel.setTime(c.activation); - } - } + // @TODO: Check if we can write cell info } void EDM4hepUtil::writeTrajectory( @@ -296,17 +266,18 @@ void EDM4hepUtil::writeTrajectory( trackState.referencePoint.z = center.z(); if (converted.covariance) { - const auto& c = converted.covariance.value(); - - trackState.covMatrix = { - static_cast(c(0, 0)), static_cast(c(1, 0)), - static_cast(c(1, 1)), static_cast(c(2, 0)), - static_cast(c(2, 1)), static_cast(c(2, 2)), - static_cast(c(3, 0)), static_cast(c(3, 1)), - static_cast(c(3, 2)), static_cast(c(3, 3)), - static_cast(c(4, 0)), static_cast(c(4, 1)), - static_cast(c(4, 2)), static_cast(c(4, 3)), - static_cast(c(4, 4))}; + auto c = [&](std::size_t row, std::size_t col) { + return static_cast(converted.covariance.value()(row, col)); + }; + + // clang-format off + trackState.covMatrix = {c(0, 0), + c(1, 0), c(1, 1), + c(2, 0), c(2, 1), c(2, 2), + c(3, 0), c(3, 1), c(3, 2), c(3, 3), + c(4, 0), c(4, 1), c(4, 2), c(4, 3), c(4, 4), + c(5, 0), c(5, 1), c(5, 2), c(5, 3), c(5, 4), c(5, 5)}; + // clang-format on } to.addToTrackStates(trackState); diff --git a/Plugins/EDM4hep/include/Acts/Plugins/EDM4hep/EDM4hepUtil.hpp b/Plugins/EDM4hep/include/Acts/Plugins/EDM4hep/EDM4hepUtil.hpp index c5fda03bc82..e4836862769 100644 --- a/Plugins/EDM4hep/include/Acts/Plugins/EDM4hep/EDM4hepUtil.hpp +++ b/Plugins/EDM4hep/include/Acts/Plugins/EDM4hep/EDM4hepUtil.hpp @@ -26,11 +26,13 @@ #include #include +#include +#include +#include +#include #include #include -#include "edm4hep/MutableTrack.h" - namespace Acts::EDM4hepUtil { static constexpr std::int32_t EDM4HEP_ACTS_POSITION_TYPE = 42; @@ -61,6 +63,12 @@ BoundTrackParameters convertTrackParametersFromEdm4hep( } // namespace detail +// Compatibility with EDM4hep < 0.99 and >= 0.99 +edm4hep::MCParticle getParticle(const edm4hep::SimTrackerHit& hit); + +void setParticle(edm4hep::MutableSimTrackerHit& hit, + const edm4hep::MCParticle& particle); + template void writeTrack(const Acts::GeometryContext& gctx, track_proxy_t track, edm4hep::MutableTrack to, double Bz, diff --git a/Plugins/EDM4hep/include/Acts/Plugins/EDM4hep/TrackerHitCompatibility.hpp b/Plugins/EDM4hep/include/Acts/Plugins/EDM4hep/TrackerHitCompatibility.hpp new file mode 100644 index 00000000000..11115e7cbe5 --- /dev/null +++ b/Plugins/EDM4hep/include/Acts/Plugins/EDM4hep/TrackerHitCompatibility.hpp @@ -0,0 +1,22 @@ +// This file is part of the ACTS project. +// +// Copyright (C) 2016 CERN for the benefit of the ACTS project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +#pragma once + +// Compatibility with EDM4hep < 0.99 and >= 0.99 +#if __has_include() +#include "edm4hep/TrackerHit3D.h" +#include "edm4hep/TrackerHit3DCollection.h" +#else +#include "edm4hep/TrackerHit.h" +#include "edm4hep/TrackerHitCollection.h" +namespace edm4hep { +using TrackerHit3DCollection = edm4hep::TrackerHitCollection; +using TrackerHit3D = edm4hep::TrackerHit; +} // namespace edm4hep +#endif diff --git a/Plugins/EDM4hep/src/EDM4hepUtil.cpp b/Plugins/EDM4hep/src/EDM4hepUtil.cpp index 515063da679..60d466d0427 100644 --- a/Plugins/EDM4hep/src/EDM4hepUtil.cpp +++ b/Plugins/EDM4hep/src/EDM4hepUtil.cpp @@ -18,9 +18,14 @@ #include -#include "edm4hep/TrackState.h" +#include +#include +#include +#include +#include -namespace Acts::EDM4hepUtil::detail { +namespace Acts::EDM4hepUtil { +namespace detail { ActsSquareMatrix<6> jacobianToEdm4hep(double theta, double qOverP, double Bz) { // Calculate jacobian from our internal parametrization (d0, z0, phi, theta, @@ -185,4 +190,27 @@ BoundTrackParameters convertTrackParametersFromEdm4hep( return {params.surface, targetPars, cov, params.particleHypothesis}; } -} // namespace Acts::EDM4hepUtil::detail +} // namespace detail + +#if EDM4HEP_VERSION_MAJOR >= 1 || \ + (EDM4HEP_VERSION_MAJOR == 0 && EDM4HEP_VERSION_MINOR == 99) +edm4hep::MCParticle getParticle(const edm4hep::SimTrackerHit& hit) { + return hit.getParticle(); +} + +void setParticle(edm4hep::MutableSimTrackerHit& hit, + const edm4hep::MCParticle& particle) { + hit.setParticle(particle); +} +#else +edm4hep::MCParticle getParticle(const edm4hep::SimTrackerHit& hit) { + return hit.getMCParticle(); +} + +void setParticle(edm4hep::MutableSimTrackerHit& hit, + const edm4hep::MCParticle& particle) { + hit.setMCParticle(particle); +} +#endif + +} // namespace Acts::EDM4hepUtil