diff --git a/CMakeLists.txt b/CMakeLists.txt index f1ae068d049..dafc65b5438 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -157,6 +157,14 @@ set_option_if(ACTS_BUILD_PLUGIN_LEGACY ACTS_BUILD_EVERYTHING) set_option_if(ACTS_BUILD_PLUGIN_EXATRKX ACTS_BUILD_EXAMPLES_EXATRKX) set_option_if(ACTS_BUILD_PLUGIN_FPEMON ACTS_BUILD_EXAMPLES OR ACTS_BUILD_EVERYTHING) +set_option_if(ACTS_SETUP_ALGEBRAPLUGINS + ACTS_BUILD_EXAMPLES OR ACTS_BUILD_EVERYTHING) +set_option_if(ACTS_SETUP_VECMEM + ACTS_BUILD_EXAMPLES OR ACTS_BUILD_EVERYTHING) +set_option_if(ACTS_SETUP_COVFIE + ACTS_BUILD_EXAMPLES OR ACTS_BUILD_EVERYTHING) +set_option_if(ACTS_BUILD_PLUGIN_COVFIE + ACTS_BUILD_EXAMPLES OR ACTS_BUILD_EVERYTHING) # feature tests include(CheckCXXSourceCompiles) diff --git a/Examples/Python/CMakeLists.txt b/Examples/Python/CMakeLists.txt index ba8672c1d74..2414ff1d93e 100644 --- a/Examples/Python/CMakeLists.txt +++ b/Examples/Python/CMakeLists.txt @@ -197,6 +197,13 @@ else() target_sources(ActsPythonBindings PRIVATE src/OnnxNeuralCalibratorStub.cpp) endif() +if(ACTS_BUILD_PLUGIN_COVFIE) + target_link_libraries(ActsPythonBindings PUBLIC ActsPluginCovfie) + target_sources(ActsPythonBindings PRIVATE src/Covfie.cpp) +else() + target_sources(ActsPythonBindings PRIVATE src/CovfieStub.cpp) +endif() + configure_file(setup.sh.in ${_python_dir}/setup.sh @ONLY) install(FILES ${_python_dir}/setup.sh DESTINATION "python") diff --git a/Examples/Python/src/Covfie.cpp b/Examples/Python/src/Covfie.cpp new file mode 100644 index 00000000000..a8d5beb2229 --- /dev/null +++ b/Examples/Python/src/Covfie.cpp @@ -0,0 +1,63 @@ +// 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 +#include + +namespace py = pybind11; +using namespace pybind11::literals; + +namespace Acts::Python { + +namespace { + +template +typename field_t::view_t newView(const field_t& field) { + typename field_t::view_t view(field); + return view; +} + +template +void declareCovfieField(py::module& m, const std::string& fieldName) { + using view_t = typename field_t::view_t; + m.def("newView", static_cast(&newView)); + py::class_>(m, fieldName.c_str()); + py::class_>( + m, (fieldName + std::string("View")).c_str()) + .def("at", &view_t::template at); +} + +} // namespace +void addCovfie(Context& ctx) { + auto main = ctx.get("main"); + auto m = main.def_submodule("covfie_conversion", + "Submodule for covfie conversion"); + + declareCovfieField( + m, "CovfieConstantField"); + declareCovfieField( + m, "CovfieAffineLinearStridedField"); + + m.def("covfieField", + py::overload_cast( + &Acts::CovfiePlugin::covfieField)); + m.def("covfieField", py::overload_cast( + &Acts::CovfiePlugin::covfieField)); + m.def( + "covfieField", + py::overload_cast&, + const std::vector&, const std::vector&>( + &Acts::CovfiePlugin::covfieField)); +} + +} // namespace Acts::Python diff --git a/Examples/Python/src/CovfieStub.cpp b/Examples/Python/src/CovfieStub.cpp new file mode 100644 index 00000000000..49ec071fd8c --- /dev/null +++ b/Examples/Python/src/CovfieStub.cpp @@ -0,0 +1,20 @@ +// 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" + +#include +#include + +namespace py = pybind11; +using namespace pybind11::literals; + +namespace Acts::Python { +void addCovfie(Context& /* ctx */) {} + +} // namespace Acts::Python diff --git a/Examples/Python/src/MagneticField.cpp b/Examples/Python/src/MagneticField.cpp index a8279675696..c26eb329d81 100644 --- a/Examples/Python/src/MagneticField.cpp +++ b/Examples/Python/src/MagneticField.cpp @@ -45,7 +45,9 @@ void addMagneticField(Context& ctx) { py::class_>( - m, "InterpolatedMagneticField"); + m, "InterpolatedMagneticField") + .def("getFieldUnchecked", + &Acts::InterpolatedMagneticField::getFieldUnchecked); m.def("solenoidFieldMap", &Acts::solenoidFieldMap, py::arg("rlim"), py::arg("zlim"), py::arg("nbins"), py::arg("field")); diff --git a/Examples/Python/src/ModuleEntry.cpp b/Examples/Python/src/ModuleEntry.cpp index cc6442fe285..bc779fdc3bf 100644 --- a/Examples/Python/src/ModuleEntry.cpp +++ b/Examples/Python/src/ModuleEntry.cpp @@ -77,6 +77,7 @@ void addSvg(Context& ctx); void addObj(Context& ctx); void addOnnx(Context& ctx); void addOnnxNeuralCalibrator(Context& ctx); +void addCovfie(Context& ctx); } // namespace Acts::Python @@ -138,4 +139,5 @@ PYBIND11_MODULE(ActsPythonBindings, m) { addSvg(ctx); addOnnx(ctx); addOnnxNeuralCalibrator(ctx); + addCovfie(ctx); } diff --git a/Examples/Python/tests/test_covfie.py b/Examples/Python/tests/test_covfie.py new file mode 100644 index 00000000000..5178c92ead3 --- /dev/null +++ b/Examples/Python/tests/test_covfie.py @@ -0,0 +1,51 @@ +import pathlib, acts, acts.examples +from acts import covfie_conversion as cc + + +def test_constant_field_conversion(): + v = acts.Vector3(1, 2, 3) + af = acts.ConstantBField(v) + cf = cc.covfieField(af) + view = cc.newView(cf) + for x, y, z in [(0, 0, 1), (1, 1, 1), (1, 0, 2)]: + assert view.at(x, y, z) == [1, 2, 3] + + +def test_root_field_conversion(): + 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)) + cf = cc.covfieField(af) + view = cc.newView(cf) + points = [ + (9300.0, 4700.0, 11200.0), + (10000.0, 10000.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), + (-10000.0, -10000.0, -13000.0), + (10000.0, 10000.0, 14300.0), + ] + + error_margin_half_width = 0.0001 + for x, y, z in points: + val = af.getFieldUnchecked(acts.Vector3(x, y, z)) + 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 + ) diff --git a/Plugins/CMakeLists.txt b/Plugins/CMakeLists.txt index 93fa92a23e8..fff533d1b37 100644 --- a/Plugins/CMakeLists.txt +++ b/Plugins/CMakeLists.txt @@ -10,6 +10,7 @@ add_component_if(Json PluginJson ACTS_BUILD_PLUGIN_JSON) 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(Covfie PluginCovfie ACTS_BUILD_PLUGIN_COVFIE) # dependent plugins. depend either on a independent plugins or on one another add_component_if(TGeo PluginTGeo ACTS_BUILD_PLUGIN_TGEO) diff --git a/Plugins/Covfie/CMakeLists.txt b/Plugins/Covfie/CMakeLists.txt new file mode 100644 index 00000000000..b17ede0cc02 --- /dev/null +++ b/Plugins/Covfie/CMakeLists.txt @@ -0,0 +1,22 @@ +add_library( + ActsPluginCovfie SHARED + src/FieldConversion.cpp) + +target_include_directories( + ActsPluginCovfie + PUBLIC + $ + $) +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}) diff --git a/Plugins/Covfie/include/Acts/Plugins/Covfie/FieldConversion.hpp b/Plugins/Covfie/include/Acts/Plugins/Covfie/FieldConversion.hpp new file mode 100644 index 00000000000..252ffebc08c --- /dev/null +++ b/Plugins/Covfie/include/Acts/Plugins/Covfie/FieldConversion.hpp @@ -0,0 +1,63 @@ +// 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// acts includes +#include "Acts/MagneticField/BFieldMapUtils.hpp" +#include "Acts/MagneticField/ConstantBField.hpp" +#include "Acts/MagneticField/MagneticFieldProvider.hpp" + +namespace Acts::CovfiePlugin { + +using builder_backend_t = + covfie::backend::strided>; + +using interpolated_field_t = covfie::field>>>; + +using constant_field_t = covfie::field< + covfie::backend::constant>; + +/// @brief Creates a covfie field from an interpolated magnetic field. +/// @param magneticField The acts interpolated magnetic field. +/// @return An affine linear strided covfie field. +interpolated_field_t 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. +constant_field_t covfieField(const Acts::ConstantBField& magneticField); + +/// @brief Creates a covfie field from a magnetic field provider by sampling it. +/// @param magneticField The acts magnetic field provider. +/// @param cache The acts cache. +/// @param nBins 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. +interpolated_field_t covfieField( + const Acts::MagneticFieldProvider& magneticField, + Acts::MagneticFieldProvider::Cache& cache, + const std::vector& nBins, const std::vector& min, + const std::vector& max); + +} // namespace Acts::CovfiePlugin diff --git a/Plugins/Covfie/src/FieldConversion.cpp b/Plugins/Covfie/src/FieldConversion.cpp new file mode 100644 index 00000000000..661f5939a50 --- /dev/null +++ b/Plugins/Covfie/src/FieldConversion.cpp @@ -0,0 +1,181 @@ +// 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/. + +#include "Acts/Plugins/Covfie/FieldConversion.hpp" + +namespace Acts::CovfiePlugin { + +/// @brief Get the value of the interpolated field at a specific position (unchecked). +/// @tparam cache_t +/// @param magneticField +/// @param cache +/// @param position +/// @return +template +auto fieldLookup(const Acts::InterpolatedMagneticField& magneticField, + [[maybe_unused]] cache_t& cache, + const Acts::Vector3& position) { + return magneticField.getFieldUnchecked(position); +} + +/// @brief Get the value of the field at a specific position of a general magnetic field. +/// @tparam cache_t +/// @param magneticField +/// @param cache +/// @param position +/// @return +template +auto fieldLookup(const Acts::MagneticFieldProvider& magneticField, + cache_t& cache, const Acts::Vector3& position) { + auto lookupResult = magneticField.getField(position, cache); + if (!lookupResult.ok()) { + throw std::runtime_error{"Field lookup failure"}; + } + return *lookupResult; +} + +/// @brief Creates a strided covfie field that stores the values of the magnetic field in the volume given by min and max using a fixed sample spacing (determined by nBins). +/// @param magneticField The acts magnetic field. +/// @param cache The acts cache. +/// @param nBins 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 A strided covfie field. +template +auto newBuilder(const magnetic_field_t& magneticField, cache_t& cache, + const point3_1_t& nBins, const point3_2_t& min, + const point3_3_t& max) { + using field_t = covfie::field; + + field_t field(covfie::make_parameter_pack( + field_t::backend_t::configuration_t{nBins[0], nBins[1], nBins[2]})); + + field_t::view_t view(field); + + std::array sampleSpacing = {(max[0] - min[0]) / (nBins[0] - 1), + (max[1] - min[1]) / (nBins[1] - 1), + (max[2] - min[2]) / (nBins[2] - 1)}; + + for (std::size_t x = 0; x < nBins[0]; x++) { + for (std::size_t y = 0; y < nBins[1]; y++) { + for (std::size_t z = 0; z < nBins[2]; z++) { + auto position = Acts::Vector3{x * sampleSpacing[0] + min[0], + y * sampleSpacing[1] + min[1], + z * sampleSpacing[2] + min[2]}; + + auto result = fieldLookup(magneticField, cache, position); + + field_t::view_t::output_t& p = view.at(x, y, z); + p[0] = static_cast(result[0]); + p[1] = static_cast(result[1]); + p[2] = static_cast(result[2]); + } + } + } + return field; +} + +/// @brief Generated the affine covfie configuration (scaling and rotation) given the size of the field (min and max) +/// @param nBins 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 The affine field configuration. +template +auto affineConfiguration(const point3_1_t& nBins, const point3_2_t& min, + const point3_3_t& max) { + auto scaling = covfie::algebra::affine<3>::scaling( + static_cast((nBins[0] - 1) / (max[0] - min[0])), + static_cast((nBins[1] - 1) / (max[1] - min[1])), + static_cast((nBins[2] - 1) / (max[2] - min[2]))); + + auto translation = covfie::algebra::affine<3>::translation( + static_cast(-min[0]), static_cast(-min[1]), + static_cast(-min[2])); + + return typename backend_t::configuration_t(scaling * translation); +} + +/// @brief Creates a covfie field from a generic magnetic field. +/// @param magneticField The generic magnetic field. +/// @param cache The cache. +/// @param nBins 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 A clamp affine linear strided covfie field. +template +interpolated_field_t covfieFieldLinear(const magnetic_field_t& magneticField, + cache_t& cache, const point3_1_t& nBins, + const point3_2_t& min, + const point3_3_t& max) { + auto builder = newBuilder(magneticField, cache, nBins, min, max); + interpolated_field_t::backend_t::configuration_t clampConfiguration{ + {std::nextafter(static_cast(min[0]), + std::numeric_limits::infinity()), + std::nextafter(static_cast(min[1]), + std::numeric_limits::infinity()), + std::nextafter(static_cast(min[2]), + std::numeric_limits::infinity())}, + {std::nextafter(static_cast(max[0]), + -std::numeric_limits::infinity()), + std::nextafter(static_cast(max[1]), + -std::numeric_limits::infinity()), + std::nextafter(static_cast(max[2]), + -std::numeric_limits::infinity())}}; + + interpolated_field_t field(covfie::make_parameter_pack( + std::move(clampConfiguration), + affineConfiguration(nBins, + min, max), + interpolated_field_t::backend_t::backend_t::backend_t::configuration_t{}, + builder.backend())); + + return field; +} + +/// @brief Creates a covfie field from a magnetic field provider by sampling it. +/// @param magneticField The acts magnetic field provider. +/// @param cache The acts cache. +/// @param nBins 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 A clamp affine linear strided covfie field. +interpolated_field_t covfieField( + const Acts::MagneticFieldProvider& magneticField, + Acts::MagneticFieldProvider::Cache& cache, + const std::vector& nBins, const std::vector& min, + const std::vector& max) { + return covfieFieldLinear(magneticField, cache, nBins, min, max); +} + +/// @brief Creates a covfie field from an interpolated magnetic field. +/// @param magneticField The acts interpolated magnetic field. +/// @return A clamp affine linear strided covfie field. +interpolated_field_t covfieField( + const Acts::InterpolatedMagneticField& magneticField) { + Acts::MagneticFieldContext ctx; + auto cache = magneticField.makeCache(ctx); + return covfieFieldLinear(magneticField, cache, magneticField.getNBins(), + magneticField.getMin(), magneticField.getMax()); +} + +/// @brief Creates a covfie field from a constant B field. +/// @param magneticField The acts constant magnetic field. +/// @return A constant covfie field. +constant_field_t covfieField(const Acts::ConstantBField& magneticField) { + auto B = magneticField.getField(); + constant_field_t field( + covfie::make_parameter_pack(constant_field_t::backend_t::configuration_t{ + static_cast(B[0]), static_cast(B[1]), + static_cast(B[2])})); + return field; +} + +} // namespace Acts::CovfiePlugin diff --git a/Tests/UnitTests/Plugins/CMakeLists.txt b/Tests/UnitTests/Plugins/CMakeLists.txt index a3ce9f373ef..ced753aeb5f 100644 --- a/Tests/UnitTests/Plugins/CMakeLists.txt +++ b/Tests/UnitTests/Plugins/CMakeLists.txt @@ -9,3 +9,4 @@ add_subdirectory_if(TGeo ACTS_BUILD_PLUGIN_TGEO) add_subdirectory_if(EDM4hep ACTS_BUILD_PLUGIN_EDM4HEP) add_subdirectory_if(FpeMonitoring ACTS_BUILD_PLUGIN_FPEMON) add_subdirectory_if(Podio ACTS_BUILD_PLUGIN_PODIO) +add_subdirectory_if(Covfie ACTS_BUILD_PLUGIN_COVFIE) diff --git a/Tests/UnitTests/Plugins/Covfie/CMakeLists.txt b/Tests/UnitTests/Plugins/Covfie/CMakeLists.txt new file mode 100644 index 00000000000..9e9eb803189 --- /dev/null +++ b/Tests/UnitTests/Plugins/Covfie/CMakeLists.txt @@ -0,0 +1,2 @@ +set(unittest_extra_libraries ActsPluginCovfie) +add_unittest(CovfieFieldConversion CovfieFieldConversionTest.cpp) \ No newline at end of file diff --git a/Tests/UnitTests/Plugins/Covfie/CovfieFieldConversionTest.cpp b/Tests/UnitTests/Plugins/Covfie/CovfieFieldConversionTest.cpp new file mode 100644 index 00000000000..6e30cfb9d93 --- /dev/null +++ b/Tests/UnitTests/Plugins/Covfie/CovfieFieldConversionTest.cpp @@ -0,0 +1,212 @@ +// 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/. + +// Acts include(s) +#include "Acts/Definitions/Units.hpp" +#include "Acts/MagneticField/ConstantBField.hpp" +#include "Acts/MagneticField/MagneticFieldContext.hpp" +#include "Acts/MagneticField/MagneticFieldProvider.hpp" +#include "Acts/MagneticField/SolenoidBField.hpp" + +// Covfie Plugin include(s) +#include "Acts/Plugins/Covfie/FieldConversion.hpp" + +// System include(s) +#include +#include +#include +#include + +// Boost include(s) +#include + +using namespace Acts::UnitLiterals; + +template +void CheckMagneticFieldEqual(const Acts::MagneticFieldProvider& fieldProvider, + cache_t& cache, view_t view, iterator_t points, + float error_margin_half_width) { + for (auto point : points) { + auto x = point[0], y = point[1], z = point[2]; + + auto lookupResult = fieldProvider.getField(Acts::Vector3{x, y, z}, cache); + if (!lookupResult.ok()) { + throw std::runtime_error{"Field lookup failure"}; + } + auto actsValueX = (*lookupResult)[0], actsValueY = (*lookupResult)[1], + actsValueZ = (*lookupResult)[2]; + + auto covfieValues = view.at(x, y, z); + auto covfieValueX = covfieValues[0], covfieValueY = covfieValues[1], + covfieValueZ = covfieValues[2]; + + auto isEqual = + error_margin_half_width < std::abs(covfieValueX - actsValueX) || + error_margin_half_width < std::abs(covfieValueY - actsValueY) || + error_margin_half_width < std::abs(covfieValueZ - actsValueZ); + + std::stringstream ss; + ss << "Fields are not equal at position (" << x << ", " << y << ", " << z + << "). Acts: (" << actsValueX << ", " << actsValueY << ", " << actsValueZ + << "), Covfie: (" << covfieValueX << ", " << covfieValueY << ", " + << covfieValueZ << ")" << std::endl; + + BOOST_CHECK_MESSAGE(!isEqual, ss.str()); + } +} + +BOOST_AUTO_TEST_SUITE(CovfiePlugin) + +BOOST_AUTO_TEST_CASE(InterpolatedMagneticField1) { + auto localToGlobalBin_xyz = [](std::array binsXYZ, + std::array nBinsXYZ) { + return (binsXYZ.at(0) * (nBinsXYZ.at(1) * nBinsXYZ.at(2)) + + binsXYZ.at(1) * nBinsXYZ.at(2) + binsXYZ.at(2)); + }; + + std::vector xPos = {0., 1., 2., 3.}; + std::vector yPos = {0., 1., 2., 3.}; + std::vector zPos = {0., 1., 2., 3.}; + + std::vector bField_xyz; + for (int i = 0; i < 64; i++) { + bField_xyz.push_back(Acts::Vector3(i, i, i)); + } + + Acts::MagneticFieldContext fieldContext; + auto actsField = Acts::fieldMapXYZ(localToGlobalBin_xyz, xPos, yPos, zPos, + bField_xyz, 1, 1, false); + auto cache = actsField.makeCache(fieldContext); + + auto field = Acts::CovfiePlugin::covfieField(actsField); + auto view = typename decltype(field)::view_t(field); + + std::array, 13> points = {{ + {0.f, 0.f, 0.f}, + {1.f, 1.f, 1.f}, + {2.f, 2.f, 2.f}, + {1.2f, 2.5f, 0.8f}, + {0.7f, 1.9f, 2.3f}, + {2.1f, 0.3f, 1.5f}, + {0.4f, 2.8f, 2.9f}, + {1.6f, 1.2f, 0.5f}, + {2.3f, 0.6f, 2.2f}, + {1.1f, 2.7f, 1.3f}, + {0.9f, 1.4f, 2.7f}, + {2.4f, 1.8f, 0.9f}, + {0.6f, 2.2f, 2.1f}, + }}; + + CheckMagneticFieldEqual(actsField, cache, view, points, 0.0001); +} + +BOOST_AUTO_TEST_CASE(InterpolatedMagneticField2) { + auto localToGlobalBin_xyz = [](std::array binsXYZ, + std::array nBinsXYZ) { + return (binsXYZ.at(0) * (nBinsXYZ.at(1) * nBinsXYZ.at(2)) + + binsXYZ.at(1) * nBinsXYZ.at(2) + binsXYZ.at(2)); + }; + + std::vector xPos = {8., 12., 16., 20.}; + std::vector yPos = {8., 12., 16., 20.}; + std::vector zPos = {8., 12., 16., 20.}; + + std::vector bField_xyz; + for (int i = 0; i < 64; i++) { + bField_xyz.push_back(Acts::Vector3(i, i * i * 0.01, i)); + } + + Acts::MagneticFieldContext fieldContext; + auto actsField = Acts::fieldMapXYZ(localToGlobalBin_xyz, xPos, yPos, zPos, + bField_xyz, 1, 1, false); + auto cache = actsField.makeCache(fieldContext); + + auto field = Acts::CovfiePlugin::covfieField(actsField); + auto view = typename decltype(field)::view_t(field); + + std::array, 13> points = {{ + {8.f, 8.f, 8.f}, + {12.f, 12.f, 12.f}, + {16.f, 16.f, 16.f}, + {8.1f, 10.2f, 12.3f}, + {9.4f, 11.5f, 13.6f}, + {10.7f, 12.8f, 14.9f}, + {11.0f, 13.1f, 15.2f}, + {12.3f, 14.4f, 16.5f}, + {13.6f, 15.7f, 17.8f}, + {14.9f, 16.0f, 18.1f}, + {16.2f, 17.3f, 19.4f}, + {17.5f, 18.6f, 19.7f}, + {18.8f, 19.9f, 14.0f}, + }}; + + CheckMagneticFieldEqual(actsField, cache, view, points, 0.0001f); +} + +BOOST_AUTO_TEST_CASE(ConstantMagneticField1) { + Acts::ConstantBField actsField(Acts::Vector3{1.3f, 2.5f, 2.f}); + Acts::MagneticFieldContext ctx; + auto cache = actsField.makeCache(ctx); + + auto field = Acts::CovfiePlugin::covfieField(actsField); + auto view = typename decltype(field)::view_t(field); + + std::array, 13> points = {{ + {8.f, 8.f, 8.f}, + {12.f, 12.f, 12.f}, + {16.f, 16.f, 16.f}, + {8.1f, 10.2f, 12.3f}, + {9.4f, 11.5f, 13.6f}, + {10.7f, 12.8f, 14.9f}, + {11.0f, 13.1f, 15.2f}, + {12.3f, 14.4f, 16.5f}, + {13.6f, 15.7f, 17.8f}, + {14.9f, 16.0f, 18.1f}, + {16.2f, 17.3f, 19.4f}, + {17.5f, 18.6f, 19.7f}, + {18.8f, 19.9f, 14.0f}, + }}; + + CheckMagneticFieldEqual(actsField, cache, view, points, 0.0901); +} + +BOOST_AUTO_TEST_CASE(MagneticFieldProvider1) { + Acts::SolenoidBField::Config cfg; + cfg.length = 5.8_m; + cfg.radius = (2.56 + 2.46) * 0.5 * 0.5_m; + cfg.nCoils = 1154; + cfg.bMagCenter = 2_T; + Acts::SolenoidBField actsField(cfg); + Acts::MagneticFieldContext ctx; + auto cache = actsField.makeCache(ctx); + + auto field = Acts::CovfiePlugin::covfieField( + actsField, cache, std::vector{20UL, 20UL, 20UL}, std::vector{0., 0., 0.}, + std::vector{20., 20., 20.}); + auto view = typename decltype(field)::view_t(field); + + std::array, 13> points = {{ + {8.f, 8.f, 8.f}, + {12.f, 12.f, 12.f}, + {16.f, 16.f, 16.f}, + {8.1f, 10.2f, 12.3f}, + {9.4f, 11.5f, 13.6f}, + {10.7f, 12.8f, 14.9f}, + {11.0f, 13.1f, 15.2f}, + {12.3f, 14.4f, 16.5f}, + {13.6f, 15.7f, 17.8f}, + {14.9f, 16.0f, 18.1f}, + {16.2f, 17.3f, 19.4f}, + {17.5f, 18.6f, 19.7f}, + {18.8f, 19.9f, 14.0f}, + }}; + + CheckMagneticFieldEqual(actsField, cache, view, points, 0.0001); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/cmake/ActsConfig.cmake.in b/cmake/ActsConfig.cmake.in index 0233e09c74a..d8619193b13 100644 --- a/cmake/ActsConfig.cmake.in +++ b/cmake/ActsConfig.cmake.in @@ -76,6 +76,9 @@ endif() if(PluginPodio IN_LIST Acts_COMPONENTS) find_dependency(podio @podio_VERSION@ CONFIG EXACT) endif() +if(PluginCovfie IN_LIST Acts_COMPONENTS) + find_dependency(covfie @covfie_VERSION@ CONFIG EXACT) +endif() # dependencies that we have built ourselves but cannot be # straightforwardly handed to cmake diff --git a/cmake/ActsExternSources.cmake b/cmake/ActsExternSources.cmake index 10bfbe13a3e..461090be5f9 100644 --- a/cmake/ActsExternSources.cmake +++ b/cmake/ActsExternSources.cmake @@ -38,7 +38,7 @@ set( ACTS_NLOHMANNJSON_SOURCE "URL;https://github.com/nlohmann/json/archive/refs/tags/v3.10.5.tar.gz;URL_HASH;SHA1=8969f5ad1a422e01f040ff48dcae9c0e6ad0811d" CACHE STRING "Source to take nlohmann_json from") mark_as_advanced( ACTS_NLOHMANN_JSON_SOURCE ) -string(REPLACE "." "_" _acts_boost_recommended_version_ ${_acts_boost_recommended_version}) +string(REPLACE "." "_" _acts_boost_recommended_version_ "${_acts_boost_recommended_version}") set( ACTS_BOOST_SOURCE "URL;https://boostorg.jfrog.io/artifactory/main/release/${_acts_boost_recommended_version}/source/boost_${_acts_boost_recommended_version_}.tar.gz" CACHE STRING "Source to take boost from") mark_as_advanced( ACTS_BOOST_SOURCE ) diff --git a/thirdparty/algebra-plugins/CMakeLists.txt b/thirdparty/algebra-plugins/CMakeLists.txt index a0126cece7f..2472c70ccd4 100644 --- a/thirdparty/algebra-plugins/CMakeLists.txt +++ b/thirdparty/algebra-plugins/CMakeLists.txt @@ -20,7 +20,7 @@ set(ALGEBRA_PLUGINS_BUILD_TESTING FALSE CACHE BOOL "Turn off the build of the Algebra Plugins unit tests") set(ALGEBRA_PLUGINS_INCLUDE_EIGEN TRUE CACHE BOOL "Turn on the build of algebra::eigen") -set(ALGEBRA_PLUGINS_INCLUDE_VC TRUE CACHE BOOL +set(ALGEBRA_PLUGINS_INCLUDE_VC FALSE CACHE BOOL "Turn on the build of algebra::vc_array") set(ALGEBRA_PLUGINS_INCLUDE_VECMEM TRUE CACHE BOOL "Turn on the build of algebra::vecmem_array") @@ -32,7 +32,7 @@ set(ALGEBRA_PLUGINS_INCLUDE_SMATRIX ${DETRAY_SMATRIX_PLUGIN} set(ALGEBRA_PLUGINS_SETUP_EIGEN3 OFF CACHE BOOL "Do not have Algebra Plugins set up Eigen3 for itself") -set(ALGEBRA_PLUGINS_SETUP_VC ON CACHE BOOL +set(ALGEBRA_PLUGINS_SETUP_VC OFF CACHE BOOL "Have Algebra Plugins set up Vc for itself") set(ALGEBRA_PLUGINS_USE_SYSTEM_VC OFF CACHE BOOL "Have Algebra Plugins build Vc itself") diff --git a/thirdparty/dfelibs/README.MD b/thirdparty/dfelibs/README.MD new file mode 100644 index 00000000000..3cf5007073e --- /dev/null +++ b/thirdparty/dfelibs/README.MD @@ -0,0 +1,4 @@ +# Build Recipe for dfelibs + +This directory holds a simple build recipe for the +[dfelibs](https://github.com/acts-project/dfelibs) project. \ No newline at end of file