From 8e3b8a69532df7f4fb8f4c4953271aa051ce1a3a Mon Sep 17 00:00:00 2001 From: Joana Niermann Date: Thu, 9 Nov 2023 07:58:12 +0100 Subject: [PATCH] This implements the material maps writing. It splits the common writer functionality for the grids in a common helper class that is inherited by the surface_grid_writer and the new material_map_writer. The material_map_writer uses the grid_payload with a material_slab_payload as value type. --- .../detray/core/detail/multi_store.hpp | 7 + .../io/common/{ => detail}/grid_writer.hpp | 127 ++++++++---------- .../detray/io/common/detail/type_traits.hpp | 46 ++++++- .../detray/io/common/detector_writer.hpp | 11 +- .../io/common/homogeneous_material_writer.hpp | 5 + .../detray/io/common/material_map_writer.hpp | 92 +++++++++++++ .../detray/io/common/surface_grid_writer.hpp | 82 +++++++++++ io/include/detray/io/json/json_writer.hpp | 12 +- .../unit_tests/io/io_json_detector_writer.cpp | 22 ++- 9 files changed, 320 insertions(+), 84 deletions(-) rename io/include/detray/io/common/{ => detail}/grid_writer.hpp (60%) create mode 100644 io/include/detray/io/common/material_map_writer.hpp create mode 100644 io/include/detray/io/common/surface_grid_writer.hpp diff --git a/core/include/detray/core/detail/multi_store.hpp b/core/include/detray/core/detail/multi_store.hpp index 83a9fcd62..6084dddeb 100644 --- a/core/include/detray/core/detail/multi_store.hpp +++ b/core/include/detray/core/detail/multi_store.hpp @@ -14,6 +14,7 @@ #include "detray/core/detail/tuple_container.hpp" #include "detray/definitions/indexing.hpp" #include "detray/definitions/qualifiers.hpp" +#include "detray/utils/type_list.hpp" #include "detray/utils/type_registry.hpp" // Vecmem include(s) @@ -358,6 +359,12 @@ class multi_store { detail::get<1>(link), std::forward(args)...); } + /// Print the types that are in the store + DETRAY_HOST + static constexpr void print() { + types::print...>>(); + } + /// @return the view on this tuple container - non-const DETRAY_HOST auto get_data() -> view_type { return m_tuple_container.get_data(); diff --git a/io/include/detray/io/common/grid_writer.hpp b/io/include/detray/io/common/detail/grid_writer.hpp similarity index 60% rename from io/include/detray/io/common/grid_writer.hpp rename to io/include/detray/io/common/detail/grid_writer.hpp index 497aad44b..2fe6a96b6 100644 --- a/io/include/detray/io/common/grid_writer.hpp +++ b/io/include/detray/io/common/detail/grid_writer.hpp @@ -14,6 +14,7 @@ #include "detray/io/common/io_interface.hpp" #include "detray/io/common/payloads.hpp" #include "detray/surface_finders/accelerator_grid.hpp" +#include "detray/utils/type_list.hpp" // System include(s) #include @@ -23,83 +24,43 @@ #include #include -namespace detray { +namespace detray::detail { /// @brief Abstract base class for accelerator grid writers -template +template class grid_writer : public writer_interface { using base_type = writer_interface; - // Bin content type to be written into the grid bin payloads - // For detector surface descriptors, write only the surface index - using content_t = std::conditional_t< - std::is_same_v, std::size_t, - value_t>; - - protected: - /// Tag the writer as "surface_grids" - inline static const std::string tag = "surface_grids"; - public: /// Same constructors for this class as for base_type using base_type::base_type; - protected: /// Serialize the header information into its payload - static grid_header_payload write_header(const detector_t& det, + template + static grid_header_payload write_header(const std::string_view writer_tag, + const grid_store_t& store, const std::string_view det_name) { grid_header_payload header_data; - header_data.common = base_type::serialize(det_name, tag); + header_data.common = base_type::serialize(det_name, writer_tag); header_data.sub_header.emplace(); auto& grid_sub_header = header_data.sub_header.value(); - grid_sub_header.n_grids = get_n_grids(det.accelerator_store()); + grid_sub_header.n_grids = get_n_grids(store); return header_data; } - /// Serialize the grid collections of a detector @param det into their io - /// payload - template < - typename V = value_t, - std::enable_if_t, - bool> = true> - static detector_grids_payload serialize( - const detector_t& det, const typename detector_t::name_map&) { - - detector_grids_payload grids_data; - - for (const auto& vol_desc : det.volumes()) { - // Links to all acceleration data structures in the volume - const auto& multi_link = vol_desc.full_link(); - - for (dindex i = 0u; i < multi_link.size(); ++i) { - const auto& acc_link = multi_link[i]; - // Don't look at empty links - if (acc_link.is_invalid()) { - continue; - } - - // If the accelerator is a grid, insert the payload - det.accelerator_store().template visit( - acc_link, vol_desc.index(), grids_data); - } - } - - return grids_data; - } - + protected: /// Serialize a grid @param gr of type @param type and index @param idx - /// into its io payload - template - static grid_payload serialize(std::size_t volume_index, - io::detail::acc_type type, - const std::size_t idx, - const grid_t& gr) { + /// into its io payload, using @param serializer for the bin content + template + static grid_payload serialize( + std::size_t volume_index, io::detail::acc_type type, + const std::size_t idx, const grid_t& gr, + std::function serializer) { grid_payload grid_data; @@ -117,7 +78,8 @@ class grid_writer : public writer_interface { // Write the surface indices for (unsigned int gid = 0u; gid < gr.nbins(); ++gid) { // Get the local bin indices and serialize the bin into its payload - grid_bin_payload binp = serialize(gr.serialize(gid), gr.bin(gid)); + grid_bin_payload binp = + serialize(gr.serialize(gid), gr.bin(gid), serializer); grid_data.bins.push_back(std::move(binp)); } @@ -160,9 +122,10 @@ class grid_writer : public writer_interface { } /// Serialize a multi-bin @param mbin into its io payload - template + template static grid_bin_payload serialize( - const n_axis::multi_bin mbin, const content_range_t& content) { + const n_axis::multi_bin mbin, const content_range_t& content, + std::function serializer) { grid_bin_payload bin_data; @@ -174,46 +137,64 @@ class grid_writer : public writer_interface { // Put all entries of the bin into the payload bin_data.content.reserve(content.size()); for (const auto& entry : content) { - bin_data.content.push_back(entry.index()); + bin_data.content.push_back(serializer(entry)); } return bin_data; } + /// Serialize a grid from a collection into its payload + /// + /// @param store the data store of grids (tuple of grid collections) + /// @param grid_link type and index of the grid + /// @param owner_idx inder of the owner of the grid (e.g. volume index) + /// @param grid_data the grid payload to be filled + /// @param serializer callable that can serialize a grid bin entry into its + /// respective IO payload (of type @tparam content_t) + template + static void serialize(const store_t& store, + typename store_t::single_link grid_link, + dindex owner_idx, + detector_grids_payload& grids_data, + serializer_t serializer) { + + // If the accelerator is a grid, insert the payload + store.template visit(grid_link, owner_idx, grids_data, + serializer); + } + private: /// Retrieve a @c grid_payload from grid collection elements struct get_grid_payload { - template + template inline void operator()( [[maybe_unused]] const grid_group_t& coll, [[maybe_unused]] const index_t& index, - [[maybe_unused]] std::size_t volume_index, - [[maybe_unused]] detector_grids_payload& grids_data) - const { + [[maybe_unused]] std::size_t link, + [[maybe_unused]] detector_grids_payload& grids_data, + [[maybe_unused]] serializer_t& serializer) const { using accel_t = typename grid_group_t::value_type; if constexpr (detail::is_grid_v) { - grids_data.grids.push_back( - serialize(volume_index, io::detail::get_grid_id(), - index, coll[index])); + grids_data.grids.push_back(serialize( + link, io::detail::get_grid_id(), index, + coll[index], serializer)); } } }; /// Retrieve number of overall grids in detector - template - static std::size_t get_n_grids( - const typename detector_t::accelerator_container& store, - std::size_t n = 0u) { + template + static std::size_t get_n_grids(const store_t& store, std::size_t n = 0u) { - using store_t = typename detector_t::accelerator_container; constexpr auto coll_id{store_t::value_types::to_id(I)}; - using accel_t = typename store_t::template get_type; + using value_type = typename store_t::template get_type; - if constexpr (detail::is_grid_v) { + if constexpr (detail::is_grid_v) { n += store.template size(); } @@ -224,4 +205,4 @@ class grid_writer : public writer_interface { } }; -} // namespace detray +} // namespace detray::detail diff --git a/io/include/detray/io/common/detail/type_traits.hpp b/io/include/detray/io/common/detail/type_traits.hpp index 4be458f9a..2adb406a6 100644 --- a/io/include/detray/io/common/detail/type_traits.hpp +++ b/io/include/detray/io/common/detail/type_traits.hpp @@ -156,6 +156,37 @@ struct mask_info +struct constains_grids; + +template