File indexing completed on 2026-11-08 09:25:38
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/data/test_case.hpp>
0010 #include <boost/test/tools/context.hpp>
0011 #include <boost/test/unit_test.hpp>
0012
0013 #include "Acts/Definitions/TrackParametrization.hpp"
0014 #include "Acts/EventData/MultiTrajectory.hpp"
0015 #include "Acts/EventData/ProxyAccessor.hpp"
0016 #include "Acts/EventData/TrackContainer.hpp"
0017 #include "Acts/EventData/TrackStatePropMask.hpp"
0018 #include "Acts/EventData/TrackStateType.hpp"
0019 #include "Acts/EventData/VectorMultiTrajectory.hpp"
0020 #include "Acts/EventData/VectorTrackContainer.hpp"
0021 #include "Acts/EventData/detail/MultiTrajectoryTestsCommon.hpp"
0022 #include "Acts/EventData/detail/TestTrackState.hpp"
0023 #include "Acts/Geometry/GeometryContext.hpp"
0024
0025 #include <random>
0026 #include <string>
0027 #include <type_traits>
0028 #include <utility>
0029
0030 namespace {
0031
0032 using namespace Acts;
0033 using namespace Acts::UnitLiterals;
0034 using namespace Acts::detail::Test;
0035 using namespace Acts::HashedStringLiteral;
0036 namespace bd = boost::unit_test::data;
0037
0038 using ParametersVector = BoundVector;
0039 using CovarianceMatrix = BoundMatrix;
0040 using Jacobian = BoundMatrix;
0041
0042 const auto gctx = GeometryContext::dangerouslyDefaultConstruct();
0043
0044 std::default_random_engine rng(31415);
0045
0046 struct Factory {
0047 using trajectory_t = VectorMultiTrajectory;
0048 using const_trajectory_t = ConstVectorMultiTrajectory;
0049
0050 VectorMultiTrajectory create() { return {}; }
0051 ConstVectorMultiTrajectory createConst() { return {}; }
0052 };
0053
0054 using CommonTests = MultiTrajectoryTestsCommon<Factory>;
0055
0056 }
0057
0058 namespace ActsTests {
0059
0060 BOOST_AUTO_TEST_SUITE(EventDataSuite)
0061
0062 BOOST_AUTO_TEST_CASE(Build) {
0063 CommonTests ct;
0064 ct.testBuild();
0065 }
0066
0067 BOOST_AUTO_TEST_CASE(TrackStateTypeIsReadOnly) {
0068 static_assert(!TrackStateType::IsReadOnly);
0069 static_assert(ConstTrackStateTypeMap::IsReadOnly);
0070 static_assert(!MutableTrackStateTypeMap::IsReadOnly);
0071 }
0072
0073 BOOST_AUTO_TEST_CASE(TrackStateTypeSharedSplitExclusive) {
0074 TrackStateType type;
0075
0076 type.setIsSharedHit();
0077 BOOST_CHECK(type.hasMeasurement());
0078 BOOST_CHECK(type.isSharedHit());
0079 BOOST_CHECK(!type.isSplitHit());
0080
0081 type.setIsSplitHit();
0082 BOOST_CHECK(type.hasMeasurement());
0083 BOOST_CHECK(type.isSplitHit());
0084 BOOST_CHECK(!type.isSharedHit());
0085
0086 type.setIsSharedHit();
0087 BOOST_CHECK(type.isSharedHit());
0088 BOOST_CHECK(!type.isSplitHit());
0089
0090 type.setIsSplitHit();
0091 type.setIsHole();
0092 BOOST_CHECK(type.isHole());
0093 BOOST_CHECK(!type.isSplitHit());
0094 BOOST_CHECK(!type.isSharedHit());
0095 }
0096
0097 BOOST_AUTO_TEST_CASE(ConstCorrectness) {
0098
0099 VectorMultiTrajectory t;
0100 auto i0 = t.addTrackState();
0101
0102 BOOST_CHECK(!IsReadOnlyMultiTrajectory<decltype(t)>::value);
0103
0104 {
0105 VectorMultiTrajectory::TrackStateProxy tsp = t.getTrackState(i0);
0106 static_cast<void>(tsp);
0107 VectorMultiTrajectory::ConstTrackStateProxy ctsp{t.getTrackState(i0)};
0108 static_cast<void>(ctsp);
0109
0110 tsp.predicted().setRandom();
0111
0112
0113
0114 }
0115
0116
0117 ConstVectorMultiTrajectory ct{t};
0118 BOOST_CHECK_EQUAL(ct.size(), t.size());
0119
0120 ConstVectorMultiTrajectory ctm{std::move(t)};
0121 BOOST_CHECK_EQUAL(ctm.size(), ct.size());
0122
0123 {
0124 static_assert(
0125 std::is_same_v<ConstVectorMultiTrajectory::ConstTrackStateProxy,
0126 decltype(ctm.getTrackState(i0))>,
0127 "Got mutable track state proxy");
0128 ConstVectorMultiTrajectory::ConstTrackStateProxy ctsp =
0129 ctm.getTrackState(i0);
0130 static_cast<void>(ctsp);
0131
0132
0133
0134 }
0135
0136
0137
0138
0139 }
0140
0141 BOOST_AUTO_TEST_CASE(ConstMutableRoundTrip) {
0142 VectorMultiTrajectory mtj;
0143 mtj.template addColumn<int>("extra_column");
0144
0145 TestTrackState pc(rng, 2u);
0146 auto ts = mtj.getTrackState(
0147 mtj.addTrackState(TrackStatePropMask::All, kTrackIndexInvalid));
0148 fillTrackState<VectorMultiTrajectory>(pc, TrackStatePropMask::All, ts);
0149 ts.template component<int>("extra_column") = 42;
0150
0151 ConstVectorMultiTrajectory cmtj{mtj};
0152
0153
0154 VectorMultiTrajectory roundTripped{cmtj};
0155 BOOST_CHECK_EQUAL(roundTripped.size(), mtj.size());
0156
0157 auto orig = mtj.getTrackState(ts.index());
0158 auto copy = roundTripped.getTrackState(ts.index());
0159
0160 BOOST_CHECK_EQUAL(copy.predicted(), orig.predicted());
0161 BOOST_CHECK_EQUAL(copy.predictedCovariance(), orig.predictedCovariance());
0162 BOOST_CHECK_EQUAL(copy.filtered(), orig.filtered());
0163 BOOST_CHECK_EQUAL(copy.smoothed(), orig.smoothed());
0164 BOOST_CHECK_EQUAL(copy.jacobian(), orig.jacobian());
0165 BOOST_CHECK_EQUAL(copy.chi2(), orig.chi2());
0166 BOOST_CHECK_EQUAL(copy.pathLength(), orig.pathLength());
0167 BOOST_CHECK_EQUAL(©.referenceSurface(), &orig.referenceSurface());
0168 BOOST_CHECK(copy.hasUncalibratedSourceLink());
0169 BOOST_CHECK_EQUAL((copy.template component<int>("extra_column")),
0170 (orig.template component<int>("extra_column")));
0171
0172
0173 copy.chi2() = orig.chi2() + 1.0f;
0174 BOOST_CHECK_NE(copy.chi2(), orig.chi2());
0175 }
0176
0177 BOOST_AUTO_TEST_CASE(Clear) {
0178 CommonTests ct;
0179 ct.testClear();
0180 }
0181
0182 BOOST_AUTO_TEST_CASE(ApplyWithAbort) {
0183 CommonTests ct;
0184 ct.testApplyWithAbort();
0185 }
0186
0187 BOOST_AUTO_TEST_CASE(AddTrackStateWithBitMask) {
0188 CommonTests ct;
0189 ct.testAddTrackStateWithBitMask();
0190 }
0191
0192 BOOST_AUTO_TEST_CASE(AddTrackStateComponents) {
0193 CommonTests ct;
0194 ct.testAddTrackStateComponents();
0195 }
0196
0197 BOOST_AUTO_TEST_CASE(AddTrackStateComponentsAfterShareAndUnset) {
0198 CommonTests ct;
0199 ct.testAddTrackStateComponentsAfterShareAndUnset();
0200 }
0201
0202
0203 BOOST_AUTO_TEST_CASE(TrackStateProxyCrossTalk) {
0204 CommonTests ct;
0205 ct.testTrackStateProxyCrossTalk(rng);
0206 }
0207
0208 BOOST_AUTO_TEST_CASE(TrackStateReassignment) {
0209 CommonTests ct;
0210 ct.testTrackStateReassignment(rng);
0211 }
0212
0213 BOOST_DATA_TEST_CASE(TrackStateProxyStorage, bd::make({1u, 2u}),
0214 nMeasurements) {
0215 CommonTests ct;
0216 ct.testTrackStateProxyStorage(rng, nMeasurements);
0217 }
0218
0219 BOOST_AUTO_TEST_CASE(TrackStateProxyAllocations) {
0220 CommonTests ct;
0221 ct.testTrackStateProxyAllocations(rng);
0222 }
0223
0224 BOOST_AUTO_TEST_CASE(TrackStateProxyGetMask) {
0225 CommonTests ct;
0226 ct.testTrackStateProxyGetMask();
0227 }
0228
0229 BOOST_AUTO_TEST_CASE(TrackStateProxyCopy) {
0230 CommonTests ct;
0231 ct.testTrackStateProxyCopy(rng);
0232 }
0233
0234 BOOST_AUTO_TEST_CASE(TrackStateCopyDynamicColumns) {
0235 CommonTests ct;
0236 ct.testTrackStateCopyDynamicColumns();
0237 }
0238
0239 BOOST_AUTO_TEST_CASE(TrackStateProxyCopyDiffMTJ) {
0240 CommonTests ct;
0241 ct.testTrackStateProxyCopyDiffMTJ();
0242 }
0243
0244 BOOST_AUTO_TEST_CASE(ProxyAssignment) {
0245 CommonTests ct;
0246 ct.testProxyAssignment();
0247 }
0248
0249 BOOST_AUTO_TEST_CASE(CopyFromConst) {
0250 CommonTests ct;
0251 ct.testCopyFromConst();
0252 }
0253
0254 BOOST_AUTO_TEST_CASE(TrackStateProxyShare) {
0255 CommonTests ct;
0256 ct.testTrackStateProxyShare(rng);
0257 }
0258
0259 BOOST_AUTO_TEST_CASE(MultiTrajectoryExtraColumns) {
0260 CommonTests ct;
0261 ct.testMultiTrajectoryExtraColumns();
0262 }
0263
0264 BOOST_AUTO_TEST_CASE(MultiTrajectoryExtraColumnsRuntime) {
0265 CommonTests ct;
0266 ct.testMultiTrajectoryExtraColumnsRuntime();
0267 }
0268
0269 BOOST_AUTO_TEST_CASE(MultiTrajectoryAllocateCalibratedInit) {
0270 CommonTests ct;
0271 ct.testMultiTrajectoryAllocateCalibratedInit(rng);
0272 }
0273
0274 BOOST_AUTO_TEST_CASE(MemoryStats) {
0275 using namespace boost::histogram;
0276 using cat = axis::category<std::string>;
0277
0278 VectorMultiTrajectory mt;
0279
0280 auto stats = mt.statistics();
0281
0282 std::stringstream ss;
0283 stats.toStream(ss);
0284 std::string out = ss.str();
0285 BOOST_CHECK(!out.empty());
0286 BOOST_CHECK_NE(out.find("total"), std::string::npos);
0287
0288 const auto& h = stats.hist;
0289
0290 auto column_axis = axis::get<cat>(h.axis(0));
0291 auto type_axis = axis::get<axis::category<>>(h.axis(1));
0292
0293 for (int t = 0; t < type_axis.size(); t++) {
0294 for (int c = 0; c < column_axis.size(); c++) {
0295 double v = h.at(c, t);
0296 BOOST_CHECK_EQUAL(v, 0.0);
0297 }
0298 }
0299
0300 TestTrackState pc(rng, 2u);
0301 auto ts = mt.makeTrackState();
0302 fillTrackState<VectorMultiTrajectory>(pc, TrackStatePropMask::All, ts);
0303
0304 stats = mt.statistics();
0305
0306 for (int t = 0; t < type_axis.size(); t++) {
0307 BOOST_TEST_CONTEXT((type_axis.bin(t) == 1 ? "meas" : "other"))
0308 for (int c = 0; c < column_axis.size(); c++) {
0309 std::string key = column_axis.bin(c);
0310 BOOST_TEST_CONTEXT("column: " << key) {
0311 double v = h.at(c, t);
0312 if (t == 0) {
0313 BOOST_CHECK_NE(v, 0.0);
0314 } else {
0315 BOOST_CHECK_EQUAL(v, 0.0);
0316 }
0317 }
0318 }
0319 }
0320 }
0321
0322 BOOST_AUTO_TEST_CASE(Accessors) {
0323 VectorMultiTrajectory mtj;
0324 mtj.addColumn<unsigned int>("ndof");
0325 mtj.addColumn<double>("super_chi2");
0326
0327 auto ts = mtj.makeTrackState();
0328
0329 ProxyAccessor<unsigned int> ndof("ndof");
0330 ConstProxyAccessor<unsigned int> ndofConst("ndof");
0331 ProxyAccessor<double> superChi2("super_chi2");
0332 ConstProxyAccessor<double> superChi2Const("super_chi2");
0333
0334 ndof(ts) = 65;
0335 BOOST_CHECK_EQUAL((ts.component<unsigned int, "ndof"_hash>()), 65);
0336 BOOST_CHECK_EQUAL(ndofConst(ts), 65);
0337
0338
0339
0340
0341 superChi2(ts) = 123.45;
0342 BOOST_CHECK_EQUAL((ts.component<double, "super_chi2"_hash>()), 123.45);
0343 BOOST_CHECK_EQUAL(superChi2Const(ts), 123.45);
0344
0345
0346
0347 }
0348
0349 BOOST_AUTO_TEST_CASE(ChangeSourceLinkType) {
0350 VectorMultiTrajectory mtj;
0351 auto ts = mtj.makeTrackState();
0352
0353 int value = 5;
0354 ts.setUncalibratedSourceLink(SourceLink{value});
0355
0356 BOOST_CHECK_EQUAL(ts.getUncalibratedSourceLink().get<int>(), value);
0357 BOOST_CHECK_THROW(ts.getUncalibratedSourceLink().get<double>(),
0358 std::bad_any_cast);
0359
0360 double otherValue = 42.42;
0361
0362
0363 ts.setUncalibratedSourceLink(SourceLink{otherValue});
0364 BOOST_CHECK_EQUAL(ts.getUncalibratedSourceLink().get<double>(), otherValue);
0365 BOOST_CHECK_THROW(ts.getUncalibratedSourceLink().get<int>(),
0366 std::bad_any_cast);
0367 }
0368
0369 BOOST_AUTO_TEST_CASE(EnsureDynamicColumnsCopyOnTrackState) {
0370 TrackContainer source{VectorTrackContainer{}, VectorMultiTrajectory{}};
0371 source.trackStateContainer().template addColumn<std::uint64_t>("counter");
0372 source.trackStateContainer().template addColumn<std::uint8_t>("odd");
0373
0374 auto sourceTrack = source.makeTrack();
0375 auto sourceState = sourceTrack.appendTrackState();
0376 sourceState.template component<std::uint64_t>("counter") = 42;
0377 sourceState.template component<std::uint8_t>("odd") = 1;
0378
0379 TrackContainer target{VectorTrackContainer{}, VectorMultiTrajectory{}};
0380 target.ensureDynamicColumns(source);
0381
0382 BOOST_CHECK(target.trackStateContainer().hasColumn(hashString("counter")));
0383 BOOST_CHECK(target.trackStateContainer().hasColumn(hashString("odd")));
0384
0385 auto targetTrack = target.makeTrack();
0386 auto targetState = targetTrack.appendTrackState();
0387 targetState.copyFrom(sourceState);
0388
0389 BOOST_CHECK_EQUAL(targetState.template component<std::uint64_t>("counter"),
0390 sourceState.template component<std::uint64_t>("counter"));
0391 BOOST_CHECK_EQUAL(targetState.template component<std::uint8_t>("odd"),
0392 sourceState.template component<std::uint8_t>("odd"));
0393 }
0394
0395 BOOST_AUTO_TEST_SUITE_END()
0396
0397 }