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