Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-09 08:21:43

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 // Exercises the backend-agnostic fit interface (HistogramFitFunction,
0010 // iterativeFit, extractMeanWidthProfiles) with ActsPlugins::RootHistogramFit
0011 // as a concrete backend.
0012 
0013 #include <boost/test/unit_test.hpp>
0014 
0015 #include "Acts/Utilities/Histogram.hpp"
0016 #include "ActsExamples/Validation/HistogramFit.hpp"
0017 #include "ActsPlugins/Root/RootHistogramFit.hpp"
0018 
0019 #include <cmath>
0020 #include <optional>
0021 #include <random>
0022 #include <string>
0023 
0024 using namespace Acts;
0025 using namespace Acts::Experimental;
0026 using namespace ActsExamples;
0027 
0028 namespace {
0029 
0030 const HistogramFitFunction rootFn = ActsPlugins::RootHistogramFit();
0031 
0032 /// Sample `count` entries from N(mean, sigma) into a fresh histogram
0033 Histogram1 sampled(const std::string& name, std::size_t count, double mean,
0034                    double sigma, int nBins, double xMin, double xMax,
0035                    std::uint32_t seed) {
0036   auto axis = AxisVariant(BoostRegularAxis(nBins, xMin, xMax, "x"));
0037   Histogram1 hist(name, name, {axis});
0038 
0039   std::mt19937 generator(seed);
0040   std::normal_distribution<double> distribution(mean, sigma);
0041   for (std::size_t i = 0; i < count; ++i) {
0042     hist.fill({distribution(generator)});
0043   }
0044 
0045   return hist;
0046 }
0047 
0048 }  // namespace
0049 
0050 BOOST_AUTO_TEST_SUITE(HistogramFitInterfaceSuite)
0051 
0052 BOOST_AUTO_TEST_CASE(IterativeFit_RecoversKnownParameters) {
0053   const Histogram1 hist =
0054       sampled("iterative", 20000, 0.3, 0.7, 60, -5.0, 5.0, 102);
0055 
0056   const auto result = iterativeFit(rootFn, hist, /*sigmaRange=*/3.0,
0057                                    /*iterations=*/3);
0058   BOOST_REQUIRE(result.has_value());
0059 
0060   const auto& [mean, sigma, meanError, sigmaError] = *result;
0061   BOOST_CHECK_CLOSE(mean, 0.3, 5.0);
0062   BOOST_CHECK_CLOSE(sigma, 0.7, 5.0);
0063   BOOST_CHECK_GT(meanError, 0.0);
0064   BOOST_CHECK_GT(sigmaError, 0.0);
0065 }
0066 
0067 // Proves extractMeanWidthProfiles works with a fit backend from outside
0068 // Examples, not just one Examples defines itself.
0069 BOOST_AUTO_TEST_CASE(ExtractMeanWidthProfiles_WorksWithRootFitter) {
0070   const int nEtaBins = 3;
0071   auto etaAxis = AxisVariant(BoostRegularAxis(nEtaBins, 0.0, 3.0, "eta"));
0072   auto resAxis = AxisVariant(BoostRegularAxis(80, -10.0, 10.0, "res"));
0073   Histogram2 hist("res_vs_eta", "Residual vs Eta", {etaAxis, resAxis});
0074 
0075   std::mt19937 generator(4242);
0076   for (int i = 0; i < nEtaBins; ++i) {
0077     std::normal_distribution<double> distribution(0.0, 0.5 + 0.3 * i);
0078     for (int n = 0; n < 20000; ++n) {
0079       hist.fill({i + 0.5, distribution(generator)});
0080     }
0081   }
0082 
0083   const auto profiles = extractMeanWidthProfiles(rootFn, hist, "mean", "width");
0084 
0085   BOOST_CHECK_EQUAL(profiles.fitFailureFraction, 0.0);
0086   for (int i = 0; i < nEtaBins; ++i) {
0087     BOOST_CHECK_CLOSE(profiles.width.binContent({i}), 0.5 + 0.3 * i, 5.0);
0088   }
0089 }
0090 
0091 BOOST_AUTO_TEST_SUITE_END()