File indexing completed on 2025-07-06 07:53:27
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/tools/detail/fwd.hpp>
0010 #include <boost/test/tools/old/interface.hpp>
0011 #include <boost/test/unit_test.hpp>
0012
0013 #include "Acts/Definitions/Algebra.hpp"
0014 #include "Acts/EventData/ParticleHypothesis.hpp"
0015 #include "Acts/EventData/TrackParameters.hpp"
0016 #include "Acts/Geometry/GeometryContext.hpp"
0017 #include "Acts/Surfaces/PlaneSurface.hpp"
0018 #include "Acts/Surfaces/RectangleBounds.hpp"
0019 #include "Acts/Surfaces/Surface.hpp"
0020 #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp"
0021 #include "Acts/TrackFinding/TrackParamsLookupAccumulator.hpp"
0022 #include "Acts/Utilities/AxisDefinitions.hpp"
0023 #include "Acts/Utilities/Grid.hpp"
0024 #include "Acts/Utilities/GridAxisGenerators.hpp"
0025
0026 #include <cmath>
0027 #include <cstddef>
0028 #include <numbers>
0029 #include <optional>
0030 #include <stdexcept>
0031 #include <vector>
0032
0033 BOOST_AUTO_TEST_SUITE(TrackParamsLookupAccumulator)
0034
0035 Acts::GeometryContext gctx;
0036
0037 using Axis =
0038 Acts::Axis<Acts::AxisType::Equidistant, Acts::AxisBoundaryType::Open>;
0039 using AxisGen = Acts::GridAxisGenerators::EqOpenEqOpen;
0040
0041 using CellBound = std::pair<std::shared_ptr<Acts::BoundTrackParameters>,
0042 std::shared_ptr<Acts::BoundTrackParameters>>;
0043
0044 using GridBound = Acts::Grid<CellBound, Axis, Axis>;
0045 using AccBound = Acts::TrackParamsLookupAccumulator<GridBound>;
0046
0047 using CellFree = std::pair<std::shared_ptr<Acts::FreeTrackParameters>,
0048 std::shared_ptr<Acts::FreeTrackParameters>>;
0049
0050 using GridFree = Acts::Grid<CellFree, Axis, Axis>;
0051 using AccFree = Acts::TrackParamsLookupAccumulator<GridFree>;
0052
0053 AxisGen axisGen{{-1, 1}, 2, {-1, 1}, 2};
0054
0055 BOOST_AUTO_TEST_CASE(Exceptions) {
0056
0057 GridBound grid(axisGen());
0058 AccBound acc(grid);
0059
0060
0061 auto transform = Acts::Transform3::Identity();
0062 auto bounds1 = std::make_shared<Acts::RectangleBounds>(1, 1);
0063 auto bounds2 = std::make_shared<Acts::RectangleBounds>(2, 2);
0064
0065 auto surf1 =
0066 Acts::Surface::makeShared<Acts::PlaneSurface>(transform, bounds1);
0067
0068 auto surf2 =
0069 Acts::Surface::makeShared<Acts::PlaneSurface>(transform, bounds2);
0070
0071
0072 Acts::Vector4 pos{1, 2, 0, 4};
0073 Acts::Vector3 dir{1, 0, 0};
0074 double P = 1.;
0075
0076 auto hypothesis1 = Acts::ParticleHypothesis::electron();
0077 auto hypothesis2 = Acts::ParticleHypothesis::muon();
0078
0079 auto pars1 = Acts::BoundTrackParameters::create(gctx, surf1, pos, dir, 1. / P,
0080 std::nullopt, hypothesis1)
0081 .value();
0082
0083 auto pars2 = Acts::BoundTrackParameters::create(gctx, surf2, pos, dir, 1. / P,
0084 std::nullopt, hypothesis1)
0085 .value();
0086
0087 auto pars3 = Acts::BoundTrackParameters::create(gctx, surf1, pos, dir, 1. / P,
0088 std::nullopt, hypothesis2)
0089 .value();
0090
0091 auto pars4 = Acts::BoundTrackParameters::create(
0092 gctx, surf1, pos, dir, -1. / P, std::nullopt, hypothesis2)
0093 .value();
0094
0095
0096 auto bin = grid.localBinsFromGlobalBin(2);
0097 auto center = grid.binCenter(bin);
0098 Acts::Vector2 loc{center.at(0), center.at(1)};
0099
0100
0101 acc.addTrack(pars1, pars1, loc);
0102
0103
0104 BOOST_CHECK_THROW(acc.addTrack(pars2, pars2, loc), std::invalid_argument);
0105
0106
0107 BOOST_CHECK_THROW(acc.addTrack(pars3, pars3, loc), std::invalid_argument);
0108
0109
0110 BOOST_CHECK_THROW(acc.addTrack(pars4, pars4, loc), std::invalid_argument);
0111 }
0112
0113 BOOST_AUTO_TEST_CASE(Accumulation) {
0114
0115 GridBound gridBound(axisGen());
0116 AccBound accBound(gridBound);
0117
0118 GridFree gridFree(axisGen());
0119 AccFree accFree(gridFree);
0120
0121
0122 auto transform = Acts::Transform3::Identity();
0123 auto bounds = std::make_shared<Acts::RectangleBounds>(1, 1);
0124 auto surf = Acts::Surface::makeShared<Acts::PlaneSurface>(transform, bounds);
0125
0126 auto hypothesis = Acts::ParticleHypothesis::electron();
0127
0128 std::vector<Acts::Vector4> avgPoss;
0129 std::vector<Acts::Vector3> avgMoms;
0130 Acts::Vector4 pos{1, 2, 0, 4};
0131 for (std::size_t i = 0; i < gridBound.size(); i++) {
0132
0133 std::array<Acts::Vector4, 4> fourPositions = {pos * (i + 1), pos * (i + 2),
0134 pos * (i + 3), pos * (i + 4)};
0135
0136 std::array<double, 4> thetas = {
0137 std::numbers::pi / (i + 1), std::numbers::pi / (i + 2),
0138 std::numbers::pi / (i + 3), std::numbers::pi / (i + 4)};
0139
0140 std::array<double, 4> phis = {
0141 2 * std::numbers::pi / (i + 1), 2 * std::numbers::pi / (i + 2),
0142 2 * std::numbers::pi / (i + 3), 2 * std::numbers::pi / (i + 4)};
0143
0144 double P = 1.5 * (i + 1);
0145
0146
0147 auto bin = gridBound.localBinsFromGlobalBin(i);
0148 auto center = gridBound.binCenter(bin);
0149 Acts::Vector2 loc{center.at(0), center.at(1)};
0150
0151
0152 Acts::Vector4 avgPos{0, 0, 0, 0};
0153 Acts::Vector3 avgMom{0, 0, 0};
0154 for (std::size_t j = 0; j < 4; j++) {
0155 Acts::Vector3 direction{std::sin(thetas.at(j)) * std::cos(phis.at(j)),
0156 std::sin(thetas.at(j)) * std::sin(phis.at(j)),
0157 std::cos(thetas.at(j))};
0158
0159 avgPos += fourPositions.at(j);
0160 avgMom += P * direction;
0161
0162
0163 auto parsBound = Acts::BoundTrackParameters::create(
0164 gctx, surf, fourPositions.at(j), direction, 1. / P,
0165 std::nullopt, hypothesis)
0166 .value();
0167
0168 auto parsFree = Acts::FreeTrackParameters(
0169 fourPositions.at(j), direction, 1. / P, std::nullopt, hypothesis);
0170
0171 accBound.addTrack(parsBound, parsBound, loc);
0172 accFree.addTrack(parsFree, parsFree, loc);
0173 }
0174 avgPoss.push_back(avgPos / fourPositions.size());
0175 avgMoms.push_back(avgMom / fourPositions.size());
0176 }
0177
0178
0179 GridBound avgGridBound = accBound.finalizeLookup();
0180 GridFree avgGridFree = accFree.finalizeLookup();
0181 for (std::size_t i = 0; i < avgGridBound.size(); i++) {
0182 auto [ipBound, refBound] = avgGridBound.at(i);
0183 auto [ipFree, refFree] = avgGridFree.at(i);
0184
0185 Acts::Vector4 avgPos = avgPoss.at(i);
0186
0187 Acts::Vector3 avgMom = avgMoms.at(i);
0188 Acts::Vector3 avgDir = avgMom.normalized();
0189 double avgP = avgMom.norm();
0190
0191 CHECK_CLOSE_ABS(ipBound->fourPosition(gctx), avgPos, 1e-3);
0192 CHECK_CLOSE_ABS(ipBound->direction(), avgDir, 1e-3);
0193 CHECK_CLOSE_ABS(ipBound->absoluteMomentum(), avgP, 1e-3);
0194
0195 CHECK_CLOSE_ABS(ipFree->fourPosition(), avgPos, 1e-3);
0196 CHECK_CLOSE_ABS(ipFree->direction(), avgDir, 1e-3);
0197 CHECK_CLOSE_ABS(ipFree->absoluteMomentum(), avgP, 1e-3);
0198 }
0199 }
0200
0201 BOOST_AUTO_TEST_SUITE_END()