Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add covfie magnetic field plugin #3479

Merged
merged 4 commits into from
Aug 29, 2024
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
3 changes: 3 additions & 0 deletions Examples/Python/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,11 @@ endif()
if(ACTS_BUILD_PLUGIN_TRACCC)
target_link_libraries(ActsPythonBindings PUBLIC ActsPluginDetray)
target_sources(ActsPythonBindings PRIVATE src/Detray.cpp)
target_link_libraries(ActsPythonBindings PUBLIC ActsPluginCovfie)
target_sources(ActsPythonBindings PRIVATE src/Covfie.cpp)
else()
target_sources(ActsPythonBindings PRIVATE src/DetrayStub.cpp)
target_sources(ActsPythonBindings PRIVATE src/CovfieStub.cpp)
endif()

if(ACTS_BUILD_PLUGIN_ACTSVG)
Expand Down
55 changes: 55 additions & 0 deletions Examples/Python/src/Covfie.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// This file is part of the Acts project.
//
// Copyright (C) 2021 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/.

#include "Acts/Plugins/Covfie/FieldConversion.hpp"
#include "Acts/Plugins/Python/Utilities.hpp"

#include <pybind11/pybind11.h>
#include <pybind11/stl.h>

namespace py = pybind11;
using namespace pybind11::literals;

namespace Acts::Python {

namespace {
template <typename field_t>
void declareCovfieField(py::module& m, const std::string& fieldName) {
using view_t = typename field_t::view_t;
m.def("toView",
[](const field_t& field) { return typename field_t::view_t(field); });
py::class_<field_t, std::shared_ptr<field_t>>(m, fieldName.c_str());
py::class_<view_t, std::shared_ptr<view_t>>(
m, (fieldName + std::string("View")).c_str())
.def("at", &view_t::template at<float, float, float>);
}
} // namespace

void addCovfie(Context& ctx) {
auto main = ctx.get("main");
auto m = main.def_submodule("covfie", "Submodule for covfie conversion");

declareCovfieField<Acts::CovfiePlugin::ConstantField>(m,
"CovfieConstantField");
declareCovfieField<Acts::CovfiePlugin::InterpolatedField>(
m, "CovfieAffineLinearStridedField");

m.def("makeCovfieField",
py::overload_cast<const Acts::InterpolatedMagneticField&>(
&Acts::CovfiePlugin::covfieField));
m.def("makeCovfieField", py::overload_cast<const Acts::ConstantBField&>(
&Acts::CovfiePlugin::covfieField));
m.def("makeCovfieField",
py::overload_cast<const Acts::MagneticFieldProvider&,
Acts::MagneticFieldProvider::Cache&,
const std::array<std::size_t, 3>&,
const Acts::Vector3&, const Acts::Vector3&>(
&Acts::CovfiePlugin::covfieField));
}

} // namespace Acts::Python
13 changes: 13 additions & 0 deletions Examples/Python/src/CovfieStub.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// This file is part of the Acts project.
//
// Copyright (C) 2021 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/.

#include "Acts/Plugins/Python/Utilities.hpp"

namespace Acts::Python {
void addCovfie(Context& /* ctx */) {}
} // 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 @@ -82,6 +82,7 @@ void addSvg(Context& ctx);
void addObj(Context& ctx);
void addOnnx(Context& ctx);
void addOnnxNeuralCalibrator(Context& ctx);
void addCovfie(Context& ctx);

} // namespace Acts::Python

Expand Down Expand Up @@ -148,4 +149,5 @@ PYBIND11_MODULE(ActsPythonBindings, m) {
addSvg(ctx);
addOnnx(ctx);
addOnnxNeuralCalibrator(ctx);
addCovfie(ctx);
}
7 changes: 7 additions & 0 deletions Examples/Python/tests/helpers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@
except ImportError:
onnxEnabled = False

try:
from acts import covfie

covfieEnabled = True
except ImportError:
covfieEnabled = False


try:
import acts.examples
Expand Down
63 changes: 63 additions & 0 deletions Examples/Python/tests/test_covfie.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import pathlib, acts, acts.examples
import pytest

from helpers import covfieEnabled


@pytest.mark.skipif(not covfieEnabled, reason="Covfie plugin not available")
def test_constant_field_conversion():
from acts import covfie

v = acts.Vector3(1, 2, 3)
af = acts.ConstantBField(v)
cf = covfie.makeCovfieField(af)
view = covfie.toView(cf)
points = [(0, 0, 1), (1, 1, 1), (1, 0, 2)]
for x, y, z in points:
assert view.at(x, y, z) == [1, 2, 3]


@pytest.mark.skipif(not covfieEnabled, reason="Covfie plugin not available")
def test_root_field_conversion():
from acts import covfie

current_file_path = pathlib.Path(__file__).resolve().parent
p = (
current_file_path.parent.parent.parent
/ "thirdparty"
/ "OpenDataDetector"
/ "data"
/ "odd-bfield.root"
)

af = acts.examples.MagneticFieldMapXyz(str(p))
bc = acts.MagneticFieldContext()
fc = af.makeCache(bc)

cf = covfie.makeCovfieField(af)
view = covfie.toView(cf)
points = [
(9300.0, 4700.0, 11200.0),
(9999.0, 9999.0, 14300.0),
(-2900.0, -4700.0, 5200.0),
(-2900.0, -4800.0, 9100.0),
(-2900.0, -5200.0, -8800.0),
(-4400.0, 4800.0, -12700.0),
(-6600.0, 1900.0, 7700.0),
(-9700.0, -900.0, 12700.0),
(-9999.0, -9999.0, -13000.0),
(9999.0, 0, 14900.0),
]

error_margin_half_width = 0.0001
for x, y, z in points:
val = af.getField(acts.Vector3(x, y, z), fc)
Bx1, By1, Bz1 = val[0], val[1], val[2]

Bx2, By2, Bz2 = tuple(view.at(x, y, z))

assert (
abs(Bx1 - Bx2) < error_margin_half_width
and abs(By1 - By2) < error_margin_half_width
and abs(Bz1 - Bz2) < error_margin_half_width
)
1 change: 1 addition & 0 deletions Plugins/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ add_component_if(Legacy PluginLegacy ACTS_BUILD_PLUGIN_LEGACY)
add_component_if(Onnx PluginOnnx ACTS_BUILD_PLUGIN_ONNX)
add_component_if(ExaTrkX PluginExaTrkX ACTS_BUILD_PLUGIN_EXATRKX)
add_component_if(Detray PluginDetray ACTS_BUILD_PLUGIN_TRACCC)
add_component_if(Covfie PluginCovfie ACTS_BUILD_PLUGIN_TRACCC)

# dependent plugins. depend either on a independent plugins or on one another
add_component_if(TGeo PluginTGeo ACTS_BUILD_PLUGIN_TGEO)
Expand Down
16 changes: 16 additions & 0 deletions Plugins/Covfie/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
add_library(ActsPluginCovfie SHARED src/FieldConversion.cpp)

target_include_directories(
ActsPluginCovfie
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
target_link_libraries(ActsPluginCovfie PUBLIC ActsCore covfie::core)

install(
TARGETS ActsPluginCovfie
EXPORT ActsPluginCovfieTargets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
install(DIRECTORY include/Acts DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
64 changes: 64 additions & 0 deletions Plugins/Covfie/include/Acts/Plugins/Covfie/FieldConversion.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// This file is part of the Acts project.
//
// Copyright (C) 2023 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 <covfie/core/algebra/affine.hpp>
#include <covfie/core/backend/primitive/array.hpp>
#include <covfie/core/backend/primitive/constant.hpp>
#include <covfie/core/backend/transformer/affine.hpp>
#include <covfie/core/backend/transformer/clamp.hpp>
#include <covfie/core/backend/transformer/linear.hpp>
#include <covfie/core/backend/transformer/strided.hpp>
#include <covfie/core/field.hpp>
#include <covfie/core/field_view.hpp>
#include <covfie/core/parameter_pack.hpp>

// acts includes
#include "Acts/MagneticField/BFieldMapUtils.hpp"
#include "Acts/MagneticField/ConstantBField.hpp"
#include "Acts/MagneticField/MagneticFieldProvider.hpp"

namespace Acts::CovfiePlugin {

using BuilderBackend =
covfie::backend::strided<covfie::vector::size3,
covfie::backend::array<covfie::vector::float3>>;

using InterpolatedField = covfie::field<covfie::backend::clamp<
covfie::backend::affine<covfie::backend::linear<BuilderBackend>>>>;

using ConstantField = covfie::field<
covfie::backend::constant<covfie::vector::float3, covfie::vector::float3>>;

/// @brief Creates a covfie field from an interpolated magnetic field.
/// @param magneticField The acts interpolated magnetic field.
/// @return An affine linear strided covfie field.
InterpolatedField covfieField(
const Acts::InterpolatedMagneticField& magneticField);

/// @brief Creates a covfie field from a constant B field.
/// @param magneticField The acts constant magnetic field.
/// @return A constant covfie field.
ConstantField covfieField(const Acts::ConstantBField& magneticField);

/// @brief Creates a covfie field from a magnetic field provider by sampling it.
/// The field must be defined within min (inclusive) and max (inclusive).
/// @param magneticField The acts magnetic field provider.
/// @param cache The acts cache.
/// @param nPoints 3D array of containing the number of bins for each axis.
/// @param min (min_x, min_y, min_z)
/// @param max (max_x, max_y, max_z)
/// @return An affine linear strided covfie field.
InterpolatedField covfieField(const Acts::MagneticFieldProvider& magneticField,
Acts::MagneticFieldProvider::Cache& cache,
const std::array<std::size_t, 3>& nPoints,
const Acts::Vector3& min,
const Acts::Vector3& max);

} // namespace Acts::CovfiePlugin
Loading
Loading