|
| 1 | +/** TRACCC library, part of the ACTS project (R&D line) |
| 2 | + * |
| 3 | + * (c) 2024 CERN for the benefit of the ACTS project |
| 4 | + * |
| 5 | + * Mozilla Public License Version 2.0 |
| 6 | + */ |
| 7 | + |
| 8 | +#pragma once |
| 9 | + |
| 10 | +// Project include(s). |
| 11 | +#include "traccc/geometry/detector.hpp" |
| 12 | +#include "traccc/geometry/host_detector.hpp" |
| 13 | +#include "traccc/geometry/move_only_any.hpp" |
| 14 | + |
| 15 | +// Detray include(s). |
| 16 | +#include <any> |
| 17 | +#include <detray/core/detector.hpp> |
| 18 | +#include <detray/detectors/default_metadata.hpp> |
| 19 | +#include <detray/detectors/telescope_metadata.hpp> |
| 20 | +#include <detray/detectors/toy_metadata.hpp> |
| 21 | + |
| 22 | +namespace traccc { |
| 23 | + |
| 24 | +class detector_buffer { |
| 25 | + public: |
| 26 | + detector_buffer() = default; |
| 27 | + detector_buffer(const detector_buffer&) = delete; |
| 28 | + detector_buffer(detector_buffer&&) = default; |
| 29 | + detector_buffer& operator=(const detector_buffer&) = delete; |
| 30 | + detector_buffer& operator=(detector_buffer&&) = default; |
| 31 | + |
| 32 | + template <typename detector_traits_t> |
| 33 | + void set(typename detector_traits_t::buffer&& obj) |
| 34 | + requires(is_detector_traits<detector_traits_t>) |
| 35 | + { |
| 36 | + m_obj.set<typename detector_traits_t::buffer>(std::move(obj)); |
| 37 | + } |
| 38 | + |
| 39 | + template <typename detector_traits_t> |
| 40 | + bool is() const |
| 41 | + requires(is_detector_traits<detector_traits_t>) |
| 42 | + { |
| 43 | + return (type() == typeid(typename detector_traits_t::buffer)); |
| 44 | + } |
| 45 | + |
| 46 | + const std::type_info& type() const { return m_obj.type(); } |
| 47 | + |
| 48 | + template <typename detector_traits_t> |
| 49 | + const typename detector_traits_t::buffer& as() const |
| 50 | + requires(is_detector_traits<detector_traits_t>) |
| 51 | + { |
| 52 | + return m_obj.as<typename detector_traits_t::buffer>(); |
| 53 | + } |
| 54 | + |
| 55 | + template <typename detector_traits_t> |
| 56 | + typename detector_traits_t::view as_view() const |
| 57 | + requires(is_detector_traits<detector_traits_t>) |
| 58 | + { |
| 59 | + return detray::get_data(as<detector_traits_t>()); |
| 60 | + } |
| 61 | + |
| 62 | + private: |
| 63 | + move_only_any m_obj; |
| 64 | +}; // class bfield |
| 65 | + |
| 66 | +/// @brief Helper function for `detector_buffer_visitor` |
| 67 | +template <typename callable_t, typename detector_t, typename... detector_ts> |
| 68 | +auto detector_buffer_visitor_helper(const detector_buffer& detector_buffer, |
| 69 | + callable_t&& callable, |
| 70 | + std::tuple<detector_t, detector_ts...>*) { |
| 71 | + if (detector_buffer.is<detector_t>()) { |
| 72 | + return callable.template operator()<detector_t>( |
| 73 | + detector_buffer.as_view<detector_t>()); |
| 74 | + } else { |
| 75 | + if constexpr (sizeof...(detector_ts) > 0) { |
| 76 | + return detector_buffer_visitor_helper( |
| 77 | + detector_buffer, std::forward<callable_t>(callable), |
| 78 | + static_cast<std::tuple<detector_ts...>*>(nullptr)); |
| 79 | + } else { |
| 80 | + std::stringstream exception_message; |
| 81 | + |
| 82 | + exception_message |
| 83 | + << "Invalid detector type (" << detector_buffer.type().name() |
| 84 | + << ") received, but this type is not supported" << std::endl; |
| 85 | + |
| 86 | + throw std::invalid_argument(exception_message.str()); |
| 87 | + } |
| 88 | + } |
| 89 | +} |
| 90 | + |
| 91 | +/// @brief Visitor for polymorphic detector buffer types |
| 92 | +/// |
| 93 | +/// This function takes a list of supported detector trait types and checks |
| 94 | +/// if the provided field is one of them. If it is, it will call the provided |
| 95 | +/// callable on a view of it and otherwise it will throw an exception. |
| 96 | +template <typename detector_buffer_list_t, typename callable_t> |
| 97 | +auto detector_buffer_visitor(const detector_buffer& detector_buffer, |
| 98 | + callable_t&& callable) { |
| 99 | + return detector_buffer_visitor_helper( |
| 100 | + detector_buffer, std::forward<callable_t>(callable), |
| 101 | + static_cast<detector_buffer_list_t*>(nullptr)); |
| 102 | +} |
| 103 | + |
| 104 | +// TODO: Docs |
| 105 | +inline detector_buffer buffer_from_host_detector(const host_detector& det, |
| 106 | + vecmem::memory_resource& mr, |
| 107 | + vecmem::copy& copy) { |
| 108 | + return host_detector_visitor<detector_type_list>( |
| 109 | + det, [&mr, ©]<typename detector_traits_t>( |
| 110 | + const typename detector_traits_t::host& detector) { |
| 111 | + traccc::detector_buffer rv; |
| 112 | + rv.set<detector_traits_t>(detray::get_buffer(detector, mr, copy)); |
| 113 | + return rv; |
| 114 | + }); |
| 115 | +} |
| 116 | + |
| 117 | +} // namespace traccc |
0 commit comments