Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-27 07:24:19

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
0008 
0009 // Project include(s)
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 // Detray IO include(s)
0016 #include "detray/io/frontend/detector_writer.hpp"
0017 
0018 // Detray test include(s)
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 // Vecmem include(s)
0025 #include <vecmem/memory/host_memory_resource.hpp>
0026 
0027 // Boost
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 /// Generate and write a telescope detector, given the commandline variables
0037 /// and a configuration for the detector writer @param writer_cfg
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   // Build the detector
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   // Write to file
0060   detray::io::write_detector(tel_det, tel_names, writer_cfg);
0061 }
0062 
0063 /// Generate and write a telescope detector, given the commandline variables
0064 /// and a configuration for the detector writer @param writer_cfg
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   // Construct the pilot track
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 }  // anonymous namespace
0108 
0109 int main(int argc, char **argv) {
0110   using scalar = test::scalar;
0111 
0112   // Options parsing
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};  // < default values for rectangles
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   // Configuration
0140   detray::io::detector_writer_config writer_cfg{};
0141   writer_cfg.format(detray::io::format::json).replace_files(false);
0142   // Default output path
0143   writer_cfg.path("./telescope_detector/");
0144 
0145   // Parse options
0146   po::variables_map vm =
0147       detray::options::parse_options(desc, argc, argv, writer_cfg);
0148 
0149   // Build the geometry
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 }