Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-12 07:52:57

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 #pragma once
0010 
0011 #include "Acts/Definitions/Units.hpp"
0012 #include "Acts/EventData/ParticleHypothesis.hpp"
0013 #include "Acts/EventData/TrackParameters.hpp"
0014 #include "Acts/Geometry/GeometryContext.hpp"
0015 #include "Acts/MagneticField/ConstantBField.hpp"
0016 #include "Acts/MagneticField/MagneticFieldContext.hpp"
0017 #include "Acts/MagneticField/MagneticFieldProvider.hpp"
0018 #include "Acts/Propagator/Propagator.hpp"
0019 #include "Acts/Tests/CommonHelpers/BenchmarkTools.hpp"
0020 #include "Acts/Utilities/Logger.hpp"
0021 
0022 #include <iostream>
0023 
0024 #include <boost/program_options.hpp>
0025 
0026 namespace Acts::Test {
0027 
0028 namespace po = boost::program_options;
0029 using namespace Acts;
0030 using namespace Acts::UnitLiterals;
0031 
0032 struct BenchmarkStepper {
0033   unsigned int toys{};
0034   double ptInGeV{};
0035   double BzInT{};
0036   double maxPathInM{};
0037   unsigned int lvl{};
0038   bool withCov{};
0039 
0040   std::optional<int> parseOptions(int argc, char* argv[]) {
0041     try {
0042       po::options_description desc("Allowed options");
0043       // clang-format off
0044       desc.add_options()
0045         ("help", "produce help message")
0046         ("toys",po::value<unsigned int>(&toys)->default_value(20000),"number of tracks to propagate")
0047         ("pT",po::value<double>(&ptInGeV)->default_value(1),"transverse momentum in GeV")
0048         ("B",po::value<double>(&BzInT)->default_value(2),"z-component of B-field in T")
0049         ("path",po::value<double>(&maxPathInM)->default_value(5),"maximum path length in m")
0050         ("cov",po::value<bool>(&withCov)->default_value(true),"propagation with covariance matrix")
0051         ("verbose",po::value<unsigned int>(&lvl)->default_value(Acts::Logging::INFO),"logging level");
0052       // clang-format on
0053       po::variables_map vm;
0054       po::store(po::parse_command_line(argc, argv, desc), vm);
0055       po::notify(vm);
0056 
0057       if (vm.contains("help")) {
0058         std::cout << desc << std::endl;
0059         return 0;
0060       }
0061     } catch (std::exception& e) {
0062       std::cerr << "error: " << e.what() << std::endl;
0063       return 1;
0064     }
0065 
0066     return std::nullopt;
0067   }
0068 
0069   std::unique_ptr<MagneticFieldProvider> makeField() const {
0070     return std::make_unique<ConstantBField>(
0071         Vector3{0, 0, BzInT * UnitConstants::T});
0072   }
0073 
0074   template <typename Stepper>
0075   void run(Stepper stepper, const std::string& name) const {
0076     using Propagator = Propagator<Stepper>;
0077     using PropagatorOptions = typename Propagator::template Options<>;
0078     using Covariance = BoundSquareMatrix;
0079 
0080     // Create a test context
0081     GeometryContext tgContext = GeometryContext();
0082     MagneticFieldContext mfContext = MagneticFieldContext();
0083 
0084     ACTS_LOCAL_LOGGER(getDefaultLogger(name, Acts::Logging::Level(lvl)));
0085 
0086     // print information about profiling setup
0087     ACTS_INFO("propagating " << toys << " tracks with pT = " << ptInGeV
0088                              << "GeV in a " << BzInT << "T B-field");
0089 
0090     Propagator propagator(std::move(stepper));
0091 
0092     PropagatorOptions options(tgContext, mfContext);
0093     options.pathLimit = maxPathInM * UnitConstants::m;
0094 
0095     Vector4 pos4(0, 0, 0, 0);
0096     Vector3 dir(1, 0, 0);
0097     Covariance cov;
0098     // clang-format off
0099     cov << 10_mm, 0, 0, 0, 0, 0,
0100             0, 10_mm, 0, 0, 0, 0,
0101             0, 0, 1, 0, 0, 0,
0102             0, 0, 0, 1, 0, 0,
0103             0, 0, 0, 0, 1_e / 10_GeV, 0,
0104             0, 0, 0, 0, 0, 0;
0105     // clang-format on
0106 
0107     std::optional<Covariance> covOpt = std::nullopt;
0108     if (withCov) {
0109       covOpt = cov;
0110     }
0111     BoundTrackParameters pars = BoundTrackParameters::createCurvilinear(
0112         pos4, dir, +1 / ptInGeV, covOpt, ParticleHypothesis::pion());
0113 
0114     double totalPathLength = 0;
0115     std::size_t numSteps = 0;
0116     std::size_t numStepTrials = 0;
0117     std::size_t numIters = 0;
0118     const auto propagationBenchResult = Acts::Test::microBenchmark(
0119         [&] {
0120           auto state = propagator.makeState(options);
0121           auto initRes = propagator.initialize(state, pars);
0122           if (!initRes.ok()) {
0123             ACTS_ERROR("initialization failed: " << initRes.error());
0124             return;
0125           }
0126           auto tmp = propagator.propagate(state);
0127           auto r = propagator.makeResult(state, tmp, options, true).value();
0128           if (totalPathLength == 0.) {
0129             ACTS_DEBUG("reached position "
0130                        << r.endParameters->position(tgContext).transpose()
0131                        << " in " << r.steps << " steps");
0132           }
0133           totalPathLength += r.pathLength;
0134           numSteps += r.steps;
0135           numStepTrials += state.stepping.nStepTrials;
0136           ++numIters;
0137         },
0138         1, toys);
0139 
0140     ACTS_INFO("Execution stats: " << propagationBenchResult);
0141     ACTS_INFO("average path length = " << totalPathLength / numIters / 1_mm
0142                                        << "mm");
0143     ACTS_INFO("average number of steps = " << 1.0 * numSteps / numIters);
0144     ACTS_INFO("step efficiency = " << 1.0 * numSteps / numStepTrials);
0145   }
0146 };
0147 
0148 }  // namespace Acts::Test