File indexing completed on 2025-08-06 08:11:37
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/data/test_case.hpp>
0010 #include <boost/test/tools/output_test_stream.hpp>
0011 #include <boost/test/unit_test.hpp>
0012
0013 #include "Acts/Definitions/Algebra.hpp"
0014 #include "Acts/Definitions/Direction.hpp"
0015 #include "Acts/Definitions/TrackParametrization.hpp"
0016 #include "Acts/Definitions/Units.hpp"
0017 #include "Acts/EventData/GenericBoundTrackParameters.hpp"
0018 #include "Acts/EventData/TrackParameters.hpp"
0019 #include "Acts/Geometry/GeometryContext.hpp"
0020 #include "Acts/Geometry/GeometryIdentifier.hpp"
0021 #include "Acts/MagneticField/ConstantBField.hpp"
0022 #include "Acts/MagneticField/MagneticFieldContext.hpp"
0023 #include "Acts/Propagator/EigenStepper.hpp"
0024 #include "Acts/Propagator/Propagator.hpp"
0025 #include "Acts/Surfaces/PerigeeSurface.hpp"
0026 #include "Acts/Surfaces/Surface.hpp"
0027 #include "Acts/Utilities/Result.hpp"
0028 #include "Acts/Vertexing/HelicalTrackLinearizer.hpp"
0029 #include "Acts/Vertexing/ImpactPointEstimator.hpp"
0030 #include "Acts/Vertexing/KalmanVertexUpdater.hpp"
0031 #include "Acts/Vertexing/LinearizedTrack.hpp"
0032 #include "Acts/Vertexing/TrackAtVertex.hpp"
0033 #include "Acts/Vertexing/Vertex.hpp"
0034
0035 #include <algorithm>
0036 #include <array>
0037 #include <cmath>
0038 #include <iostream>
0039 #include <memory>
0040 #include <optional>
0041 #include <random>
0042 #include <tuple>
0043 #include <type_traits>
0044 #include <utility>
0045 #include <vector>
0046
0047 namespace bdata = boost::unit_test::data;
0048 using namespace Acts::UnitLiterals;
0049
0050 namespace Acts::Test {
0051
0052 using Covariance = BoundSquareMatrix;
0053 using Propagator = Acts::Propagator<EigenStepper<>>;
0054 using Linearizer = HelicalTrackLinearizer;
0055
0056
0057 GeometryContext geoContext = GeometryContext();
0058 MagneticFieldContext magFieldContext = MagneticFieldContext();
0059
0060
0061 std::uniform_real_distribution<double> vXYDist(-0.1_mm, 0.1_mm);
0062
0063 std::uniform_real_distribution<double> vZDist(-20_mm, 20_mm);
0064
0065 std::uniform_real_distribution<double> d0Dist(-0.01_mm, 0.01_mm);
0066
0067 std::uniform_real_distribution<double> z0Dist(-0.2_mm, 0.2_mm);
0068
0069 std::uniform_real_distribution<double> pTDist(0.4_GeV, 10_GeV);
0070
0071 std::uniform_real_distribution<double> phiDist(-M_PI, M_PI);
0072
0073 std::uniform_real_distribution<double> thetaDist(1.0, M_PI - 1.0);
0074
0075 std::uniform_real_distribution<double> qDist(-1, 1);
0076
0077 std::uniform_real_distribution<double> resIPDist(0., 100_um);
0078
0079 std::uniform_real_distribution<double> resAngDist(0., 0.1);
0080
0081 std::uniform_real_distribution<double> resQoPDist(-0.01, 0.01);
0082
0083
0084
0085
0086
0087 BOOST_AUTO_TEST_CASE(Kalman_Vertex_Updater) {
0088 bool debug = false;
0089
0090
0091 unsigned int nTests = 10;
0092
0093
0094 int mySeed = 31415;
0095 std::mt19937 gen(mySeed);
0096
0097
0098 auto bField = std::make_shared<ConstantBField>(Vector3{0.0, 0.0, 1_T});
0099
0100
0101 EigenStepper<> stepper(bField);
0102
0103
0104 auto propagator = std::make_shared<Propagator>(stepper);
0105
0106
0107 Linearizer::Config ltConfig;
0108 ltConfig.bField = bField;
0109 ltConfig.propagator = propagator;
0110 Linearizer linearizer(ltConfig);
0111 auto fieldCache = bField->makeCache(magFieldContext);
0112
0113
0114 std::shared_ptr<PerigeeSurface> perigeeSurface =
0115 Surface::makeShared<PerigeeSurface>(Vector3(0., 0., 0.));
0116
0117
0118
0119
0120 for (unsigned int i = 0; i < nTests; ++i) {
0121 if (debug) {
0122 std::cout << "Test " << i + 1 << std::endl;
0123 }
0124
0125 double q = qDist(gen) < 0 ? -1. : 1.;
0126
0127
0128 BoundTrackParameters::ParametersVector paramVec;
0129
0130 paramVec << d0Dist(gen), z0Dist(gen), phiDist(gen), thetaDist(gen),
0131 q / pTDist(gen), 0.;
0132
0133 if (debug) {
0134 std::cout << "Creating track parameters: " << paramVec << std::endl;
0135 }
0136
0137
0138 Covariance covMat;
0139
0140
0141 double res_d0 = resIPDist(gen);
0142 double res_z0 = resIPDist(gen);
0143 double res_ph = resAngDist(gen);
0144 double res_th = resAngDist(gen);
0145 double res_qp = resQoPDist(gen);
0146
0147 covMat << res_d0 * res_d0, 0., 0., 0., 0., 0., 0., res_z0 * res_z0, 0., 0.,
0148 0., 0., 0., 0., res_ph * res_ph, 0., 0., 0., 0., 0., 0.,
0149 res_th * res_th, 0., 0., 0., 0., 0., 0., res_qp * res_qp, 0., 0., 0.,
0150 0., 0., 0., 1.;
0151 BoundTrackParameters params(perigeeSurface, paramVec, std::move(covMat),
0152 ParticleHypothesis::pion());
0153
0154 std::shared_ptr<PerigeeSurface> perigee =
0155 Surface::makeShared<PerigeeSurface>(Vector3::Zero());
0156
0157
0158 LinearizedTrack linTrack =
0159 linearizer
0160 .linearizeTrack(params, 0, *perigee, geoContext, magFieldContext,
0161 fieldCache)
0162 .value();
0163
0164
0165 TrackAtVertex trkAtVtx(0., params, InputTrack{¶ms});
0166
0167
0168 trkAtVtx.linearizedState = linTrack;
0169 trkAtVtx.isLinearized = true;
0170
0171
0172 Vector3 vtxPos(vXYDist(gen), vXYDist(gen), vZDist(gen));
0173 Vertex vtx(vtxPos);
0174 vtx.setFullCovariance(SquareMatrix4::Identity() * 0.01);
0175
0176
0177 KalmanVertexUpdater::updateVertexWithTrack(vtx, trkAtVtx, 3);
0178
0179 if (debug) {
0180 std::cout << "Old vertex position: " << vtxPos << std::endl;
0181 std::cout << "New vertex position: " << vtx.position() << std::endl;
0182 }
0183
0184 double oldDistance = vtxPos.norm();
0185 double newDistance = vtx.position().norm();
0186
0187 if (debug) {
0188 std::cout << "Old distance: " << oldDistance << std::endl;
0189 std::cout << "New distance: " << newDistance << std::endl;
0190 }
0191
0192
0193 BOOST_CHECK_LT(newDistance, oldDistance);
0194
0195
0196
0197
0198
0199 BOOST_CHECK(vtx.tracks().empty());
0200
0201 }
0202
0203 }
0204
0205
0206
0207
0208 BOOST_AUTO_TEST_CASE(Kalman_Vertex_TrackUpdater) {
0209 bool debug = true;
0210
0211
0212 unsigned int nTests = 10;
0213
0214
0215 int mySeed = 31415;
0216 std::mt19937 gen(mySeed);
0217
0218
0219 auto bField = std::make_shared<ConstantBField>(Vector3{0.0, 0.0, 1_T});
0220
0221
0222 EigenStepper<> stepper(bField);
0223
0224
0225 auto propagator = std::make_shared<Propagator>(stepper);
0226
0227
0228 ImpactPointEstimator::Config ip3dEstConfig(bField, propagator);
0229 ImpactPointEstimator ip3dEst(ip3dEstConfig);
0230 ImpactPointEstimator::State state{bField->makeCache(magFieldContext)};
0231
0232
0233
0234 Linearizer::Config ltConfig;
0235 ltConfig.bField = bField;
0236 ltConfig.propagator = propagator;
0237 Linearizer linearizer(ltConfig);
0238 auto fieldCache = bField->makeCache(magFieldContext);
0239
0240
0241 std::shared_ptr<PerigeeSurface> perigeeSurface =
0242 Surface::makeShared<PerigeeSurface>(Vector3(0., 0., 0.));
0243
0244
0245
0246
0247
0248 for (unsigned int i = 0; i < nTests; ++i) {
0249
0250 double q = qDist(gen) < 0 ? -1. : 1.;
0251
0252
0253 BoundTrackParameters::ParametersVector paramVec;
0254
0255 paramVec << d0Dist(gen), z0Dist(gen), phiDist(gen), thetaDist(gen),
0256 q / pTDist(gen), 0.;
0257
0258 if (debug) {
0259 std::cout << "Creating track parameters: " << paramVec << std::endl;
0260 }
0261
0262
0263 Covariance covMat;
0264
0265
0266 double res_d0 = resIPDist(gen);
0267 double res_z0 = resIPDist(gen);
0268 double res_ph = resAngDist(gen);
0269 double res_th = resAngDist(gen);
0270 double res_qp = resQoPDist(gen);
0271
0272 covMat << res_d0 * res_d0, 0., 0., 0., 0., 0., 0., res_z0 * res_z0, 0., 0.,
0273 0., 0., 0., 0., res_ph * res_ph, 0., 0., 0., 0., 0., 0.,
0274 res_th * res_th, 0., 0., 0., 0., 0., 0., res_qp * res_qp, 0., 0., 0.,
0275 0., 0., 0., 1.;
0276 BoundTrackParameters params(perigeeSurface, paramVec, std::move(covMat),
0277 ParticleHypothesis::pion());
0278
0279 std::shared_ptr<PerigeeSurface> perigee =
0280 Surface::makeShared<PerigeeSurface>(Vector3::Zero());
0281
0282
0283 LinearizedTrack linTrack =
0284 linearizer
0285 .linearizeTrack(params, 0, *perigee, geoContext, magFieldContext,
0286 fieldCache)
0287 .value();
0288
0289
0290 TrackAtVertex trkAtVtx(0., params, InputTrack{¶ms});
0291
0292
0293 trkAtVtx.linearizedState = linTrack;
0294 trkAtVtx.isLinearized = true;
0295
0296
0297 auto fittedParamsCopy = trkAtVtx.fittedParams;
0298
0299
0300 Vector3 vtxPos(vXYDist(gen), vXYDist(gen), vZDist(gen));
0301 Vertex vtx(vtxPos);
0302
0303
0304 KalmanVertexUpdater::updateTrackWithVertex(trkAtVtx, vtx, 3);
0305
0306
0307 double oldDistance =
0308 ip3dEst.calculateDistance(geoContext, fittedParamsCopy, vtxPos, state)
0309 .value();
0310
0311
0312 double newDistance =
0313 ip3dEst
0314 .calculateDistance(geoContext, trkAtVtx.fittedParams, vtxPos, state)
0315 .value();
0316 if (debug) {
0317 std::cout << "Old distance: " << oldDistance << std::endl;
0318 std::cout << "New distance: " << newDistance << std::endl;
0319 }
0320
0321
0322 BOOST_CHECK_NE(fittedParamsCopy, trkAtVtx.fittedParams);
0323
0324
0325 BOOST_CHECK_LT(newDistance, oldDistance);
0326
0327 }
0328
0329 }
0330
0331 }