File indexing completed on 2025-10-22 07:53:29
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/data/test_case.hpp>
0010 #include <boost/test/unit_test.hpp>
0011
0012 #include "Acts/EventData/MultiTrajectory.hpp"
0013 #include "Acts/EventData/TrackContainer.hpp"
0014 #include "Acts/EventData/TrackStateType.hpp"
0015 #include "Acts/EventData/VectorMultiTrajectory.hpp"
0016 #include "Acts/EventData/VectorTrackContainer.hpp"
0017 #include "Acts/Geometry/GeometryIdentifier.hpp"
0018 #include "Acts/Surfaces/CurvilinearSurface.hpp"
0019 #include "Acts/Surfaces/PerigeeSurface.hpp"
0020 #include "Acts/Surfaces/PlaneSurface.hpp"
0021 #include "Acts/TrackFinding/TrackSelector.hpp"
0022 #include "Acts/Utilities/AngleHelpers.hpp"
0023
0024 #include <limits>
0025 #include <numbers>
0026
0027 using namespace Acts;
0028 namespace bdata = boost::unit_test::data;
0029
0030 struct MockTrack {
0031 static constexpr bool ReadOnly = true;
0032 using Container = VectorTrackContainer;
0033 using Trajectory = VectorMultiTrajectory;
0034 using IndexType = TrackIndexType;
0035
0036 double m_theta;
0037 double m_phi;
0038 double m_pt;
0039 double m_loc0;
0040 double m_loc1;
0041 double m_time;
0042 std::size_t m_nMeasurements;
0043 std::size_t m_nHoles;
0044 std::size_t m_nOutliers;
0045 std::size_t m_nSharedHits;
0046 float m_chi2;
0047
0048 bool hasReferenceSurface() const { return true; }
0049 double theta() const { return m_theta; }
0050 double phi() const { return m_phi; }
0051 double transverseMomentum() const { return m_pt; }
0052 double loc0() const { return m_loc0; }
0053 double loc1() const { return m_loc1; }
0054 double time() const { return m_time; }
0055 std::size_t nMeasurements() const { return m_nMeasurements; }
0056 std::size_t nHoles() const { return m_nHoles; }
0057 std::size_t nOutliers() const { return m_nOutliers; }
0058 std::size_t nSharedHits() const { return m_nSharedHits; }
0059 float chi2() const { return m_chi2; }
0060
0061
0062 private:
0063 struct MockTrackState {
0064 const Surface& referenceSurface() const {
0065 static const std::shared_ptr<PlaneSurface> srf =
0066 CurvilinearSurface(Vector3::Zero(), Vector3::UnitZ()).planeSurface();
0067 return *srf;
0068 }
0069
0070 ConstTrackStateType typeFlags() const {
0071 static const ConstTrackStateType::raw_type raw{0};
0072 return ConstTrackStateType{raw};
0073 }
0074 };
0075
0076 struct TrackStateRange {
0077 auto begin() const { return m_trackStates.begin(); }
0078 auto end() const { return m_trackStates.end(); }
0079
0080 private:
0081 std::vector<MockTrackState> m_trackStates;
0082 };
0083
0084 public:
0085 TrackStateRange trackStatesReversed() const { return {}; }
0086 };
0087
0088 namespace ActsTests {
0089
0090 BOOST_AUTO_TEST_SUITE(TrackFindingSuite)
0091
0092 std::vector<double> etaValues{-5.0, -4.5, -4.0, -3.5, -3.0, -2.5, -2.0, -1.5,
0093 -1.0, -0.5, 0.0, 0.5, 1.0, 1.5, 2.0, 2.5,
0094 3.0, 3.5, 4.0, 4.5, 5.0, 1.0};
0095
0096 BOOST_DATA_TEST_CASE(TestSingleBinCase, bdata::make(etaValues), eta) {
0097 TrackSelector::EtaBinnedConfig cfgBase;
0098
0099 MockTrack baseTrack{};
0100 baseTrack.m_theta = AngleHelpers::thetaFromEta(eta);
0101 baseTrack.m_phi = 0.5;
0102 baseTrack.m_pt = 0.5;
0103 baseTrack.m_loc0 = 0.5;
0104 baseTrack.m_loc1 = 0.5;
0105 baseTrack.m_time = 0.5;
0106 baseTrack.m_nMeasurements = 1;
0107 baseTrack.m_nHoles = 0;
0108 baseTrack.m_nOutliers = 0;
0109 baseTrack.m_nSharedHits = 0;
0110 baseTrack.m_chi2 = 0.0;
0111
0112 {
0113 TrackSelector selector{cfgBase};
0114
0115 BOOST_CHECK(selector.isValidTrack(baseTrack));
0116 }
0117
0118 auto check = [&](const auto& var, const auto& minPtr, const auto& maxPtr,
0119 const auto& propPtr) {
0120 BOOST_TEST_INFO_SCOPE("Testing " << var);
0121 MockTrack track = baseTrack;
0122
0123 auto cfgMinOnly = cfgBase;
0124 auto cfgMaxOnly = cfgBase;
0125 auto cfgMinMax = cfgBase;
0126
0127 cfgMinOnly.cutSets.at(0).*minPtr = -1;
0128 cfgMinMax.cutSets.at(0).*minPtr = -1;
0129 cfgMaxOnly.cutSets.at(0).*maxPtr = 1;
0130 cfgMinMax.cutSets.at(0).*maxPtr = 1;
0131
0132 TrackSelector minOnly{cfgMinOnly};
0133 TrackSelector maxOnly{cfgMaxOnly};
0134 TrackSelector minMax{cfgMinMax};
0135
0136 BOOST_CHECK(minOnly.isValidTrack(track));
0137 BOOST_CHECK(maxOnly.isValidTrack(track));
0138 BOOST_CHECK(minMax.isValidTrack(track));
0139
0140
0141 track.*propPtr = -1.1;
0142
0143 BOOST_CHECK(!minOnly.isValidTrack(track));
0144 BOOST_CHECK(maxOnly.isValidTrack(track));
0145 BOOST_CHECK(!minMax.isValidTrack(track));
0146
0147
0148 track.*propPtr = 1.1;
0149
0150 BOOST_CHECK(minOnly.isValidTrack(track));
0151 BOOST_CHECK(!maxOnly.isValidTrack(track));
0152 BOOST_CHECK(!minMax.isValidTrack(track));
0153 };
0154
0155 check("loc0", &TrackSelector::Config::loc0Min,
0156 &TrackSelector::Config::loc0Max, &MockTrack::m_loc0);
0157
0158 check("loc1", &TrackSelector::Config::loc1Min,
0159 &TrackSelector::Config::loc1Max, &MockTrack::m_loc1);
0160
0161 check("phi", &TrackSelector::Config::phiMin, &TrackSelector::Config::phiMax,
0162 &MockTrack::m_phi);
0163
0164 check("time", &TrackSelector::Config::timeMin,
0165 &TrackSelector::Config::timeMax, &MockTrack::m_time);
0166
0167 {
0168 BOOST_TEST_INFO_SCOPE("pt min");
0169 auto cfg = cfgBase;
0170 cfg.cutSets.at(0).ptMin = {0.2};
0171 TrackSelector selector{cfg};
0172 MockTrack track = baseTrack;
0173 BOOST_CHECK(selector.isValidTrack(track));
0174 track.m_pt = 0.1;
0175 BOOST_CHECK(!selector.isValidTrack(track));
0176 }
0177
0178 {
0179 BOOST_TEST_INFO_SCOPE("pt max");
0180 auto cfg = cfgBase;
0181 cfg.cutSets.at(0).ptMax = {1.0};
0182 TrackSelector selector{cfg};
0183 MockTrack track = baseTrack;
0184 BOOST_CHECK(selector.isValidTrack(track));
0185 track.m_pt = 1.1;
0186 BOOST_CHECK(!selector.isValidTrack(track));
0187 }
0188
0189 {
0190 BOOST_TEST_INFO_SCOPE("pt min max");
0191 auto cfg = cfgBase;
0192 cfg.cutSets.at(0).ptMin = {0.2};
0193 cfg.cutSets.at(0).ptMax = {1.0};
0194 TrackSelector selector{cfg};
0195 MockTrack track = baseTrack;
0196 BOOST_CHECK(selector.isValidTrack(track));
0197 track.m_pt = 0.1;
0198 BOOST_CHECK(!selector.isValidTrack(track));
0199 track.m_pt = 1.1;
0200 BOOST_CHECK(!selector.isValidTrack(track));
0201 }
0202
0203 {
0204 BOOST_TEST_INFO_SCOPE("eta min");
0205 auto cfg = cfgBase;
0206 cfg.cutSets.at(0).etaMin = {-1.0};
0207 TrackSelector selector{cfg};
0208 MockTrack track = baseTrack;
0209 track.m_theta = AngleHelpers::thetaFromEta(0.5);
0210 BOOST_CHECK(selector.isValidTrack(track));
0211 track.m_theta = AngleHelpers::thetaFromEta(-1.1);
0212 BOOST_CHECK(!selector.isValidTrack(track));
0213 }
0214
0215 {
0216 BOOST_TEST_INFO_SCOPE("eta max");
0217 auto cfg = cfgBase;
0218 cfg.cutSets.at(0).etaMax = {1.0};
0219 TrackSelector selector{cfg};
0220 MockTrack track = baseTrack;
0221 track.m_theta = AngleHelpers::thetaFromEta(0.5);
0222 BOOST_CHECK(selector.isValidTrack(track));
0223 track.m_theta = AngleHelpers::thetaFromEta(1.1);
0224 BOOST_CHECK(!selector.isValidTrack(track));
0225 }
0226
0227 {
0228 BOOST_TEST_INFO_SCOPE("eta min max");
0229 auto cfg = cfgBase;
0230 cfg.cutSets.at(0).etaMin = {-1.0};
0231 cfg.cutSets.at(0).etaMax = {1.0};
0232 TrackSelector selector{cfg};
0233 MockTrack track = baseTrack;
0234 track.m_theta = AngleHelpers::thetaFromEta(0.5);
0235 BOOST_CHECK(selector.isValidTrack(track));
0236 track.m_theta = AngleHelpers::thetaFromEta(-1.1);
0237 BOOST_CHECK(!selector.isValidTrack(track));
0238 track.m_theta = AngleHelpers::thetaFromEta(1.1);
0239 BOOST_CHECK(!selector.isValidTrack(track));
0240 }
0241
0242 {
0243 BOOST_TEST_INFO_SCOPE("abs eta min");
0244 auto cfg = cfgBase;
0245 cfg.cutSets.at(0).absEtaMin = {0.2};
0246 TrackSelector selector{cfg};
0247 MockTrack track = baseTrack;
0248 track.m_theta = AngleHelpers::thetaFromEta(0.5);
0249 BOOST_CHECK(selector.isValidTrack(track));
0250 track.m_theta = AngleHelpers::thetaFromEta(-0.5);
0251 BOOST_CHECK(selector.isValidTrack(track));
0252
0253 track.m_theta = AngleHelpers::thetaFromEta(0.1);
0254 BOOST_CHECK(!selector.isValidTrack(track));
0255 track.m_theta = AngleHelpers::thetaFromEta(-0.1);
0256 BOOST_CHECK(!selector.isValidTrack(track));
0257 }
0258
0259 {
0260 BOOST_TEST_INFO_SCOPE("abs eta max");
0261 auto cfg = cfgBase;
0262 cfg.cutSets.at(0).absEtaMax = {1.0};
0263 TrackSelector selector{cfg};
0264 MockTrack track = baseTrack;
0265 track.m_theta = AngleHelpers::thetaFromEta(0.5);
0266 BOOST_CHECK(selector.isValidTrack(track));
0267 track.m_theta = AngleHelpers::thetaFromEta(-0.5);
0268 BOOST_CHECK(selector.isValidTrack(track));
0269
0270 track.m_theta = AngleHelpers::thetaFromEta(1.1);
0271 BOOST_CHECK(!selector.isValidTrack(track));
0272 track.m_theta = AngleHelpers::thetaFromEta(-1.1);
0273 BOOST_CHECK(!selector.isValidTrack(track));
0274 }
0275
0276 {
0277 BOOST_TEST_INFO_SCOPE("abs eta min max");
0278 auto cfg = cfgBase;
0279 cfg.cutSets.at(0).absEtaMin = {0.2};
0280 cfg.cutSets.at(0).absEtaMax = {1.0};
0281 TrackSelector selector{cfg};
0282 MockTrack track = baseTrack;
0283 track.m_theta = AngleHelpers::thetaFromEta(0.5);
0284 BOOST_CHECK(selector.isValidTrack(track));
0285 track.m_theta = AngleHelpers::thetaFromEta(-0.5);
0286 BOOST_CHECK(selector.isValidTrack(track));
0287
0288 track.m_theta = AngleHelpers::thetaFromEta(0.1);
0289 BOOST_CHECK(!selector.isValidTrack(track));
0290 track.m_theta = AngleHelpers::thetaFromEta(-0.1);
0291 BOOST_CHECK(!selector.isValidTrack(track));
0292
0293 track.m_theta = AngleHelpers::thetaFromEta(1.1);
0294 BOOST_CHECK(!selector.isValidTrack(track));
0295 track.m_theta = AngleHelpers::thetaFromEta(-1.1);
0296 BOOST_CHECK(!selector.isValidTrack(track));
0297 }
0298
0299 {
0300 BOOST_TEST_INFO_SCOPE("nMeas min");
0301 auto cfg = cfgBase;
0302 cfg.cutSets.at(0).minMeasurements = {1};
0303 TrackSelector selector{cfg};
0304 MockTrack track = baseTrack;
0305 track.m_nMeasurements = {2};
0306 BOOST_CHECK(selector.isValidTrack(track));
0307 track.m_nMeasurements = {1};
0308 BOOST_CHECK(selector.isValidTrack(track));
0309 track.m_nMeasurements = {0};
0310 BOOST_CHECK(!selector.isValidTrack(track));
0311 }
0312
0313 {
0314 BOOST_TEST_INFO_SCOPE("nHoles max");
0315 auto cfg = cfgBase;
0316 cfg.cutSets.at(0).maxHoles = {3};
0317 TrackSelector selector{cfg};
0318 MockTrack track = baseTrack;
0319 track.m_nHoles = {2};
0320 BOOST_CHECK(selector.isValidTrack(track));
0321 track.m_nHoles = {3};
0322 BOOST_CHECK(selector.isValidTrack(track));
0323 track.m_nHoles = {4};
0324 BOOST_CHECK(!selector.isValidTrack(track));
0325 }
0326
0327 {
0328 BOOST_TEST_INFO_SCOPE("nOutliers max");
0329 auto cfg = cfgBase;
0330 cfg.cutSets.at(0).maxOutliers = {3};
0331 TrackSelector selector{cfg};
0332 MockTrack track = baseTrack;
0333 track.m_nOutliers = {2};
0334 BOOST_CHECK(selector.isValidTrack(track));
0335 track.m_nOutliers = {3};
0336 BOOST_CHECK(selector.isValidTrack(track));
0337 track.m_nOutliers = {4};
0338 BOOST_CHECK(!selector.isValidTrack(track));
0339 }
0340
0341 {
0342 BOOST_TEST_INFO_SCOPE("nSharedHits max");
0343 auto cfg = cfgBase;
0344 cfg.cutSets.at(0).maxSharedHits = {3};
0345 TrackSelector selector{cfg};
0346 MockTrack track = baseTrack;
0347 track.m_nSharedHits = {2};
0348 BOOST_CHECK(selector.isValidTrack(track));
0349 track.m_nSharedHits = {3};
0350 BOOST_CHECK(selector.isValidTrack(track));
0351 track.m_nSharedHits = {4};
0352 BOOST_CHECK(!selector.isValidTrack(track));
0353 }
0354
0355 {
0356 BOOST_TEST_INFO_SCOPE("nSharedHits max");
0357 auto cfg = cfgBase;
0358 cfg.cutSets.at(0).maxChi2 = {3};
0359 TrackSelector selector{cfg};
0360 MockTrack track = baseTrack;
0361 track.m_chi2 = {2};
0362 BOOST_CHECK(selector.isValidTrack(track));
0363 track.m_chi2 = {3};
0364 BOOST_CHECK(selector.isValidTrack(track));
0365 track.m_chi2 = {4};
0366 BOOST_CHECK(!selector.isValidTrack(track));
0367 }
0368 }
0369
0370 BOOST_AUTO_TEST_CASE(TestSingleBinEtaCutByBinEdge) {
0371 TrackSelector selector{TrackSelector::EtaBinnedConfig(1.0).addCuts(2.0)};
0372
0373 BOOST_TEST_INFO_SCOPE(selector.config());
0374
0375 MockTrack track{};
0376 track.m_theta = AngleHelpers::thetaFromEta(0.0);
0377 BOOST_CHECK(!selector.isValidTrack(track));
0378
0379 track.m_theta = AngleHelpers::thetaFromEta(0.5);
0380 BOOST_CHECK(!selector.isValidTrack(track));
0381
0382
0383
0384 track.m_theta = AngleHelpers::thetaFromEta(1.01);
0385 BOOST_CHECK(selector.isValidTrack(track));
0386
0387 track.m_theta = AngleHelpers::thetaFromEta(1.5);
0388 BOOST_CHECK(selector.isValidTrack(track));
0389
0390 track.m_theta = AngleHelpers::thetaFromEta(2.0);
0391 BOOST_CHECK(!selector.isValidTrack(track));
0392 }
0393
0394 BOOST_AUTO_TEST_CASE(TestMultiBinCuts) {
0395 MockTrack baseTrack{};
0396 baseTrack.m_theta = AngleHelpers::thetaFromEta(1.0);
0397 baseTrack.m_phi = 0.5;
0398 baseTrack.m_pt = 0.5;
0399 baseTrack.m_loc0 = 0.5;
0400 baseTrack.m_loc1 = 0.5;
0401 baseTrack.m_time = 0.5;
0402 baseTrack.m_nMeasurements = 1;
0403 baseTrack.m_nHoles = 0;
0404 baseTrack.m_nOutliers = 0;
0405 baseTrack.m_nSharedHits = 0;
0406 baseTrack.m_chi2 = 0.0;
0407
0408 using Config = TrackSelector::Config;
0409
0410 using factory_ptr_t = Config& (Config::*)(double, double);
0411 using prop_ptr_t = double MockTrack::*;
0412
0413 auto check = [&](const char* name, const factory_ptr_t& factory,
0414 const prop_ptr_t& prop) {
0415 BOOST_TEST_CONTEXT(name) {
0416 auto cfg = TrackSelector::EtaBinnedConfig{0.0};
0417
0418 cfg.addCuts(2.0, [&](auto& c) { (c.*factory)(-1.0, 1.0); })
0419 .addCuts([&](auto& c) { (c.*factory)(-2.0, 2.0); });
0420
0421 TrackSelector selector{cfg};
0422
0423 BOOST_TEST_INFO_SCOPE(cfg);
0424
0425 {
0426
0427 MockTrack track = baseTrack;
0428 track.m_theta = AngleHelpers::thetaFromEta(0.0);
0429
0430 BOOST_CHECK(selector.isValidTrack(track));
0431
0432 track.*prop = -1.1;
0433 BOOST_CHECK(!selector.isValidTrack(track));
0434
0435 track.*prop = 1.1;
0436 BOOST_CHECK(!selector.isValidTrack(track));
0437 }
0438
0439 {
0440
0441 MockTrack track = baseTrack;
0442 track.m_theta = AngleHelpers::thetaFromEta(1.0);
0443
0444 BOOST_CHECK(selector.isValidTrack(track));
0445
0446 track.*prop = -1.1;
0447 BOOST_CHECK(!selector.isValidTrack(track));
0448
0449 track.*prop = 1.1;
0450 BOOST_CHECK(!selector.isValidTrack(track));
0451 }
0452
0453 {
0454
0455 MockTrack track = baseTrack;
0456 track.m_theta = AngleHelpers::thetaFromEta(
0457 2.0 - std::numeric_limits<double>::epsilon());
0458
0459 BOOST_CHECK(selector.isValidTrack(track));
0460
0461 track.*prop = -1.1;
0462 BOOST_CHECK(!selector.isValidTrack(track));
0463
0464 track.*prop = 1.1;
0465 BOOST_CHECK(!selector.isValidTrack(track));
0466 }
0467
0468 {
0469
0470 MockTrack track = baseTrack;
0471 track.m_theta = AngleHelpers::thetaFromEta(2.0);
0472
0473 BOOST_CHECK(selector.isValidTrack(track));
0474
0475 track.*prop = -1.1;
0476 BOOST_CHECK(selector.isValidTrack(track));
0477
0478 track.*prop = 1.1;
0479 BOOST_CHECK(selector.isValidTrack(track));
0480
0481 track.*prop = -2.1;
0482 BOOST_CHECK(!selector.isValidTrack(track));
0483
0484 track.*prop = 2.1;
0485 BOOST_CHECK(!selector.isValidTrack(track));
0486 }
0487
0488 {
0489
0490 MockTrack track = baseTrack;
0491 track.m_theta = AngleHelpers::thetaFromEta(10.0);
0492
0493 track.*prop = -1.1;
0494 BOOST_CHECK(selector.isValidTrack(track));
0495
0496 track.*prop = 1.1;
0497 BOOST_CHECK(selector.isValidTrack(track));
0498
0499 track.*prop = -2.1;
0500 BOOST_CHECK(!selector.isValidTrack(track));
0501
0502 track.*prop = 2.1;
0503 BOOST_CHECK(!selector.isValidTrack(track));
0504 }
0505 }
0506 };
0507
0508 check("loc0", &Config::loc0, &MockTrack::m_loc0);
0509 check("loc1", &Config::loc1, &MockTrack::m_loc1);
0510 check("time", &Config::time, &MockTrack::m_time);
0511 check("phi", &Config::phi, &MockTrack::m_phi);
0512 check("pt", &Config::pt, &MockTrack::m_pt);
0513 }
0514
0515 BOOST_AUTO_TEST_CASE(TestBinSelection) {
0516 using EtaBinnedConfig = TrackSelector::EtaBinnedConfig;
0517 constexpr double inf = std::numeric_limits<double>::infinity();
0518
0519 {
0520 EtaBinnedConfig cfg{std::vector<double>{0, inf}};
0521 for (int i = -1; i <= 1; i = i + 2) {
0522 BOOST_CHECK_EQUAL(cfg.binIndex(i * 0.0), 0);
0523 BOOST_CHECK_EQUAL(cfg.binIndex(i * 1.0), 0);
0524 BOOST_CHECK_EQUAL(cfg.binIndex(i * 2.0), 0);
0525 BOOST_CHECK_EQUAL(cfg.binIndex(i * 3.0), 0);
0526 BOOST_CHECK_EQUAL(cfg.binIndex(i * 10.0), 0);
0527 BOOST_CHECK_EQUAL(cfg.binIndex(i * 1000.0), 0);
0528 }
0529 }
0530
0531 {
0532 EtaBinnedConfig cfg{std::vector<double>{0, 0.5, 1.5, 2.5, 3.0, inf}};
0533 for (int i = -1; i <= 1; i = i + 2) {
0534 BOOST_CHECK_EQUAL(cfg.binIndex(i * 0.0), 0);
0535 BOOST_CHECK_EQUAL(cfg.binIndex(i * 1.0), 1);
0536 BOOST_CHECK_EQUAL(cfg.binIndex(i * 2.0), 2);
0537 BOOST_CHECK_EQUAL(cfg.binIndex(i * 3.0), 4);
0538 BOOST_CHECK_EQUAL(cfg.binIndex(i * 10.0), 4);
0539 BOOST_CHECK_EQUAL(cfg.binIndex(i * 1000.0), 4);
0540 }
0541 }
0542
0543 {
0544 EtaBinnedConfig cfg{std::vector<double>{0, 1, 2}};
0545 for (int i = -1; i <= 1; i = i + 2) {
0546 BOOST_CHECK_EQUAL(cfg.binIndex(i * 0.0), 0);
0547 BOOST_CHECK_EQUAL(cfg.binIndex(i * 1.0), 1);
0548 BOOST_CHECK_EQUAL(
0549 cfg.binIndex(i * (2.0 - std::numeric_limits<double>::epsilon())), 1);
0550 BOOST_CHECK_THROW(cfg.binIndex(i * 2.0), std::invalid_argument);
0551 }
0552 }
0553 }
0554
0555 BOOST_AUTO_TEST_CASE(TestConstructor) {
0556
0557 {
0558 TrackSelector::EtaBinnedConfig cfg{std::vector<double>{0, 1, 4}};
0559 cfg.cutSets.at(0).ptMin = 0.9;
0560 cfg.cutSets.at(1).ptMin = 0.4;
0561 TrackSelector{cfg};
0562 }
0563
0564 {
0565
0566 TrackSelector::EtaBinnedConfig cfg{std::vector<double>{0, 1, 4}};
0567
0568
0569 TrackSelector{cfg};
0570
0571
0572 cfg.cutSets.resize(1);
0573 BOOST_CHECK_THROW(TrackSelector{cfg}, std::invalid_argument);
0574
0575
0576 cfg.cutSets.resize(3);
0577 BOOST_CHECK_THROW(TrackSelector{cfg}, std::invalid_argument);
0578 }
0579
0580
0581 TrackSelector::Config cuts;
0582 TrackSelector selector{cuts};
0583 BOOST_CHECK_EQUAL(selector.config().absEtaEdges.size(), 2);
0584
0585 {
0586
0587 auto cfg = TrackSelector::EtaBinnedConfig(0);
0588 cfg.addCuts(2.0, [](auto& c) { c.loc0(-1.0, 1.0); });
0589 BOOST_CHECK_THROW(cfg.addCuts(1.0), std::invalid_argument);
0590 BOOST_CHECK_THROW(TrackSelector::EtaBinnedConfig(0).addCuts(-2.0),
0591 std::invalid_argument);
0592 }
0593
0594 {
0595 auto cfg = TrackSelector::EtaBinnedConfig(1.0);
0596
0597 cfg.addCuts(2.0, [](auto& c) { c.loc0(-1.0, 1.0); });
0598 BOOST_CHECK_EQUAL(cfg.nEtaBins(), 1);
0599 BOOST_CHECK_EQUAL(cfg.getCuts(1.5).loc0Min, -1.0);
0600 BOOST_CHECK_EQUAL(cfg.getCuts(1.5).loc0Max, 1.0);
0601
0602 cfg.addCuts(3.0, [](auto& c) { c.loc0(-2.0, 2.0); });
0603 BOOST_CHECK_EQUAL(cfg.nEtaBins(), 2);
0604 BOOST_CHECK_EQUAL(cfg.getCuts(2.5).loc0Min, -2.0);
0605 BOOST_CHECK_EQUAL(cfg.getCuts(2.5).loc0Max, 2.0);
0606
0607 cfg.addCuts(4.0, [](auto& c) { c.loc0(-3.0, 3.0); });
0608 BOOST_CHECK_EQUAL(cfg.nEtaBins(), 3);
0609 BOOST_CHECK_EQUAL(cfg.getCuts(3.5).loc0Min, -3.0);
0610 BOOST_CHECK_EQUAL(cfg.getCuts(3.5).loc0Max, 3.0);
0611 }
0612 }
0613
0614 BOOST_AUTO_TEST_CASE(SubsetHitCountCut) {
0615 auto makeSurface = [](GeometryIdentifier id) {
0616 std::shared_ptr<PlaneSurface> srf =
0617 CurvilinearSurface(Vector3::Zero(), Vector3::UnitZ()).planeSurface();
0618
0619 srf->assignGeometryId(id);
0620 return srf;
0621 };
0622
0623 auto addTrackState = [](auto& track, const auto& surface,
0624 TrackStateFlag flag) {
0625 auto ts = track.appendTrackState();
0626 ts.setReferenceSurface(surface);
0627 ts.typeFlags().set(flag);
0628 return ts;
0629 };
0630
0631 auto addMeasurement = [&](auto& track, const auto& surface) {
0632 return addTrackState(track, surface, TrackStateFlag::MeasurementFlag);
0633 };
0634
0635 auto addMaterial = [&](auto& track, const auto& surface) {
0636 return addTrackState(track, surface, TrackStateFlag::MaterialFlag);
0637 };
0638
0639 TrackContainer tc{VectorTrackContainer{}, VectorMultiTrajectory{}};
0640
0641 auto makeTrack = [&]() {
0642 auto track = tc.makeTrack();
0643
0644 using namespace Acts::UnitLiterals;
0645 track.parameters() << 0, 0, std::numbers::pi / 2., std::numbers::pi / 2.,
0646 1 / 1_GeV, 0;
0647 auto perigee = Surface::makeShared<PerigeeSurface>(Vector3::Zero());
0648 track.setReferenceSurface(perigee);
0649 return track;
0650 };
0651
0652 auto vol7_lay3_sen2 = makeSurface(
0653 GeometryIdentifier{}.withVolume(7).withLayer(3).withSensitive(2));
0654 auto vol7_lay4 = makeSurface(GeometryIdentifier{}.withVolume(7).withLayer(4));
0655 auto vol7_lay3_sen8 = makeSurface(
0656 GeometryIdentifier{}.withVolume(7).withLayer(3).withSensitive(8));
0657 auto vol7_lay5_sen11 = makeSurface(
0658 GeometryIdentifier{}.withVolume(7).withLayer(5).withSensitive(11));
0659 auto vol7_lay5_sen12 = makeSurface(
0660 GeometryIdentifier{}.withVolume(7).withLayer(5).withSensitive(12));
0661 auto vol7_lay6_sen3 = makeSurface(
0662 GeometryIdentifier{}.withVolume(7).withLayer(6).withSensitive(3));
0663
0664 auto vol8_lay8_sen1 = makeSurface(
0665 GeometryIdentifier{}.withVolume(8).withLayer(8).withSensitive(1));
0666 auto vol8_lay8_sen2 = makeSurface(
0667 GeometryIdentifier{}.withVolume(8).withLayer(8).withSensitive(2));
0668 auto vol8_lay9_sen1 = makeSurface(
0669 GeometryIdentifier{}.withVolume(8).withLayer(9).withSensitive(1));
0670
0671 TrackSelector::Config cfgVol7;
0672 cfgVol7.measurementCounter.addCounter({GeometryIdentifier{}.withVolume(7)},
0673 3);
0674 TrackSelector selectorVol7{cfgVol7};
0675
0676 auto trackVol7 = makeTrack();
0677
0678 BOOST_CHECK(!selectorVol7.isValidTrack(trackVol7));
0679
0680
0681 addMeasurement(trackVol7, vol7_lay3_sen2);
0682 addMaterial(trackVol7, vol7_lay4);
0683
0684 BOOST_CHECK(!selectorVol7.isValidTrack(trackVol7));
0685 addMeasurement(trackVol7, vol7_lay5_sen11);
0686 BOOST_CHECK(!selectorVol7.isValidTrack(trackVol7));
0687
0688
0689 addMeasurement(trackVol7, vol7_lay6_sen3);
0690 BOOST_CHECK(selectorVol7.isValidTrack(trackVol7));
0691
0692 TrackSelector::Config cfgVol8;
0693 cfgVol8.measurementCounter.addCounter({GeometryIdentifier{}.withVolume(8)},
0694 2);
0695 TrackSelector selectorVol8{cfgVol8};
0696
0697
0698 BOOST_CHECK(!selectorVol8.isValidTrack(trackVol7));
0699
0700 auto trackVol8 = makeTrack();
0701 BOOST_CHECK(!selectorVol8.isValidTrack(trackVol8));
0702
0703 addMeasurement(trackVol8, vol8_lay8_sen1);
0704 BOOST_CHECK(!selectorVol8.isValidTrack(trackVol8));
0705 addMeasurement(trackVol8, vol8_lay8_sen2);
0706 BOOST_CHECK(selectorVol8.isValidTrack(trackVol8));
0707 addMeasurement(trackVol8, vol8_lay9_sen1);
0708 BOOST_CHECK(selectorVol8.isValidTrack(trackVol8));
0709
0710 TrackSelector::Config cfgVol7Lay5;
0711 cfgVol7Lay5.measurementCounter.addCounter(
0712 {GeometryIdentifier{}.withVolume(7).withLayer(5)}, 2);
0713 TrackSelector selectorVol7Lay5{cfgVol7Lay5};
0714
0715
0716 BOOST_CHECK(!selectorVol7Lay5.isValidTrack(trackVol7));
0717 addMeasurement(trackVol7, vol7_lay5_sen12);
0718 BOOST_CHECK(selectorVol7Lay5.isValidTrack(trackVol7));
0719
0720
0721 TrackSelector::Config cfgVol7Or8;
0722 cfgVol7Or8.measurementCounter.addCounter(
0723 {GeometryIdentifier{}.withVolume(7), GeometryIdentifier{}.withVolume(8)},
0724 4);
0725 TrackSelector selectorVol7Or8{cfgVol7Or8};
0726
0727
0728
0729 BOOST_CHECK(selectorVol7Or8.isValidTrack(trackVol7));
0730
0731 BOOST_CHECK(!selectorVol7Or8.isValidTrack(trackVol8));
0732
0733
0734 addMeasurement(trackVol8, vol7_lay3_sen8);
0735
0736 BOOST_CHECK(selectorVol7Or8.isValidTrack(trackVol8));
0737
0738 TrackSelector::Config cfgVol7And8;
0739 cfgVol7And8.measurementCounter.addCounter(
0740 {GeometryIdentifier{}.withVolume(7)}, 4);
0741 cfgVol7And8.measurementCounter.addCounter(
0742 {GeometryIdentifier{}.withVolume(8)}, 2);
0743 TrackSelector selectorVol7And8{cfgVol7And8};
0744
0745
0746 BOOST_CHECK(!selectorVol7And8.isValidTrack(trackVol7));
0747
0748 addMeasurement(trackVol7, vol8_lay8_sen1);
0749 addMeasurement(trackVol7, vol8_lay8_sen2);
0750
0751 BOOST_CHECK(selectorVol7And8.isValidTrack(trackVol7));
0752 }
0753
0754 BOOST_AUTO_TEST_SUITE_END()
0755
0756 }