Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-07 08:28:13

0001 // SPDX-License-Identifier: LGPL-3.0-or-later
0002 // Copyright (C) 2026 ePIC Collaboration
0003 
0004 #include <catch2/catch_approx.hpp>
0005 #include <catch2/catch_test_macros.hpp>
0006 #include <edm4eic/CovDiag3f.h>
0007 #include <edm4eic/TrackParametersCollection.h>
0008 #include <edm4eic/TrackSeedCollection.h>
0009 #include <edm4eic/TrackerHitCollection.h>
0010 #include <edm4hep/Vector3f.h>
0011 #include <podio/RelationRange.h>
0012 #include <cmath>
0013 #include <string_view>
0014 
0015 #include "algorithms/tracking/TrackSeeding.h"
0016 #include "algorithms/tracking/TrackSeedingConfig.h"
0017 
0018 using eicrecon::TrackSeeding;
0019 using eicrecon::TrackSeedingConfig;
0020 
0021 namespace {
0022 
0023 void checkThreeHitsProduceOneSeed(TrackSeedingConfig::SeedingMethod seedingMethod,
0024                                   std::string_view algoName) {
0025   TrackSeeding algo(algoName);
0026   TrackSeedingConfig cfg;
0027   cfg.seedingMethod = seedingMethod;
0028   cfg.rMin          = 0.0f;
0029   cfg.rMax          = 1000.0f;
0030   cfg.zMin          = -1000.0f;
0031   cfg.zMax          = 1000.0f;
0032   cfg.minPt         = 0.01f;
0033   // Use a small positive per-side Δr_min so that the middle SP is not counted
0034   // as its own top/bottom candidate. Acts' KD-tree range check is
0035   // min <= v < max (inclusive min), and DoubletSeedFinder accepts Δr == 0;
0036   // combined, Δr_min = 0 makes each hit appear as one of its own top
0037   // candidates and yields spurious self-referential seeds in Seeding2.
0038   // (cfg.deltaRMin only feeds Seeding2's BroadTripletSeedFilter, not the
0039   // doublet formation, so it does not need to be adjusted here.)
0040   cfg.deltaRMinBottomSP = 1.0f;
0041   cfg.deltaRMinTopSP    = 1.0f;
0042   cfg.deltaRMaxBottomSP = 1000.0f;
0043   cfg.deltaRMaxTopSP    = 1000.0f;
0044   // Loosen the two cuts that this toy triplet violates under default
0045   // configuration (both back-ends): the mid-top pair has Δφ ≈ 0.106 rad
0046   // (default cap 0.085), and the geometric impact parameter is ≈ 5 mm
0047   // (default cap 3 mm). All other defaults (rMinMiddle=20/rMaxMiddle=400,
0048   // cotThetaMax≈27, collisionRegion±250) are already satisfied.
0049   cfg.deltaPhiMax = 1.0f;
0050   cfg.impactMax   = 1000.0f;
0051   algo.applyConfig(cfg);
0052   algo.init();
0053 
0054   edm4eic::TrackerHitCollection hits;
0055   // Hits are chosen so that (r, z) is very nearly collinear. This is required
0056   // by Acts::SeedFinderOrthogonal, which has a hard-coded (non-configurable)
0057   // triplet alignment cut in the r-z plane of 0.005 rad. Seeding2 does not
0058   // have this cut, but keeping the hits collinear works for both back-ends.
0059   hits.create(1, edm4hep::Vector3f(6.0f, 33.0f, 10.0f), edm4eic::CovDiag3f(), 0.0f, 0.0f, 1.0f,
0060               0.0f);
0061   hits.create(2, edm4hep::Vector3f(14.0f, 52.0f, 20.0f), edm4eic::CovDiag3f(), 0.0f, 0.0f, 1.0f,
0062               0.0f);
0063   hits.create(3, edm4hep::Vector3f(26.0f, 67.0f, 28.868f), edm4eic::CovDiag3f(), 0.0f, 0.0f, 1.0f,
0064               0.0f);
0065 
0066   edm4eic::TrackSeedCollection seeds;
0067   edm4eic::TrackParametersCollection params;
0068   algo.process({&hits}, {&seeds, &params});
0069 
0070   REQUIRE(seeds.size() == 1);
0071   REQUIRE(params.size() == 1);
0072   REQUIRE(seeds[0].getHits().size() == 3);
0073 
0074   const auto param = params[0];
0075   CHECK(std::isfinite(param.getPhi()));
0076   CHECK(std::isfinite(param.getTheta()));
0077   CHECK(std::isfinite(param.getQOverP()));
0078   CHECK(param.getTheta() == Catch::Approx(1.0666f).epsilon(0.1f));
0079   CHECK(param.getQOverP() != Catch::Approx(0.0f));
0080   CHECK(seeds[0].getParams().getQOverP() == Catch::Approx(param.getQOverP()));
0081 }
0082 
0083 void checkAcceptedSpacePointEmpty(TrackSeedingConfig::SeedingMethod seedingMethod,
0084                                   std::string_view algoName) {
0085   TrackSeeding algo(algoName);
0086   TrackSeedingConfig cfg;
0087   cfg.seedingMethod = seedingMethod;
0088   cfg.rMin          = 0.0f;
0089   cfg.rMax          = 1.0f;
0090   cfg.zMin          = -1.0f;
0091   cfg.zMax          = 1.0f;
0092   algo.applyConfig(cfg);
0093   algo.init();
0094 
0095   edm4eic::TrackerHitCollection hits;
0096   hits.create(1, edm4hep::Vector3f(50.0f, 0.0f, 10.0f), edm4eic::CovDiag3f(), 0.0f, 0.0f, 1.0f,
0097               0.0f);
0098   hits.create(2, edm4hep::Vector3f(60.0f, 0.0f, 20.0f), edm4eic::CovDiag3f(), 0.0f, 0.0f, 1.0f,
0099               0.0f);
0100 
0101   edm4eic::TrackSeedCollection seeds;
0102   edm4eic::TrackParametersCollection params;
0103   algo.process({&hits}, {&seeds, &params});
0104 
0105   REQUIRE(seeds.empty());
0106   REQUIRE(params.empty());
0107 }
0108 
0109 } // namespace
0110 
0111 #if TRACKSEEDING_HAS_SEEDING2 || TRACKSEEDING_HAS_SEEDING
0112 TEST_CASE("TrackSeeding (Seeding2): three hits produce one seed with stable parameters",
0113           "[TrackSeeding]") {
0114   checkThreeHitsProduceOneSeed(TrackSeedingConfig::SeedingMethod::Seeding2,
0115                                "test_track_seeding_seeding2");
0116 }
0117 
0118 TEST_CASE("TrackSeeding (Seeding2): accepted-spacepoint-empty path exits cleanly",
0119           "[TrackSeeding]") {
0120   checkAcceptedSpacePointEmpty(TrackSeedingConfig::SeedingMethod::Seeding2,
0121                                "test_track_seeding_seeding2_empty");
0122 }
0123 #endif
0124 
0125 #if TRACKSEEDING_HAS_ORTHOGONAL
0126 TEST_CASE("TrackSeeding (Orthogonal): three hits produce one seed with stable parameters",
0127           "[TrackSeeding]") {
0128   checkThreeHitsProduceOneSeed(TrackSeedingConfig::SeedingMethod::Orthogonal,
0129                                "test_track_seeding_orthogonal");
0130 }
0131 
0132 TEST_CASE("TrackSeeding (Orthogonal): accepted-spacepoint-empty path exits cleanly",
0133           "[TrackSeeding]") {
0134   checkAcceptedSpacePointEmpty(TrackSeedingConfig::SeedingMethod::Orthogonal,
0135                                "test_track_seeding_orthogonal_empty");
0136 }
0137 #endif