12#include "detray/builders/surface_factory_interface.hpp"
13#include "detray/core/concepts.hpp"
14#include "detray/core/detail/data_context.hpp"
15#include "detray/definitions/algebra.hpp"
16#include "detray/definitions/detail/qualifiers.hpp"
17#include "detray/definitions/geometry.hpp"
18#include "detray/definitions/indexing.hpp"
19#include "detray/geometry/mask.hpp"
20#include "detray/geometry/shapes/rectangle2D.hpp"
21#include "detray/material/material.hpp"
22#include "detray/utils/logging.hpp"
34template <concepts::scalar scalar_t>
59 std::vector<scalar_t>
m_tilt = {0.f, 0.f};
97 const std::vector<std::vector<scalar_t>> &bnds) {
114 const std::vector<scalar_t> &ps) {
122 const std::vector<scalar_t> &ps) {
130 const std::vector<scalar_t> &t) {
138 const std::vector<unsigned int> &b) {
182template <concepts::detector detector_t,
typename mask_shape_t = trapezo
id2D>
184 using algebra_t =
typename detector_t::algebra_type;
200 for (
const unsigned int n_bins : m_cfg.binning()) {
229 typename detector_t::surface_lookup_container &surfaces,
230 typename detector_t::transform_container &transforms,
231 typename detector_t::mask_container &masks,
232 typename detector_t::geometry_context ctx = {})
234 DETRAY_VERBOSE_HOST(
"Generate silicon tracker endcap modules...");
235 DETRAY_VERBOSE_HOST(
"-> Generate " <<
size() <<
" surfaces");
237 using surface_t =
typename detector_t::surface_type;
238 using nav_link_t =
typename surface_t::navigation_link;
239 using mask_link_t =
typename surface_t::mask_link;
240 using material_link_t =
typename surface_t::material_link;
242 auto volume_idx{volume.index()};
243 const dindex surfaces_offset{
static_cast<dindex>(surfaces.size())};
244 constexpr auto invalid_src_link{detail::invalid_value<std::uint64_t>()};
247 constexpr auto mask_id{
248 types::id<typename detector_t::masks, mask<mask_shape_t, algebra_t>>};
250 constexpr auto no_material{surface_t::material_id::e_none};
252 const auto mask_volume_link{
static_cast<nav_link_t
>(volume_idx)};
255 std::vector<scalar_t> radii{};
257 scalar_t delta_r{m_cfg.outer_radius() - m_cfg.inner_radius()};
264 if (m_cfg.binning().size() == 1u) {
265 radii.push_back(0.5f * (m_cfg.inner_radius() + m_cfg.outer_radius()));
268 scalar_t tot_length{0.f};
269 for (
const auto &bounds : m_cfg.module_bounds()) {
272 tot_length += 2.f * bounds.at(trapezoid2D::e_half_length_2) +
277 scalar_t r_overlap{(tot_length - delta_r) /
278 static_cast<scalar_t
>(m_cfg.module_bounds().size())};
281 scalar_t prev_r{m_cfg.inner_radius() + r_overlap};
282 scalar_t prev_hl{0.f};
283 scalar_t prev_ol{0.f};
285 for (
const auto &bounds : m_cfg.module_bounds()) {
286 const scalar_t mod_hlength{bounds.at(trapezoid2D::e_half_length_2)};
288 radii.push_back(prev_r + prev_hl - prev_ol + mod_hlength);
289 prev_r = radii.back();
290 prev_ol = 2.f * r_overlap;
291 prev_hl = mod_hlength;
298 for (
unsigned int ir = 0u; ir < radii.size(); ++ir) {
301 const scalar_t center{m_cfg.center()};
302 const scalar_t staggered_center{
303 (ir % 2u != 0 ? center + 0.5f * m_cfg.ring_stagger()
304 : center - 0.5f * m_cfg.ring_stagger())};
305 const scalar_t rz{radii.size() == 1u ? center : staggered_center};
308 const scalar_t sub_stagger{m_cfg.phi_sub_stagger().size() > 1u
309 ? m_cfg.phi_sub_stagger().at(ir)
312 std::vector<point3_t> module_positions =
313 module_positions_ring(rz, radii.at(ir), m_cfg.phi_stagger().at(ir),
314 sub_stagger, m_cfg.binning().at(ir));
317 for (
const point3_t &mod_position : module_positions) {
319 mask_link_t mask_link{mask_id, {masks.template
size<mask_id>(), 1u}};
323 surfaces.push_back({transforms.size(ctx), mask_link, material_link,
324 volume_idx, surface_id::e_sensitive},
330 point3_t mod_center{mod_position};
331 mod_center[2] *=
static_cast<scalar_t
>(m_cfg.side());
333 const scalar_t mod_phi{vector::phi(mod_position)};
334 const vector3_t mod_loc_y{math::cos(mod_phi), math::sin(mod_phi),
335 static_cast<scalar_t
>(0)};
337 const vector3_t mod_loc_z{
static_cast<scalar_t
>(0),
338 static_cast<scalar_t
>(0),
339 static_cast<scalar_t
>(m_cfg.side())};
340 const vector3_t mod_loc_x{vector::cross(mod_loc_y, mod_loc_z)};
343 transforms.emplace_back(ctx, mod_center, mod_loc_z, mod_loc_x);
347 std::vector<scalar_t> mask_values{m_cfg.module_bounds().at(ir)};
348 assert(!mask_values.empty());
351 if constexpr (std::is_same_v<mask_shape_t, trapezoid2D>) {
353 1.f / (2.f * mask_values.at(trapezoid2D::e_half_length_2))};
355 mask_values.resize(trapezoid2D::e_size);
356 mask_values.at(trapezoid2D::e_divisor) = div;
359 masks.template emplace_back<mask_id>(empty_context{}, mask_values,
363 return {surfaces_offset,
static_cast<dindex>(surfaces.size())};
376 auto module_positions_ring(
const scalar_t z,
const scalar_t radius,
377 const scalar_t phi_stagger,
378 const scalar_t phi_sub_stagger,
379 const unsigned int n_phi_bins)
const {
381 std::vector<point3_t> mod_positions;
382 mod_positions.reserve(n_phi_bins);
386 static_cast<scalar_t
>(n_phi_bins)};
389 for (
unsigned int iphi = 0u; iphi < n_phi_bins; ++iphi) {
395 if (phi_sub_stagger != 0.f && (n_phi_bins % 4u == 0u)) {
397 if ((iphi % 4u) == 0u) {
398 rzs = phi_sub_stagger;
399 }
else if (((iphi + 1u) % 4u) == 0u) {
400 rzs = -phi_sub_stagger;
404 const scalar_t phi{min_phi +
static_cast<scalar_t
>(iphi) * phi_step};
406 const scalar_t rz{iphi % 2u != 0
u ? z - 0.5f * phi_stagger
407 : z + 0.5f * phi_stagger};
408 mod_positions.push_back(
409 {radius * math::cos(phi), radius * math::sin(phi), rz + rzs});
411 return mod_positions;
415 endcap_generator_config<scalar_t> m_cfg{};
auto size() const -> dindex override
Definition endcap_generator.hpp:198
endcap_generator(const endcap_generator_config< scalar_t > &cfg)
Build an endcap layer according to the parameters given in.
Definition endcap_generator.hpp:193
auto push_back(std::vector< surface_data< detector_t > > &&) -> void override
Ignore supplied surface data because this factory generates its own.
Definition endcap_generator.hpp:215
void push_back(surface_data< detector_t > &&) override
Add data to the factory.
Definition endcap_generator.hpp:211
void clear() override
This is a surface generator, no external surface data needed.
Definition endcap_generator.hpp:209
auto operator()(typename detector_t::volume_type &volume, 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={}) -> dindex_range override
Create a pixel tracker endcap layer with two rings.
Definition endcap_generator.hpp:228
Bind transform and mask data together for surface building.
Definition surface_factory_interface.hpp:37
virtual dindex size() const =0
constexpr double u
atomic mass unit u
Definition Units.hpp:155
Detray include(s).
Definition array_operators.hpp:18
get_scalar_t< A, T > dscalar
Scalar type for algebra A and value type T.
Definition algebra.hpp:64
detail::index_range< dindex > dindex_range
Index ranges and sequences.
Definition indexing.hpp:24
unsigned int dindex
Default index type.
Definition indexing.hpp:18
constexpr dindex dindex_invalid
Global invalid index definition.
Definition indexing.hpp:21
get_vector3D_t< A, T > dvector3D
Three-dimensional vector type for algebra A and value type T.
Definition algebra.hpp:80
get_transform3D_t< A, T > dtransform3D
Three-dimensional transform type for algebra A and value type T.
Definition algebra.hpp:84
get_point3D_t< A, T > dpoint3D
Three-dimensional point type for algebra A and value type T.
Definition algebra.hpp:72
static constexpr scalar_t pi
π
Definition units.hpp:136
configuration for the barrel module generator
Definition endcap_generator.hpp:35
std::vector< scalar_t > m_phi_stagger
Stagger in phi (per ring).
Definition endcap_generator.hpp:53
constexpr const auto & binning() const
Return the binning.
Definition endcap_generator.hpp:175
constexpr const auto & module_tilt() const
Return the module tilt.
Definition endcap_generator.hpp:172
constexpr endcap_generator_config & ring_stagger(const scalar_t rs)
Set the ring stagger.
Definition endcap_generator.hpp:106
std::vector< scalar_t > m_tilt
Module tilt (per ring).
Definition endcap_generator.hpp:59
constexpr endcap_generator_config & outer_radius(const scalar_t r)
Set the outer radius.
Definition endcap_generator.hpp:89
constexpr scalar_t inner_radius() const
Return the inner radius.
Definition endcap_generator.hpp:154
constexpr endcap_generator_config & inner_radius(const scalar_t r)
Set the inner radius.
Definition endcap_generator.hpp:82
constexpr endcap_generator_config & binning(const std::vector< unsigned int > &b)
Set the binning.
Definition endcap_generator.hpp:137
scalar_t m_ring_stagger
Stagger between the two rings.
Definition endcap_generator.hpp:51
constexpr endcap_generator_config & phi_sub_stagger(const std::vector< scalar_t > &ps)
Set the phi sub stagger.
Definition endcap_generator.hpp:121
std::vector< scalar_t > m_phi_sub_stagger
Substagger in phi (per ring).
Definition endcap_generator.hpp:56
endcap_generator_config & module_bounds(const std::vector< std::vector< scalar_t > > &bnds)
Set the module bounds.
Definition endcap_generator.hpp:96
constexpr endcap_generator_config & phi_stagger(const std::vector< scalar_t > &ps)
Set the phi stagger.
Definition endcap_generator.hpp:113
const auto & module_bounds() const
Return the module bounds.
Definition endcap_generator.hpp:160
constexpr const auto & phi_stagger() const
Return the phi stagger.
Definition endcap_generator.hpp:166
int m_side
Construct positive or negative endcap.
Definition endcap_generator.hpp:37
constexpr endcap_generator_config & module_tilt(const std::vector< scalar_t > &t)
Set the module tilt.
Definition endcap_generator.hpp:129
scalar_t m_outer_radius
Outer layer radius.
Definition endcap_generator.hpp:43
constexpr int side() const
Getters.
Definition endcap_generator.hpp:148
constexpr scalar_t outer_radius() const
Return the outer radius.
Definition endcap_generator.hpp:157
constexpr scalar_t center() const
Return the center.
Definition endcap_generator.hpp:151
scalar_t m_center_z
Center position (|z|).
Definition endcap_generator.hpp:39
constexpr endcap_generator_config & side(const int s)
Setters.
Definition endcap_generator.hpp:68
std::vector< std::vector< scalar_t > > m_mask_values
Boundary values for the module masks (per ring).
Definition endcap_generator.hpp:45
std::vector< unsigned int > m_binning
Number of modules in phi (per ring).
Definition endcap_generator.hpp:61
constexpr endcap_generator_config & center(const scalar_t z)
Set the center.
Definition endcap_generator.hpp:75
constexpr scalar_t ring_stagger() const
Return the ring stagger.
Definition endcap_generator.hpp:163
scalar_t m_inner_radius
Inner layer radius.
Definition endcap_generator.hpp:41
constexpr const auto & phi_sub_stagger() const
Return the phi sub stagger.
Definition endcap_generator.hpp:169
static constexpr scalar_t mm
Native length unit, the millimetre.
Definition units.hpp:27