Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,33 +12,33 @@
#include "ActsExamples/EventData/Cluster.hpp"
#include "ActsExamples/EventData/Measurement.hpp"
#include "ActsExamples/Framework/DataHandle.hpp"
#include "ActsExamples/Io/EDM4hep/EDM4hepUtil.hpp"
#include "ActsExamples/Io/Podio/PodioInputConverter.hpp"

#include <memory>
#include <string>

namespace ActsExamples {

/// Read in a measurement cluster collection as EDM4hep from a @c podio::Frame.
///
/// Inpersistent information:
/// - hit index
/// - 1D local coords?
/// - segment path
///
/// Known issues:
/// - cluster channels are read from inappropriate fields
/// - local 2D coordinates and time are read from position
class DD4hepDetector;

/// Read in a measurement collection from EDM4hep TrackerHitLocal format.
class EDM4hepMeasurementInputConverter final : public PodioInputConverter {
public:
struct Config {
/// Where to read the input frame from.
std::string inputFrame;
/// Name of the input tracker hit local collection.
std::string inputTrackerHitsLocal;
/// Output measurement collection.
std::string outputMeasurements;
/// Output measurement to sim hit collection.
std::string outputMeasurementSimHitsMap;
/// Output cluster collection (optional).
std::string outputClusters;

/// DD4hep detector for cellID to geometry identifier resolution.
std::shared_ptr<DD4hepDetector> dd4hepDetector;
};

/// Construct the cluster reader.
Expand All @@ -59,6 +59,8 @@ class EDM4hepMeasurementInputConverter final : public PodioInputConverter {
private:
Config m_cfg;

EDM4hepUtil::MapGeometryIdFrom m_geometryMapper;

WriteDataHandle<MeasurementContainer> m_outputMeasurements{
this, "OutputMeasurements"};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@

#pragma once

#include "Acts/Geometry/TrackingGeometry.hpp"
#include "ActsExamples/EventData/Cluster.hpp"
#include "ActsExamples/EventData/Measurement.hpp"
#include "ActsExamples/Framework/DataHandle.hpp"
#include "ActsExamples/Io/Podio/CollectionBaseWriteHandle.hpp"
#include "ActsExamples/Io/Podio/PodioOutputConverter.hpp"

#include <memory>
#include <string>

namespace ActsExamples {
Expand All @@ -33,12 +35,11 @@ class EDM4hepMeasurementOutputConverter final : public PodioOutputConverter {
struct Config {
/// Which measurement collection to write.
std::string inputMeasurements;
/// Which cluster collection to write (optional)
std::string inputClusters;
/// Name of the output tracker hit plane collection.
std::string outputTrackerHitsPlane = "ActsTrackerHitsPlane";
/// Name of the output tracker hit raw collection.
std::string outputTrackerHitsRaw = "ActsTrackerHitsRaw";
std::string outputTrackerHitsLocal;

/// Tracking geometry for surface lookup (local-to-global transform).
std::shared_ptr<const Acts::TrackingGeometry> trackingGeometry;
};

/// Constructor with
Expand All @@ -64,12 +65,8 @@ class EDM4hepMeasurementOutputConverter final : public PodioOutputConverter {
ReadDataHandle<MeasurementContainer> m_inputMeasurements{this,
"InputMeasurements"};

ReadDataHandle<ClusterContainer> m_inputClusters{this, "InputClusters"};

CollectionBaseWriteHandle m_outputTrackerHitsPlane{this,
"OutputTrackerHitsPlane"};
CollectionBaseWriteHandle m_outputTrackerHitsRaw{this,
"OutputTrackerHitsRaw"};
CollectionBaseWriteHandle m_outputTrackerHitsLocal{this,
"OutputTrackerHitsLocal"};
};

} // namespace ActsExamples
44 changes: 30 additions & 14 deletions Examples/Io/EDM4hep/include/ActsExamples/Io/EDM4hep/EDM4hepUtil.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
#include "ActsExamples/EventData/SimParticle.hpp"
#include "ActsExamples/EventData/Trajectories.hpp"
#include "ActsFatras/EventData/Hit.hpp"
#include "ActsPlugins/EDM4hep/TrackerHitCompatibility.hpp"
#include <ActsPodioEdm/MutableTrackerHitLocal.h>
#include <ActsPodioEdm/TrackerHitLocal.h>
Comment thread
paulgessinger marked this conversation as resolved.

#include <functional>

Expand Down Expand Up @@ -95,21 +96,36 @@ VariableBoundMeasurementProxy readMeasurement(
const edm4hep::TrackerHit3DCollection* fromClusters, Cluster* toCluster,
const MapGeometryIdFrom& geometryMapper);

/// Writes a measurement cluster to EDM4hep.
/// Writes an ACTS measurement to EDM4hep.
///
/// Inpersistent information:
/// - hit index
/// - 1D local coords?
/// - segment path
/// Converts bound parameters (local coordinates, time) and covariance from an
/// ACTS measurement to a MutableTrackerHitLocal. The surface is used
/// to obtain the detector cell ID from the DD4hepDetectorElement and to
/// transform local coordinates to global position.
///
/// Known issues:
/// - cluster channels are written to inappropriate fields
/// - local 2D coordinates and time are written to position
void writeMeasurement(const ConstVariableBoundMeasurementProxy& from,
edm4hep::MutableTrackerHitPlane to,
const Cluster* fromCluster,
edm4hep::TrackerHit3DCollection& toClusters,
const MapGeometryIdTo& geometryMapper);
/// @param gctx The geometry context for coordinate transformations.
/// @param from The ACTS measurement to convert.
/// @param to The EDM4hep tracker hit to write to.
/// @param surface The surface associated with the measurement (must have a
/// DD4hepDetectorElement placement).
void writeMeasurement(const Acts::GeometryContext& gctx,
const ConstVariableBoundMeasurementProxy& from,
ActsPodioEdm::MutableTrackerHitLocal& to,
const Acts::Surface& surface);

/// Reads a measurement from an EDM4hep TrackerHitLocal.
///
/// Converts bound parameters, covariance, and indices from an EDM4hep
/// TrackerHitLocal into an ACTS measurement. The geometry mapper is used to
/// convert the cell ID to a geometry identifier.
///
/// @param container The measurement container to insert into.
/// @param from The EDM4hep tracker hit to read from.
/// @param geometryMapper Function to map cell ID to geometry identifier.
/// @return Proxy to the created measurement.
VariableBoundMeasurementProxy readMeasurement(
MeasurementContainer& container, const ActsPodioEdm::TrackerHitLocal& from,
const MapGeometryIdFrom& geometryMapper);

/// Writes a trajectory to EDM4hep.
///
Expand Down
45 changes: 29 additions & 16 deletions Examples/Io/EDM4hep/src/EDM4hepMeasurementInputConverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,16 @@

#include "ActsExamples/Io/EDM4hep/EDM4hepMeasurementInputConverter.hpp"

#include "ActsExamples/DD4hepDetector/DD4hepDetector.hpp"
#include "ActsExamples/EventData/Cluster.hpp"
#include "ActsExamples/EventData/Measurement.hpp"
#include "ActsExamples/Io/EDM4hep/EDM4hepUtil.hpp"
#include "ActsPlugins/EDM4hep/PodioUtil.hpp"
#include "ActsPlugins/DD4hep/DD4hepDetectorElement.hpp"
#include <ActsPodioEdm/TrackerHitLocalCollection.h>

#include <stdexcept>

#include <edm4hep/TrackerHitPlane.h>
#include <edm4hep/TrackerHitPlaneCollection.h>
#include <DD4hep/Detector.h>
#include <podio/Frame.h>

namespace ActsExamples {
Expand All @@ -30,34 +31,46 @@ EDM4hepMeasurementInputConverter::EDM4hepMeasurementInputConverter(
if (m_cfg.outputMeasurements.empty()) {
throw std::invalid_argument("Missing measurement output collection");
}
if (m_cfg.dd4hepDetector == nullptr) {
throw std::invalid_argument("Missing DD4hep detector");
}

m_outputMeasurements.initialize(m_cfg.outputMeasurements);
m_outputMeasurementSimHitsMap.initialize(m_cfg.outputMeasurementSimHitsMap);
m_outputClusters.maybeInitialize(m_cfg.outputClusters);

m_geometryMapper = [detector = m_cfg.dd4hepDetector](std::uint64_t cellId) {
const auto& vm = detector->dd4hepDetector().volumeManager();
const auto detElement = vm.lookupDetElement(cellId);

const auto* ext =
detElement.extension<ActsPlugins::DD4hepDetectorElementExtension>(
false);
if (ext == nullptr) {
throw std::runtime_error(
"EDM4hepMeasurementInputConverter: DetElement has no "
"DD4hepDetectorElementExtension for cellId " +
std::to_string(cellId));
}
return ext->detectorElement().surface().geometryId();
};
}

ProcessCode EDM4hepMeasurementInputConverter::convert(
const AlgorithmContext& ctx, const podio::Frame& frame) const {
MeasurementContainer measurements;
ClusterContainer clusters;
// TODO what about those?
IndexMultimap<Index> measurementSimHitsMap;

const auto& trackerHitPlaneCollection =
frame.get<edm4hep::TrackerHitPlaneCollection>("ActsTrackerHitsPlane");
const auto& trackerHitRawCollection =
frame.get<edm4hep::TrackerHit3DCollection>("ActsTrackerHitsRaw");

for (const auto& trackerHitPlane : trackerHitPlaneCollection) {
Cluster cluster;
EDM4hepUtil::readMeasurement(
measurements, trackerHitPlane, &trackerHitRawCollection, &cluster,
[](std::uint64_t cellId) { return Acts::GeometryIdentifier(cellId); });
const auto& trackerHitLocalCollection =
frame.get<ActsPodioEdm::TrackerHitLocalCollection>(
m_cfg.inputTrackerHitsLocal);

clusters.push_back(std::move(cluster));
for (const auto& trackerHitLocal : trackerHitLocalCollection) {
EDM4hepUtil::readMeasurement(measurements, trackerHitLocal,
m_geometryMapper);
}

// Write the data to the EventStore
m_outputMeasurements(ctx, std::move(measurements));
m_outputMeasurementSimHitsMap(ctx, std::move(measurementSimHitsMap));
if (!m_cfg.outputClusters.empty()) {
Expand Down
44 changes: 24 additions & 20 deletions Examples/Io/EDM4hep/src/EDM4hepMeasurementOutputConverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
#include "ActsExamples/EventData/Cluster.hpp"
#include "ActsExamples/EventData/Measurement.hpp"
#include "ActsExamples/Io/EDM4hep/EDM4hepUtil.hpp"
#include "ActsPlugins/EDM4hep/TrackerHitCompatibility.hpp"
#include <ActsPodioEdm/TrackerHitLocalCollection.h>

#include <stdexcept>

#include <edm4hep/TrackerHitPlane.h>
#include <edm4hep/TrackerHitPlaneCollection.h>
Expand All @@ -24,23 +28,18 @@ EDM4hepMeasurementOutputConverter::EDM4hepMeasurementOutputConverter(
: PodioOutputConverter("EDM4hepMeasurementOutputConverter",
std::move(logger)),
m_cfg(config) {
if (m_cfg.trackingGeometry == nullptr) {
throw std::runtime_error(
"EDM4hepMeasurementOutputConverter: trackingGeometry is null");
}

m_inputMeasurements.initialize(m_cfg.inputMeasurements);
m_inputClusters.maybeInitialize(m_cfg.inputClusters);
m_outputTrackerHitsPlane.initialize(m_cfg.outputTrackerHitsPlane);
m_outputTrackerHitsRaw.initialize(m_cfg.outputTrackerHitsRaw);
m_outputTrackerHitsLocal.initialize(m_cfg.outputTrackerHitsLocal);
}

ProcessCode EDM4hepMeasurementOutputConverter::execute(
const AlgorithmContext& ctx) const {
ClusterContainer clusters;

edm4hep::TrackerHitPlaneCollection hitsPlane;
edm4hep::TrackerHit3DCollection hits;

if (!m_cfg.inputClusters.empty()) {
ACTS_VERBOSE("Fetch clusters for writing: " << m_cfg.inputClusters);
clusters = m_inputClusters(ctx);
}
ActsPodioEdm::TrackerHitLocalCollection hits;

const auto measurements = m_inputMeasurements(ctx);

Expand All @@ -50,23 +49,28 @@ ProcessCode EDM4hepMeasurementOutputConverter::execute(
for (Index hitIdx = 0u; hitIdx < measurements.size(); ++hitIdx) {
ConstVariableBoundMeasurementProxy from =
measurements.getMeasurement(hitIdx);
const Cluster* fromCluster = clusters.empty() ? nullptr : &clusters[hitIdx];

auto to = hitsPlane.create();
EDM4hepUtil::writeMeasurement(
from, to, fromCluster, hits,
[](Acts::GeometryIdentifier id) { return id.value(); });
const Acts::Surface* surface =
m_cfg.trackingGeometry->findSurface(from.geometryId());
if (surface == nullptr) {
throw std::runtime_error(
"EDM4hepMeasurementOutputConverter: surface not found for geometry "
"id " +
std::to_string(from.geometryId().value()));
}

auto to = hits.create();
EDM4hepUtil::writeMeasurement(ctx.geoContext, from, to, *surface);
}

m_outputTrackerHitsPlane(ctx, std::move(hitsPlane));
m_outputTrackerHitsRaw(ctx, std::move(hits));
m_outputTrackerHitsLocal(ctx, std::move(hits));

return ProcessCode::SUCCESS;
}

std::vector<std::string> EDM4hepMeasurementOutputConverter::collections()
const {
return {m_cfg.outputTrackerHitsPlane, m_cfg.outputTrackerHitsRaw};
return {m_cfg.outputTrackerHitsLocal};
}

} // namespace ActsExamples
Loading
Loading