Skip to content

Commit

Permalink
ref: Use the detector builder for the wire chamber geometry (#853)
Browse files Browse the repository at this point in the history
Use the detector builder to build the wire chamber test geometry instead of deprecated building code that lives directly in the detector. For this, a new wire_layer_generator was added, similar to the geometry generators of the toy detector. The deprecated geometry building code was removed from the detector, except the function set_transform, which is needed in the jacobian validation. This should be removed again, as soon as different geometry contexts can be put into the detector. The different volume builders are now friends of the detector and (at some point) the builder classes should be the only ones that can modify a detector object.

The wire chamber detector can now additionally be built with straw tubes, e.g:

./bin/detray_generate_wire_chamber --straw_tubes
  • Loading branch information
niermann999 authored Oct 15, 2024
1 parent e0d1d15 commit ce2f877
Show file tree
Hide file tree
Showing 29 changed files with 864 additions and 909 deletions.
88 changes: 55 additions & 33 deletions core/include/detray/builders/cylinder_portal_generator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ struct cylinder_portal_config {
/// Build inner cylinder portal (will use the same distance to the layer
/// that was found for the outer cylinder portal)
bool m_build_inner{true};
/// Autofit the lower/upper z extend and inner/outer radii
bool m_do_autofit{true};
/// Minimal envelope for the portals (used in autofitting)
scalar_t m_envelope{100.f * unit<scalar_t>::um};
/// Fixed inner radius during autofit
Expand All @@ -47,6 +49,10 @@ struct cylinder_portal_config {
m_build_inner = b;
return *this;
}
constexpr cylinder_portal_config &do_autofit(const bool b) {
m_do_autofit = b;
return *this;
}
constexpr cylinder_portal_config &envelope(const scalar_t e) {
m_envelope = e;
return *this;
Expand Down Expand Up @@ -83,8 +89,9 @@ struct cylinder_portal_config {

/// Getters
/// @{
constexpr scalar_t envelope() const { return m_envelope; }
constexpr bool build_inner() const { return m_build_inner; }
constexpr bool do_autofit() const { return m_do_autofit; }
constexpr scalar_t envelope() const { return m_envelope; }
constexpr scalar_t fixed_inner_radius() const { return m_fixed_inner_r; }
constexpr scalar_t fixed_outer_radius() const { return m_fixed_outer_r; }
constexpr scalar_t fixed_half_length() const { return m_fixed_z; }
Expand Down Expand Up @@ -181,42 +188,57 @@ class cylinder_portal_generator final
assert(volume.id() == volume_id::e_cylinder);
const dindex vol_idx{volume.index()};

// Need surfaces to wrap
const std::size_t n_surfaces{surfaces.size()};
assert(n_surfaces != 0u);

// The bounding boxes around the module surfaces
std::vector<aabb_t> boxes;
boxes.reserve(n_surfaces);

for (const auto &sf : surfaces) {
masks.template visit<bounding_box_creator>(
sf.mask(), m_cfg.envelope(), transforms.at(sf.transform(), ctx),
boxes);
if (!m_cfg.do_autofit()) {
// Without autofit, the portal bounds have to be given explicitly
assert(!(m_cfg.fixed_inner_radius() == 0.f &&
m_cfg.fixed_outer_radius() == 0.f) ||
m_cfg.fixed_half_length() != 0.f);
} else {
// Need surfaces in volume to do autofit
assert(n_surfaces != 0u);
}

// Build an aabb in the global space around the surface aabbs
aabb_t world_box{boxes, boxes.size(), m_cfg.envelope()};
// translation
const point3_t center = world_box.template center<point3_t>();

// The world box local frame is the global coordinate frame
const point3_t box_min = world_box.template loc_min<point3_t>();
const point3_t box_max = world_box.template loc_max<point3_t>();

// Get the half lengths for the cylinder height and disc translation
const point3_t h_lengths = 0.5f * (box_max - box_min);
const scalar h_x{math::fabs(h_lengths[0])};
const scalar h_y{math::fabs(h_lengths[1])};
const scalar h_z{math::fabs(h_lengths[2])};

const scalar_t outer_r_min{math::max(h_x, h_y)};
const scalar_t mean_radius{get_mean_radius(surfaces, transforms)};

scalar_t outer_r{outer_r_min};
scalar_t inner_r{mean_radius - (outer_r - mean_radius)};
scalar_t lower_z{math::min(center[2] - h_z, center[2] + h_z)};
scalar_t upper_z{math::max(center[2] - h_z, center[2] + h_z)};
scalar_t inner_r{m_cfg.fixed_inner_radius()};
scalar_t outer_r{m_cfg.fixed_outer_radius()};
scalar_t lower_z{-m_cfg.fixed_half_length()};
scalar_t upper_z{m_cfg.fixed_half_length()};

if (m_cfg.do_autofit()) {
// The bounding boxes around the module surfaces
std::vector<aabb_t> boxes;
boxes.reserve(n_surfaces);

for (const auto &sf : surfaces) {
masks.template visit<bounding_box_creator>(
sf.mask(), m_cfg.envelope(),
transforms.at(sf.transform(), ctx), boxes);
}

// Build an aabb in the global space around the surface aabbs
aabb_t world_box{boxes, boxes.size(), m_cfg.envelope()};
// translation
const point3_t center = world_box.template center<point3_t>();

// The world box local frame is the global coordinate frame
const point3_t box_min = world_box.template loc_min<point3_t>();
const point3_t box_max = world_box.template loc_max<point3_t>();

// Get the half lengths for the cylinder height and disc translation
const point3_t h_lengths = 0.5f * (box_max - box_min);
const scalar h_x{math::fabs(h_lengths[0])};
const scalar h_y{math::fabs(h_lengths[1])};
const scalar h_z{math::fabs(h_lengths[2])};

const scalar_t outer_r_min{math::max(h_x, h_y)};
const scalar_t mean_radius{get_mean_radius(surfaces, transforms)};

outer_r = outer_r_min;
inner_r = mean_radius - (outer_r - mean_radius);
lower_z = math::min(center[2] - h_z, center[2] + h_z);
upper_z = math::max(center[2] - h_z, center[2] + h_z);
}

// Observe boundary conditions
if (m_cfg.fixed_inner_radius() > 0.f) {
Expand Down
2 changes: 1 addition & 1 deletion core/include/detray/builders/grid_builder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ class grid_builder : public volume_decorator<detector_t> {

// Add the grid to the detector and link it to its volume
constexpr auto gid{detector_t::accel::template get_id<grid_t>()};
det.accelerator_store().template push_back<gid>(m_grid);
det._accelerators.template push_back<gid>(m_grid);
vol_ptr->set_link(m_id, gid,
det.accelerator_store().template size<gid>() - 1);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ class homogeneous_material_builder final : public volume_decorator<detector_t> {
}

// Add material to the detector
det.append_materials(std::move(m_materials));
det._materials.append(std::move(m_materials));
m_materials.clear_all();

// Call the underlying volume builder(s) and give the volume to the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class homogeneous_volume_material_builder final
vol->set_material(material_id, coll_size);

// Append the material
det.material_store().template push_back<material_id>(m_volume_material);
det._materials.template push_back<material_id>(m_volume_material);

// Give the volume to the next decorator
return vol;
Expand Down
4 changes: 2 additions & 2 deletions core/include/detray/builders/material_map_builder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ class material_map_builder final : public volume_decorator<detector_t> {
[[maybe_unused]] auto [mat_id, mat_idx] = sf.template visit_mask<
detail::add_sf_material_map<materials_t>>(
m_factory, m_bin_data.at(sf_idx), m_n_bins.at(sf_idx),
axis_spans, det.material_store());
axis_spans, det._materials);

// Make sure the linking was precomputed correctly
assert(mat_id == sf_desc.material().id());
Expand Down Expand Up @@ -176,7 +176,7 @@ class material_map_builder final : public volume_decorator<detector_t> {

// Current sizes of the material stores
std::map<std::size_t, dindex> size_map;
det.material_store().template apply<detail::material_coll_size>(
det._materials.template apply<detail::material_coll_size>(
size_map, std::make_index_sequence<materials_t::n_types>{});

// Update the counts with the detector offset
Expand Down
1 change: 0 additions & 1 deletion core/include/detray/builders/surface_factory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ class surface_factory : public surface_factory_interface<detector_t> {
using sf_data_collection = std::vector<surface_data_t>;

/// Empty factory.
DETRAY_HOST
surface_factory() = default;

/// @returns the current number of surfaces that will be built by this
Expand Down
4 changes: 2 additions & 2 deletions core/include/detray/builders/volume_builder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ class volume_builder : public volume_builder_interface<detector_t> {
m_volume.set_index(static_cast<dindex>(det.volumes().size()));

m_volume.set_transform(det.transform_store().size());
det.transform_store().push_back(m_trf);
det._transforms.push_back(m_trf);

// Add all data from the builder to the detector containers
add_to_detector(ctx, det);
Expand All @@ -104,7 +104,7 @@ class volume_builder : public volume_builder_interface<detector_t> {
m_masks.clear_all();

// Pass to decorator builders
return &(det.volumes().back());
return &(det._volumes.back());
}

/// Adds a placement transform @param trf for the volume
Expand Down
11 changes: 11 additions & 0 deletions core/include/detray/core/detail/container_buffers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,17 @@ dvector_buffer<std::remove_cv_t<T>> get_buffer(
buff_type);
}

/// @brief Get the buffer representation of a vecmem vector - non-const
template <class T>
dvector_buffer<std::remove_cv_t<T>> get_buffer(
const dvector<T>& vec, vecmem::memory_resource& mr, vecmem::copy& cpy,
detray::copy cpy_type = detray::copy::sync,
vecmem::data::buffer_type buff_type = vecmem::data::buffer_type::fixed_size
/*, stream*/) {
return detray::get_buffer(detray::get_data(vec), mr, cpy, cpy_type,
buff_type);
}

/// Get the vecmem view type of a vector buffer
///
/// @note this is needed, because the corresponding vecmem::get_data() function
Expand Down
Loading

0 comments on commit ce2f877

Please sign in to comment.