File indexing completed on 2026-05-27 07:24:19
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include "detray/definitions/algebra.hpp"
0011 #include "detray/definitions/units.hpp"
0012 #include "detray/geometry/mask.hpp"
0013 #include "detray/geometry/shapes.hpp"
0014
0015
0016 #include "detray/io/frontend/detector_writer.hpp"
0017
0018
0019 #include "detray/options/detector_io_options.hpp"
0020 #include "detray/options/parse_options.hpp"
0021 #include "detray/test/common/build_telescope_detector.hpp"
0022 #include "detray/test/framework/types.hpp"
0023
0024
0025 #include <vecmem/memory/host_memory_resource.hpp>
0026
0027
0028 #include "detray/options/boost_program_options.hpp"
0029
0030 namespace po = boost::program_options;
0031
0032 using namespace detray;
0033
0034 namespace {
0035
0036
0037
0038 template <typename mask_shape_t, typename value_t,
0039 template <typename> class trajectory_t, concepts::algebra algebra_t>
0040 void write_telecope(const po::variables_map &vm,
0041 io::detector_writer_config &writer_cfg,
0042 std::vector<value_t> &mask_params,
0043 const trajectory_t<algebra_t> &traj) {
0044 using scalar_t = dscalar<algebra_t>;
0045
0046 detray::tel_det_config<algebra_t, mask_shape_t, trajectory_t> tel_cfg{
0047 mask_params, traj};
0048
0049 tel_cfg.n_surfaces(vm["modules"].as<unsigned int>());
0050 tel_cfg.length(vm["length"].as<scalar_t>());
0051 tel_cfg.mat_thickness(vm["thickness"].as<scalar_t>());
0052 tel_cfg.envelope(vm["envelope"].as<scalar_t>());
0053
0054
0055 vecmem::host_memory_resource host_mr;
0056 auto [tel_det, tel_names] =
0057 build_telescope_detector<algebra_t>(host_mr, tel_cfg);
0058
0059
0060 detray::io::write_detector(tel_det, tel_names, writer_cfg);
0061 }
0062
0063
0064
0065 template <typename mask_shape_t, typename value_t>
0066 void write_telecope(const po::variables_map &vm,
0067 io::detector_writer_config &writer_cfg,
0068 std::vector<value_t> &mask_params) {
0069 using detector_t = detector<telescope_metadata<test::algebra, mask_shape_t>>;
0070 using algebra_t = typename detector_t::algebra_type;
0071 using scalar_t = dscalar<algebra_t>;
0072 using vector3_t = dvector3D<algebra_t>;
0073
0074
0075 std::string direction{vm["direction"].as<std::string>()};
0076 vector3_t dir;
0077 if (direction == "x") {
0078 dir = {1.f, 0.f, 0.f};
0079 } else if (direction == "y") {
0080 dir = {{0.f, 1.f, 0.f}};
0081 } else if (direction == "z") {
0082 dir = {0.f, 0.f, 1.f};
0083 }
0084
0085 if (!vm.count("b_field")) {
0086 detray::detail::ray<algebra_t> r{};
0087 r.set_dir(dir);
0088
0089 write_telecope<mask_shape_t>(vm, writer_cfg, mask_params, r);
0090 } else {
0091 const auto b_field = vm["b_field"].as<std::vector<scalar_t>>();
0092 if (b_field.size() == 3u) {
0093 vector3_t B{b_field[0] * unit<scalar_t>::T,
0094 b_field[1] * unit<scalar_t>::T,
0095 b_field[2] * unit<scalar_t>::T};
0096
0097 const auto p{vm["p"].as<scalar_t>() * unit<scalar_t>::GeV};
0098 detray::detail::helix<algebra_t> h{{0.f, 0.f, 0.f}, 0.f, dir, 1.f / p, B};
0099
0100 write_telecope<mask_shape_t>(vm, writer_cfg, mask_params, h);
0101 } else {
0102 throw std::invalid_argument("B-field vector has to have three entries");
0103 }
0104 }
0105 }
0106
0107 }
0108
0109 int main(int argc, char **argv) {
0110 using scalar = test::scalar;
0111
0112
0113 po::options_description desc("\nTelescope detector generation options");
0114
0115 std::vector<scalar> mask_params{
0116 20.f * unit<scalar>::mm,
0117 20.f * unit<scalar>::mm};
0118 desc.add_options()("modules", po::value<unsigned int>()->default_value(10u),
0119 "number of modules in telescope [1-20]")(
0120 "type", po::value<std::string>()->default_value("rectangle"),
0121 "type of the telescope modules [rectangle, trapezoid, annulus, ring, "
0122 "cylinder]")("params",
0123 po::value<std::vector<scalar>>(&mask_params)->multitoken(),
0124 "Mask values for the shape given in 'type'")(
0125 "length", po::value<scalar>()->default_value(500.f * unit<scalar>::mm),
0126 "length of the telescope [mm]")(
0127 "thickness", po::value<scalar>()->default_value(1.f * unit<scalar>::mm),
0128 "thickness of the module silicon material")(
0129 "envelope", po::value<scalar>()->default_value(100.f * unit<scalar>::um),
0130 "minimal distance between sensitive surfaces and portals")(
0131 "direction", po::value<std::string>()->default_value("z"),
0132 "direction of the telescope in global frame [x, y, z]")(
0133 "b_field",
0134 boost::program_options::value<std::vector<scalar>>()->multitoken(),
0135 "B field vector for a pilot helix [T]")(
0136 "p", po::value<scalar>()->default_value(10.f * unit<scalar>::GeV),
0137 "Total momentum of the pilot track [GeV]");
0138
0139
0140 detray::io::detector_writer_config writer_cfg{};
0141 writer_cfg.format(detray::io::format::json).replace_files(false);
0142
0143 writer_cfg.path("./telescope_detector/");
0144
0145
0146 po::variables_map vm =
0147 detray::options::parse_options(desc, argc, argv, writer_cfg);
0148
0149
0150 std::string type{vm["type"].as<std::string>()};
0151 if (type == "rectangle") {
0152 write_telecope<rectangle2D>(vm, writer_cfg, mask_params);
0153 } else if (type == "trapezoid") {
0154 write_telecope<trapezoid2D>(vm, writer_cfg, mask_params);
0155 } else if (type == "annulus") {
0156 write_telecope<annulus2D>(vm, writer_cfg, mask_params);
0157 } else if (type == "ring") {
0158 write_telecope<ring2D>(vm, writer_cfg, mask_params);
0159 } else if (type == "cylinder") {
0160 write_telecope<cylinder2D>(vm, writer_cfg, mask_params);
0161 }
0162 }