Skip to content

Commit

Permalink
feat: detray geometry/material conversion in examples (acts-project#3579
Browse files Browse the repository at this point in the history
)

This PR builds upon acts-project#3546 (and others) and introduces the first tests to run detray geometry conversion in memory and then write out json files.

It also introduces a `DetrayPropagator` which implements the `ActsExamples::PropagatorInterface` and hence can be run with the `ActsExamples::PropagationAlgorithm`, see below:

![Screenshot 2024-09-02 at 11 08 54](https://github.com/user-attachments/assets/fad997ff-cd99-4911-837c-2a8201ac7533)

*NOTE*
The `propagate()` method of `detray` is currently not const, hence the propagator needs to be `mutable` for the moment, a fix for detray is in preparation.

Currently possible:
 - [x] geometry writing (validated)
 - [ ] material writing (validated) - will be part of a followup PR


@niermann999 @stephenswat can you please have a look at the implementation of the `DetrayStore` and the `DetrayHotStore` in particular, the idea here is to not expose `vecmem` specifics to the python bindings.

For handling `Traccc/Detray` in the `ActsFramework` I propose the following:
- pure geometry conversion and e.g. writing to files can be done with the `Python/src/Detray.cpp` binding code
- all the rest goes into `ActsExamples/Algorithms/Framework/Traccc` with its associated bindings.


@EleniXoch FYI
  • Loading branch information
asalzburger authored Sep 4, 2024
1 parent 4646759 commit 9e1d9ef
Show file tree
Hide file tree
Showing 27 changed files with 783 additions and 393 deletions.
2 changes: 1 addition & 1 deletion .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ build_exatrkx_cpu:
- git checkout $HEAD_SHA
- cd ..
- mkdir build
# Here we only do a minimal build without examples to save ressources
# Here we only do a minimal build without examples to save resources
- >
cmake -B build -S src
--preset=gitlab-ci-exatrkx
Expand Down
3 changes: 2 additions & 1 deletion Core/include/Acts/Material/HomogeneousSurfaceMaterial.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ class HomogeneousSurfaceMaterial : public ISurfaceMaterial {
/// @copydoc ISurfaceMaterial::materialSlab(const Vector3&) const
///
/// @note the input parameter is ignored
const MaterialSlab& materialSlab(const Vector3& gp) const final;
const MaterialSlab& materialSlab(const Vector3& gp = Vector3{0., 0.,
0.}) const final;

/// The inherited methods - for MaterialSlab access
using ISurfaceMaterial::materialSlab;
Expand Down
1 change: 1 addition & 0 deletions Examples/Algorithms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ add_subdirectory(Geometry)
add_subdirectory(MaterialMapping)
add_subdirectory(Printers)
add_subdirectory(Propagation)
add_subdirectory_if(Traccc ACTS_BUILD_PLUGIN_TRACCC)
add_subdirectory(TrackFinding)
add_subdirectory_if(TrackFindingExaTrkX ACTS_BUILD_EXAMPLES_EXATRKX)
add_subdirectory_if(TrackFindingML ACTS_BUILD_PLUGIN_ONNX)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,6 @@
#include <string>
#include <unordered_map>

namespace Acts {
class Surface;
}

namespace ActsExamples {

class PropagatorInterface;
Expand Down
17 changes: 17 additions & 0 deletions Examples/Algorithms/Traccc/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
add_library(ActsExamplesTraccc INTERFACE)

target_include_directories(
ActsExamplesTraccc
INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
)

target_link_libraries(
ActsExamplesTraccc
INTERFACE
ActsCore
ActsExamplesFramework
ActsExamplesPropagation
ActsPluginDetray
)

install(TARGETS ActsExamplesTraccc LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
// This file is part of the Acts project.
//
// Copyright (C) 2024 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 http://mozilla.org/MPL/2.0/.

#pragma once

#include "Acts/Geometry/GeometryIdentifier.hpp"
#include "Acts/Utilities/Logger.hpp"
#include "Acts/Utilities/Result.hpp"
#include "ActsExamples/EventData/PropagationSummary.hpp"
#include "ActsExamples/Propagation/PropagationAlgorithm.hpp"
#include "ActsExamples/Propagation/PropagatorInterface.hpp"
#include "ActsExamples/Traccc/DetrayStore.hpp"

#include <detray/navigation/navigator.hpp>
#include <detray/utils/inspectors.hpp>

namespace ActsExamples {

/// Define the algebra type
using DetrayAlgebraType = typename Acts::DetrayHostDetector::algebra_type;

/// Type that holds the intersection information
using DetrayIntersection =
detray::intersection2D<typename Acts::DetrayHostDetector::surface_type,
DetrayAlgebraType>;

/// Inspector that records all encountered surfaces
using DetrayObjectTracer =
detray::navigation::object_tracer<DetrayIntersection, detray::dvector,
detray::navigation::status::e_on_module,
detray::navigation::status::e_on_portal>;

/// Inspector that prints the navigator state from within the navigator's
/// method calls (cannot be done with an actor)
using DetrayPrintInspector = detray::navigation::print_inspector;

template <typename propagator_t, typename detray_store_t>
class DetrayPropagator : public PropagatorInterface {
public:
/// Create a DetrayPropagator
///
/// @param propagator The actual detray propagator to wrap
/// @param detrayStore The detray store to access the detector
/// @param logger The logger instance
DetrayPropagator(propagator_t&& propagator,
std::shared_ptr<const detray_store_t> detrayStore,
std::unique_ptr<const Acts::Logger> logger =
Acts::getDefaultLogger("DetrayPropagator",
Acts::Logging::INFO))
: PropagatorInterface(),
m_propagator(std::move(propagator)),
m_detrayStore(std::move(detrayStore)),
m_logger(std::move(logger)) {}

///@brief Execute a propagation for charged particle parameters
///
///@param context The algorithm context
///@param cfg The propagation algorithm configuration
///@param logger A logger wrapper instance
///@param startParameters The start parameters
///@return PropagationOutput
Acts::Result<PropagationOutput> execute(
const AlgorithmContext& context,
[[maybe_unused]] const PropagationAlgorithm::Config& cfg,
const Acts::Logger& logger,
const Acts::BoundTrackParameters& startParameters) const final {
// Get the geometry context form the algorithm context
const auto& geoContext = context.geoContext;
// Get the track information
const Acts::Vector3 position = startParameters.position(geoContext);
const Acts::Vector3 direction = startParameters.momentum().normalized();

ACTS_VERBOSE("Starting propagation at " << position.transpose()
<< " with direction "
<< direction.transpose());

// Now follow that ray with the same track and check, if we find
// the same volumes and distances along the way
detray::free_track_parameters<DetrayAlgebraType> track(
{position.x(), position.y(), position.z()}, 0.f,
{direction.x(), direction.y(), direction.z()},
startParameters.charge());

typename propagator_t::state propagation(track, m_detrayStore->detector);

// Run the actual propagation
m_propagator.propagate(propagation);

// Retrieve navigation information
auto& inspector = propagation._navigation.inspector();
auto& objectTracer = inspector.template get<DetrayObjectTracer>();

PropagationSummary summary(startParameters);
// Translate the objects into the steps
for (const auto& object : objectTracer.object_trace) {
// Get the position of the object
const auto& dposition = object.pos;
const auto& sfDesription = object.intersection.sf_desc;
const auto sf =
detray::tracking_surface{m_detrayStore->detector, sfDesription};
Acts::GeometryIdentifier geoID{sf.source()};
// Create a step from the object
Acts::detail::Step step;
step.position = Acts::Vector3(dposition[0], dposition[1], dposition[2]);
step.geoID = geoID;
step.navDir = object.intersection.direction ? Acts::Direction::Forward
: Acts::Direction::Backward;
summary.steps.emplace_back(step);
}
RecordedMaterial recordedMaterial;
return std::pair{std::move(summary), std::move(recordedMaterial)};
}

private:
/// The propagator @todo fix when propagate() method is const in detray
mutable propagator_t m_propagator;

/// The detray detector store and memory resource
std::shared_ptr<const detray_store_t> m_detrayStore = nullptr;

/// The logging instance
std::unique_ptr<const Acts::Logger> m_logger = nullptr;

const Acts::Logger& logger() const { return *m_logger; }
};

} // namespace ActsExamples
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// This file is part of the Acts project.
//
// Copyright (C) 2024 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 http://mozilla.org/MPL/2.0/.

#pragma once

#include "Acts/Plugins/Detray/DetrayConversionUtils.hpp"
#include "Acts/Plugins/Detray/DetrayConverter.hpp"

#include <memory>

#include <vecmem/memory/host_memory_resource.hpp>
#include <vecmem/memory/memory_resource.hpp>

namespace ActsExamples {

// The Detray host store that is used to store the detector
// and the associated memory resource
template <typename memory_source_t>
struct DetrayStore {
// Constructor from arguments
DetrayStore(std::shared_ptr<memory_source_t> mSource,
Acts::DetrayHostDetector&& det)
: memoryResource(std::move(mSource)), detector(std::move(det)) {}

// The memory resource
std::shared_ptr<memory_source_t> memoryResource = nullptr;
// The detray detector instance
Acts::DetrayHostDetector detector;

// Create a Detray detector and store it with its memory Source in
///
/// @param gctx the geometry context
/// @param detector the detector to be converted
/// @param options the conversion options
static inline std::shared_ptr<const DetrayStore<memory_source_t>> create(
const Acts::GeometryContext& gctx,
const Acts::Experimental::Detector& detector,
const Acts::DetrayConverter::Options& options) {
auto memoryResource = std::make_shared<memory_source_t>();
auto DetrayHostDetector = Acts::DetrayConverter().convert<>(
gctx, detector, *memoryResource, options);

return std::make_shared<DetrayStore<memory_source_t>>(
memoryResource, std::move(DetrayHostDetector));
}
};

using DetrayHostStore = DetrayStore<vecmem::host_memory_resource>;

} // namespace ActsExamples
3 changes: 3 additions & 0 deletions Examples/Python/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,12 @@ if(ACTS_BUILD_PLUGIN_TRACCC)
target_sources(ActsPythonBindings PRIVATE src/Detray.cpp)
target_link_libraries(ActsPythonBindings PUBLIC ActsPluginCovfie)
target_sources(ActsPythonBindings PRIVATE src/Covfie.cpp)
target_link_libraries(ActsPythonBindings PUBLIC ActsExamplesTraccc)
target_sources(ActsPythonBindings PRIVATE src/Traccc.cpp)
else()
target_sources(ActsPythonBindings PRIVATE src/DetrayStub.cpp)
target_sources(ActsPythonBindings PRIVATE src/CovfieStub.cpp)
target_sources(ActsPythonBindings PRIVATE src/TracccStub.cpp)
endif()

if(ACTS_BUILD_PLUGIN_ACTSVG)
Expand Down
34 changes: 32 additions & 2 deletions Examples/Python/src/Detray.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,42 @@ namespace Acts::Python {
void addDetray(Context& ctx) {
auto [m, mex] = ctx.get("main", "examples");

auto detray = m.def_submodule("detray");
{
py::class_<detector<default_metadata>,
std::shared_ptr<detector<default_metadata>>>(m,
std::shared_ptr<detector<default_metadata>>>(detray,
"detray_detector");
}

{ mex.def("writeToJson", &DetrayConverter::writeToJson); }
{
// This test function will convert an ACTS detector into a detray detector
// and write it to the corresponding json files.
//
// The memory resource and the detector are destroyed after the function
detray.def("writeToJson", [](const GeometryContext& gctx,
const Experimental::Detector& detector) {
auto memoryResource = vecmem::host_memory_resource();

DetrayConverter::Options options;
options.writeToJson = true;
options.convertMaterial = false;
options.convertSurfaceGrids = true;
auto DetrayHostDetector =
DetrayConverter().convert<>(gctx, detector, memoryResource, options);
});
}

{
auto converter = py::class_<DetrayConverter>(detray, "DetrayConverter");

auto options = py::class_<DetrayConverter::Options>(converter, "Options")
.def(py::init<>());

ACTS_PYTHON_STRUCT_BEGIN(options, DetrayConverter::Options);
ACTS_PYTHON_MEMBER(convertMaterial);
ACTS_PYTHON_MEMBER(convertSurfaceGrids);
ACTS_PYTHON_MEMBER(writeToJson);
ACTS_PYTHON_STRUCT_END();
}
}
} // namespace Acts::Python
2 changes: 2 additions & 0 deletions Examples/Python/src/ModuleEntry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ void addObj(Context& ctx);
void addOnnx(Context& ctx);
void addOnnxNeuralCalibrator(Context& ctx);
void addCovfie(Context& ctx);
void addTraccc(Context& ctx);
void addHashing(Context& ctx);

} // namespace Acts::Python
Expand Down Expand Up @@ -151,5 +152,6 @@ PYBIND11_MODULE(ActsPythonBindings, m) {
addOnnx(ctx);
addOnnxNeuralCalibrator(ctx);
addCovfie(ctx);
addTraccc(ctx);
addHashing(ctx);
}
Loading

0 comments on commit 9e1d9ef

Please sign in to comment.