ACTS
Experiment-independent tracking
Loading...
Searching...
No Matches
wire_layer_generator.hpp
1// This file is part of the ACTS project.
2//
3// Copyright (C) 2016 CERN for the benefit of the ACTS project
4//
5// This Source Code Form is subject to the terms of the Mozilla Public
6// License, v. 2.0. If a copy of the MPL was not distributed with this
7// file, You can obtain one at https://mozilla.org/MPL/2.0/.
8
9#pragma once
10
11// Project include(s)
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/line.hpp"
21#include "detray/utils/axis_rotation.hpp"
22#include "detray/utils/logging.hpp"
23#include "detray/utils/unit_vectors.hpp"
24
25// System include(s)
26#include <cassert>
27#include <limits>
28
29namespace detray {
30
32template <concepts::scalar scalar_t>
35 scalar_t m_half_z{1000.f * unit<scalar_t>::mm};
42
48 constexpr wire_layer_generator_config &half_length(const scalar_t hz) {
49 m_half_z = hz;
50 return *this;
51 }
52
55 constexpr wire_layer_generator_config &cell_size(const scalar_t c) {
56 m_cell_size = c;
57 return *this;
58 }
59
62 constexpr wire_layer_generator_config &stereo_angle(const scalar_t angle) {
63 m_stereo_angle = angle;
64 return *this;
65 }
66
69 constexpr wire_layer_generator_config &inner_layer_radius(const scalar_t r) {
71 return *this;
72 }
73
74
79 constexpr scalar_t half_length() const { return m_half_z; }
82 constexpr scalar_t cell_size() const { return m_cell_size; }
85 constexpr scalar_t stereo_angle() const { return m_stereo_angle; }
88 constexpr scalar_t inner_layer_radius() const { return m_layer_radius; }
90};
91
96template <concepts::detector detector_t, typename mask_shape_t = line_square>
98 : public surface_factory_interface<detector_t> {
99 using algebra_t = typename detector_t::algebra_type;
100 using scalar_t = dscalar<algebra_t>;
101 using transform3_t = dtransform3D<algebra_t>;
102 using point3_t = dpoint3D<algebra_t>;
103 using vector3_t = dvector3D<algebra_t>;
104
105 public:
108 DETRAY_HOST
111 : m_cfg{cfg},
112 m_layer_central_rad{m_cfg.inner_layer_radius() + m_cfg.cell_size()} {}
113
115 DETRAY_HOST
116 auto size() const -> dindex override {
117 const scalar_t circumference{2.f * constant<scalar_t>::pi *
118 m_layer_central_rad};
119 return static_cast<dindex>(
120 std::floor(circumference / 2.f * m_cfg.cell_size()));
121 }
122
125 DETRAY_HOST
126 void clear() override { /*Do nothing*/ };
127 DETRAY_HOST
129 surface_data<detector_t> && /*unused*/) override { /*Do nothing*/ }
130 DETRAY_HOST
132 auto push_back(std::vector<surface_data<detector_t>> && /*unused*/)
133 -> void override { /*Do nothing*/ }
134
135
143 DETRAY_HOST
145 auto operator()(typename detector_t::volume_type &volume,
146 typename detector_t::surface_lookup_container &surfaces,
147 typename detector_t::transform_container &transforms,
148 typename detector_t::mask_container &masks,
149 typename detector_t::geometry_context ctx = {})
150 -> dindex_range override {
151 DETRAY_VERBOSE_HOST("Generate modules for wire chamber layer...");
152 DETRAY_VERBOSE_HOST("-> Generate " << size() << " surfaces");
153
154 using surface_t = typename detector_t::surface_type;
155 using nav_link_t = typename surface_t::navigation_link;
156 using mask_link_t = typename surface_t::mask_link;
157 using material_link_t = typename surface_t::material_link;
158
159 // Volume that this layer will be added to
160 auto volume_idx{volume.index()};
161
162 const dindex surfaces_offset{static_cast<dindex>(surfaces.size())};
163 constexpr auto invalid_src_link{detail::invalid_value<std::uint64_t>()};
164
165 // The type id of the surface mask shape (drift cell or straw tube)
166 constexpr auto mask_id{
167 types::id<typename detector_t::masks, mask<mask_shape_t, algebra_t>>};
168 // Modules link back to mother volume in navigation
169 const auto mask_volume_link{static_cast<nav_link_t>(volume_idx)};
170
171 // Cell center positions
172 detray::dvector<point3_t> cell_centers{};
173 // Distance between wires in phi
174 const scalar_t delta = 2.f * m_cfg.cell_size() / m_layer_central_rad;
175 scalar_t phi{0.f};
176 while (phi <= 2.f * constant<scalar_t>::pi) {
177 const scalar_t x = m_layer_central_rad * math::cos(phi);
178 const scalar_t y = m_layer_central_rad * math::sin(phi);
179 const scalar_t z = 0.f;
180
181 cell_centers.push_back({x, y, z});
182 phi += delta;
183 }
184
185 // Generate a wire surface at every position
186 for (const point3_t &cell_center : cell_centers) {
187 // Mask link for the cell
188 mask_link_t mask_link{mask_id, {masks.template size<mask_id>(), 1u}};
189 // The material will be added in a later step
190 material_link_t material_link{surface_t::material_id::e_none,
192 // Link the placement transform to the surface
193 const auto trf_index = transforms.size(ctx);
194
195 surfaces.push_back({trf_index, mask_link, material_link, volume_idx,
196 surface_id::e_sensitive},
197 invalid_src_link);
198
199 // The wire bounds
200 masks.template emplace_back<mask_id>(empty_context{}, mask_volume_link,
201 m_cfg.cell_size(),
202 m_cfg.half_length());
203
204 // Build the transform
205 vector3_t z_axis{0.f, 0.f, 1.f};
206 const vector3_t r_axis = vector::normalize(cell_center);
207 z_axis = axis_rotation<algebra_t>(r_axis, m_cfg.stereo_angle())(z_axis);
208 const vector3_t x_axis =
209 unit_vectors<vector3_t>().make_curvilinear_unit_u(z_axis);
210
211 transforms.emplace_back(ctx, cell_center, z_axis, x_axis);
212 }
213
214 return {surfaces_offset, static_cast<dindex>(surfaces.size())};
215 }
216
217 private:
219 wire_layer_generator_config<scalar_t> m_cfg{};
222 scalar_t m_layer_central_rad{};
223};
224
225} // namespace detray
Bind transform and mask data together for surface building.
Definition surface_factory_interface.hpp:37
virtual dindex size() const =0
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 wire chamber barrel layer.
Definition wire_layer_generator.hpp:145
auto push_back(std::vector< surface_data< detector_t > > &&) -> void override
Ignore supplied surface data because this factory generates its own.
Definition wire_layer_generator.hpp:132
wire_layer_generator(const wire_layer_generator_config< scalar_t > &cfg)
Build a wire chamber/straw tube layer according to the parameters given in.
Definition wire_layer_generator.hpp:109
void push_back(surface_data< detector_t > &&) override
Add data to the factory.
Definition wire_layer_generator.hpp:128
auto size() const -> dindex override
Definition wire_layer_generator.hpp:116
void clear() override
This is a surface generator, no external surface data needed.
Definition wire_layer_generator.hpp:126
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
vecmem::vector< value_t > dvector
Vector container backed by vecmem.
Definition containers.hpp:34
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
static constexpr scalar_t mm
Native length unit, the millimetre.
Definition units.hpp:27
static constexpr scalar_t mrad
Conversion factor from milliradians to radians.
Definition units.hpp:113
configuration for the wire layer generator
Definition wire_layer_generator.hpp:33
constexpr wire_layer_generator_config & stereo_angle(const scalar_t angle)
Set the stereo angle.
Definition wire_layer_generator.hpp:62
constexpr scalar_t cell_size() const
Return the cell size.
Definition wire_layer_generator.hpp:82
scalar_t m_cell_size
Cell size/radius.
Definition wire_layer_generator.hpp:37
constexpr wire_layer_generator_config & inner_layer_radius(const scalar_t r)
Set the inner layer radius.
Definition wire_layer_generator.hpp:69
constexpr scalar_t stereo_angle() const
Return the stereo angle.
Definition wire_layer_generator.hpp:85
scalar_t m_stereo_angle
Stereo angle between wires.
Definition wire_layer_generator.hpp:39
constexpr scalar_t half_length() const
Getters.
Definition wire_layer_generator.hpp:79
scalar_t m_half_z
Half length of the layer (z).
Definition wire_layer_generator.hpp:35
constexpr wire_layer_generator_config & cell_size(const scalar_t c)
Set the cell size.
Definition wire_layer_generator.hpp:55
constexpr scalar_t inner_layer_radius() const
Return the inner layer radius.
Definition wire_layer_generator.hpp:88
scalar_t m_layer_radius
Layer radius.
Definition wire_layer_generator.hpp:41
constexpr wire_layer_generator_config & half_length(const scalar_t hz)
Setters.
Definition wire_layer_generator.hpp:48