File indexing completed on 2025-01-18 09:12:49
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/unit_test.hpp>
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Definitions/TrackParametrization.hpp"
0013 #include "Acts/Definitions/Units.hpp"
0014 #include "Acts/EventData/TrackParameters.hpp"
0015 #include "Acts/EventData/detail/TestSourceLink.hpp"
0016 #include "Acts/Geometry/GeometryContext.hpp"
0017 #include "Acts/Geometry/GeometryIdentifier.hpp"
0018 #include "Acts/Geometry/LayerCreator.hpp"
0019 #include "Acts/Geometry/TrackingGeometry.hpp"
0020 #include "Acts/MagneticField/ConstantBField.hpp"
0021 #include "Acts/MagneticField/MagneticFieldContext.hpp"
0022 #include "Acts/Propagator/EigenStepper.hpp"
0023 #include "Acts/Propagator/Navigator.hpp"
0024 #include "Acts/Propagator/Propagator.hpp"
0025 #include "Acts/Seeding/EstimateTrackParamsFromSeed.hpp"
0026 #include "Acts/Surfaces/Surface.hpp"
0027 #include "Acts/Tests/CommonHelpers/CylindricalTrackingGeometry.hpp"
0028 #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp"
0029 #include "Acts/Tests/CommonHelpers/MeasurementsCreator.hpp"
0030 #include "Acts/Utilities/Logger.hpp"
0031
0032 #include <algorithm>
0033 #include <array>
0034 #include <cmath>
0035 #include <iterator>
0036 #include <map>
0037 #include <memory>
0038 #include <optional>
0039 #include <random>
0040 #include <utility>
0041 #include <vector>
0042
0043 #include "SpacePoint.hpp"
0044
0045 namespace {
0046
0047 using namespace Acts;
0048 using namespace Acts::Test;
0049 using namespace Acts::UnitLiterals;
0050
0051 using ConstantFieldStepper = Acts::EigenStepper<>;
0052 using ConstantFieldPropagator =
0053 Acts::Propagator<ConstantFieldStepper, Acts::Navigator>;
0054
0055 const GeometryContext geoCtx;
0056 const MagneticFieldContext magCtx;
0057
0058
0059 CylindricalTrackingGeometry geometryStore(geoCtx);
0060 const auto geometry = geometryStore();
0061
0062
0063 const MeasurementResolutionMap resolutions = {
0064 {GeometryIdentifier(),
0065 MeasurementResolution{MeasurementType::eLoc01, {0, 0}}}};
0066
0067
0068 CurvilinearTrackParameters makeParameters(double phi, double theta, double p,
0069 double q) {
0070
0071 Acts::BoundVector stddev;
0072 stddev[Acts::eBoundLoc0] = 100_um;
0073 stddev[Acts::eBoundLoc1] = 100_um;
0074 stddev[Acts::eBoundTime] = 25_ns;
0075 stddev[Acts::eBoundPhi] = 2_degree;
0076 stddev[Acts::eBoundTheta] = 2_degree;
0077 stddev[Acts::eBoundQOverP] = 1 / 100_GeV;
0078 BoundSquareMatrix cov = stddev.cwiseProduct(stddev).asDiagonal();
0079
0080 Vector4 mPos4(0., 0., 0., 0.);
0081 return CurvilinearTrackParameters(mPos4, phi, theta, q / p, cov,
0082 ParticleHypothesis::pionLike(std::abs(q)));
0083 }
0084
0085 std::default_random_engine rng(42);
0086
0087 }
0088
0089 BOOST_AUTO_TEST_CASE(trackparameters_estimation_test) {
0090
0091
0092 Acts::Navigator navigator({
0093 geometry,
0094 true,
0095 true,
0096 false
0097 });
0098 const Vector3 bField(0, 0, 2._T);
0099 auto field = std::make_shared<Acts::ConstantBField>(bField);
0100 ConstantFieldStepper stepper(std::move(field));
0101
0102 ConstantFieldPropagator propagator(std::move(stepper), std::move(navigator));
0103
0104 std::array<double, 2> pArray = {0.5_GeV, 1.0_GeV};
0105 std::array<double, 3> phiArray = {20._degree, 0._degree - 20._degree};
0106 std::array<double, 3> thetaArray = {80._degree, 90.0_degree, 100._degree};
0107 std::array<double, 2> qArray = {1, -1};
0108
0109 auto logger = Acts::getDefaultLogger("estimateTrackParamsFromSeed",
0110 Acts::Logging::INFO);
0111
0112 for (const auto& p : pArray) {
0113 for (const auto& phi : phiArray) {
0114 for (const auto& theta : thetaArray) {
0115 for (const auto& q : qArray) {
0116 BOOST_TEST_INFO("Test track with p = " << p << ", phi = " << phi
0117 << ", theta = " << theta
0118 << ", q = " << q);
0119 auto start = makeParameters(phi, theta, p, q);
0120 auto measurements = createMeasurements(propagator, geoCtx, magCtx,
0121 start, resolutions, rng);
0122
0123
0124 std::map<GeometryIdentifier::Value, SpacePoint> spacePoints;
0125 const Surface* bottomSurface = nullptr;
0126 for (const auto& sl : measurements.sourceLinks) {
0127 const auto geoId = sl.m_geometryId;
0128 const auto& layer = geoId.layer();
0129 auto it = spacePoints.find(layer);
0130
0131 if (it != spacePoints.end()) {
0132 continue;
0133 }
0134 const auto surface = geometry->findSurface(geoId);
0135 const auto& localPos = sl.parameters;
0136 Vector3 globalFakeMom(1, 1, 1);
0137 Vector3 globalPos =
0138 surface->localToGlobal(geoCtx, localPos, globalFakeMom);
0139
0140
0141 float r = std::hypot(globalPos.x(), globalPos.y());
0142 spacePoints.emplace(
0143 layer, SpacePoint{static_cast<float>(globalPos.x()),
0144 static_cast<float>(globalPos.y()),
0145 static_cast<float>(globalPos.z()), r,
0146 static_cast<int>(geoId.layer()), 0., 0.,
0147 std::nullopt, std::nullopt});
0148 if (spacePoints.size() == 1) {
0149 bottomSurface = surface;
0150 }
0151 }
0152
0153
0154 if (spacePoints.size() < 3) {
0155 BOOST_TEST_WARN("Number of space points less than 3.");
0156 continue;
0157 }
0158
0159
0160 const auto& expParams = measurements.truthParameters[0];
0161 BOOST_TEST_INFO(
0162 "The truth track parameters at the bottom space point: \n"
0163 << expParams.transpose());
0164
0165
0166 std::array<const SpacePoint*, 3> spacePointPtrs{};
0167 std::transform(spacePoints.begin(), std::next(spacePoints.begin(), 3),
0168 spacePointPtrs.begin(),
0169 [](const auto& sp) { return &sp.second; });
0170
0171
0172 FreeVector estFreeParams =
0173 estimateTrackParamsFromSeed(spacePointPtrs, bField);
0174 BOOST_CHECK(!estFreeParams.hasNaN());
0175
0176
0177 auto estFullParamsResult = estimateTrackParamsFromSeed(
0178 geoCtx, spacePointPtrs, *bottomSurface, bField);
0179 BOOST_CHECK(estFullParamsResult.ok());
0180 const auto& estFullParams = estFullParamsResult.value();
0181 BOOST_TEST_INFO(
0182 "The estimated full track parameters at the bottom space point: "
0183 "\n"
0184 << estFullParams.transpose());
0185
0186 CHECK_CLOSE_ABS(estFullParams[eBoundLoc0], expParams[eBoundLoc0],
0187 1e-5);
0188 CHECK_CLOSE_ABS(estFullParams[eBoundLoc1], expParams[eBoundLoc1],
0189 1e-5);
0190
0191 CHECK_CLOSE_ABS(estFullParams[eBoundPhi], expParams[eBoundPhi], 1e-1);
0192 CHECK_CLOSE_ABS(estFullParams[eBoundTheta], expParams[eBoundTheta],
0193 1e-2);
0194 CHECK_CLOSE_ABS(estFullParams[eBoundQOverP], expParams[eBoundQOverP],
0195 1e-2);
0196
0197 CHECK_CLOSE_ABS(estFullParams[eBoundTime], 0, 1e-6);
0198 }
0199 }
0200 }
0201 }
0202 }