Skip to content

Commit

Permalink
Add material grid types to detectors
Browse files Browse the repository at this point in the history
  • Loading branch information
niermann999 committed Sep 21, 2023
1 parent 9d70e9d commit b56814c
Show file tree
Hide file tree
Showing 12 changed files with 221 additions and 70 deletions.
2 changes: 1 addition & 1 deletion core/include/detray/core/detector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ class detector {

/// Forward mask types that are present in this detector
using material_container =
typename metadata::template material_store<tuple_type, vector_type>;
typename metadata::template material_store<tuple_type, container_t>;
using materials = typename material_container::value_types;
using material_link = typename material_container::single_link;

Expand Down
66 changes: 56 additions & 10 deletions core/include/detray/core/detector_metadata.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,38 @@ struct default_metadata {
using slab = material_slab<detray::scalar>;
using rod = material_rod<detray::scalar>;

/// @TODO material grids
/// Material grid types (default boundaries: closed binning)
/// @{
/// ...

// Material grid definition: bin-content: std::array<material_Slab, 1>
template <typename grid_shape_t, typename container_t>
using material_grid_t =
grid<coordinate_axes<grid_shape_t, false, container_t>, slab,
simple_serializer, regular_attacher<1>>;

// Rectangular material grid
template <typename container_t>
using rectangular_mat_grid_t =
material_grid_t<rectangle2D<>::axes<>, container_t>;

// Disc material grid
template <typename container_t>
using disc_mat_grid_t = material_grid_t<ring2D<>::axes<>, container_t>;

// Cylindrical material grid
template <typename container_t>
using cylinder2_mat_grid_t =
material_grid_t<cylinder2D<>::axes<>, container_t>;

// Cuboid volume material grid
template <typename container_t>
using cuboid_mat_grid_t = material_grid_t<cuboid3D<>::axes<>, container_t>;

// Cylindrical volume material grid
template <typename container_t>
using cylinder3_mat_grid_t =
material_grid_t<cylinder3D::axes<>, container_t>;

/// @}

/// surface grid types (default boundaries: closed binning)
Expand Down Expand Up @@ -162,19 +191,36 @@ unbounded_cell, unmasked_plane*/>;

/// Give your material types a name (needs to be consecutive and has to
/// match the types position in the mask store!)
/// @TODO: Add the material grid types for every surface shape
enum class material_ids {
e_slab = 0,
e_rod = 1,
// ... material map types
e_none = 2,
// Material texture (grid) shapes
e_rectangle2_map = 0u,
e_trapezoid2_map = 0u,
e_annulus2_map = 1u,
e_ring2_map = 1u,
e_cylinder2_map = 2u,
e_cell_wire_map = 6u,
e_straw_wire_map = 6u,
// Volume material
e_cuboid3_map = 3u,
e_cylinder3_map = 4u,
// Homogeneous mapetrial
e_slab = 5u,
e_rod = 6u,
e_none = 7u,
};

/// How to store materials
template <template <typename...> class tuple_t = dtuple,
template <typename...> class vector_t = dvector>
using material_store = regular_multi_store<material_ids, empty_context,
tuple_t, vector_t, slab, rod>;
typename container_t = host_container_types>
using material_store =
multi_store<material_ids, empty_context, tuple_t,
grid_collection<rectangular_mat_grid_t<container_t>>,
grid_collection<disc_mat_grid_t<container_t>>,
grid_collection<cylinder2_mat_grid_t<container_t>>,
grid_collection<cuboid_mat_grid_t<container_t>>,
grid_collection<cylinder3_mat_grid_t<container_t>>,
typename container_t::template vector_type<slab>,
typename container_t::template vector_type<rod>>;

/// How to link to the entries in the data stores
using transform_link = typename transform_store<>::link_type;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ struct pointwise_material_interactor : actor {

template <typename material_group_t, typename index_t>
DETRAY_HOST_DEVICE inline bool operator()(
const material_group_t &material_group,
const index_t &material_range, state &s,
const material_group_t &material_group, const index_t &mat_index,
state &s,
const bound_track_parameters<transform3_type> &bound_params,
const scalar_type cos_inc_angle, const scalar_type approach) const {

Expand All @@ -77,14 +77,17 @@ struct pointwise_material_interactor : actor {

bool success = false;

for (const auto &mat :
detray::ranges::subrange(material_group, material_range)) {
if constexpr (detail::is_grid_v<
typename material_group_t::value_type>) {
return false;
} else {
const auto &mat = material_group[mat_index];

// return early in case of vacuum or zero thickness
if (not mat) {
continue;
return false;
}
success |= true;
success = true;

const scalar_type path_segment{
mat.path_segment(cos_inc_angle, approach)};
Expand Down Expand Up @@ -112,9 +115,9 @@ struct pointwise_material_interactor : actor {
mat.path_segment_in_X0(cos_inc_angle, approach),
s.pdg, s.mass, qop, charge);
}
}

return success;
return success;
}
}
};

Expand Down
38 changes: 38 additions & 0 deletions core/include/detray/surface_finders/grid/grid_collection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,48 @@ class grid_collection<
return static_cast<dindex>(m_offsets.size());
}

/// @returns an iterator that points to the first grid
/// @note Not implemented!
DETRAY_HOST_DEVICE
constexpr auto begin() noexcept -> bool { return true; }

/// @returns an iterator that points to the coll. end
/// @note Not implemented!
DETRAY_HOST_DEVICE
constexpr auto end() noexcept -> bool { return false; }

/// @returns the number of grids in the collection - const
DETRAY_HOST_DEVICE
constexpr auto empty() const noexcept -> bool { return m_offsets.empty(); }

/// @brief Resize the underlying containers
/// @note Not defined! The amount of memory can differ for every grid
DETRAY_HOST_DEVICE
constexpr void resize(std::size_t) noexcept { /*Not defined*/
}

/// @brief Reserve memory
/// @note Not defined! The amount of memory can differ for every grid
DETRAY_HOST_DEVICE
constexpr void reserve(std::size_t) noexcept { /*Not defined*/
}

/// Removes all data from the grid collection containers
DETRAY_HOST_DEVICE
constexpr void clear() noexcept {
m_offsets.clear();
m_bins.clear();
m_axes_data.clear();
m_bin_edges.clear();
}

/// Insert a number of grids
/// @note Not defined! There is no grid iterator implementation
template <typename... Args>
DETRAY_HOST_DEVICE constexpr void insert(Args &&...) noexcept {
/*Not defined*/
}

/// @returns the offsets for the grids in the bin storage - const
DETRAY_HOST_DEVICE
constexpr auto offsets() const -> const vector_type<size_type> & {
Expand Down
19 changes: 9 additions & 10 deletions io/include/detray/io/common/detail/type_traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,22 +157,21 @@ struct mask_info<io::detail::mask_shape::trapezoid2, detector_t,
/// @}

template <class detector_t, typename = void>
struct is_homogeneous_material : public std::false_type {};
struct has_homogeneous_material : public std::false_type {};

/// Is the value type in the detector material store a simple material or is it
/// wrapped in another class (e.g. grids for material maps)
template <class detector_t>
struct is_homogeneous_material<
struct has_homogeneous_material<
detector_t,
std::enable_if_t<
std::is_base_of_v<detail::homogeneous_material_tag,
typename detail::tuple_element_t<
0, typename detector_t::material_container::
tuple_type>::value_type>,
void>> : public std::true_type {};
std::enable_if_t<detector_t::materials::template is_defined<
material_slab<typename detector_t::scalar_type>>() or
detector_t::materials::template is_defined<
material_rod<typename detector_t::scalar_type>>(),
void>> : public std::true_type {};

template <typename T>
inline constexpr bool is_homogeneous_material_v =
is_homogeneous_material<T>::value;
inline constexpr bool has_homogeneous_material_v =
has_homogeneous_material<T>::value;

} // namespace detray::detail
2 changes: 1 addition & 1 deletion io/include/detray/io/common/detector_writer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ detail::detector_component_writers<detector_t> assemble_writer(
// Find other writers, depending on the detector type
if (cfg.write_material()) {
// Simple material
if constexpr (detail::is_homogeneous_material_v<detector_t>) {
if constexpr (detail::has_homogeneous_material_v<detector_t>) {
writers.template add<json_homogeneous_material_writer>();
}
// Material maps
Expand Down
32 changes: 22 additions & 10 deletions io/include/detray/io/common/homogeneous_material_writer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ class homogeneous_material_writer : public writer_interface<detector_t> {
/// Serialize the header information into its payload
static homogeneous_material_header_payload write_header(
const detector_t& det, const std::string_view det_name) {
using mat_types = typename detector_t::material_container::value_types;

homogeneous_material_header_payload header_data;

Expand All @@ -49,15 +48,16 @@ class homogeneous_material_writer : public writer_interface<detector_t> {

header_data.sub_header.emplace();
auto& mat_sub_header = header_data.sub_header.value();
mat_sub_header.n_slabs =
materials.template size<mat_types::to_id(0u)>();
if constexpr (detector_t::materials::template is_defined<
material_slab<scalar_t>>()) {
mat_sub_header.n_slabs =
materials.template size<detector_t::materials::id::e_slab>();
}
mat_sub_header.n_rods = 0u;
if constexpr (mat_types::n_types == 2u) {
// The compiler looks at this code, even if the number of material
// types is one. Therefore, "mat_types::n_types - 1" is safer to use
if constexpr (detector_t::materials::template is_defined<
material_rod<scalar_t>>()) {
mat_sub_header.n_rods =
materials
.template size<mat_types::to_id(mat_types::n_types - 1)>();
materials.template size<detector_t::materials::id::e_rod>();
}

return header_data;
Expand Down Expand Up @@ -161,8 +161,20 @@ class homogeneous_material_writer : public writer_interface<detector_t> {
template <typename material_group_t, typename index_t>
inline auto operator()(const material_group_t& material_group,
const index_t& index) const {
return homogeneous_material_writer<detector_t>::serialize(
material_group[index], index);
using material_t = typename material_group_t::value_type;

constexpr bool is_slab =
std::is_same_v<material_t, material_slab<scalar_t>>;
constexpr bool is_rod =
std::is_same_v<material_t, material_rod<scalar_t>>;

if constexpr (is_slab or is_rod) {

return homogeneous_material_writer<detector_t>::serialize(
material_group[index], index);
} else {
return material_slab_payload{};
}
}
};
};
Expand Down
10 changes: 5 additions & 5 deletions tests/unit_tests/cpu/material_maps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ GTEST_TEST(detray_material, annulus_map) {

// Add some material entries
scalar thickness = 2.f * unit<scalar>::mm;
for (std::size_t gbin = 0; gbin < annulus_map.nbins(); ++gbin) {
for (dindex gbin = 0; gbin < annulus_map.nbins(); ++gbin) {
annulus_map.populate(gbin,
material_t(silicon_tml<scalar>{}, thickness));
thickness += 1.f * unit<scalar>::mm;
Expand Down Expand Up @@ -96,7 +96,7 @@ GTEST_TEST(detray_material, cylinder_map) {
EXPECT_EQ(z_axis.max(), hz);

scalar thickness = 2.f * unit<scalar>::mm;
for (std::size_t gbin = 0; gbin < cylinder_map.nbins(); ++gbin) {
for (dindex gbin = 0; gbin < cylinder_map.nbins(); ++gbin) {
cylinder_map.populate(gbin, material_t(vacuum<scalar>{}, thickness));
thickness += 1.f * unit<scalar>::mm;
}
Expand Down Expand Up @@ -137,7 +137,7 @@ GTEST_TEST(detray_material, rectangle_map) {
EXPECT_EQ(y_axis.max(), hy);

scalar thickness = 2.f * unit<scalar>::mm;
for (std::size_t gbin = 0; gbin < rectangle_map.nbins(); ++gbin) {
for (dindex gbin = 0; gbin < rectangle_map.nbins(); ++gbin) {
rectangle_map.populate(gbin,
material_t(oxygen_gas<scalar>{}, thickness));
thickness += 1.f * unit<scalar>::mm;
Expand Down Expand Up @@ -179,7 +179,7 @@ GTEST_TEST(detray_material, disc_map) {
EXPECT_EQ(phi_axis.max(), constant<scalar>::pi);

scalar thickness = 2.f * unit<scalar>::mm;
for (std::size_t gbin = 0; gbin < disc_map.nbins(); ++gbin) {
for (dindex gbin = 0; gbin < disc_map.nbins(); ++gbin) {
disc_map.populate(gbin, material_t(aluminium<scalar>{}, thickness));
thickness += 1.f * unit<scalar>::mm;
}
Expand Down Expand Up @@ -222,7 +222,7 @@ GTEST_TEST(detray_material, trapezoid_map) {
EXPECT_EQ(y_axis.max(), hy);

scalar thickness = 2.f * unit<scalar>::mm;
for (std::size_t gbin = 0; gbin < trapezoid_map.nbins(); ++gbin) {
for (dindex gbin = 0; gbin < trapezoid_map.nbins(); ++gbin) {
trapezoid_map.populate(gbin, material_t(gold<scalar>{}, thickness));
thickness += 1.f * unit<scalar>::mm;
}
Expand Down
7 changes: 4 additions & 3 deletions tutorials/include/detray/tutorial/detector_metadata.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,10 @@ struct my_metadata {
/// How to store and link materials. The material does not make use of
/// conditions data ( @c empty_context )
template <template <typename...> class tuple_t = dtuple,
template <typename...> class vector_t = dvector>
using material_store = regular_multi_store<material_ids, empty_context,
tuple_t, vector_t, slab>;
typename container_t = host_container_types>
using material_store =
multi_store<material_ids, empty_context, tuple_t,
typename container_t::template vector_type<slab>>;

/// Surface descriptor type used for sensitives, passives and portals
/// It holds the indices to the surface data in the detector data stores
Expand Down
Loading

0 comments on commit b56814c

Please sign in to comment.