Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-14 09:23:08

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 #include <boost/test/unit_test.hpp>
0010 
0011 #include <set>
0012 
0013 #include "StrawHitGeneratorHelper.hpp"
0014 #include "TFile.h"
0015 #include "TTree.h"
0016 
0017 constexpr auto logLvl = Acts::Logging::Level::INFO;
0018 constexpr std::size_t nEvents = 5;
0019 
0020 ACTS_LOCAL_LOGGER(getDefaultLogger("StrawLineSeederTest", logLvl));
0021 
0022 #define DECLARE_BRANCH(dTYPE, NAME) \
0023   dTYPE NAME{};                     \
0024   outTree->Branch(#NAME, &NAME);
0025 
0026 namespace ActsTests {
0027 
0028 void testSeeder(RandomEngine& engine, TFile& outFile) {
0029   auto outTree = std::make_unique<TTree>("StrawSeederTree", "StrawSeederTree");
0030 
0031   DECLARE_BRANCH(double, trueY0);
0032   DECLARE_BRANCH(double, trueTheta);
0033   DECLARE_BRANCH(std::size_t, nTruthStraws);
0034   DECLARE_BRANCH(std::size_t, nTruthStrips);
0035   DECLARE_BRANCH(std::vector<double>, recoY0);
0036   DECLARE_BRANCH(std::vector<double>, recoTheta);
0037   DECLARE_BRANCH(std::vector<std::size_t>, nStraws);
0038   DECLARE_BRANCH(std::vector<std::size_t>, nStrips);
0039   DECLARE_BRANCH(std::size_t, nSeeds);
0040 
0041   using GenCfg_t = MeasurementGenerator::Config;
0042   GenCfg_t genCfg{};
0043   genCfg.twinStraw = false;
0044   genCfg.createStrips = true;
0045 
0046   CompositeSpacePointLineSeeder::Config seederCfg{};
0047   seederCfg.busyLayerLimit = 20;
0048   const CompositeSpacePointLineSeeder seeder{
0049       seederCfg, getDefaultLogger("StrawLineSeederTest", logLvl)};
0050 
0051   for (std::size_t evt = 0; evt < nEvents; ++evt) {
0052     if (evt % 100 == 0) {
0053       ACTS_INFO("Generating event " << evt);
0054     }
0055     const auto line = generateLine(engine, logger());
0056     auto linePars = line.parameters();
0057     trueY0 = linePars[toUnderlying(FitParIndex::y0)];
0058     trueTheta = linePars[toUnderlying(FitParIndex::theta)];
0059     auto testTubes =
0060         MeasurementGenerator::spawn(line, 0._ns, engine, genCfg, logger());
0061     nTruthStraws = static_cast<std::size_t>(std::ranges::count_if(
0062         testTubes, [](const auto& testSp) { return testSp->isStraw(); }));
0063     nTruthStrips = static_cast<std::size_t>(std::ranges::count_if(
0064         testTubes, [](const auto& testSp) { return !testSp->isStraw(); }));
0065     auto calibrator = std::make_unique<SpCalibrator>();
0066 
0067     using SeedState_t =
0068         CompositeSpacePointLineSeeder::SeedingState<Container_t, Container_t,
0069                                                     SpSorter>;
0070     SeedState_t seedOpts{testTubes, calibrator.get()};
0071     seedOpts.strawRadius = 15._mm;
0072     ACTS_DEBUG(seedOpts);
0073     nSeeds = 0;
0074     CalibrationContext cctx{};
0075     while (auto seed = seeder.nextSeed(cctx, seedOpts)) {
0076       ACTS_DEBUG("Seed finder loop " << seedOpts);
0077       if (seed == std::nullopt) {
0078         break;
0079       }
0080       recoTheta.push_back(seed->parameters[toUnderlying(FitParIndex::theta)]);
0081       recoY0.push_back(seed->parameters[toUnderlying(FitParIndex::y0)]);
0082 
0083       const auto seedStraws = static_cast<std::size_t>(std::ranges::count_if(
0084           seed->hits, [](const auto& testMe) { return testMe->isStraw(); }));
0085       const auto seedStrips = seed->hits.size() - seedStraws;
0086       nStraws.push_back(seedStraws);
0087       nStrips.push_back(seedStrips);
0088       ++nSeeds;
0089     }
0090     ACTS_DEBUG("======Event " << evt << " found " << nSeeds << " seeds.");
0091 
0092     outTree->Fill();
0093     recoY0.clear();
0094     recoTheta.clear();
0095     nStraws.clear();
0096     nStrips.clear();
0097   }
0098   outFile.WriteObject(outTree.get(), outTree->GetName());
0099 }
0100 
0101 using GenCfg_t = MeasurementGenerator::Config;
0102 
0103 BOOST_AUTO_TEST_SUITE(SeedingSuite)
0104 BOOST_AUTO_TEST_CASE(SeederTest) {
0105   RandomEngine engine{1602};
0106   std::unique_ptr<TFile> outFile{
0107       TFile::Open("StrawLineSeedTest.root", "RECREATE")};
0108 
0109   BOOST_CHECK_EQUAL(outFile->IsZombie(), false);
0110 
0111   testSeeder(engine, *outFile);
0112 }
0113 BOOST_AUTO_TEST_CASE(SeedTangents) {
0114   RandomEngine engine{117};
0115   constexpr double tolerance = 1.e-3;
0116 
0117   using Seeder = CompositeSpacePointLineSeeder;
0118   using SeedAux = CompSpacePointAuxiliaries;
0119   using enum Seeder::TangentAmbi;
0120   GenCfg_t genCfg{};
0121   genCfg.createStrips = false;
0122   genCfg.createStraws = true;
0123   genCfg.smearRadius = false;
0124   for (std::size_t evt = 0; evt < nEvents; ++evt) {
0125     const auto line = generateLine(engine, logger());
0126     auto testTubes =
0127         MeasurementGenerator::spawn(line, 0._ns, engine, genCfg, logger());
0128 
0129     const double lineTanBeta = line.direction().y() / line.direction().z();
0130     const double lineY0 = line.position().y();
0131 
0132     for (std::size_t m1 = testTubes.size() - 1; m1 > testTubes.size() / 2;
0133          --m1) {
0134       for (std::size_t m2 = 0; m2 < m1; ++m2) {
0135         const auto& bottomTube = *testTubes[m2];
0136         const auto& topTube = *testTubes[m1];
0137 
0138         const int signTop = SeedAux::strawSign(line, topTube);
0139         const int signBot = SeedAux::strawSign(line, bottomTube);
0140         const auto trueAmbi = Seeder::encodeAmbiguity(signTop, signBot);
0141 
0142         ACTS_DEBUG(__func__ << "() " << __LINE__ << " - "
0143                             << std::format("bottom tube @ {:}, r: {:.3f}({:})",
0144                                            toString(bottomTube.localPosition()),
0145                                            (signBot * bottomTube.driftRadius()),
0146                                            signBot > 0 ? "R" : "L")
0147                             << ", "
0148                             << std::format("top tube @ {:}, r: {:.3f} ({:})",
0149                                            toString(topTube.localPosition()),
0150                                            (signTop * topTube.driftRadius()),
0151                                            signTop > 0 ? "R" : "L"));
0152 
0153         bool seenTruePars{false};
0154         std::set<std::pair<double, double>> fourSeedPars{};
0155         for (const auto ambi : {LL, RL, LR, RR}) {
0156           const auto pars =
0157               Seeder::constructTangentLine(topTube, bottomTube, ambi);
0158 
0159           const bool isTruePars =
0160               Acts::abs(std::tan(pars.theta) - lineTanBeta) < tolerance &&
0161               Acts::abs(lineY0 - pars.y0) < tolerance;
0162           seenTruePars |= isTruePars;
0163           ACTS_VERBOSE(__func__
0164                        << "() " << __LINE__ << " - Test ambiguity "
0165                        << CompositeSpacePointLineSeeder::toString(ambi)
0166                        << " -> "
0167                        << std::format("theta: {:.3f}, ", pars.theta / 1._degree)
0168                        << std::format("tanTheta: {:.3f}, ",
0169                                       std::tan(pars.theta))
0170                        << std::format("y0: {:.3f}", pars.y0)
0171                        << (!isTruePars ? (ambi == trueAmbi ? " xxxxxx" : "")
0172                                        : " <-------"));
0173           const Vector3 seedPos = pars.y0 * Vector3::UnitY();
0174           const Vector3 seedDir =
0175               makeDirectionFromAxisTangents(0., std::tan(pars.theta));
0176 
0177           const double chi2Top = SeedAux::chi2Term(seedPos, seedDir, topTube);
0178           const double chi2Bot =
0179               SeedAux::chi2Term(seedPos, seedDir, bottomTube);
0180           ACTS_VERBOSE(__func__ << "() " << __LINE__
0181                                 << " - Resulting chi2 top: " << chi2Top
0182                                 << ", bottom: " << chi2Bot);
0183           BOOST_CHECK_LE(chi2Top, 1.e-17);
0184           BOOST_CHECK_LE(chi2Bot, 1.e-17);
0185           BOOST_CHECK_EQUAL(
0186               fourSeedPars.insert(std::make_pair(pars.theta, pars.y0)).second,
0187               true);
0188         }
0189         BOOST_CHECK_EQUAL(seenTruePars, true);
0190         BOOST_CHECK_EQUAL(fourSeedPars.size(), 4);
0191         const auto seedPars =
0192             Seeder::constructTangentLine(topTube, bottomTube, trueAmbi);
0193         /// Construct line parameters
0194         ACTS_DEBUG(__func__
0195                    << "() " << __LINE__ << " - Line tan theta: " << lineTanBeta
0196                    << ", reconstructed tan theta: " << std::tan(seedPars.theta)
0197                    << ", line y0: " << lineY0
0198                    << ", reconstructed y0: " << seedPars.y0);
0199         BOOST_CHECK_CLOSE(std::tan(seedPars.theta), lineTanBeta, tolerance);
0200         BOOST_CHECK_CLOSE(seedPars.y0, lineY0, tolerance);
0201       }
0202     }
0203   }
0204 }
0205 }  // namespace ActsTests
0206 BOOST_AUTO_TEST_SUITE_END()