Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-08-16 08:18:00

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/units.hpp"
0011 #include "detray/geometry/identifier.hpp"
0012 #include "detray/propagator/actors.hpp"
0013 #include "detray/propagator/propagation_config.hpp"
0014 #include "detray/tracks/tracks.hpp"
0015 
0016 // Detray test include(s)
0017 #include "detray/test/common/bfield.hpp"
0018 #include "detray/test/common/build_toy_detector.hpp"
0019 #include "detray/test/common/track_generators.hpp"
0020 #include "detray/test/framework/types.hpp"
0021 #include "detray/test/utils/data_record.hpp"
0022 #include "detray/test/validation/detector_scanner.hpp"
0023 #include "detray/test/validation/propagation_validation.hpp"
0024 
0025 // Vecmem include(s)
0026 #include <vecmem/memory/host_memory_resource.hpp>
0027 
0028 // google-test include(s).
0029 #include <gtest/gtest.h>
0030 
0031 using namespace detray;
0032 
0033 // Algebra types
0034 using test_algebra = test::algebra;
0035 using scalar = test::scalar;
0036 using point2 = test::point2;
0037 using vector3 = test::vector3;
0038 
0039 // Test class for the backward propagation
0040 // Input tuple: < truth_pT, % max missed surfaces, % max additional surfaces >
0041 class PropagationValidation
0042     : public ::testing::TestWithParam<
0043           std::tuple<scalar, unsigned int, float, float>> {};
0044 
0045 TEST_P(PropagationValidation, forward_backward) {
0046   using detector_t = detector<toy_metadata<test_algebra>>;
0047   using algebra_t = detector_t::algebra_type;
0048   using bfield_t = bfield::const_field_t<scalar>;
0049   using track_t = free_track_parameters<algebra_t>;
0050 
0051   using data_record_t = intersection_record<detector_t>;
0052   using intersection_trace_t = dvector<data_record_t>;
0053   using generator_t = random_track_generator<track_t>;
0054 
0055   vecmem::host_memory_resource host_mr;
0056 
0057   // Build detector and magnetic field
0058   toy_det_config<scalar> toy_cfg{};
0059   toy_cfg.n_brl_layers(4u).n_edc_layers(7u);
0060   // No material to prevent energy loss during parameter transport
0061   // (comparing to truth helices)
0062   toy_cfg.use_material_maps(false).use_homogeneous_material(false);
0063   const auto [det, names] = build_toy_detector<test_algebra>(host_mr, toy_cfg);
0064 
0065   // Create b field
0066   vector3 B{0.f, 0.f, 2.f * unit<scalar>::T};
0067   const bfield_t hom_bfield = create_const_field<scalar>(B);
0068   std::optional<bfield_t::view_t> field_view{hom_bfield};
0069 
0070   // Geometry context
0071   detector_t::geometry_context gctx{};
0072 
0073   // Let the Newton algorithm dynamically choose tol. based on approx. error
0074   constexpr scalar truth_mask_tol{detray::detail::invalid_value<scalar>()};
0075   const scalar truth_pT{std::get<0>(GetParam())};
0076 
0077   propagation::config prop_cfg{};
0078   prop_cfg.navigation.estimate_scattering_noise = false;
0079   prop_cfg.navigation.search_window = {3u, 3u};
0080 
0081   propagation_validation_config<scalar> test_cfg{};
0082   test_cfg.propagation = prop_cfg;
0083   test_cfg.particle = muon<scalar>();
0084   test_cfg.display_svg = false;  //< faster runtime in the CI
0085   test_cfg.max_percent_missed = std::get<2>(GetParam());
0086   test_cfg.max_percent_additional = std::get<3>(GetParam());
0087 
0088   generator_t::configuration trk_gen_cfg{};
0089   trk_gen_cfg.n_tracks(std::get<1>(GetParam()));
0090   trk_gen_cfg.p_T(truth_pT);
0091   trk_gen_cfg.randomize_charge(true);
0092   // Make sure at least one sensitive is found (otherwise truth trace is empty)
0093   trk_gen_cfg.eta_range(-4.f, 4.f);
0094 
0095   // Generate the tracks and truth traces for the comparison
0096   std::vector<track_t> tracks{};
0097   std::vector<dvector<data_record_t>> truth_traces_fw{};
0098 
0099   for (auto track : generator_t{trk_gen_cfg}) {
0100     assert(track.qop() != 0.f);
0101     tracks.push_back(track);
0102 
0103     detail::helix<algebra_t> h{track, B};
0104     intersection_trace_t intersection_trace = detector_scanner::run<helix_scan>(
0105         gctx, det, h, truth_mask_tol, track.p(test_cfg.particle.charge()));
0106 
0107     // Only keep the sensitive surfaces
0108     intersection_trace_t module_trace{};
0109     for (const data_record_t& rec : intersection_trace) {
0110       if (rec.intersection.surface().is_sensitive()) {
0111         module_trace.push_back(rec);
0112       }
0113     }
0114     truth_traces_fw.push_back(std::move(module_trace));
0115   }
0116 
0117   // Run the propagation and compare the collected data with the truth traces
0118   const bool success = propagation_validation(det, names, field_view, test_cfg,
0119                                               tracks, truth_traces_fw);
0120   ASSERT_TRUE(success);
0121 }
0122 
0123 // % of missed surfaces is high likely due to the instability of the
0124 // helix intersections in single precision
0125 INSTANTIATE_TEST_SUITE_P(
0126     detray_propagator, PropagationValidation,
0127     ::testing::Values(
0128         std::make_tuple(100.f * unit<scalar>::GeV, 1000u, 0.2f, 0.1f),
0129         std::make_tuple(5.f * unit<scalar>::GeV, 1000u, 0.2f, 0.1f),
0130         std::make_tuple(1.f * unit<scalar>::GeV, 500u, 0.f, 0.f),
0131         std::make_tuple(0.5f * unit<scalar>::GeV, 500u, 0.2f, 0.1f)));