File indexing completed on 2026-05-27 07:24:12
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011
0012 #include "detray/builders/surface_factory_interface.hpp"
0013 #include "detray/core/detail/data_context.hpp"
0014 #include "detray/definitions/algebra.hpp"
0015 #include "detray/definitions/detail/qualifiers.hpp"
0016 #include "detray/definitions/geometry.hpp"
0017 #include "detray/definitions/indexing.hpp"
0018 #include "detray/geometry/mask.hpp"
0019 #include "detray/geometry/shapes/rectangle2D.hpp"
0020 #include "detray/utils/logging.hpp"
0021
0022
0023 #include <algorithm>
0024 #include <cassert>
0025 #include <limits>
0026
0027 namespace detray {
0028
0029
0030
0031
0032 template <concepts::scalar scalar_t>
0033 struct barrel_generator_config {
0034
0035 scalar_t m_half_z{500.f * unit<scalar_t>::mm};
0036
0037 std::vector<scalar_t> m_mask_values{8.4f * unit<scalar_t>::mm,
0038 36.f * unit<scalar_t>::mm};
0039
0040 scalar_t m_tilt_phi{0.14f};
0041
0042 scalar_t m_radius{32.f * unit<scalar_t>::mm};
0043
0044 scalar_t m_radial_stagger{0.5f * unit<scalar_t>::mm};
0045
0046 scalar_t m_z_overlap{2.f * unit<scalar_t>::mm};
0047
0048 std::pair<unsigned int, unsigned int> m_binning = {16u, 14u};
0049
0050
0051
0052 constexpr barrel_generator_config &half_length(const scalar_t hz) {
0053 m_half_z = hz;
0054 return *this;
0055 }
0056 barrel_generator_config &module_bounds(const std::vector<scalar_t> &bnds) {
0057 m_mask_values.clear();
0058 std::ranges::copy(bnds, std::back_inserter(m_mask_values));
0059 return *this;
0060 }
0061 constexpr barrel_generator_config &tilt_phi(const scalar_t tilt) {
0062 m_tilt_phi = tilt;
0063 return *this;
0064 }
0065 constexpr barrel_generator_config &radius(const scalar_t r) {
0066 m_radius = r;
0067 return *this;
0068 }
0069 constexpr barrel_generator_config &radial_stagger(const scalar_t r_st) {
0070 m_radial_stagger = r_st;
0071 return *this;
0072 }
0073 constexpr barrel_generator_config &z_overlap(const scalar_t zo) {
0074 m_z_overlap = zo;
0075 return *this;
0076 }
0077 constexpr barrel_generator_config &binning(const unsigned int n_phi,
0078 const unsigned int n_z) {
0079 m_binning = {n_phi, n_z};
0080 return *this;
0081 }
0082 constexpr barrel_generator_config &binning(
0083 const std::pair<unsigned int, const unsigned int> &binning) {
0084 m_binning = binning;
0085 return *this;
0086 }
0087
0088
0089
0090
0091 constexpr scalar_t half_length() const { return m_half_z; }
0092 const std::vector<scalar_t> &module_bounds() const { return m_mask_values; }
0093 constexpr scalar_t tilt_phi() const { return m_tilt_phi; }
0094 constexpr scalar_t radius() const { return m_radius; }
0095 constexpr scalar_t radial_stagger() const { return m_radial_stagger; }
0096 constexpr scalar_t z_overlap() const { return m_z_overlap; }
0097 constexpr const auto &binning() const { return m_binning; }
0098
0099 };
0100
0101
0102
0103
0104 template <typename detector_t, typename mask_shape_t = rectangle2D>
0105 class barrel_generator final : public surface_factory_interface<detector_t> {
0106 using algebra_t = typename detector_t::algebra_type;
0107 using scalar_t = dscalar<algebra_t>;
0108 using transform3_t = dtransform3D<algebra_t>;
0109 using point3_t = dpoint3D<algebra_t>;
0110 using vector3_t = dvector3D<algebra_t>;
0111
0112 public:
0113
0114 DETRAY_HOST
0115 explicit barrel_generator(const barrel_generator_config<scalar_t> &cfg)
0116 : m_cfg{cfg} {}
0117
0118
0119 DETRAY_HOST
0120 auto size() const -> dindex override {
0121 return static_cast<dindex>(m_cfg.binning().first * m_cfg.binning().second);
0122 }
0123
0124
0125
0126 DETRAY_HOST
0127 void clear() override { };
0128 DETRAY_HOST
0129 void push_back(
0130 surface_data<detector_t> && ) override { }
0131 DETRAY_HOST
0132 auto push_back(std::vector<surface_data<detector_t>> && )
0133 -> void override { }
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143 DETRAY_HOST
0144 auto operator()(typename detector_t::volume_type &volume,
0145 typename detector_t::surface_lookup_container &surfaces,
0146 typename detector_t::transform_container &transforms,
0147 typename detector_t::mask_container &masks,
0148 typename detector_t::geometry_context ctx = {})
0149 -> dindex_range override {
0150 DETRAY_VERBOSE_HOST("Generate silicon tracker barrel modules...");
0151 DETRAY_VERBOSE_HOST("-> Generate " << size() << " surfaces");
0152
0153 using surface_t = typename detector_t::surface_type;
0154 using nav_link_t = typename surface_t::navigation_link;
0155 using mask_link_t = typename surface_t::mask_link;
0156 using material_link_t = typename surface_t::material_link;
0157
0158 const dindex surfaces_offset{static_cast<dindex>(surfaces.size())};
0159 constexpr auto invalid_src_link{detail::invalid_value<std::uint64_t>()};
0160
0161
0162 constexpr auto mask_id{
0163 types::id<typename detector_t::masks, mask<mask_shape_t, algebra_t>>};
0164
0165
0166 constexpr auto no_material{surface_t::material_id::e_none};
0167
0168 auto volume_idx{volume.index()};
0169
0170 const auto mask_volume_link{static_cast<nav_link_t>(volume_idx)};
0171
0172
0173 const unsigned int n_phi_bins{m_cfg.binning().first};
0174 const unsigned int n_z_bins{m_cfg.binning().second};
0175
0176
0177 std::vector<point3_t> mod_centers;
0178 mod_centers.reserve(n_phi_bins * n_z_bins);
0179
0180
0181 const scalar_t phi_step{2.f * constant<scalar_t>::pi /
0182 static_cast<scalar_t>(n_phi_bins)};
0183 const scalar_t min_phi{-constant<scalar_t>::pi + 0.5f * phi_step};
0184
0185
0186 const scalar_t z_start{
0187 -0.5f * static_cast<scalar_t>(n_z_bins - 1u) *
0188 (2.f * m_cfg.module_bounds().at(1) - m_cfg.z_overlap())};
0189 const scalar_t z_step{(math::fabs(z_start) - z_start) /
0190 static_cast<scalar_t>(n_z_bins - 1)};
0191
0192
0193 for (unsigned int z_bin = 0u; z_bin < n_z_bins; ++z_bin) {
0194
0195 const scalar_t mod_z{z_start + static_cast<scalar_t>(z_bin) * z_step};
0196 const scalar_t mod_r{
0197 (z_bin % 2u) != 0u ? m_cfg.radius() - 0.5f * m_cfg.radial_stagger()
0198 : m_cfg.radius() + 0.5f * m_cfg.radial_stagger()};
0199
0200 for (unsigned int phiBin = 0u; phiBin < n_phi_bins; ++phiBin) {
0201
0202 const scalar_t mod_phi{min_phi +
0203 static_cast<scalar_t>(phiBin) * phi_step};
0204 mod_centers.push_back(point3_t{mod_r * math::cos(mod_phi),
0205 mod_r * math::sin(mod_phi), mod_z});
0206 }
0207 }
0208
0209
0210 for (auto &mod_center : mod_centers) {
0211
0212 mask_link_t mask_link = {mask_id, {masks.template size<mask_id>(), 1u}};
0213 material_link_t material_link{no_material, dindex_invalid};
0214 const auto trf_index = transforms.size(ctx);
0215
0216 surfaces.push_back({trf_index, mask_link, material_link, volume_idx,
0217 surface_id::e_sensitive},
0218 invalid_src_link);
0219
0220
0221
0222 const scalar_t mod_phi{vector::phi(mod_center)};
0223
0224 const scalar_t tilt_phi{m_cfg.tilt_phi()};
0225 const vector3_t mod_local_z{math::cos(mod_phi + tilt_phi),
0226 math::sin(mod_phi + tilt_phi),
0227 static_cast<scalar_t>(0)};
0228
0229 const vector3_t mod_local_x{-math::sin(mod_phi + tilt_phi),
0230 math::cos(mod_phi + tilt_phi),
0231 static_cast<scalar_t>(0)};
0232
0233
0234 transforms.emplace_back(ctx, mod_center, mod_local_z, mod_local_x);
0235 }
0236
0237
0238 masks.template emplace_back<mask_id>(empty_context{}, m_cfg.module_bounds(),
0239 mask_volume_link);
0240
0241 return {surfaces_offset, static_cast<dindex>(surfaces.size())};
0242 }
0243
0244 private:
0245
0246 barrel_generator_config<scalar_t> m_cfg{};
0247 };
0248
0249 }