diff --git a/Examples/Algorithms/Digitization/CMakeLists.txt b/Examples/Algorithms/Digitization/CMakeLists.txt index 14729f2784f..de98c7e74d4 100644 --- a/Examples/Algorithms/Digitization/CMakeLists.txt +++ b/Examples/Algorithms/Digitization/CMakeLists.txt @@ -3,6 +3,7 @@ add_library( SHARED src/DigitizationAlgorithm.cpp src/DigitizationConfig.cpp + src/DigitizationCoordinatesConverter.cpp src/MeasurementCreation.cpp src/DigitizationConfigurator.cpp src/ModuleClusters.cpp diff --git a/Examples/Algorithms/Digitization/include/ActsExamples/Digitization/DigitizationCoordinatesConverter.hpp b/Examples/Algorithms/Digitization/include/ActsExamples/Digitization/DigitizationCoordinatesConverter.hpp new file mode 100644 index 00000000000..2b7e6ba26a2 --- /dev/null +++ b/Examples/Algorithms/Digitization/include/ActsExamples/Digitization/DigitizationCoordinatesConverter.hpp @@ -0,0 +1,39 @@ +// 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 "ActsExamples/Digitization/DigitizationConfig.hpp" + +namespace ActsExamples { + +/// Utility that converts hit coordinates. +class DigitizationCoordinatesConverter final { + public: + /// Construct the converter + /// + /// @param config is the configuration + DigitizationCoordinatesConverter(DigitizationConfig config); + + /// Get const access to the config + const DigitizationConfig& config() const { return m_cfg; } + + /// Convert the hit coordinates to the local frame. + std::tuple globalToLocal(std::uint64_t moduleId, double x, + double y, double z) const; + + /// Convert the hit coordinates to the global frame. + std::tuple localToGlobal(std::uint64_t moduleId, + double x, double y) const; + + private: + /// Configuration + DigitizationConfig m_cfg; +}; + +} // namespace ActsExamples diff --git a/Examples/Algorithms/Digitization/src/DigitizationCoordinatesConverter.cpp b/Examples/Algorithms/Digitization/src/DigitizationCoordinatesConverter.cpp new file mode 100644 index 00000000000..454f2bfeedc --- /dev/null +++ b/Examples/Algorithms/Digitization/src/DigitizationCoordinatesConverter.cpp @@ -0,0 +1,63 @@ +// 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/. + +#include "ActsExamples/Digitization/DigitizationCoordinatesConverter.hpp" + +#include "Acts/Definitions/Algebra.hpp" +#include "Acts/Geometry/GeometryContext.hpp" + +#include +#include +#include + +ActsExamples::DigitizationCoordinatesConverter:: + DigitizationCoordinatesConverter(DigitizationConfig config) + : m_cfg(std::move(config)) { + if (m_cfg.surfaceByIdentifier.empty()) { + throw std::invalid_argument("Missing Surface-GeometryID association map"); + } +} + +std::tuple +ActsExamples::DigitizationCoordinatesConverter::globalToLocal( + std::uint64_t moduleId, double x, double y, double z) const { + const Acts::GeometryIdentifier moduleGeoId = moduleId; + auto surfaceItr = m_cfg.surfaceByIdentifier.find(moduleGeoId); + if (surfaceItr == m_cfg.surfaceByIdentifier.end()) { + throw std::runtime_error("Surface not found for moduleGeoId"); + } + + // Transform the position into the local surface frame + const Acts::Surface* surfacePtr = surfaceItr->second; + const auto& invTransform = + surfacePtr->transform(Acts::GeometryContext()).inverse(); + + const Acts::Vector3 pos(x, y, z); + Acts::Vector2 pos2Local = (invTransform * pos).segment<2>(0); + + return {pos2Local.x(), pos2Local.y()}; +} + +std::tuple +ActsExamples::DigitizationCoordinatesConverter::localToGlobal( + std::uint64_t moduleId, double x, double y) const { + const Acts::GeometryIdentifier moduleGeoId = moduleId; + auto surfaceItr = m_cfg.surfaceByIdentifier.find(moduleGeoId); + if (surfaceItr == m_cfg.surfaceByIdentifier.end()) { + throw std::runtime_error("Surface not found for moduleGeoId"); + } + + // Transform the position into the global frame + const Acts::Surface* surfacePtr = surfaceItr->second; + const auto& transform = surfacePtr->transform(Acts::GeometryContext()); + + const Acts::Vector3 pos(x, y, 0); + Acts::Vector3 pos2Global = (transform * pos); + + return {pos2Global.x(), pos2Global.y(), pos2Global.z()}; +} diff --git a/Examples/Python/src/Digitization.cpp b/Examples/Python/src/Digitization.cpp index c392d6dcc8c..948bcc9593b 100644 --- a/Examples/Python/src/Digitization.cpp +++ b/Examples/Python/src/Digitization.cpp @@ -13,6 +13,7 @@ #include "ActsExamples/Digitization/DigitizationAlgorithm.hpp" #include "ActsExamples/Digitization/DigitizationConfig.hpp" #include "ActsExamples/Digitization/DigitizationConfigurator.hpp" +#include "ActsExamples/Digitization/DigitizationCoordinatesConverter.hpp" #include "ActsExamples/Framework/AlgorithmContext.hpp" #include "ActsExamples/Io/Json/JsonDigitizationConfig.hpp" @@ -101,6 +102,19 @@ void addDigitization(Context& ctx) { ACTS_PYTHON_MEMBER(outputDigiComponents); ACTS_PYTHON_STRUCT_END(); } + + { + py::class_>( + mex, "DigitizationCoordinatesConverter") + .def(py::init(), py::arg("config")) + .def_property_readonly( + "config", &ActsExamples::DigitizationCoordinatesConverter::config) + .def("globalToLocal", + &ActsExamples::DigitizationCoordinatesConverter::globalToLocal) + .def("localToGlobal", + &ActsExamples::DigitizationCoordinatesConverter::localToGlobal); + } } } // namespace Acts::Python