diff --git a/core/include/detray/core/detail/surface_lookup.hpp b/core/include/detray/core/detail/surface_lookup.hpp new file mode 100644 index 0000000000..6b2a66d33d --- /dev/null +++ b/core/include/detray/core/detail/surface_lookup.hpp @@ -0,0 +1,256 @@ +/** Detray library, part of the ACTS project (R&D line) + * + * (c) 2022-2023 CERN for the benefit of the ACTS project + * + * Mozilla Public License Version 2.0 + */ + +#pragma once + +// Project include(s) +#include "detray/core/detail/container_buffers.hpp" +#include "detray/core/detail/container_views.hpp" +#include "detray/definitions/indexing.hpp" +#include "detray/definitions/qualifiers.hpp" +#include "detray/geometry/barcode.hpp" + +// Vecmem include(s) +#include + +// System include(s) +#include + +namespace detray { + +/// General case: Brute force search for the corresponding sf-descriptor +struct default_searcher { + + template class container_t = dvector> + auto operator()(const container_t &sf_container) { + // Check that this searcher can be used on the passed surface container + static_assert( + std::is_same_v, + "Source link searcher not compatible with detector"); + + // Cannot assume any sorting + for (const auto &sf : sf_container) { + if (sf.source == m_source) { + return sf; + } + } + } + + /// The query source link + std::uint64_t m_source; +}; + +/// Couple the surface descriptor to a source link +template +struct source_link : sf_desc_t { + + source_link() = default; + + source_link(sf_desc_t sf_desc, std::uint64_t src) + : sf_desc_t{sf_desc}, source{src} {} + + std::uint64_t source{detail::invalid_value()}; +}; + +/// @brief Wraps a vector-like container that holds the surface descriptors of a +/// detector and makes them searchable by index and source link. +/// +/// @tparam sf_desc_t The surface descriptor type +/// @tparam container_t The type of container to use for the descriptor +/// collection. +template class container_t = dvector> +class surface_lookup { + + public: + /// Underlying container type that can handle vecmem views + using base_type = container_t>; + using size_type = typename base_type::size_type; + using value_type = typename base_type::value_type; + using iterator = typename base_type::iterator; + using const_iterator = typename base_type::const_iterator; + + /// Vecmem view types + using view_type = detail::get_view_t>>; + using const_view_type = + detail::get_view_t>>; + using buffer_type = + detail::get_buffer_t>>; + + /// Empty container + constexpr surface_lookup() = default; + + /// Construct with a specific memory resource @param resource + /// (host-side only) + template , + bool> = true> + DETRAY_HOST explicit surface_lookup(allocator_t &resource) + : m_container(&resource) {} + + /// Copy Construct with a specific memory resource @param resource + /// (host-side only) + template < + typename allocator_t = vecmem::memory_resource, + typename C = container_t>, + std::enable_if_t>>, + bool> = true> + DETRAY_HOST explicit surface_lookup(allocator_t &resource, + const source_link &arg) + : m_container(&resource, arg) {} + + /// Construct from the container @param view . Mainly used device-side. + template , + bool> = true> + DETRAY_HOST_DEVICE surface_lookup(container_view_t &view) + : m_container(view) {} + + /// @returns the size of the underlying container + DETRAY_HOST_DEVICE + constexpr auto size() const noexcept -> dindex { + return static_cast(m_container.size()); + } + + /// @returns true if the underlying container is empty + DETRAY_HOST_DEVICE + constexpr auto empty() const noexcept -> bool { + return m_container.empty(); + } + + /// Reserve memory of size @param n for a given geometry context + DETRAY_HOST void reserve(std::size_t n) { m_container.reserve(n); } + + /// Resize the underlying container to @param n for a given geometry context + DETRAY_HOST void resize(std::size_t n) { m_container.resize(n); } + + /// Removes and destructs all elements in the container. + DETRAY_HOST void clear() { m_container.clear(); } + + /// @returns the collections iterator at the start position. + DETRAY_HOST_DEVICE + constexpr decltype(auto) begin() { return m_container.begin(); } + + /// @returns the collections iterator sentinel. + DETRAY_HOST_DEVICE + constexpr decltype(auto) end() { return m_container.end(); } + + /// @returns the collections iterator at the start position - const + DETRAY_HOST_DEVICE + constexpr decltype(auto) begin() const { return m_container.begin(); } + + /// @returns the collections iterator sentinel - const + DETRAY_HOST_DEVICE + constexpr decltype(auto) end() const { return m_container.end(); } + + /// @returns the reverse iterator at the start position - const + DETRAY_HOST_DEVICE + constexpr decltype(auto) rbegin() const { return m_container.rbegin(); } + + /// @returns the reverse iterator sentinel - const + DETRAY_HOST_DEVICE + constexpr decltype(auto) rend() const { return m_container.rend(); } + + /// Elementwise access. Needs @c operator[] for storage type - non-const + DETRAY_HOST_DEVICE + constexpr decltype(auto) operator[](const std::size_t i) { + return m_container[i]; + } + + /// Elementwise access. Needs @c operator[] for storage type - const + DETRAY_HOST_DEVICE + constexpr decltype(auto) operator[](const std::size_t i) const { + return m_container[i]; + } + + /// @returns context based access to an element (also range checked) + DETRAY_HOST_DEVICE + constexpr decltype(auto) at(const dindex i) noexcept { + return m_container.at(i); + } + + /// @returns context based access to an element (also range checked) - const + DETRAY_HOST_DEVICE + constexpr decltype(auto) at(const dindex i) const noexcept { + return m_container.at(i); + } + + /// @returns the surface descriptor according to the global surface index + /// @param sf_index + DETRAY_HOST_DEVICE + constexpr decltype(auto) search(dindex sf_index) const { + return m_container[sf_index]; + } + + /// @returns the surface descriptor according to the surface barcode + /// @param bcd + DETRAY_HOST_DEVICE + constexpr decltype(auto) search(geometry::barcode bcd) const { + return search(bcd.index()); + } + + /// @returns the surface descriptor according to the searcher passed as + /// @param source_searcher + template + DETRAY_HOST_DEVICE constexpr decltype(auto) search( + searcher_t &&source_searcher) const { + return source_searcher(m_container); + } + + /// Add a new element to the collection + /// + /// @param sf_desc the surface descriptor + /// @param src the source index + DETRAY_HOST constexpr auto push_back(sf_desc_t sf_desc, + std::uint64_t src) noexcept(false) + -> void { + m_container.push_back({sf_desc, src}); + } + + /// Add a new element to the collection - copy + /// + /// @param sf_link the detray source link + DETRAY_HOST constexpr auto push_back( + source_link sf_link) noexcept(false) -> void { + m_container.push_back(sf_link); + } + + /// Insert a surface descriptor @param sf_desc and its source index + /// @param src into the container + DETRAY_HOST void insert( + sf_desc_t sf_desc, + std::uint64_t src = + detail::invalid_value()) noexcept(false) { + insert({sf_desc, src}); + } + + /// Insert a source link @param sf_link at the position of its surface + /// index. + DETRAY_HOST void insert(source_link sf_link) noexcept(false) { + if (m_container.size() < sf_link.index() + 1u) { + m_container.resize(sf_link.index() + 1u); + } + m_container.at(sf_link.index()) = sf_link; + } + + /// @return the view on the underlying container - non-const + DETRAY_HOST auto get_data() -> view_type { + return detray::get_data(m_container); + } + + /// @return the view on the underlying container - const + DETRAY_HOST auto get_data() const -> const_view_type { + return detray::get_data(m_container); + } + + private: + /// The underlying container implementation + base_type m_container; +}; + +} // namespace detray diff --git a/core/include/detray/core/detector.hpp b/core/include/detray/core/detector.hpp index a1b1df3121..6752b033b0 100644 --- a/core/include/detray/core/detector.hpp +++ b/core/include/detray/core/detector.hpp @@ -10,14 +10,13 @@ // Project include(s) #include "detray/core/detail/container_buffers.hpp" #include "detray/core/detail/container_views.hpp" +#include "detray/core/detail/surface_lookup.hpp" #include "detray/core/detector_metadata.hpp" #include "detray/definitions/containers.hpp" #include "detray/definitions/qualifiers.hpp" #include "detray/geometry/detail/volume_descriptor.hpp" -#include "detray/geometry/detector_volume.hpp" -#include "detray/geometry/surface.hpp" -#include "detray/tools/volume_builder.hpp" -#include "detray/utils/ranges.hpp" +#include "detray/tools/volume_builder.hpp" // @TODO remove +#include "detray/utils/ranges.hpp" // @TODO remove // Vecmem include(s) #include @@ -30,9 +29,9 @@ namespace detray { -/// @brief Forward declaration of a detector view type -template -struct detector_view; +// Forward declare the volume builder +template +class volume_builder; /// @brief The detector definition. /// @@ -41,27 +40,23 @@ struct detector_view; /// structures. Its view type is used to move the data between host and device. /// /// @tparam metadata helper that defines collection and link types centrally -/// @tparam bfield_t the type of the b-field frontend /// @tparam container_t type collection of the underlying containers -/// @tparam source_link the surface source link template class detector { // Allow the building of the detector containers - friend class volume_builder_interface>; + friend class volume_builder>; public: /// Algebra types - /// @TODO: scalar as a template parameter + /// @TODO: algebra plugin as a template parameter using scalar_type = scalar; using point3 = __plugin::point3; using vector3 = __plugin::vector3; using point2 = __plugin::point2; - using metadata = metadata_t; - /// Raw container types template using array_type = typename container_t::template array_type; @@ -76,12 +71,15 @@ class detector { /// In case the detector needs to be printed using name_map = std::map; + /// Main definition of geometry types + using metadata = metadata_t; + /// The surface takes a mask (defines the local coordinates and the surface /// extent), its material, a link to an element in the transform container /// to define its placement and a source link to the object it represents. using surface_type = typename metadata::surface_type; using surface_container = vector_type; - using surface_lookup_container = surface_container; + using surface_lookup_container = surface_lookup; /// Forward the alignable transform container (surface placements) and /// the geo context (e.g. for alignment) @@ -121,20 +119,21 @@ class detector { typename metadata::template volume_finder; /// Detector view types - using view_type = - dmulti_view, dvector_view, - typename transform_container::view_type, - typename mask_container::view_type, - typename material_container::view_type, - typename accelerator_container::view_type, - typename volume_finder::view_type>; + /// @TODO: Switch to const_view_type always if possible + using view_type = dmulti_view, + typename surface_lookup_container::view_type, + typename transform_container::view_type, + typename mask_container::view_type, + typename material_container::view_type, + typename accelerator_container::view_type, + typename volume_finder::view_type>; static_assert(detail::is_device_view_v, "Detector view type ill-formed"); using const_view_type = dmulti_view, - dvector_view, + typename surface_lookup_container::const_view_type, typename transform_container::const_view_type, typename mask_container::const_view_type, typename material_container::const_view_type, @@ -146,7 +145,8 @@ class detector { /// Detector buffer types using buffer_type = - dmulti_buffer, dvector_buffer, + dmulti_buffer, + typename surface_lookup_container::buffer_type, typename transform_container::buffer_type, typename mask_container::buffer_type, typename material_container::buffer_type, @@ -162,14 +162,14 @@ class detector { detector &operator=(const detector &) = delete; detector(detector &&) = default; - /// Allowed costructor + /// Allowed constructors /// @{ /// Default construction /// @param resource memory resource for the allocation of members DETRAY_HOST explicit detector(vecmem::memory_resource &resource) : _volumes(&resource), - _surfaces(&resource), + _surfaces(resource), _transforms(resource), _masks(resource), _materials(resource), @@ -177,7 +177,7 @@ class detector { _volume_finder(resource), _resource(&resource) {} - /// Constructor with detector_data + /// Constructor from detector data view template , bool> = true> @@ -191,74 +191,58 @@ class detector { _volume_finder(detray::detail::get<6>(det_data.m_view)) {} /// @} - /// Add a new volume and retrieve a reference to it. - /// - /// @param id the shape id for the volume - /// @param accel_link of the volume, where to entry the surface finder - /// - /// @return non-const reference to the new volume - DETRAY_HOST - volume_type &new_volume( - const volume_id id, - typename volume_type::link_type::index_type srf_finder_link = {}) { - volume_type &cvolume = _volumes.emplace_back(id); - cvolume.set_index(static_cast(_volumes.size()) - 1u); - cvolume - .template set_link(0)>( - srf_finder_link); - - return cvolume; - } - /// @return the sub-volumes of the detector - const access DETRAY_HOST_DEVICE inline auto volumes() const -> const vector_type & { return _volumes; } - /// @return the sub-volumes of the detector - non-const access + /// @return the volume by @param volume_index - const access DETRAY_HOST_DEVICE - inline auto volumes() -> vector_type & { return _volumes; } + inline const auto &volume(dindex volume_index) const { + return _volumes[volume_index]; + } - /// @return the volume for a @param volume_descr - const access + /// @return the volume by global cartesian @param position - const access DETRAY_HOST_DEVICE - inline auto volume(const volume_type &volume_descr) const - -> const detector_volume { - return detector_volume{*this, volume_descr}; + inline const auto &volume(const point3 &p) const { + // The 3D cylindrical volume search grid is concentric + const transform3 identity{}; + const auto loc_pos = + _volume_finder.global_to_local(identity, p, identity.translation()); + + // Only one entry per bin + dindex volume_index{*_volume_finder.search(loc_pos)}; + return _volumes[volume_index]; } - /// @return the volume for a @param volume_descr - non-const access + /// @return the sub-volumes of the detector - const access DETRAY_HOST_DEVICE - inline auto volume(volume_type &volume_descr) -> detector_volume { - return detector_volume{*this, volume_descr}; + inline auto surfaces() const -> const surface_lookup_container & { + return _surfaces; } - /// @return the volume by @param volume_index - const access - DETRAY_HOST_DEVICE - inline auto volume_by_index(dindex volume_index) const - -> const detector_volume { - return detector_volume{*this, _volumes[volume_index]}; + /// @returns a surface using a query objetc @param q. This can be an index, + /// a barcode or a source link searcher (see @c surface_lookup class) + template + DETRAY_HOST_DEVICE constexpr decltype(auto) surface(query_t &&q) const { + return _surfaces.search(std::forward(q)); } - /// @return the volume by @param volume_index - non-const access + /// @return detector transform store DETRAY_HOST_DEVICE - inline auto volume_by_index(dindex volume_index) - -> detector_volume { - return detector_volume{*this, _volumes[volume_index]}; + inline auto transform_store() const -> const transform_container & { + return _transforms; } - /// @return the volume by global cartesian @param position - const access + /// @return all surface/portal masks in the geometry - const access DETRAY_HOST_DEVICE - inline auto volume_by_pos(const point3 &p) const - -> const detector_volume { - // The 3D cylindrical volume search grid is concentric - const transform3 identity{}; - const auto loc_pos = - _volume_finder.global_to_local(identity, p, identity.translation()); + inline auto mask_store() const -> const mask_container & { return _masks; } - // Only one entry per bin - dindex volume_index{*_volume_finder.search(loc_pos)}; - return detector_volume{*this, _volumes[volume_index]}; + /// @return all materials in the geometry - const access + DETRAY_HOST_DEVICE + inline auto material_store() const -> const material_container & { + return _materials; } /// @returns access to the surface finder container @@ -267,10 +251,85 @@ class detector { return _accelerators; } - /// @returns access to the surface finder container + /// @return the volume grid - const access DETRAY_HOST_DEVICE - inline auto accelerator_store() -> accelerator_container & { - return _accelerators; + inline auto volume_search_grid() const -> const volume_finder & { + return _volume_finder; + } + + /// @returns view of a detector + DETRAY_HOST auto get_data() -> view_type { + return view_type{ + detray::get_data(_volumes), detray::get_data(_surfaces), + detray::get_data(_transforms), detray::get_data(_masks), + detray::get_data(_materials), detray::get_data(_accelerators), + detray::get_data(_volume_finder)}; + } + + /// @returns const view of a detector + DETRAY_HOST auto get_data() const -> const_view_type { + return const_view_type{ + detray::get_data(_volumes), detray::get_data(_surfaces), + detray::get_data(_transforms), detray::get_data(_masks), + detray::get_data(_materials), detray::get_data(_accelerators), + detray::get_data(_volume_finder)}; + } + + /// @param names maps a volume to its string representation. + /// @returns a string representation of the detector. + DETRAY_HOST + auto to_string(const name_map &names) const -> std::string { + std::stringstream ss; + + ss << "[>] Detector '" << names.at(0) << "' has " << _volumes.size() + << " volumes." << std::endl; + + for (const auto [i, v] : detray::views::enumerate(_volumes)) { + ss << "[>>] Volume at index " << i << ": " << std::endl; + ss << " - name: '" << names.at(v.index() + 1u) << "'" << std::endl; + + ss << " contains " + << v.template n_objects() + << " sensitive surfaces " << std::endl; + + ss << " " + << v.template n_objects() << " portals " + << std::endl; + + ss << " " << _accelerators.n_collections() + << " surface finders " << std::endl; + + if (v.accel_index() != dindex_invalid) { + ss << " sf finder id " << v.accel_type() << " sf finders idx " + << v.accel_index() << std::endl; + } + } + + return ss.str(); + } + + /// @return the pointer of memoery resource - non-const access + DETRAY_HOST + auto *resource() { return _resource; } + + /// @return the pointer of memoery resource + DETRAY_HOST + const auto *resource() const { return _resource; } + + ///------------------------------------------------------------------------ + /// @TODO Make the following methods private or remove them once all of the + /// geometry building code has been migrated to the detector builder + ///------------------------------------------------------------------------ + + /// @return the sub-volumes of the detector - non-const access + DETRAY_HOST_DEVICE + inline auto volumes() -> vector_type & { return _volumes; } + + /// Append new portals(surfaces) to the detector + DETRAY_HOST + inline void append_portals(surface_container &&new_surfaces) { + _accelerators.template push_back( + std::move(new_surfaces)); } /// @returns all portals - const @@ -282,14 +341,6 @@ class detector { return _accelerators.template get().all(); } - /// @returns all portals - non-const - /// @note Depending on the detector type, this can also container other - /// surfaces - DETRAY_HOST_DEVICE - inline auto &portals() { - return _accelerators.template get().all(); - } - /// @returns the portals of a given volume @param v - const /// @note Depending on the detector type, this can also container other /// surfaces @@ -297,7 +348,7 @@ class detector { // Index of the portal collection in the surface store const dindex pt_coll_idx{ - v.template link().index()}; + v.template accel_link().index()}; const auto &pt_coll = _accelerators.template get()[pt_coll_idx]; @@ -305,51 +356,37 @@ class detector { return pt_coll.all(); } - /// @return the sub-volumes of the detector - const access - DETRAY_HOST_DEVICE - inline auto surface_lookup() const -> const vector_type & { - return _surfaces; + /// Append new portals(surfaces) to the detector + DETRAY_HOST + inline void append_portals(surface_lookup_container &&new_surfaces) { + surface_container descriptors; + std::transform( + new_surfaces.begin(), new_surfaces.end(), + std::back_inserter(descriptors), + [](typename surface_lookup_container::value_type &sf) { + return static_cast(sf); + }); + _accelerators.template push_back( + std::move(descriptors)); } /// @return the sub-volumes of the detector - non-const access DETRAY_HOST_DEVICE - inline auto surface_lookup() -> vector_type & { - return _surfaces; - } - - /// @returns a surface using its barcode - const - DETRAY_HOST_DEVICE - constexpr auto surface(geometry::barcode bcd) const - -> const surface_type & { - return _surfaces[bcd.index()]; - } + inline auto surfaces() -> surface_lookup_container & { return _surfaces; } - /// @returns the overall number of surfaces in the detector DETRAY_HOST_DEVICE - constexpr auto n_surfaces() const -> dindex { - return static_cast(_surfaces.size()); - } - - /// Add a new surface to the lookup according to its index. - DETRAY_HOST - constexpr auto add_surface_to_lookup(const surface_type sf) -> void { - if (_surfaces.size() < sf.index() + 1) { - _surfaces.resize(sf.index() + 1); - } - _surfaces.at(sf.index()) = sf; + inline auto transform_store(const geometry_context & /*ctx*/ = {}) + -> transform_container & { + return _transforms; } - /// Append new portals(surfaces) to the detector + /// Append a new transform store to the detector DETRAY_HOST - inline void append_portals(surface_container &&new_surfaces) { - _accelerators.template push_back( - std::move(new_surfaces)); + inline void append_transforms(transform_container &&new_transforms, + const geometry_context ctx = {}) { + _transforms.append(std::move(new_transforms), ctx); } - /// @return all surface/portal masks in the geometry - const access - DETRAY_HOST_DEVICE - inline auto mask_store() const -> const mask_container & { return _masks; } - /// @return all surface/portal masks in the geometry - non-const access DETRAY_HOST_DEVICE inline auto mask_store() -> mask_container & { return _masks; } @@ -360,12 +397,6 @@ class detector { _masks.append(std::move(new_masks)); } - /// @return all materials in the geometry - const access - DETRAY_HOST_DEVICE - inline auto material_store() const -> const material_container & { - return _materials; - } - /// @return all materials in the geometry - non-const access DETRAY_HOST_DEVICE inline auto material_store() -> material_container & { return _materials; } @@ -376,28 +407,55 @@ class detector { _materials.append(std::move(new_materials)); } - /// Get all transform in an index range from the detector - const + /// @returns access to the surface finder container + DETRAY_HOST_DEVICE + inline auto accelerator_store() -> accelerator_container & { + return _accelerators; + } + + /// Add the volume grid - move semantics /// - /// @param ctx The context of the call + /// @param v_grid the volume grid to be added + DETRAY_HOST + inline auto set_volume_finder(volume_finder &&v_grid) -> void { + _volume_finder = std::move(v_grid); + } + + /// Add the volume grid - copy semantics /// - /// @return detector transform store - DETRAY_HOST_DEVICE - inline auto transform_store(const geometry_context & /*ctx*/ = {}) const - -> const transform_container & { - return _transforms; + /// @param v_grid the volume grid to be added + DETRAY_HOST + inline auto set_volume_finder(const volume_finder &v_grid) -> void { + _volume_finder = v_grid; } + /// @returns const access to the detector's volume search structure DETRAY_HOST_DEVICE - inline auto transform_store(const geometry_context & /*ctx*/ = {}) - -> transform_container & { - return _transforms; + inline auto volume_search_grid() -> volume_finder & { + return _volume_finder; } - /// Append a new transform store to the detector + ///------------------------------------------------------------------------ + /// @TODO Remove the following methods once all of the geometry building + /// code has been migrated to the detector builder + ///------------------------------------------------------------------------ + + /// Add a new volume and retrieve a reference to it. + /// + /// @param id the shape id for the volume + /// @param acc_link of the volume, where to entry the surface finder + /// + /// @return non-const reference to the new volume DETRAY_HOST - inline void append_transforms(transform_container &&new_transforms, - const geometry_context ctx = {}) { - _transforms.append(std::move(new_transforms), ctx); + volume_type &new_volume( + const volume_id id, + typename volume_type::accel_link_type::index_type acc_link = {}) { + volume_type &cvolume = _volumes.emplace_back(id); + cvolume.set_index(static_cast(_volumes.size()) - 1u); + cvolume.template set_accel_link< + static_cast(0)>(acc_link); + + return cvolume; } /// Add a new full set of detector components (e.g. transforms or volumes) @@ -430,10 +488,10 @@ class detector { // Don't overwrite the surface index if it has been set already // (e.g. with a special sorting) if (sf.barcode().is_invalid()) { - sf.set_index(n_surfaces()); + sf.set_index(_surfaces.size()); assert(!sf.barcode().is_invalid()); } - add_surface_to_lookup(sf); + _surfaces.insert(sf); } // Append surfaces to base surface collection @@ -441,7 +499,7 @@ class detector { surfaces_per_vol); // Update the surface link in a volume - vol.template set_link( + vol.template set_accel_link( accel::id::e_default, _accelerators.template size() - 1); @@ -479,33 +537,7 @@ class detector { trfs_per_vol); } - /// Add the volume grid - move semantics - /// - /// @param v_grid the volume grid to be added - DETRAY_HOST - inline auto set_volume_finder(volume_finder &&v_grid) -> void { - _volume_finder = std::move(v_grid); - } - - /// Add the volume grid - copy semantics - /// - /// @param v_grid the volume grid to be added - DETRAY_HOST - inline auto set_volume_finder(const volume_finder &v_grid) -> void { - _volume_finder = v_grid; - } - - /// @return the volume grid - const access - DETRAY_HOST_DEVICE - inline auto volume_search_grid() const -> const volume_finder & { - return _volume_finder; - } - - /// @returns const access to the detector's volume search structure - DETRAY_HOST_DEVICE - inline auto volume_search_grid() -> volume_finder & { - return _volume_finder; - } + ///------------------------------------------------------------------------ /// @returns the maximum number of surface candidates that any volume may /// return. @@ -520,65 +552,6 @@ class detector { return *std::max_element(n_candidates.begin(), n_candidates.end()); } - /// @returns view of a detector - DETRAY_HOST auto get_data() -> view_type { - return view_type{ - detray::get_data(_volumes), detray::get_data(_surfaces), - detray::get_data(_transforms), detray::get_data(_masks), - detray::get_data(_materials), detray::get_data(_accelerators), - detray::get_data(_volume_finder)}; - } - - /// @returns const view of a detector - DETRAY_HOST auto get_data() const -> const_view_type { - return const_view_type{ - detray::get_data(_volumes), detray::get_data(_surfaces), - detray::get_data(_transforms), detray::get_data(_masks), - detray::get_data(_materials), detray::get_data(_accelerators), - detray::get_data(_volume_finder)}; - } - - /// @param names maps a volume to its string representation. - /// @returns a string representation of the detector. - DETRAY_HOST - auto to_string(const name_map &names) const -> std::string { - std::stringstream ss; - - ss << "[>] Detector '" << names.at(0) << "' has " << _volumes.size() - << " volumes." << std::endl; - - for (const auto [i, v] : detray::views::enumerate(_volumes)) { - ss << "[>>] Volume at index " << i << ": " << std::endl; - ss << " - name: '" << names.at(v.index() + 1u) << "'" << std::endl; - - ss << " contains " - << v.template n_objects() - << " sensitive surfaces " << std::endl; - - ss << " " - << v.template n_objects() << " portals " - << std::endl; - - ss << " " << _accelerators.n_collections() - << " surface finders " << std::endl; - - if (v.accel_index() != dindex_invalid) { - ss << " sf finder id " << v.accel_type() << " sf finders idx " - << v.accel_index() << std::endl; - } - } - - return ss.str(); - } - - /// @return the pointer of memoery resource - non-const access - DETRAY_HOST - auto *resource() { return _resource; } - - /// @return the pointer of memoery resource - DETRAY_HOST - const auto *resource() const { return _resource; } - private: /// Contains the detector sub-volumes. volume_container _volumes; diff --git a/core/include/detray/core/detector_metadata.hpp b/core/include/detray/core/detector_metadata.hpp index 05ce9073d3..18210da0a3 100644 --- a/core/include/detray/core/detector_metadata.hpp +++ b/core/include/detray/core/detector_metadata.hpp @@ -223,11 +223,9 @@ unbounded_cell, unmasked_plane*/>; using transform_link = typename transform_store<>::link_type; using mask_link = typename mask_store<>::single_link; using material_link = typename material_store<>::single_link; - using source_link = std::uint64_t; /// Surface type used for sensitives, passives and portals using surface_type = - surface_descriptor; + surface_descriptor; /// How to index the constituent objects (surfaces) in a volume /// If they share the same index value here, they will be added into the diff --git a/core/include/detray/definitions/geometry.hpp b/core/include/detray/definitions/geometry.hpp index 4dbe66122d..4f4344c7f3 100644 --- a/core/include/detray/definitions/geometry.hpp +++ b/core/include/detray/definitions/geometry.hpp @@ -37,7 +37,8 @@ enum class surface_id : std::uint_least8_t { e_portal = 0u, e_sensitive = 1u, e_passive = 2u, - e_unknown = 3u + e_unknown = 3u, + e_all = e_unknown }; } // namespace detray diff --git a/core/include/detray/geometry/detail/surface_descriptor.hpp b/core/include/detray/geometry/detail/surface_descriptor.hpp index 277b2315c7..0502810912 100644 --- a/core/include/detray/geometry/detail/surface_descriptor.hpp +++ b/core/include/detray/geometry/detail/surface_descriptor.hpp @@ -27,12 +27,10 @@ namespace detray { /// @tparam material_registry_t the type collection of material that can be /// linked to the surface /// @tparam transform_link_t how to reference the surfaces transforms -/// @tparam source_link_t the type of the source link representation template , typename material_link_t = dtyped_index, typename transform_link_t = dindex, - typename navigation_link_t = dindex, - typename source_link_t = std::uint64_t> + typename navigation_link_t = dindex> class surface_descriptor { public: @@ -45,7 +43,6 @@ class surface_descriptor { using mask_id = typename mask_link::id_type; using material_link = material_link_t; using material_id = typename material_link::id_type; - using source_link = source_link_t; /// Constructor with full arguments - move semantics /// @@ -58,11 +55,10 @@ class surface_descriptor { DETRAY_HOST constexpr surface_descriptor(transform_link &&trf, mask_link &&mask, material_link &&material, dindex volume, - source_link &&src, surface_id sf_id) + surface_id sf_id) : _mask(std::move(mask)), _material(std::move(material)), - _trf(std::move(trf)), - _src(std::move(src)) { + _trf(std::move(trf)) { m_barcode = geometry::barcode{}.set_volume(volume).set_id(sf_id); } @@ -79,9 +75,8 @@ class surface_descriptor { constexpr surface_descriptor(const transform_link trf, const mask_link &mask, const material_link &material, - const dindex volume, const source_link &src, - const surface_id sf_id) - : _mask(mask), _material(material), _trf(trf), _src(src) { + const dindex volume, const surface_id sf_id) + : _mask(mask), _material(material), _trf(trf) { m_barcode = geometry::barcode{}.set_volume(volume).set_id(sf_id); } @@ -95,8 +90,7 @@ class surface_descriptor { DETRAY_HOST_DEVICE constexpr auto operator==(const surface_descriptor &rhs) const -> bool { return (_mask == rhs._mask and _material == rhs._material and - _trf == rhs._trf and _src == rhs._src and - m_barcode == rhs.m_barcode); + _trf == rhs._trf and m_barcode == rhs.m_barcode); } /// Sets a new surface barcode @@ -171,10 +165,6 @@ class surface_descriptor { return _material; } - /// @return the source link - DETRAY_HOST_DEVICE - constexpr auto source() const -> const source_link & { return _src; } - /// @returns true if the surface is a senstive detector module. DETRAY_HOST_DEVICE constexpr auto is_sensitive() const -> bool { @@ -209,7 +199,6 @@ class surface_descriptor { mask_link _mask{}; material_link _material{}; transform_link_t _trf{}; - source_link_t _src{}; }; } // namespace detray diff --git a/core/include/detray/geometry/detail/volume_descriptor.hpp b/core/include/detray/geometry/detail/volume_descriptor.hpp index 6dc7dd9749..4aae9f6343 100644 --- a/core/include/detray/geometry/detail/volume_descriptor.hpp +++ b/core/include/detray/geometry/detail/volume_descriptor.hpp @@ -34,6 +34,9 @@ class volume_descriptor { /// Ids of objects that can be distinguished by the volume using object_id = ID; + /// How to access the surface ranges in the detector surface lookup + using sf_link_type = dmulti_index; + /// How to access objects (e.g. sensitives/passives/portals) in this /// volume. Keeps one accelerator structure link per object type (by ID): /// @@ -43,7 +46,7 @@ class volume_descriptor { /// E.g. a 'portal' can be found under @c ID::e_portal in this link, /// and will then receive link to the @c brute_force_finder that holds the /// portals (the accelerator structure's id and index). - using link_type = dmulti_index; + using accel_link_type = dmulti_index; /// Default constructor builds an ~infinitely long cylinder constexpr volume_descriptor() = default; @@ -75,20 +78,103 @@ class volume_descriptor { m_transform = trf_idx; } + /// @returns surface link for all object types - const + DETRAY_HOST_DEVICE constexpr auto sf_link() const -> const sf_link_type & { + return m_sf_links; + } + + /// @returns surface descriptor link for a specific type of object - const + template + DETRAY_HOST_DEVICE constexpr auto sf_link() const -> const + typename sf_link_type::index_type & { + return detail::get(id)>(m_sf_links); + } + + /// @returns surface descriptor link for a specific type of object + template + DETRAY_HOST_DEVICE constexpr auto sf_link() -> + typename sf_link_type::index_type & { + return detail::get(id)>(m_sf_links); + } + + /// @returns surface descriptor link for all surface types + DETRAY_HOST_DEVICE constexpr auto full_sf_range() const -> + typename sf_link_type::index_type { + + using idx_range_t = typename sf_link_type::index_type; + + const auto min{detail::get<0>(detail::get<0>(m_sf_links))}; + const auto max{detail::get<1>(detail::get<1>(m_sf_links))}; + + // Portals can be at the beginning or end of the surface range + return min < max + ? idx_range_t{min, max} + : idx_range_t{detail::get<0>(detail::get<1>(m_sf_links)), + detail::get<1>(detail::get<0>(m_sf_links))}; + } + + /// Set or update the index into a geometry container identified by the + /// obj_id. + /// + /// @note There is no check of overlapping index ranges between the object + /// types. Use with care! + /// + /// @param other Surface index range + template + DETRAY_HOST auto update_sf_link( + const typename sf_link_type::index_type &other) noexcept -> void { + auto &rg = sf_link(); + // Range not set yet - initialize + constexpr typename sf_link_type::index_type empty{}; + if (rg == empty) { + rg = other; + } else { + // Update + assert(detail::get<1>(rg) == detail::get<0>(other)); + detail::get<1>(rg) = detail::get<1>(other); + } + } + + /// Set or update the index into a geometry container identified by the + /// obj_id. + /// + /// @note There is no check of overlapping index ranges between the object + /// types. Use with care! + /// + /// @param shift shift of the surface range in a larger container. + /// @param n_surfaces the number of surfaces in this range. + template + DETRAY_HOST auto update_sf_link(std::size_t shift, + std::size_t n_surfaces = 0) noexcept + -> void { + auto &rg = sf_link(); + // Range not set yet - initialize + constexpr typename sf_link_type::index_type empty{}; + if (rg == empty) { + std::get<0>(rg) = shift; + std::get<1>(rg) = shift + n_surfaces; + return; + } + // Update + detail::get<0>(rg) += shift; + detail::get<1>(rg) += shift; + } + /// @returns link to all acceleration data structures - const access - DETRAY_HOST_DEVICE constexpr auto full_link() const -> const link_type & { + DETRAY_HOST_DEVICE constexpr auto accel_link() const + -> const accel_link_type & { return m_accel_links; } /// @returns acc data structure link for a specific type of object - const template - DETRAY_HOST_DEVICE constexpr auto link() const -> const link_t & { + DETRAY_HOST_DEVICE constexpr auto accel_link() const -> const link_t & { return detail::get(m_accel_links); } /// Set surface finder link from @param link template - DETRAY_HOST constexpr auto set_link(const link_t link) -> void { + DETRAY_HOST constexpr auto set_accel_link(const link_t link) -> void { detail::get(m_accel_links) = link; } @@ -96,9 +182,9 @@ class volume_descriptor { /// acceleration data structure (e.g. type and index of grid in surface /// store) template - DETRAY_HOST constexpr auto set_link(const typename link_t::id_type id, - const typename link_t::index_type index) - -> void { + DETRAY_HOST constexpr auto set_accel_link( + const typename link_t::id_type id, + const typename link_t::index_type index) -> void { detail::get(m_accel_links) = link_t{id, index}; } @@ -121,8 +207,11 @@ class volume_descriptor { /// Volume index in the detector's volume container dindex m_transform{dindex_invalid}; + /// Index range for every object type + sf_link_type m_sf_links{}; + /// Links for every object type to an acceleration data structure - link_type m_accel_links{}; + accel_link_type m_accel_links{}; }; } // namespace detray diff --git a/core/include/detray/geometry/detector_volume.hpp b/core/include/detray/geometry/detector_volume.hpp index 3f6a87ec28..853730124c 100644 --- a/core/include/detray/geometry/detector_volume.hpp +++ b/core/include/detray/geometry/detector_volume.hpp @@ -13,6 +13,7 @@ #include "detray/definitions/indexing.hpp" #include "detray/definitions/qualifiers.hpp" #include "detray/geometry/detail/volume_kernels.hpp" +#include "detray/utils/ranges.hpp" // System include(s) #include @@ -32,8 +33,6 @@ namespace detray { /// accelerator data structure, e.g. portals reside in a brute force /// accelerator (a simple vector), while sensitive surfaces are usually sorted /// into a spacial grid. -/// -/// @TODO: Add access to the volume placement transform and volume center template // @TODO: This needs a concept class detector_volume { @@ -41,12 +40,6 @@ class detector_volume { using descr_t = typename detector_t::volume_type; public: - /// In case the geometry needs to be printed - using name_map = dmap; - - /// Allow detector to access descriptor. @TODO: Remove once possible - friend detector_t; - /// Not allowed: always needs a detector and a descriptor. detector_volume() = delete; @@ -58,7 +51,7 @@ class detector_volume { /// Constructor from detector @param det and volume index @param vol_idx in /// that detector. constexpr detector_volume(const detector_t &det, const dindex vol_idx) - : detector_volume(det, det.volume_by_index(vol_idx)) {} + : detector_volume(det, det.volume(vol_idx)) {} /// Equality operator /// @@ -76,18 +69,12 @@ class detector_volume { DETRAY_HOST_DEVICE constexpr auto index() const -> dindex { return m_desc.index(); } - /// @returns the volume name (add an offset for the detector name). - DETRAY_HOST_DEVICE - constexpr auto name(const name_map &names) const -> const std::string & { - return names.at(m_desc.index() + 1u); - } - /// @returns the (non contextual) transform for the placement of the /// volume in the detector geometry. DETRAY_HOST_DEVICE constexpr auto transform() const -> const typename detector_t::transform3 & { - return m_detector.transform_store({})[m_desc.transform()]; + return m_detector.transform_store()[m_desc.transform()]; } /// @returns the center point of the volume. @@ -96,6 +83,25 @@ class detector_volume { return transform().translation(); } + /// @returns an iterator pair for the requested type of surfaces. + template + DETRAY_HOST_DEVICE constexpr decltype(auto) surfaces() const { + if constexpr (sf_type == surface_id::e_all) { + return detray::ranges::subrange{m_detector.surfaces(), + m_desc.full_sf_range()}; + } else { + return detray::ranges::subrange{m_detector.surfaces(), + m_desc.template sf_link()}; + } + } + + /// @returns an iterator pair for the requested type of surfaces. + DETRAY_HOST_DEVICE constexpr decltype(auto) portals() const { + return detray::ranges::subrange{ + m_detector.surfaces(), + m_desc.template sf_link()}; + } + /// Apply a functor to all surfaces in the volume. /// /// @tparam functor_t the prescription to be applied to the surfaces @@ -103,7 +109,7 @@ class detector_volume { template (descr_t::object_id::e_size) - 1, typename... Args> - DETRAY_HOST_DEVICE constexpr void visit_surfaces(Args &&... args) const { + DETRAY_HOST_DEVICE constexpr void visit_surfaces(Args &&...args) const { visit_surfaces_impl>( std::forward(args)...); } @@ -118,8 +124,8 @@ class detector_volume { template (descr_t::object_id::e_size) - 1, typename track_t, typename... Args> - DETRAY_HOST_DEVICE constexpr void visit_neighborhood( - const track_t &track, Args &&... args) const { + DETRAY_HOST_DEVICE constexpr void visit_neighborhood(const track_t &track, + Args &&...args) const { visit_surfaces_impl>( m_detector, m_desc, track, std::forward(args)...); } @@ -133,9 +139,8 @@ class detector_volume { // Get the index of the surface collection with type index 'I' constexpr auto sf_col_id{ static_cast(I)}; - const auto &link{ - m_desc - .template link(I)>()}; + const auto &link{m_desc.template accel_link< + static_cast(I)>()}; // Check if this volume holds such a collection and, if so, add max // number of candidates that we can expect from it @@ -186,12 +191,18 @@ class detector_volume { << *this << std::endl; return false; } - const auto &acc_link = m_desc.full_link(); + const auto &acc_link = m_desc.accel_link(); if (detail::is_invalid_value(acc_link[0])) { os << "ERROR: Link to portal lookup broken in volume: " << acc_link << "\n in volume: " << *this << std::endl; return false; } + const auto &sf_link = m_desc.sf_link(); + if (detail::is_invalid_value(sf_link[0])) { + os << "ERROR: Link to portal surfaces broken in volume: " << sf_link + << "\n in volume: " << *this << std::endl; + return false; + } // Warnings bool suspicious_links = false; @@ -221,7 +232,7 @@ class detector_volume { os << "id: " << static_cast(v.m_desc.id()); os << " | index: " << v.m_desc.index(); os << " | trf.: " << v.m_desc.transform(); - os << " | acc link: " << v.m_desc.full_link(); + os << " | acc link: " << v.m_desc.accel_link(); return os; } @@ -235,11 +246,10 @@ class detector_volume { int I = static_cast(descr_t::object_id::e_size) - 1, typename... Args> DETRAY_HOST_DEVICE constexpr void visit_surfaces_impl( - Args &&... args) const { + Args &&...args) const { // Get the acceleration data structures for this volume - const auto &link{ - m_desc - .template link(I)>()}; + const auto &link{m_desc.template accel_link< + static_cast(I)>()}; // Only visit, if object type is contained in volume if (not link.is_invalid()) { diff --git a/core/include/detray/geometry/surface.hpp b/core/include/detray/geometry/surface.hpp index 00c909be8f..3343741ca3 100644 --- a/core/include/detray/geometry/surface.hpp +++ b/core/include/detray/geometry/surface.hpp @@ -107,7 +107,9 @@ class surface { /// @returns the surface source link DETRAY_HOST_DEVICE - constexpr auto source() const { return m_desc.source(); } + constexpr auto source() const { + return m_detector.surface(m_desc.barcode()).source; + } /// @returns true if the surface is a senstive detector module. DETRAY_HOST_DEVICE @@ -136,7 +138,7 @@ class surface { /// @returns the coordinate transform matrix of the surface DETRAY_HOST_DEVICE constexpr auto transform(const context &ctx) const -> const transform3 & { - return m_detector.transform_store(ctx)[m_desc.transform()]; + return m_detector.transform_store().at(m_desc.transform(), ctx); } /// @returns the centroid of the surface mask in local cartesian coordinates @@ -289,7 +291,7 @@ class surface { /// @tparam functor_t the prescription to be applied to the mask /// @tparam Args types of additional arguments to the functor template - DETRAY_HOST_DEVICE constexpr auto visit_mask(Args &&... args) const { + DETRAY_HOST_DEVICE constexpr auto visit_mask(Args &&...args) const { const auto &masks = m_detector.mask_store(); return masks.template visit(m_desc.mask(), @@ -301,7 +303,7 @@ class surface { /// @tparam functor_t the prescription to be applied to the mask /// @tparam Args types of additional arguments to the functor template - DETRAY_HOST_DEVICE constexpr auto visit_material(Args &&... args) const { + DETRAY_HOST_DEVICE constexpr auto visit_material(Args &&...args) const { const auto &materials = m_detector.material_store(); return materials.template visit(m_desc.material(), @@ -318,7 +320,7 @@ class surface { os << "ERROR: Invalid barcode for surface:\n" << *this << std::endl; return false; } - if (index() >= m_detector.surface_lookup().size()) { + if (index() >= m_detector.surfaces().size()) { os << "ERROR: Surface index out of bounds for surface:\n" << *this << std::endl; return false; diff --git a/core/include/detray/geometry/volume_connector.hpp b/core/include/detray/geometry/volume_connector.hpp index 47ed8cbcf6..9b9efe0bbe 100644 --- a/core/include/detray/geometry/volume_connector.hpp +++ b/core/include/detray/geometry/volume_connector.hpp @@ -75,7 +75,7 @@ void connect_cylindrical_volumes( const auto &ref = volume_grid.bin(seed[0], seed[1]); // Build and add the portal surfaces - auto &volume = d.volume_by_index(ref); + auto &volume = d.volume(ref); // Collect portals per seed vector_type, dindex>> diff --git a/core/include/detray/geometry/volume_graph.hpp b/core/include/detray/geometry/volume_graph.hpp index 6448afbd0b..2940ab2fe4 100644 --- a/core/include/detray/geometry/volume_graph.hpp +++ b/core/include/detray/geometry/volume_graph.hpp @@ -135,7 +135,7 @@ class volume_graph { } /// Dereference operator @returns a graph node - node operator*() { return node(m_det.volume(*m_vol_itr)); } + node operator*() { return node({m_det, m_vol_itr->index()}); } /// Prefix increment. No postfix increment implemented iterator &operator++() { diff --git a/core/include/detray/propagator/navigator.hpp b/core/include/detray/propagator/navigator.hpp index 6badd0ec53..00d2fd63f4 100644 --- a/core/include/detray/propagator/navigator.hpp +++ b/core/include/detray/propagator/navigator.hpp @@ -508,7 +508,7 @@ class navigator { state &navigation = propagation._navigation; const auto det = navigation.detector(); const auto &track = propagation._stepping(); - const auto &volume = det->volume_by_index(navigation.volume()); + const auto volume = detector_volume{*det, navigation.volume()}; // Clean up state navigation.clear(); diff --git a/core/include/detray/tools/bin_fillers.hpp b/core/include/detray/tools/bin_fillers.hpp index 7d9c7c7423..f68f6c57e1 100644 --- a/core/include/detray/tools/bin_fillers.hpp +++ b/core/include/detray/tools/bin_fillers.hpp @@ -35,11 +35,11 @@ struct fill_by_bin { typename grid_t::value_type single_element; }; - template DETRAY_HOST auto operator()(grid_t &grid, const volume_t &, - const surface_container &, + const surface_container_t &, const mask_container &, const context_t, std::vector> &bins) const -> void { @@ -57,17 +57,18 @@ struct fill_by_bin { /// @param ctx the geometry context struct fill_by_pos { - template DETRAY_HOST auto operator()(grid_t &grid, const volume_t &vol, - const surface_container &surfaces, + const surface_container_t &surfaces, const transform_container &transforms, const mask_container & /*masks*/, const context_t ctx, Args &&...) const -> void { // Fill the volumes surfaces into the grid for (const auto [idx, sf] : detray::views::enumerate(surfaces)) { + // no portals in grids allowed if (not sf.is_sensitive() or sf.volume() != vol.index()) { continue; @@ -103,11 +104,11 @@ struct bin_associator { det.transform_store(), ctx); } - template DETRAY_HOST auto operator()(grid_t &grid, const volume_t &, - const surface_container &surfaces, + const surface_container_t &surfaces, const transform_container &transforms, const mask_container &masks, const context_t ctx, Args &&...) const -> void { diff --git a/core/include/detray/tools/cuboid_portal_generator.hpp b/core/include/detray/tools/cuboid_portal_generator.hpp index 930f3904fc..21a4e54c02 100644 --- a/core/include/detray/tools/cuboid_portal_generator.hpp +++ b/core/include/detray/tools/cuboid_portal_generator.hpp @@ -79,7 +79,7 @@ class cuboid_portal_generator final /// @param ctx the geometry context (not needed for portals). DETRAY_HOST auto operator()(typename detector_t::volume_type &volume, - typename detector_t::surface_container &surfaces, + typename detector_t::surface_lookup_container &surfaces, typename detector_t::transform_container &transforms, typename detector_t::mask_container &masks, typename detector_t::geometry_context ctx = {}) const @@ -95,6 +95,8 @@ class cuboid_portal_generator final using aabb_t = axis_aligned_bounding_volume>; + constexpr auto invalid_src_link{detail::invalid_value()}; + // Only build box portals for cuboid volumes assert(volume.id() == volume_id::e_cuboid); // Need surfaces to wrap @@ -165,11 +167,13 @@ class cuboid_portal_generator final // Build the portal surfaces dindex trf_idx{transforms.size(ctx) - 2}; - surfaces.emplace_back(trf_idx, mask_link, material_link, volume_idx, - dindex_invalid, surface_id::e_portal); + surfaces.push_back({trf_idx, mask_link, material_link, volume_idx, + surface_id::e_portal}, + invalid_src_link); - surfaces.emplace_back(++trf_idx, mask_link, material_link, volume_idx, - dindex_invalid, surface_id::e_portal); + surfaces.push_back({++trf_idx, mask_link, material_link, volume_idx, + surface_id::e_portal}, + invalid_src_link); // // ... x-z plane @@ -187,11 +191,13 @@ class cuboid_portal_generator final transforms.emplace_back(ctx, static_cast(center - shift), new_z, new_x); - surfaces.emplace_back(++trf_idx, mask_link, material_link, volume_idx, - dindex_invalid, surface_id::e_portal); + surfaces.push_back({++trf_idx, mask_link, material_link, volume_idx, + surface_id::e_portal}, + invalid_src_link); - surfaces.emplace_back(++trf_idx, mask_link, material_link, volume_idx, - dindex_invalid, surface_id::e_portal); + surfaces.push_back({++trf_idx, mask_link, material_link, volume_idx, + surface_id::e_portal}, + invalid_src_link); // // ... y-z plane @@ -209,11 +215,13 @@ class cuboid_portal_generator final transforms.emplace_back(ctx, static_cast(center - shift), new_z, new_x); - surfaces.emplace_back(++trf_idx, mask_link, material_link, volume_idx, - dindex_invalid, surface_id::e_portal); + surfaces.push_back({++trf_idx, mask_link, material_link, volume_idx, + surface_id::e_portal}, + invalid_src_link); - surfaces.emplace_back(++trf_idx, mask_link, material_link, volume_idx, - dindex_invalid, surface_id::e_portal); + surfaces.push_back({++trf_idx, mask_link, material_link, volume_idx, + surface_id::e_portal}, + invalid_src_link); return {surfaces_offset, static_cast(surfaces.size())}; } diff --git a/core/include/detray/tools/grid_builder.hpp b/core/include/detray/tools/grid_builder.hpp index 0da37dca89..42e3d13d5f 100644 --- a/core/include/detray/tools/grid_builder.hpp +++ b/core/include/detray/tools/grid_builder.hpp @@ -77,7 +77,7 @@ class grid_builder final : public volume_decorator { DETRAY_HOST void fill_grid( const detector_t &det, const volume_type &vol, const typename detector_t::geometry_context ctx = {}, - const bin_filler_t bin_filler = {}, Args &&... args) { + const bin_filler_t bin_filler = {}, Args &&...args) { bin_filler(m_grid, det, vol, ctx, args...); } @@ -90,7 +90,7 @@ class grid_builder final : public volume_decorator { const volume_type &vol, const surface_container_t &surfaces, const transform_container_t &transforms, const mask_container_t &masks, const typename detector_t::geometry_context ctx = {}, - const bin_filler_t bin_filler = {}, Args &&... args) { + const bin_filler_t bin_filler = {}, Args &&...args) { bin_filler(m_grid, vol, surfaces, transforms, masks, ctx, args...); } @@ -145,7 +145,7 @@ class grid_builder final : public volume_decorator { } if (itr->is_sensitive() or (m_add_passives and itr->is_passive())) { - const auto vol = det.volume_by_index(itr->volume()); + const auto vol = detector_volume{det, itr->volume()}; // The current volume is already built, so the surface // interface is safe to use const auto sf = surface{det, *itr}; @@ -171,7 +171,7 @@ class grid_builder final : public volume_decorator { // Add the grid to the detector and link it to its volume constexpr auto gid{detector_t::accel::template get_id()}; det.accelerator_store().template push_back(m_grid); - vol_ptr->template set_link< + vol_ptr->template set_accel_link< detector_t::volume_type::object_id::e_sensitive>( gid, det.accelerator_store().template size() - 1); diff --git a/core/include/detray/tools/material_factory.hpp b/core/include/detray/tools/material_factory.hpp index ade17ee12d..6ff4898077 100644 --- a/core/include/detray/tools/material_factory.hpp +++ b/core/include/detray/tools/material_factory.hpp @@ -187,7 +187,7 @@ class material_factory final : public factory_decorator { /// @param material material store of the volume builder that the new /// materials get added to. DETRAY_HOST - auto operator()(typename detector_t::surface_container &surfaces, + auto operator()(typename detector_t::surface_lookup_container &surfaces, typename detector_t::material_container &materials) { using link_t = typename detector_t::surface_type::material_link; diff --git a/core/include/detray/tools/surface_factory.hpp b/core/include/detray/tools/surface_factory.hpp index 130da307b2..0c1595fd5f 100644 --- a/core/include/detray/tools/surface_factory.hpp +++ b/core/include/detray/tools/surface_factory.hpp @@ -142,7 +142,7 @@ class surface_factory : public surface_factory_interface { DETRAY_HOST auto operator()([[maybe_unused]] typename detector_t::volume_type &volume, [[maybe_unused]] - typename detector_t::surface_container &surfaces, + typename detector_t::surface_lookup_container &surfaces, [[maybe_unused]] typename detector_t::transform_container &transforms, [[maybe_unused]] typename detector_t::mask_container &masks, @@ -211,8 +211,9 @@ class surface_factory : public surface_factory_interface { // Add the surface descriptor at the position given by 'sf_idx' this->insert_in_container( surfaces, - {trf_idx, mask_link, material_link, volume.index(), - m_sources[idx], m_types[idx]}, + {surface_t{trf_idx, mask_link, material_link, + volume.index(), m_types[idx]}, + m_sources[idx]}, sf_idx); } } diff --git a/core/include/detray/tools/surface_factory_interface.hpp b/core/include/detray/tools/surface_factory_interface.hpp index 00d6a83500..e949f95c71 100644 --- a/core/include/detray/tools/surface_factory_interface.hpp +++ b/core/include/detray/tools/surface_factory_interface.hpp @@ -113,7 +113,7 @@ class surface_factory_interface { DETRAY_HOST virtual auto operator()( typename detector_t::volume_type &volume, - typename detector_t::surface_container &surfaces, + typename detector_t::surface_lookup_container &surfaces, typename detector_t::transform_container &transforms, typename detector_t::mask_container &masks, typename detector_t::geometry_context ctx = {}) const @@ -182,7 +182,7 @@ class factory_decorator : public surface_factory_interface { DETRAY_HOST auto operator()(typename detector_t::volume_type &volume, - typename detector_t::surface_container &surfaces, + typename detector_t::surface_lookup_container &surfaces, typename detector_t::transform_container &transforms, typename detector_t::mask_container &masks, typename detector_t::geometry_context ctx = {}) const diff --git a/core/include/detray/tools/telescope_generator.hpp b/core/include/detray/tools/telescope_generator.hpp index f7f0108d70..e3654be881 100644 --- a/core/include/detray/tools/telescope_generator.hpp +++ b/core/include/detray/tools/telescope_generator.hpp @@ -98,7 +98,7 @@ class telescope_generator final : public surface_factory_interface { /// @param ctx the geometry context (not needed for portals). DETRAY_HOST auto operator()(typename detector_t::volume_type &volume, - typename detector_t::surface_container &surfaces, + typename detector_t::surface_lookup_container &surfaces, typename detector_t::transform_container &transforms, typename detector_t::mask_container &masks, typename detector_t::geometry_context ctx = {}) const @@ -110,6 +110,7 @@ class telescope_generator final : public surface_factory_interface { using material_link_t = typename surface_t::material_link; const dindex surfaces_offset{static_cast(surfaces.size())}; + constexpr auto invalid_src_link{detail::invalid_value()}; // The type id of the surface mask shape constexpr auto mask_id{detector_t::mask_container::template get_id< @@ -135,9 +136,8 @@ class telescope_generator final : public surface_factory_interface { detail::invalid_value()}; const auto trf_index = transforms.size(ctx); - surfaces.emplace_back(trf_index, mask_link, material_link, - volume_idx, dindex_invalid, - surface_id::e_sensitive); + surfaces.push_back({trf_index, mask_link, material_link, + volume_idx, surface_id::e_sensitive}, invalid_src_link); // The rectangle bounds for this module masks.template emplace_back(empty_context{}, m_boundaries, diff --git a/core/include/detray/tools/volume_builder.hpp b/core/include/detray/tools/volume_builder.hpp index 7d355fcae9..48c90ded4e 100644 --- a/core/include/detray/tools/volume_builder.hpp +++ b/core/include/detray/tools/volume_builder.hpp @@ -47,9 +47,9 @@ class volume_builder : public volume_builder_interface { m_volume.set_index(idx); // The first surface search data structure in every volume is a brute // force method that will at least contain the portals - m_volume - .template set_link(0)>( - detector_t::accel::id::e_default, 0); + m_volume.template set_accel_link< + static_cast(0)>( + detector_t::accel::id::e_default, 0); }; /// Adds the @param name of the volume to a @param name_map @@ -131,7 +131,7 @@ class volume_builder : public volume_builder_interface { protected: /// @returns Access to the surface descriptor data - typename detector_t::surface_container& surfaces() override { + typename detector_t::surface_lookup_container& surfaces() override { return m_surfaces; } @@ -157,37 +157,76 @@ class volume_builder : public volume_builder_interface { // Append transforms const auto trf_offset = det.transform_store().size(ctx); - det.append_transforms(std::move(m_transforms), ctx); + det._transforms.append(std::move(m_transforms), ctx); + + // Surface index offset in the global detector container + auto sf_offset{static_cast(det.surfaces().size())}; + + // Find the portal range and add it to the volume surface link + auto is_portal = [](const auto& sf) { return sf.is_portal(); }; + + auto first_pt = std::find_if(std::begin(m_surfaces), + std::end(m_surfaces), is_portal) - + std::begin(m_surfaces); + + auto last_pt = std::rend(m_surfaces) - + std::find_if(std::rbegin(m_surfaces), + std::rend(m_surfaces), is_portal); + + // Identify the portal index range in the global container + dindex_range pt_range{static_cast(first_pt) + sf_offset, + static_cast(last_pt) + sf_offset}; + + m_volume.template update_sf_link(pt_range); + + dindex first_sf{first_pt == 0 ? last_pt : 0}; + dindex last_sf{first_sf == 0 ? first_pt + : m_surfaces.size() + sf_offset}; + + m_volume.template update_sf_link( + {first_sf, last_sf}); // Update mask and transform index of surfaces and set the // correct index of the surface in container - auto sf_offset{static_cast(det.surface_lookup().size())}; for (auto& sf_desc : m_surfaces) { const auto sf = surface{det, sf_desc}; sf.template visit_mask(sf_desc); sf_desc.set_volume(m_volume.index()); sf_desc.update_transform(trf_offset); sf_desc.set_index(sf_offset++); - det.add_surface_to_lookup(sf_desc); + det._surfaces.insert(sf_desc); } - // Append surfaces - det.append_portals(std::move(m_surfaces)); - - // Update the surface link in the volume. In the volume builder, all - // surfaces are filled into the default brute_force accelerator. - // For the other accelerators (grid etc.) there need to be dedicated - // builders + // Place all surfaces in the brute force search method. + // In the volume builder, all surfaces are filled into the default + // brute_force accelerator. For the other accelerators (grid etc.) + // there need to be dedicated builders constexpr auto default_acc_id{detector_t::accel::id::e_default}; - m_volume.template set_link( + + // Strip the source link from the lookup data structure + typename detector_t::surface_container descriptors; + descriptors.reserve(m_surfaces.size()); + std::transform( + m_surfaces.begin(), m_surfaces.end(), + std::back_inserter(descriptors), + [](typename detector_t::surface_lookup_container::value_type& sf) { + return static_cast< + typename detector_t::surface_container::value_type>(sf); + }); + + // Add to the detector and update the accelerator link in the volume. + det._accelerators.template push_back( + std::move(descriptors)); + + m_volume.template set_accel_link( default_acc_id, det.accelerator_store().template size() - 1u); // Append masks - det.append_masks(std::move(m_masks)); + det._masks.append(std::move(m_masks)); - // Finally, add the volume descriptor - det.volumes().push_back(m_volume); + // Finally, add the volume descriptor to the detector + det._volumes.push_back(m_volume); } /// Volume descriptor of the volume under construction @@ -195,9 +234,9 @@ class volume_builder : public volume_builder_interface { /// Placement of the volume under construction typename detector_t::transform3 m_trf{}; - /// Data of conatined surfaces + /// Data of contained surfaces /// @{ - typename detector_t::surface_container m_surfaces{}; + typename detector_t::surface_lookup_container m_surfaces{}; typename detector_t::transform_container m_transforms{}; typename detector_t::mask_container m_masks{}; /// @} diff --git a/core/include/detray/tools/volume_builder_interface.hpp b/core/include/detray/tools/volume_builder_interface.hpp index 6327ff4c16..83e2463260 100644 --- a/core/include/detray/tools/volume_builder_interface.hpp +++ b/core/include/detray/tools/volume_builder_interface.hpp @@ -82,7 +82,7 @@ class volume_builder_interface { protected: /// Access to builder data /// @{ - virtual typename detector_t::surface_container &surfaces() = 0; + virtual typename detector_t::surface_lookup_container &surfaces() = 0; virtual typename detector_t::transform_container &transforms() = 0; virtual typename detector_t::mask_container &masks() = 0; /// @} @@ -153,7 +153,7 @@ class volume_decorator : public volume_builder_interface { /// @} protected: - typename detector_t::surface_container &surfaces() override { + typename detector_t::surface_lookup_container &surfaces() override { return m_builder->surfaces(); } typename detector_t::transform_container &transforms() override { diff --git a/core/include/detray/utils/consistency_checker.hpp b/core/include/detray/utils/consistency_checker.hpp index 8e87187c10..c98f895919 100644 --- a/core/include/detray/utils/consistency_checker.hpp +++ b/core/include/detray/utils/consistency_checker.hpp @@ -142,7 +142,7 @@ inline void check_empty(const detector_t &det) { if (det.volumes().empty()) { throw std::runtime_error("ERROR: No volumes in detector"); } - if (det.surface_lookup().empty()) { + if (det.surfaces().empty()) { throw std::runtime_error("ERROR: No surfaces found"); } if (det.transform_store().empty()) { @@ -212,7 +212,7 @@ inline bool check_consistency(const detector_t &det) { // Check the surfaces in the detector's surface lookup for (const auto &[idx, sf_desc] : - detray::views::enumerate(det.surface_lookup())) { + detray::views::enumerate(det.surfaces())) { const auto sf = surface{det, sf_desc}; // Check that nothing is obviously broken @@ -231,7 +231,7 @@ inline bool check_consistency(const detector_t &det) { // Check that the surface can be found in its volume's acceleration // data structures (if there are no grids, must at least be in the // brute force method) - const auto vol = det.volume_by_index(sf.volume()); + const auto vol = detector_volume{det, sf.volume()}; bool is_registered = false; vol.template visit_surfaces( diff --git a/io/include/detray/io/common/geometry_writer.hpp b/io/include/detray/io/common/geometry_writer.hpp index 6204fc6935..1251fb889e 100644 --- a/io/include/detray/io/common/geometry_writer.hpp +++ b/io/include/detray/io/common/geometry_writer.hpp @@ -50,7 +50,7 @@ class geometry_writer : public writer_interface { header_data.sub_header.emplace(); auto& geo_sub_header = header_data.sub_header.value(); geo_sub_header.n_volumes = det.volumes().size(); - geo_sub_header.n_surfaces = det.n_surfaces(); + geo_sub_header.n_surfaces = det.surfaces().size(); return header_data; } @@ -139,7 +139,7 @@ class geometry_writer : public writer_interface { // Count the surfaces belonging to this volume std::size_t sf_idx{0}; - for (const auto& sf_desc : det.surface_lookup()) { + for (const auto& sf_desc : det.surfaces()) { if (sf_desc.volume() == vol_desc.index()) { vol_data.surfaces.push_back( serialize(surface{det, sf_desc}, sf_idx++)); @@ -147,7 +147,7 @@ class geometry_writer : public writer_interface { } // Only run the query, if object type is contained in volume - const auto& link = vol_desc.full_link(); + const auto& link = vol_desc.accel_link(); // Initialize the std::optional if (link.size() > 1u) { vol_data.acc_links.emplace(); diff --git a/io/include/detray/io/common/homogeneous_material_writer.hpp b/io/include/detray/io/common/homogeneous_material_writer.hpp index 189f0e4526..a537722c69 100644 --- a/io/include/detray/io/common/homogeneous_material_writer.hpp +++ b/io/include/detray/io/common/homogeneous_material_writer.hpp @@ -109,7 +109,7 @@ class homogeneous_material_writer : public writer_interface { // Find all surfaces that belong to the volume and count them std::size_t sf_idx{0u}, slab_idx{0u}, rod_idx{0u}; - for (const auto& sf_desc : det.surface_lookup()) { + for (const auto& sf_desc : det.surfaces()) { if (sf_desc.volume() != vol_desc.index()) { continue; } diff --git a/io/include/detray/io/common/material_map_writer.hpp b/io/include/detray/io/common/material_map_writer.hpp index 02e3071b66..9dc50965af 100644 --- a/io/include/detray/io/common/material_map_writer.hpp +++ b/io/include/detray/io/common/material_map_writer.hpp @@ -66,7 +66,7 @@ class material_map_writer for (const auto& vol_desc : det.volumes()) { /// Check if a surface has a metrial map - for (const auto& sf_desc : det.surface_lookup()) { + for (const auto& sf_desc : det.surfaces()) { if (sf_desc.volume() != vol_desc.index()) { continue; } diff --git a/io/include/detray/io/common/surface_grid_writer.hpp b/io/include/detray/io/common/surface_grid_writer.hpp index 48446b9212..650c2c2fa6 100644 --- a/io/include/detray/io/common/surface_grid_writer.hpp +++ b/io/include/detray/io/common/surface_grid_writer.hpp @@ -59,7 +59,7 @@ class surface_grid_writer for (const auto& vol_desc : det.volumes()) { // Links to all acceleration data structures in the volume - const auto& multi_link = vol_desc.full_link(); + const auto& multi_link = vol_desc.accel_link(); for (dindex i = 0u; i < multi_link.size(); ++i) { const auto& acc_link = multi_link[i]; diff --git a/plugins/svgtools/include/detray/plugins/svgtools/conversion/grid.hpp b/plugins/svgtools/include/detray/plugins/svgtools/conversion/grid.hpp index f2514f7b6b..ba435a2f46 100644 --- a/plugins/svgtools/include/detray/plugins/svgtools/conversion/grid.hpp +++ b/plugins/svgtools/include/detray/plugins/svgtools/conversion/grid.hpp @@ -138,8 +138,9 @@ std::optional grid(const detector_t& detector, using d_scalar_t = typename detector_t::scalar_type; using geo_object_ids = typename detector_t::geo_obj_ids; - const auto& vol_desc = detector.volumes()[index]; - const auto& link = vol_desc.template link(); + const auto vol_desc = detector.volumes()[index]; + const auto link = + vol_desc.template accel_link(); actsvg::proto::grid p_grid; if (not link.is_invalid()) { diff --git a/plugins/svgtools/include/detray/plugins/svgtools/illustrator.hpp b/plugins/svgtools/include/detray/plugins/svgtools/illustrator.hpp index 76a92da1b3..100623428a 100644 --- a/plugins/svgtools/include/detray/plugins/svgtools/illustrator.hpp +++ b/plugins/svgtools/include/detray/plugins/svgtools/illustrator.hpp @@ -94,9 +94,7 @@ class illustrator { const typename detector_t::geometry_context& gctx = {}) const { const auto surface = detray::surface{ - _detector, - _detector.surface_lookup()[static_cast(index)]}; - + _detector, _detector.surface(static_cast(index))}; auto ret = svgtools::utils::group(prefix); actsvg::svg::object svg_sur; std::array color; diff --git a/plugins/svgtools/include/detray/plugins/svgtools/utils/link_utils.hpp b/plugins/svgtools/include/detray/plugins/svgtools/utils/link_utils.hpp index ddd5f42b37..d71a9a5211 100644 --- a/plugins/svgtools/include/detray/plugins/svgtools/utils/link_utils.hpp +++ b/plugins/svgtools/include/detray/plugins/svgtools/utils/link_utils.hpp @@ -32,7 +32,7 @@ inline auto get_linked_volume(const detector_t& detector, const detray::surface& d_portal) { assert(is_not_world_portal(d_portal)); const auto d_link_idx = d_portal.template visit_mask(); - return detector.volume_by_index(d_link_idx); + return detector_volume{detector, d_link_idx}; } /// @brief Calculates the start and end point of the link. diff --git a/plugins/svgtools/include/detray/plugins/svgtools/utils/volume_utils.hpp b/plugins/svgtools/include/detray/plugins/svgtools/utils/volume_utils.hpp index af08a6db2a..d266c1a2af 100644 --- a/plugins/svgtools/include/detray/plugins/svgtools/utils/volume_utils.hpp +++ b/plugins/svgtools/include/detray/plugins/svgtools/utils/volume_utils.hpp @@ -15,8 +15,8 @@ namespace detray::svgtools::utils { template auto surface_lookup(const detector_t& detector, const detector_volume& d_volume) { - typename detector_t::surface_lookup_container descriptors; - for (auto desc : detector.surface_lookup()) { + typename detector_t::surface_container descriptors; + for (auto desc : detector.surfaces()) { if (desc.volume() == d_volume.index()) { descriptors.push_back(desc); } @@ -27,7 +27,7 @@ auto surface_lookup(const detector_t& detector, template auto surface_indices(const detector_t& detector, const dindex volume_index) { const auto d_volume = - detector.volume_by_index(static_cast(volume_index)); + detector_volume{detector, static_cast(volume_index)}; const auto descriptors = surface_lookup(detector, d_volume); std::vector ret; for (const auto& desc : descriptors) { diff --git a/tests/benchmarks/cpu/find_volume.cpp b/tests/benchmarks/cpu/find_volume.cpp index 573749c7da..6a94991098 100644 --- a/tests/benchmarks/cpu/find_volume.cpp +++ b/tests/benchmarks/cpu/find_volume.cpp @@ -56,7 +56,7 @@ void BM_FIND_VOLUMES(benchmark::State &state) { for (unsigned int i0 = 0u; i0 < itest; ++i0) { test::vector3 rz{static_cast(i0) * step0, 0.f, static_cast(i1) * step1}; - const auto &v = d.volume_by_pos(rz); + const auto &v = d.volume(rz); benchmark::DoNotOptimize(successful); benchmark::DoNotOptimize(unsuccessful); diff --git a/tests/benchmarks/cpu/intersect_all.cpp b/tests/benchmarks/cpu/intersect_all.cpp index 702e12359e..99b0d16bd4 100644 --- a/tests/benchmarks/cpu/intersect_all.cpp +++ b/tests/benchmarks/cpu/intersect_all.cpp @@ -69,7 +69,7 @@ void BM_INTERSECT_ALL(benchmark::State &state) { for (const auto track : trk_generator) { // Loop over all surfaces in detector - for (const auto &sf_desc : d.surface_lookup()) { + for (const auto &sf_desc : d.surfaces()) { const auto sf = surface{d, sf_desc}; sf.template visit_mask( intersections, detail::ray(track), sf_desc, transforms); diff --git a/tests/benchmarks/cpu/intersect_surfaces.cpp b/tests/benchmarks/cpu/intersect_surfaces.cpp index 5637821ab2..b32b7cc705 100644 --- a/tests/benchmarks/cpu/intersect_surfaces.cpp +++ b/tests/benchmarks/cpu/intersect_surfaces.cpp @@ -115,7 +115,7 @@ void BM_INTERSECT_CYLINDERS(benchmark::State &state) { mask_link_t mask_link{mask_ids::e_cylinder2, 0}; material_link_t material_link{material_ids::e_slab, 0}; - plane_surface plane(test::transform3(), mask_link, material_link, 0u, false, + plane_surface plane(test::transform3(), mask_link, material_link, 0u, surface_id::e_sensitive); // Iterate through uniformly distributed momentum directions @@ -170,7 +170,7 @@ void BM_INTERSECT_PORTAL_CYLINDERS(benchmark::State &state) { mask_link_t mask_link{mask_ids::e_cylinder2, 0u}; material_link_t material_link{material_ids::e_slab, 0u}; - plane_surface plane(test::transform3(), mask_link, material_link, 0u, false, + plane_surface plane(test::transform3(), mask_link, material_link, 0u, surface_id::e_sensitive); // Iterate through uniformly distributed momentum directions @@ -222,7 +222,7 @@ void BM_INTERSECT_CONCETRIC_CYLINDERS(benchmark::State &state) { mask_link_t mask_link{mask_ids::e_conc_cylinder3, 0u}; material_link_t material_link{material_ids::e_slab, 0u}; - plane_surface plane(test::transform3(), mask_link, material_link, 0u, false, + plane_surface plane(test::transform3(), mask_link, material_link, 0u, surface_id::e_sensitive); // Iterate through uniformly distributed momentum directions diff --git a/tests/common/include/tests/common/test_toy_detector.hpp b/tests/common/include/tests/common/test_toy_detector.hpp index 9bd3b17826..4ac4b57404 100644 --- a/tests/common/include/tests/common/test_toy_detector.hpp +++ b/tests/common/include/tests/common/test_toy_detector.hpp @@ -67,7 +67,7 @@ inline bool test_toy_detector( using material_ids = typename detector_t::materials::id; using material_link_t = typename detector_t::surface_type::material_link; using accel_ids = typename detector_t::accel::id; - using accel_link_t = typename volume_t::link_type::index_type; + using accel_link_t = typename volume_t::accel_link_type::index_type; EXPECT_EQ(names.at(0u), "toy_detector"); @@ -76,7 +76,7 @@ inline bool test_toy_detector( geo_context_t ctx{}; auto& volumes = toy_det.volumes(); - auto& surfaces = toy_det.surface_lookup(); + auto& surfaces = toy_det.surfaces(); auto& accel = toy_det.accelerator_store(); auto& transforms = toy_det.transform_store(); auto& masks = toy_det.mask_store(); @@ -102,7 +102,7 @@ inline bool test_toy_detector( // Check number of geomtery objects EXPECT_EQ(volumes.size(), 20u); - EXPECT_EQ(toy_det.n_surfaces(), 3244u); + EXPECT_EQ(toy_det.surfaces().size(), 3244u); EXPECT_EQ(transforms.size(ctx), 3264u); EXPECT_EQ(masks.template size(), 2492u); EXPECT_EQ(masks.template size(), 648u); @@ -136,9 +136,9 @@ inline bool test_toy_detector( const darray& range, const accel_link_t& /*accel_link*/) { EXPECT_EQ(vol_itr->index(), vol_index); - EXPECT_EQ(vol_itr->template link().id(), + EXPECT_EQ(vol_itr->template accel_link().id(), accel_ids::e_brute_force); - EXPECT_EQ(vol_itr->template link().index(), + EXPECT_EQ(vol_itr->template accel_link().index(), range[0]); }; @@ -240,7 +240,7 @@ inline bool test_toy_detector( const darray& pt_range, const darray& sf_range = {0u, 0u}) { // Link to the acceleration data structures the volume holds - const auto& link = vol_itr->full_link(); + const auto& link = vol_itr->accel_link(); // Test the portal search const auto& bf_finder = diff --git a/tests/common/include/tests/common/tools/particle_gun.hpp b/tests/common/include/tests/common/tools/particle_gun.hpp index e5acf9e94a..350ea300bb 100644 --- a/tests/common/include/tests/common/tools/particle_gun.hpp +++ b/tests/common/include/tests/common/tools/particle_gun.hpp @@ -59,7 +59,7 @@ struct particle_gun { std::vector intersections{}; - for (const auto &sf_desc : detector.surface_lookup()) { + for (const auto &sf_desc : detector.surfaces()) { // Retrieve candidate(s) from the surface const auto sf = surface{detector, sf_desc}; sf.template visit_mask( diff --git a/tests/common/include/tests/common/tools/test_surfaces.hpp b/tests/common/include/tests/common/tools/test_surfaces.hpp index 971263c339..5e00ccff04 100644 --- a/tests/common/include/tests/common/tools/test_surfaces.hpp +++ b/tests/common/include/tests/common/tools/test_surfaces.hpp @@ -67,7 +67,7 @@ planes_along_direction(const dvector &distances, vector3 direction) { plane_material_link_t material_link{plane_material_ids::e_plane_slab, 0u}; surfaces.emplace_back(std::move(trf), std::move(mask_link), - std::move(material_link), 0u, false, + std::move(material_link), 0u, surface_id::e_sensitive); surfaces.back().set_index(idx); } diff --git a/tests/include/detray/test/planes_along_direction.hpp b/tests/include/detray/test/planes_along_direction.hpp index f29489e674..a7c5605292 100644 --- a/tests/include/detray/test/planes_along_direction.hpp +++ b/tests/include/detray/test/planes_along_direction.hpp @@ -50,7 +50,7 @@ planes_along_direction(const dvector &distances, vector3 direction) { plane_material_link_t material_link{plane_material_ids::e_plane_slab, 0u}; surfaces.emplace_back(std::move(trf), std::move(mask_link), - std::move(material_link), 0u, false, + std::move(material_link), 0u, surface_id::e_sensitive); surfaces.back().set_index(idx); } diff --git a/tests/unit_tests/cpu/core_detector.cpp b/tests/unit_tests/cpu/core_detector.cpp index b020740852..cc2de9895c 100644 --- a/tests/unit_tests/cpu/core_detector.cpp +++ b/tests/unit_tests/cpu/core_detector.cpp @@ -63,7 +63,6 @@ void prefill_detector(detector_t& d, material_id::e_slab, materials.template size() - 1}; surfaces.emplace_back(trfs.size(ctx) - 1, mask_link, material_link, 0u, - detray::dindex_invalid, detray::surface_id::e_sensitive); surfaces.back().set_index( static_cast(surfaces.size() - 1u)); @@ -81,7 +80,6 @@ void prefill_detector(detector_t& d, material_link = {material_id::e_slab, materials.template size() - 1}; surfaces.emplace_back(trfs.size(ctx) - 1, mask_link, material_link, 0u, - detray::dindex_invalid, detray::surface_id::e_sensitive); surfaces.back().set_index( static_cast(surfaces.size() - 1u)); @@ -99,14 +97,13 @@ void prefill_detector(detector_t& d, material_link = {material_id::e_rod, materials.template size() - 1}; surfaces.emplace_back(trfs.size(ctx) - 1, mask_link, material_link, 0u, - detray::dindex_invalid, detray::surface_id::e_sensitive); surfaces.back().set_index( static_cast(surfaces.size() - 1u)); // Add surfaces to lookup, so they can be easily fetched using a barcode for (const auto sf : surfaces) { - d.add_surface_to_lookup(sf); + d.surfaces().insert(sf); } // Add the new data @@ -563,11 +560,12 @@ GTEST_TEST(detray_tools, detector_volume_construction) { // Check the acceleration data structure link dtyped_index acc_link{accel_id::e_default, 1u}; - ASSERT_TRUE(vol.full_link().size() == geo_obj_id::e_size); - EXPECT_EQ(vol.link(), acc_link); - EXPECT_EQ(vol.link(), acc_link); + ASSERT_TRUE(vol.accel_link().size() == geo_obj_id::e_size); + EXPECT_EQ(vol.accel_link(), acc_link); + EXPECT_EQ(vol.accel_link(), acc_link); // Not set by the vanilla volume builder - EXPECT_TRUE(detail::is_invalid_value(vol.link())); + EXPECT_TRUE( + detail::is_invalid_value(vol.accel_link())); EXPECT_EQ(d.portals().size(), 19u); EXPECT_EQ(d.mask_store().template size(), 2u); @@ -580,7 +578,7 @@ GTEST_TEST(detray_tools, detector_volume_construction) { // check surface type and volume link std::vector sf_ids{}; - sf_ids.reserve(d.n_surfaces()); + sf_ids.reserve(d.surfaces().size()); sf_ids.insert(sf_ids.end(), 3u, surface_id::e_sensitive); sf_ids.insert(sf_ids.end(), 4u, surface_id::e_portal); sf_ids.insert(sf_ids.end(), 6u, surface_id::e_sensitive); @@ -588,7 +586,7 @@ GTEST_TEST(detray_tools, detector_volume_construction) { sf_ids.insert(sf_ids.end(), 3u, surface_id::e_sensitive); std::vector volume_links{}; - volume_links.reserve(d.n_surfaces()); + volume_links.reserve(d.surfaces().size()); volume_links.insert(volume_links.end(), 3u, 0u); volume_links.insert(volume_links.end(), 16u, 1u); @@ -605,7 +603,7 @@ GTEST_TEST(detray_tools, detector_volume_construction) { // check that the transform indices are continuous for the newly added // surfaces. The first new transform belongs to the volume itself for (std::size_t idx : - detray::views::iota(dindex_range{3, d.n_surfaces()})) { + detray::views::iota(dindex_range{3, d.surfaces().size()})) { geometry::barcode bcd{}; bcd.set_index(idx); EXPECT_EQ(d.surface(bcd).transform(), idx + 1) @@ -739,8 +737,8 @@ GTEST_TEST(detray_tools, detector_builder) { // vecmem::host_memory_resource host_mr; const detector_t d = det_builder.build(host_mr); - const auto& vol0 = d.volume_by_index(0u); - const auto& vol1 = d.volume_by_index(1u); + const auto& vol0 = detector_volume{d, 0u}; + const auto& vol1 = detector_volume{d, 1u}; // check the results EXPECT_EQ(d.volumes().size(), 2u); @@ -761,7 +759,7 @@ GTEST_TEST(detray_tools, detector_builder) { EXPECT_EQ(vol0.n_max_candidates(), 3u); EXPECT_EQ(vol1.n_max_candidates(), 9u); - EXPECT_EQ(d.surface_lookup().size(), 12u); + EXPECT_EQ(d.surfaces().size(), 12u); EXPECT_EQ(d.mask_store().template size(), 0u); EXPECT_EQ(d.mask_store().template size(), 0u); EXPECT_EQ(d.mask_store().template size(), 0u); diff --git a/tests/unit_tests/cpu/geometry_surface.cpp b/tests/unit_tests/cpu/geometry_surface.cpp index 408f00bbcb..18edcdbc7a 100644 --- a/tests/unit_tests/cpu/geometry_surface.cpp +++ b/tests/unit_tests/cpu/geometry_surface.cpp @@ -45,12 +45,11 @@ GTEST_TEST(detray_geometry, surface_descriptor) { material_link_t material_id{material_ids::e_slab, 0u}; surface_descriptor desc( - 1u, mask_id, material_id, 2u, 3u, surface_id::e_sensitive); + 1u, mask_id, material_id, 2u, surface_id::e_sensitive); // Test access ASSERT_EQ(desc.transform(), 1u); ASSERT_EQ(desc.volume(), 2u); - ASSERT_EQ(desc.source(), 3u); ASSERT_EQ(desc.id(), surface_id::e_sensitive); ASSERT_FALSE(desc.is_portal()); ASSERT_FALSE(desc.is_passive()); @@ -68,7 +67,6 @@ GTEST_TEST(detray_geometry, surface_descriptor) { ASSERT_EQ(desc.transform(), 8u); ASSERT_EQ(desc.volume(), 5u); - ASSERT_EQ(desc.source(), 3u); ASSERT_EQ(desc.id(), surface_id::e_portal); ASSERT_EQ(desc.index(), 6u); ASSERT_TRUE(desc.is_portal()); @@ -96,7 +94,7 @@ GTEST_TEST(detray_geometry, surface) { auto ctx = typename detector_t::geometry_context{}; - const auto disc_descr = toy_det.surface_lookup()[13u]; + const auto disc_descr = toy_det.surfaces()[13u]; const auto disc = surface{toy_det, disc_descr}; // IDs diff --git a/tests/unit_tests/cpu/geometry_volume.cpp b/tests/unit_tests/cpu/geometry_volume.cpp index 977f308bbf..6295066a3a 100644 --- a/tests/unit_tests/cpu/geometry_volume.cpp +++ b/tests/unit_tests/cpu/geometry_volume.cpp @@ -7,6 +7,7 @@ // Project include(s) #include "detray/definitions/units.hpp" +#include "detray/detectors/create_toy_geometry.hpp" #include "detray/geometry/detail/volume_descriptor.hpp" #include "detray/test/types.hpp" @@ -33,7 +34,7 @@ enum accel_ids : unsigned int { } // namespace // This tests the detector volume class and its many links -GTEST_TEST(detray_geometry, detector_volume) { +GTEST_TEST(detray_geometry, volume_descriptor) { using namespace detray; using accel_link_t = dtyped_index; @@ -42,26 +43,44 @@ GTEST_TEST(detray_geometry, detector_volume) { // Check construction, setters and getters volume_t v1(volume_id::e_cylinder); v1.set_index(12345u); - v1.template set_link({accel_ids::e_default, 1u}); - v1.template set_link({accel_ids::e_grid, 12u}); + v1.template set_accel_link( + {accel_ids::e_default, 1u}); + v1.template set_accel_link( + {accel_ids::e_grid, 12u}); ASSERT_TRUE(v1.id() == volume_id::e_cylinder); ASSERT_TRUE(v1.index() == 12345u); - ASSERT_TRUE(v1.template link().id() == + ASSERT_TRUE(v1.template accel_link().id() == accel_ids::e_default); - ASSERT_TRUE(v1.template link().index() == 1u); - ASSERT_TRUE(v1.template link().id() == + ASSERT_TRUE(v1.template accel_link().index() == 1u); + ASSERT_TRUE(v1.template accel_link().id() == accel_ids::e_grid); - ASSERT_TRUE(v1.template link().index() == 12u); + ASSERT_TRUE(v1.template accel_link().index() == + 12u); // Check copy constructor const auto v2 = volume_t(v1); ASSERT_EQ(v2.id(), volume_id::e_cylinder); ASSERT_EQ(v2.index(), 12345u); - ASSERT_TRUE(v2.template link().id() == + ASSERT_TRUE(v2.template accel_link().id() == accel_ids::e_default); - ASSERT_TRUE(v2.template link().index() == 1u); - ASSERT_TRUE(v2.template link().id() == + ASSERT_TRUE(v2.template accel_link().index() == 1u); + ASSERT_TRUE(v2.template accel_link().id() == accel_ids::e_grid); - ASSERT_TRUE(v2.template link().index() == 12u); + ASSERT_TRUE(v2.template accel_link().index() == + 12u); +} + +/// This tests the functionality of a detector volume interface +GTEST_TEST(detray_geometry, detector_volume) { + + using namespace detray; + + vecmem::host_memory_resource host_mr; + const auto [toy_det, names] = create_toy_geometry(host_mr); + + // Volume 7 is a barrrel layer with sensitive surfaces + const auto vol7 = detector_volume{toy_det, 7u}; + + std::cout << vol7 << std::endl; } diff --git a/tests/unit_tests/cpu/grid_grid_builder.cpp b/tests/unit_tests/cpu/grid_grid_builder.cpp index 26128be8b3..e9511a43e9 100644 --- a/tests/unit_tests/cpu/grid_grid_builder.cpp +++ b/tests/unit_tests/cpu/grid_grid_builder.cpp @@ -261,15 +261,15 @@ GTEST_TEST(detray_tools, decorator_grid_builder) { sf_range[1] = {acc_ids::e_cylinder2_grid, 0u}; // toy detector makes no distinction between the surface types - EXPECT_EQ(vol.template link(), + EXPECT_EQ(vol.template accel_link(), sf_range[geo_obj_id::e_portal]); - EXPECT_EQ(vol.template link(), + EXPECT_EQ(vol.template accel_link(), sf_range[geo_obj_id::e_sensitive]); - EXPECT_EQ(vol.template link(), + EXPECT_EQ(vol.template accel_link(), sf_range[geo_obj_id::e_passive]); // Only the portals should be in the detector's surface container now - EXPECT_EQ(d.surface_lookup().size(), 7u); + EXPECT_EQ(d.surfaces().size(), 7u); EXPECT_EQ(d.mask_store().template size(), 3u); EXPECT_EQ(d.mask_store().template size(), 0u); EXPECT_EQ(d.mask_store().template size(), 3u); diff --git a/tests/unit_tests/cpu/sf_finder_brute_force.cpp b/tests/unit_tests/cpu/sf_finder_brute_force.cpp index fcc04bb9e0..67f78c60e3 100644 --- a/tests/unit_tests/cpu/sf_finder_brute_force.cpp +++ b/tests/unit_tests/cpu/sf_finder_brute_force.cpp @@ -97,7 +97,7 @@ GTEST_TEST(detray_surface_finders, brute_force_search) { // Now run a brute force surface search in the first barrel layer dindex test_vol_idx{7UL}; - const auto& vol = det.volume_by_index(test_vol_idx); + const auto vol = detector_volume{det, test_vol_idx}; // track in x-direction detail::ray trk({0.f, 0.f, 0.f}, 0.f, diff --git a/tests/unit_tests/cpu/test_telescope_detector.cpp b/tests/unit_tests/cpu/test_telescope_detector.cpp index fdea0a10b5..e01cd1099d 100644 --- a/tests/unit_tests/cpu/test_telescope_detector.cpp +++ b/tests/unit_tests/cpu/test_telescope_detector.cpp @@ -64,6 +64,8 @@ GTEST_TEST(detray_detectors, telescope_detector) { using namespace detray; + using detector_t = detector>>; + // Use rectangle surfaces mask> rectangle{0u, 20.f * unit::mm, 20.f * unit::mm}; @@ -105,6 +107,13 @@ GTEST_TEST(detray_detectors, telescope_detector) { const auto [z_tel_det1, z_tel_names1] = create_telescope_detector(host_mr, tel_cfg.positions(positions)); + // Some general checks + const auto vol0 = detector_volume{z_tel_det1, 0u}; + ASSERT_EQ(vol0.portals().size(), 6u); + ASSERT_EQ(vol0.surfaces().size(), positions.size() + 6u); + ASSERT_EQ(vol0.template surfaces().size(), + positions.size()); + // Test this only once, it is the same for all telescope detectors EXPECT_EQ(z_tel_names1.at(0u), "telescope_detector"); EXPECT_EQ(z_tel_names1.at(1u), "telescope_world_0"); @@ -122,10 +131,10 @@ GTEST_TEST(detray_detectors, telescope_detector) { detail::check_consistency(z_tel_det2); // Compare - for (std::size_t i{0u}; i < z_tel_det1.surface_lookup().size(); ++i) { + for (std::size_t i{0u}; i < z_tel_det1.surfaces().size(); ++i) { geometry::barcode bcd{}; bcd.set_volume(0u).set_index(i); - bcd.set_id((i == z_tel_det1.surface_lookup().size() - 1u) + bcd.set_id((i == z_tel_det1.surfaces().size() - 1u) ? surface_id::e_portal : surface_id::e_sensitive); EXPECT_TRUE(z_tel_det1.surface(bcd) == z_tel_det2.surface(bcd)); diff --git a/tests/unit_tests/cpu/tools_intersection_kernel.cpp b/tests/unit_tests/cpu/tools_intersection_kernel.cpp index f1952aa7f1..85b0f0174b 100644 --- a/tests/unit_tests/cpu/tools_intersection_kernel.cpp +++ b/tests/unit_tests/cpu/tools_intersection_kernel.cpp @@ -114,16 +114,16 @@ GTEST_TEST(detray_intersection, intersection_kernel_ray) { empty_context{}); // The surfaces and their store - surface_t rectangle_surface(0u, {e_rectangle2, 0u}, {e_slab, 0u}, 0u, 0u, + surface_t rectangle_surface(0u, {e_rectangle2, 0u}, {e_slab, 0u}, 0u, surface_id::e_sensitive); - surface_t trapezoid_surface(1u, {e_trapezoid2, 0u}, {e_slab, 1u}, 0u, 1u, + surface_t trapezoid_surface(1u, {e_trapezoid2, 0u}, {e_slab, 1u}, 0u, surface_id::e_sensitive); - surface_t annulus_surface(2u, {e_annulus2, 0u}, {e_slab, 2u}, 0u, 2u, + surface_t annulus_surface(2u, {e_annulus2, 0u}, {e_slab, 2u}, 0u, surface_id::e_sensitive); - surface_t cyl_surface(3u, {e_cylinder2, 0u}, {e_slab, 2u}, 0u, 3u, + surface_t cyl_surface(3u, {e_cylinder2, 0u}, {e_slab, 2u}, 0u, surface_id::e_passive); surface_t cyl_portal_surface(4u, {e_cylinder2_portal, 0u}, {e_slab, 2u}, 0u, - 4u, surface_id::e_portal); + surface_id::e_portal); surface_container_t surfaces = {rectangle_surface, trapezoid_surface, annulus_surface, cyl_surface, cyl_portal_surface}; @@ -245,10 +245,10 @@ GTEST_TEST(detray_intersection, intersection_kernel_helix) { // The surfaces and their store const surface_t rectangle_surface(0u, {e_rectangle2, 0u}, {e_slab, 0u}, 0u, - 0u, surface_id::e_sensitive); + surface_id::e_sensitive); const surface_t trapezoid_surface(1u, {e_trapezoid2, 0u}, {e_slab, 1u}, 0u, - 1u, surface_id::e_sensitive); - const surface_t annulus_surface(2u, {e_annulus2, 0u}, {e_slab, 2u}, 0u, 2u, + surface_id::e_sensitive); + const surface_t annulus_surface(2u, {e_annulus2, 0u}, {e_slab, 2u}, 0u, surface_id::e_sensitive); surface_container_t surfaces = {rectangle_surface, trapezoid_surface, annulus_surface}; diff --git a/tests/unit_tests/cpu/tools_material_builder.cpp b/tests/unit_tests/cpu/tools_material_builder.cpp index 0ab1223d4f..577ea92258 100644 --- a/tests/unit_tests/cpu/tools_material_builder.cpp +++ b/tests/unit_tests/cpu/tools_material_builder.cpp @@ -200,7 +200,7 @@ GTEST_TEST(detray_tools, decorator_material_builder) { EXPECT_EQ(vol.index(), 0u); EXPECT_EQ(vol.id(), volume_id::e_cylinder); - EXPECT_EQ(d.surface_lookup().size(), 7u); + EXPECT_EQ(d.surfaces().size(), 7u); EXPECT_EQ(d.transform_store().size(), 8u); EXPECT_EQ(d.mask_store().template size(), 2u); EXPECT_EQ(d.mask_store().template size(), 0u); @@ -211,7 +211,7 @@ GTEST_TEST(detray_tools, decorator_material_builder) { EXPECT_EQ(d.material_store().template size(), 7u); EXPECT_EQ(d.material_store().template size(), 0u); - for (auto [idx, sf_desc] : detray::views::enumerate(d.surface_lookup())) { + for (auto [idx, sf_desc] : detray::views::enumerate(d.surfaces())) { const auto &mat_link = sf_desc.material(); EXPECT_EQ(mat_link.id(), material_id::e_slab); EXPECT_EQ(mat_link.index(), idx); @@ -294,7 +294,7 @@ GTEST_TEST(detray_tools, detector_builder_with_material) { // vecmem::host_memory_resource host_mr; const detector_t d = det_builder.build(host_mr); - const auto &vol = d.volume_by_index(0u); + const auto vol = detector_volume{d, 0u}; // check the results EXPECT_EQ(d.volumes().size(), 1u); @@ -306,14 +306,13 @@ GTEST_TEST(detray_tools, detector_builder_with_material) { EXPECT_TRUE(vol.transform() == trf); EXPECT_TRUE(d.transform_store()[0u] == trf); - EXPECT_EQ(d.surface_lookup().size(), 7u); + EXPECT_EQ(d.surfaces().size(), 7u); EXPECT_EQ(d.mask_store().template size(), 3u); EXPECT_EQ(d.mask_store().template size(), 1u); EXPECT_EQ(d.material_store().template size(), 7u); // Check the material links - for (const auto [idx, sf_desc] : - detray::views::enumerate(d.surface_lookup())) { + for (const auto [idx, sf_desc] : detray::views::enumerate(d.surfaces())) { EXPECT_EQ(sf_desc.material().id(), material_id::e_slab); EXPECT_EQ(sf_desc.material().index(), idx); } diff --git a/tests/unit_tests/device/cuda/detector_cuda.cpp b/tests/unit_tests/device/cuda/detector_cuda.cpp index 39d9abe9f2..3d2db34c2e 100644 --- a/tests/unit_tests/device/cuda/detector_cuda.cpp +++ b/tests/unit_tests/device/cuda/detector_cuda.cpp @@ -35,7 +35,7 @@ TEST(detector_cuda, detector) { // host objects auto& volumes_host = toy_det.volumes(); - auto& surfaces_host = toy_det.surface_lookup(); + auto& surfaces_host = toy_det.surfaces(); auto& transforms_host = toy_det.transform_store(); auto& masks_host = toy_det.mask_store(); auto& discs_host = masks_host.get(); @@ -74,7 +74,7 @@ TEST(detector_cuda, detector) { // check if the same surface objects are copied for (unsigned int i = 0u; i < surfaces_host.size(); i++) { - EXPECT_EQ(surfaces_host[i] == surfaces_device[i], true); + EXPECT_EQ(surfaces_device[i] == surfaces_host[i], true); } // check if the same transform objects are copied diff --git a/tests/unit_tests/device/cuda/detector_cuda_kernel.cu b/tests/unit_tests/device/cuda/detector_cuda_kernel.cu index 683d53160a..4dab2c41c8 100644 --- a/tests/unit_tests/device/cuda/detector_cuda_kernel.cu +++ b/tests/unit_tests/device/cuda/detector_cuda_kernel.cu @@ -37,8 +37,8 @@ __global__ void detector_test_kernel( } // copy objects - surfaces - for (unsigned int i = 0u; i < det_device.surface_lookup().size(); i++) { - surfaces_device[i] = det_device.surface_lookup()[i]; + for (unsigned int i = 0u; i < det_device.surfaces().size(); i++) { + surfaces_device[i] = det_device.surfaces()[i]; } // copy objects - transforms diff --git a/tests/unit_tests/io/io_json_detector_reader.cpp b/tests/unit_tests/io/io_json_detector_reader.cpp index 5826e2334e..cb01aecf25 100644 --- a/tests/unit_tests/io/io_json_detector_reader.cpp +++ b/tests/unit_tests/io/io_json_detector_reader.cpp @@ -168,7 +168,7 @@ TEST(io, json_toy_geometry) { const auto& masks = comp_det.mask_store(); EXPECT_EQ(comp_det.volumes().size(), 20u); - EXPECT_EQ(comp_det.n_surfaces(), 3244u); + EXPECT_EQ(comp_det.surfaces().size(), 3244u); EXPECT_EQ(comp_det.transform_store().size(), 3264u); EXPECT_EQ(masks.template size(), 2492u); EXPECT_EQ(masks.template size(), 2492u); diff --git a/tutorials/include/detray/tutorial/detector_metadata.hpp b/tutorials/include/detray/tutorial/detector_metadata.hpp index 11fdd45be1..1b4aae8119 100644 --- a/tutorials/include/detray/tutorial/detector_metadata.hpp +++ b/tutorials/include/detray/tutorial/detector_metadata.hpp @@ -123,10 +123,8 @@ struct my_metadata { using transform_link = typename transform_store<>::link_type; using mask_link = typename mask_store<>::single_link; using material_link = typename material_store<>::single_link; - using source_link = std::uint64_t; using surface_type = - surface_descriptor; + surface_descriptor; /// The acceleration data structures live in another tuple that needs to /// indexed correctly diff --git a/tutorials/include/detray/tutorial/square_surface_generator.hpp b/tutorials/include/detray/tutorial/square_surface_generator.hpp index 0b4fe36296..096fa3e79e 100644 --- a/tutorials/include/detray/tutorial/square_surface_generator.hpp +++ b/tutorials/include/detray/tutorial/square_surface_generator.hpp @@ -60,7 +60,7 @@ class square_surface_generator final /// @param ctx the geometry context. DETRAY_HOST auto operator()(typename detector_t::volume_type &volume, - typename detector_t::surface_container &surfaces, + typename detector_t::surface_lookup_container &surfaces, typename detector_t::transform_container &transforms, typename detector_t::mask_container &masks, typename detector_t::geometry_context ctx = {}) const @@ -76,6 +76,8 @@ class square_surface_generator final // In case the surfaces container is prefilled with other surfaces dindex surfaces_offset = static_cast(surfaces.size()); + constexpr auto invalid_src_link{detail::invalid_value()}; + // Produce a series of square surfaces, scalar_t z_translation{0.f}; for (unsigned int i = 0u; i < m_n_squares; ++i) { @@ -95,9 +97,10 @@ class square_surface_generator final material_link_t material_link{ no_material, detail::invalid_value()}; - surfaces.emplace_back(transforms.size(ctx) - 1u, mask_link, - material_link, volume.index(), dindex_invalid, - surface_id::e_sensitive); + surfaces.push_back( + {transforms.size(ctx) - 1u, mask_link, material_link, + volume.index(), surface_id::e_sensitive}, + invalid_src_link); } return {surfaces_offset, static_cast(surfaces.size())}; diff --git a/tutorials/src/device/cuda/detector_construction.cpp b/tutorials/src/device/cuda/detector_construction.cpp index 4d024aea4f..850736d176 100644 --- a/tutorials/src/device/cuda/detector_construction.cpp +++ b/tutorials/src/device/cuda/detector_construction.cpp @@ -74,8 +74,8 @@ int main() { auto vol_buff = detray::get_buffer(det_host.volumes(), dev_mr, cuda_cpy, detray::copy::sync, vecmem::data::buffer_type::fixed_size); - auto sf_buff = detray::get_buffer(det_host.surface_lookup(), dev_mr, - cuda_cpy, detray::copy::sync, + auto sf_buff = detray::get_buffer(det_host.surfaces(), dev_mr, cuda_cpy, + detray::copy::sync, vecmem::data::buffer_type::fixed_size); // Use resizable buffer and asynchronous copy for alignment auto trf_buff = detray::get_buffer(det_host.transform_store(), dev_mr, diff --git a/utils/include/detray/detectors/create_toy_geometry.hpp b/utils/include/detray/detectors/create_toy_geometry.hpp index 6da534c02c..e25f2b91cf 100644 --- a/utils/include/detray/detectors/create_toy_geometry.hpp +++ b/utils/include/detray/detectors/create_toy_geometry.hpp @@ -198,7 +198,7 @@ inline void create_barrel_modules(context_t &ctx, volume_type &vol, materials.template size()}; const auto trf_index = transforms.size(ctx); surfaces.emplace_back(trf_index, mask_link, material_link, volume_idx, - dindex_invalid, surface_id::e_sensitive); + surface_id::e_sensitive); // The rectangle bounds for this module masks.template emplace_back( @@ -279,7 +279,7 @@ inline void add_cylinder_grid(const typename detector_t::geometry_context &ctx, // Iterate the surfaces and update their links const auto trf_offset{det.transform_store().size(ctx)}; - auto sf_offset{det.n_surfaces()}; + auto sf_offset{det.surfaces().size()}; for (auto &sf_desc : surfaces) { // Make sure the volume was constructed correctly assert(sf_desc.volume() < det.volumes().size()); @@ -292,7 +292,7 @@ inline void add_cylinder_grid(const typename detector_t::geometry_context &ctx, sf_desc.set_index(sf_offset++); // Copy surface descriptor into global lookup - det.add_surface_to_lookup(sf_desc); + det.surfaces().insert(sf_desc); } // Add transforms, masks and material to detector @@ -303,12 +303,12 @@ inline void add_cylinder_grid(const typename detector_t::geometry_context &ctx, // Add new grid to the detector gbuilder.init_grid(cyl_mask, {module_factory.cfg.m_binning.first, module_factory.cfg.m_binning.second}); - gbuilder.fill_grid(detector_volume{det, vol}, det.surface_lookup(), + gbuilder.fill_grid(detector_volume{det, vol}, det.surfaces(), det.transform_store(), det.mask_store(), ctx); assert(gbuilder.get().all().size() == surfaces.size()); det.accelerator_store().template push_back(gbuilder.get()); - vol.template set_link( + vol.template set_accel_link( grid_id, det.accelerator_store().template size() - 1u); } @@ -359,7 +359,7 @@ inline void add_disc_grid(const typename detector_t::geometry_context &ctx, // Iterate the surfaces and update their links const auto trf_offset{det.transform_store().size(ctx)}; - auto sf_offset{det.n_surfaces()}; + auto sf_offset{det.surfaces().size()}; for (auto &sf_desc : surfaces) { // Make sure the volume was constructed correctly assert(sf_desc.volume() < det.volumes().size()); @@ -372,7 +372,7 @@ inline void add_disc_grid(const typename detector_t::geometry_context &ctx, sf_desc.set_index(sf_offset++); // Copy surface descriptor into global lookup - det.add_surface_to_lookup(sf_desc); + det.surfaces().insert(sf_desc); } // Add transforms, masks and material to detector @@ -383,12 +383,12 @@ inline void add_disc_grid(const typename detector_t::geometry_context &ctx, // Add new grid to the detector gbuilder.init_grid(disc_mask, {module_factory.cfg.disc_binning.size(), module_factory.cfg.disc_binning.back()}); - gbuilder.fill_grid(detector_volume{det, vol}, det.surface_lookup(), + gbuilder.fill_grid(detector_volume{det, vol}, det.surfaces(), det.transform_store(), det.mask_store(), ctx); assert(gbuilder.get().all().size() == surfaces.size()); det.accelerator_store().template push_back(gbuilder.get()); - vol.template set_link( + vol.template set_accel_link( grid_id, det.accelerator_store().template size() - 1u); } @@ -544,7 +544,7 @@ inline void create_endcap_modules(context_t &ctx, volume_type &vol, // Surfaces with the linking into the local containers surfaces.emplace_back(transforms.size(ctx), mask_link, - material_link, volume_idx, dindex_invalid, + material_link, volume_idx, surface_id::e_sensitive); // the module transform from the position @@ -611,9 +611,9 @@ inline void add_beampipe( beampipe.set_transform(det.transform_store().size()); det.transform_store().emplace_back(ctx); - beampipe.template set_link( + beampipe.template set_accel_link( detector_t::accel::id::e_default, 0u); - beampipe.template set_link( + beampipe.template set_accel_link( detector_t::accel::id::e_default, 0u); // This is the beampipe surface diff --git a/utils/include/detray/detectors/create_wire_chamber.hpp b/utils/include/detray/detectors/create_wire_chamber.hpp index 54484ba1ab..54cbaa100d 100644 --- a/utils/include/detray/detectors/create_wire_chamber.hpp +++ b/utils/include/detray/detectors/create_wire_chamber.hpp @@ -210,8 +210,7 @@ inline auto create_wire_chamber(vecmem::memory_resource &resource, materials.template size()}; const auto trf_index = transforms.size(ctx0); surfaces.emplace_back(trf_index, mask_link, material_link, - volume_idx, dindex_invalid, - surface_id::e_sensitive); + volume_idx, surface_id::e_sensitive); // The wire bounds masks.template emplace_back( @@ -232,7 +231,7 @@ inline auto create_wire_chamber(vecmem::memory_resource &resource, // Iterate the surfaces and update their links const auto trf_offset{det.transform_store().size(ctx0)}; - auto sf_offset{det.n_surfaces()}; + auto sf_offset{det.surfaces().size()}; for (auto &sf_desc : surfaces) { // Make sure the volume was constructed correctly @@ -246,7 +245,7 @@ inline auto create_wire_chamber(vecmem::memory_resource &resource, sf_desc.set_index(sf_offset++); // Copy surface descriptor into global lookup - det.add_surface_to_lookup(sf_desc); + det.surfaces().insert(sf_desc); } // Add transforms, masks and material to detector @@ -288,11 +287,11 @@ inline auto create_wire_chamber(vecmem::memory_resource &resource, // Add new grid to the detector gbuilder.init_grid(cyl_mask, {100u, 1u}); - gbuilder.fill_grid(detector_volume{det, vol}, det.surface_lookup(), + gbuilder.fill_grid(detector_volume{det, vol}, det.surfaces(), det.transform_store(), det.mask_store(), ctx0); det.accelerator_store().template push_back(gbuilder.get()); - vol.template set_link( + vol.template set_accel_link( grid_id, det.accelerator_store().template size() - 1u); // Add volume grid diff --git a/utils/include/detray/detectors/detector_helper.hpp b/utils/include/detray/detectors/detector_helper.hpp index a27ebdfa59..73665d7bfd 100644 --- a/utils/include/detray/detectors/detector_helper.hpp +++ b/utils/include/detray/detectors/detector_helper.hpp @@ -105,9 +105,9 @@ struct detector_helper { ? surface_id::e_portal : surface_id::e_passive; - auto &sf_ref = surfaces.emplace_back(transforms.size(ctx) - 1u, - mask_link, material_link, - volume_idx, dindex_invalid, sf_id); + auto &sf_ref = + surfaces.emplace_back(transforms.size(ctx) - 1u, mask_link, + material_link, volume_idx, sf_id); return std::tie(sf_ref, mask_ref); } @@ -161,9 +161,9 @@ struct detector_helper { const surface_id sf_id = (volume_link != volume_idx) ? surface_id::e_portal : surface_id::e_sensitive; - auto &sf_ref = surfaces.emplace_back(transforms.size(ctx) - 1u, - mask_link, material_link, - volume_idx, dindex_invalid, sf_id); + auto &sf_ref = + surfaces.emplace_back(transforms.size(ctx) - 1u, mask_link, + material_link, volume_idx, sf_id); return std::tie(sf_ref, mask_ref); } diff --git a/utils/include/detray/detectors/itk_metadata.hpp b/utils/include/detray/detectors/itk_metadata.hpp index d1cdfab035..c528fd5b79 100644 --- a/utils/include/detray/detectors/itk_metadata.hpp +++ b/utils/include/detray/detectors/itk_metadata.hpp @@ -127,11 +127,9 @@ struct itk_metadata { using transform_link = typename transform_store<>::link_type; using mask_link = typename mask_store<>::single_link; using material_link = typename material_store<>::single_link; - using source_link = std::uint64_t; /// Surface type used for sensitives, passives and portals using surface_type = - surface_descriptor; + surface_descriptor; /// How to index the constituent objects in a volume /// If they share the same index value here, they will be added into the diff --git a/utils/include/detray/detectors/telescope_metadata.hpp b/utils/include/detray/detectors/telescope_metadata.hpp index 9f15e253d1..68e532f0c6 100644 --- a/utils/include/detray/detectors/telescope_metadata.hpp +++ b/utils/include/detray/detectors/telescope_metadata.hpp @@ -99,17 +99,15 @@ struct telescope_metadata { using transform_link = typename transform_store<>::link_type; using mask_link = typename mask_store<>::single_link; using material_link = typename material_store<>::single_link; - using source_link = std::uint64_t; /// Surface type used for sensitives, passives and portals using surface_type = - surface_descriptor; + surface_descriptor; /// No grids/other acceleration data structure, everything is brute forced enum geo_objects : std::uint8_t { - e_sensitive = 0, e_portal = 0, - e_size = 1, + e_sensitive = 1, + e_size = 2, e_all = e_size, }; diff --git a/utils/include/detray/detectors/toy_metadata.hpp b/utils/include/detray/detectors/toy_metadata.hpp index 2d7180bb3b..3b858f6ce4 100644 --- a/utils/include/detray/detectors/toy_metadata.hpp +++ b/utils/include/detray/detectors/toy_metadata.hpp @@ -120,11 +120,9 @@ struct toy_metadata { using transform_link = typename transform_store<>::link_type; using mask_link = typename mask_store<>::single_link; using material_link = typename material_store<>::single_link; - using source_link = std::uint64_t; /// Surface type used for sensitives, passives and portals using surface_type = - surface_descriptor; + surface_descriptor; /// Portals and passives in the brute froce search, sensitives in the grids enum geo_objects : std::uint8_t {