File indexing completed on 2026-10-13 08:37:10
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/Units.hpp"
0013 #include "Acts/EventData/Types.hpp"
0014 #include "Acts/EventData/VectorMultiTrajectory.hpp"
0015 #include "Acts/EventData/VectorTrackContainer.hpp"
0016 #include "Acts/EventData/detail/TestSourceLink.hpp"
0017 #include "Acts/Geometry/CuboidVolumeBuilder.hpp"
0018 #include "Acts/Geometry/TrackingGeometry.hpp"
0019 #include "Acts/Geometry/TrackingGeometryBuilder.hpp"
0020 #include "Acts/Material/HomogeneousSurfaceMaterial.hpp"
0021 #include "Acts/Material/MaterialSlab.hpp"
0022 #include "Acts/Propagator/EigenStepper.hpp"
0023 #include "Acts/Propagator/Navigator.hpp"
0024 #include "Acts/Propagator/Propagator.hpp"
0025 #include "Acts/Propagator/StraightLineStepper.hpp"
0026 #include "Acts/Surfaces/PlaneSurface.hpp"
0027 #include "Acts/Surfaces/RectangleBounds.hpp"
0028 #include "Acts/TrackFitting/GlobalChiSquareFitter.hpp"
0029 #include "Acts/Utilities/Logger.hpp"
0030 #include "Acts/Visualization/EventDataView3D.hpp"
0031 #include "Acts/Visualization/GeometryView3D.hpp"
0032 #include "Acts/Visualization/ObjVisualization3D.hpp"
0033 #include "ActsTests/CommonHelpers/DetectorElementStub.hpp"
0034 #include "ActsTests/CommonHelpers/MeasurementsCreator.hpp"
0035 #include "ActsTests/CommonHelpers/PredefinedMaterials.hpp"
0036
0037 #include <numbers>
0038 #include <vector>
0039
0040 #include "FitterTestsCommon.hpp"
0041
0042 using namespace Acts;
0043 using namespace Acts::Experimental;
0044 using namespace Acts::UnitLiterals;
0045 using namespace Acts::detail::Test;
0046
0047 Logging::Level logLevel = Logging::VERBOSE;
0048 const auto gx2fLogger = getDefaultLogger("Gx2f", logLevel);
0049
0050 namespace ActsTests {
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064 static void drawMeasurements(
0065 IVisualization3D& helper, const Measurements& measurements,
0066 const std::shared_ptr<const TrackingGeometry>& geometry,
0067 const GeometryContext& geoCtx, double locErrorScale = 1.,
0068 const ViewConfig& viewConfig = s_viewMeasurement) {
0069 std::cout << "\n*** Draw measurements ***\n" << std::endl;
0070
0071 for (auto& singleMeasurement : measurements.sourceLinks) {
0072 auto cov = singleMeasurement.covariance;
0073 auto lposition = singleMeasurement.parameters;
0074
0075 auto surf = geometry->findSurface(singleMeasurement.m_geometryId);
0076 auto transf = surf->localToGlobalTransform(geoCtx);
0077
0078 EventDataView3D::drawMeasurement(helper, lposition, cov, transf,
0079 locErrorScale, viewConfig);
0080 }
0081 }
0082
0083
0084 BoundTrackParameters makeParameters(
0085 const double x = 0.0_m, const double y = 0.0_m, const double z = 0.0_m,
0086 const double w = 42_ns, const double phi = 0_degree,
0087 const double theta = 90_degree, const double p = 2_GeV,
0088 const double q = 1_e) {
0089
0090 BoundVector stddev;
0091 stddev[eBoundLoc0] = 100_um;
0092 stddev[eBoundLoc1] = 100_um;
0093 stddev[eBoundTime] = 25_ns;
0094 stddev[eBoundPhi] = 2_degree;
0095 stddev[eBoundTheta] = 2_degree;
0096 stddev[eBoundQOverP] = 1 / 100_GeV;
0097 const BoundMatrix cov = stddev.cwiseProduct(stddev).asDiagonal();
0098
0099 const Vector4 mPos4(x, y, z, w);
0100 return BoundTrackParameters::createCurvilinear(mPos4, phi, theta, q / p, cov,
0101 ParticleHypothesis::pion());
0102 }
0103
0104 static std::vector<SourceLink> prepareSourceLinks(
0105 const std::vector<TestSourceLink>& sourceLinks) {
0106 std::vector<SourceLink> result;
0107 std::transform(sourceLinks.begin(), sourceLinks.end(),
0108 std::back_inserter(result),
0109 [](const auto& sl) { return SourceLink{sl}; });
0110 return result;
0111 }
0112
0113
0114
0115
0116
0117
0118 std::shared_ptr<const TrackingGeometry> makeToyDetector(
0119 const GeometryContext& geoCtx, const std::size_t nSurfaces = 5,
0120 const std::set<std::size_t>& surfaceIndexWithMaterial = {}) {
0121 if (nSurfaces < 1) {
0122 throw std::invalid_argument("At least 1 surfaces needs to be created.");
0123 }
0124
0125
0126 const double halfSizeSurface = 1_m;
0127
0128
0129 const double rotationAngle = std::numbers::pi / 2.;
0130 const Vector3 xPos(std::cos(rotationAngle), 0., std::sin(rotationAngle));
0131 const Vector3 yPos(0., 1., 0.);
0132 const Vector3 zPos(-std::sin(rotationAngle), 0., std::cos(rotationAngle));
0133
0134
0135 CuboidVolumeBuilder cvb;
0136
0137
0138 std::vector<CuboidVolumeBuilder::SurfaceConfig> surfaceConfig;
0139 for (std::size_t surfPos = 1; surfPos <= nSurfaces; surfPos++) {
0140
0141 CuboidVolumeBuilder::SurfaceConfig cfg;
0142 cfg.position = {surfPos * UnitConstants::m, 0., 0.};
0143
0144
0145 cfg.rotation.col(0) = xPos;
0146 cfg.rotation.col(1) = yPos;
0147 cfg.rotation.col(2) = zPos;
0148
0149
0150 cfg.rBounds = std::make_shared<const RectangleBounds>(
0151 RectangleBounds(halfSizeSurface, halfSizeSurface));
0152
0153
0154 if (surfaceIndexWithMaterial.contains(surfPos)) {
0155
0156 MaterialSlab matProp(makeSilicon(), 5_mm);
0157 cfg.surMat = std::make_shared<HomogeneousSurfaceMaterial>(matProp);
0158 }
0159
0160
0161 cfg.thickness = 1_um;
0162
0163 cfg.detElementConstructor =
0164 [](const Transform3& trans,
0165 const std::shared_ptr<const RectangleBounds>& bounds,
0166 double thickness) {
0167 return new DetectorElementStub(trans, bounds, thickness);
0168 };
0169 surfaceConfig.push_back(cfg);
0170 }
0171
0172
0173 std::vector<CuboidVolumeBuilder::LayerConfig> layerConfig;
0174 for (auto& sCfg : surfaceConfig) {
0175 CuboidVolumeBuilder::LayerConfig cfg;
0176 cfg.surfaceCfg = {sCfg};
0177 cfg.active = true;
0178 cfg.envelopeX = {-0.1_mm, 0.1_mm};
0179 cfg.envelopeY = {-0.1_mm, 0.1_mm};
0180 cfg.envelopeZ = {-0.1_mm, 0.1_mm};
0181 layerConfig.push_back(cfg);
0182 }
0183
0184
0185 CuboidVolumeBuilder::VolumeConfig volumeConfig;
0186 volumeConfig.length = {(nSurfaces + 1) * 1_m, 2 * halfSizeSurface,
0187 2 * halfSizeSurface};
0188 volumeConfig.position = {volumeConfig.length.x() / 2, 0., 0.};
0189 volumeConfig.layerCfg = layerConfig;
0190 volumeConfig.name = "TestVolume";
0191
0192
0193 CuboidVolumeBuilder::Config config;
0194 config.length = {(nSurfaces + 1) * 1_m, 2 * halfSizeSurface,
0195 2 * halfSizeSurface};
0196 config.position = {volumeConfig.length.x() / 2, 0., 0.};
0197 config.volumeCfg = {volumeConfig};
0198
0199 cvb.setConfig(config);
0200
0201 TrackingGeometryBuilder::Config tgbCfg;
0202
0203 tgbCfg.trackingVolumeBuilders.push_back(
0204 [=](const auto& context, const auto& inner, const auto&) {
0205 return cvb.trackingVolume(context, inner, nullptr);
0206 });
0207
0208 TrackingGeometryBuilder tgb(tgbCfg);
0209
0210 std::unique_ptr<const TrackingGeometry> detector =
0211 tgb.trackingGeometry(geoCtx);
0212 return detector;
0213 }
0214
0215 struct Detector {
0216
0217 std::shared_ptr<const TrackingGeometry> geometry;
0218 };
0219
0220 BOOST_AUTO_TEST_SUITE(TrackFittingSuite)
0221
0222 ACTS_LOCAL_LOGGER(getDefaultLogger("Gx2fTests", logLevel))
0223
0224
0225 const auto geoCtx = GeometryContext::dangerouslyDefaultConstruct();
0226 const MagneticFieldContext magCtx;
0227 const CalibrationContext calCtx;
0228
0229
0230 const MeasurementResolution resPixel = {MeasurementType::eLoc01,
0231 {25_um, 50_um}};
0232 const MeasurementResolution resStrip0 = {MeasurementType::eLoc0, {25_um}};
0233 const MeasurementResolution resStrip1 = {MeasurementType::eLoc1, {50_um}};
0234 const MeasurementResolutionMap resMapAllPixel = {
0235 {GeometryIdentifier().withVolume(0), resPixel}};
0236
0237
0238
0239 BOOST_AUTO_TEST_CASE(NoFit) {
0240 ACTS_INFO("*** Test: NoFit -- Start");
0241
0242 std::default_random_engine rng(42);
0243
0244 ACTS_DEBUG("Create the detector");
0245 const std::size_t nSurfaces = 5;
0246 Detector detector;
0247 detector.geometry = makeToyDetector(geoCtx, nSurfaces);
0248
0249 ACTS_DEBUG("Set the start parameters for measurement creation and fit");
0250 const auto parametersMeasurements = makeParameters();
0251 const auto startParametersFit = makeParameters(
0252 7_mm, 11_mm, 15_mm, 42_ns, 10_degree, 80_degree, 1_GeV, 1_e);
0253
0254 ACTS_DEBUG("Create the measurements");
0255 using SimPropagator = Propagator<StraightLineStepper, Navigator>;
0256 const SimPropagator simPropagator = makeStraightPropagator(detector.geometry);
0257 const auto measurements =
0258 createMeasurements(simPropagator, geoCtx, magCtx, parametersMeasurements,
0259 resMapAllPixel, rng);
0260 const auto sourceLinks = prepareSourceLinks(measurements.sourceLinks);
0261 ACTS_VERBOSE("sourceLinks.size() = " << sourceLinks.size());
0262
0263 ACTS_DEBUG("Set up the fitter");
0264
0265 using Gx2Fitter = Gx2Fitter<SimPropagator, VectorMultiTrajectory>;
0266 const Gx2Fitter fitter(simPropagator, gx2fLogger->clone());
0267
0268 const Surface* rSurface = ¶metersMeasurements.referenceSurface();
0269
0270 Gx2FitterExtensions<VectorMultiTrajectory> extensions;
0271 extensions.calibrator
0272 .connect<&testSourceLinkCalibratorStrict<VectorMultiTrajectory>>();
0273 TestSourceLink::SurfaceAccessor surfaceAccessor{*detector.geometry};
0274 extensions.surfaceAccessor
0275 .connect<&TestSourceLink::SurfaceAccessor::operator()>(&surfaceAccessor);
0276
0277 Gx2FitterOptions gx2fOptions(geoCtx, magCtx, calCtx, extensions,
0278 PropagatorPlainOptions(geoCtx, magCtx), rSurface,
0279 false, false, FreeToBoundCorrection(false), 0,
0280 0);
0281
0282 TrackContainer tracks{VectorTrackContainer{}, VectorMultiTrajectory{}};
0283
0284 ACTS_DEBUG("Fit the track");
0285 ACTS_VERBOSE("startParameter unsmeared:\n" << parametersMeasurements);
0286 ACTS_VERBOSE("startParameter fit:\n" << startParametersFit);
0287 const auto res = fitter.fit(sourceLinks.begin(), sourceLinks.end(),
0288 startParametersFit, gx2fOptions, tracks);
0289
0290 BOOST_REQUIRE(res.ok());
0291
0292 const auto& track = *res;
0293 BOOST_CHECK_EQUAL(track.tipIndex(), kTrackIndexInvalid);
0294 BOOST_CHECK(track.hasReferenceSurface());
0295
0296
0297 BOOST_CHECK_EQUAL(track.chi2(), 0.);
0298 BOOST_CHECK_EQUAL(track.nDoF(), 0u);
0299 BOOST_CHECK_EQUAL(track.nHoles(), 0u);
0300 BOOST_CHECK_EQUAL(track.nMeasurements(), 0u);
0301 BOOST_CHECK_EQUAL(track.nSharedHits(), 0u);
0302 BOOST_CHECK_EQUAL(track.nOutliers(), 0u);
0303
0304
0305 BOOST_CHECK_EQUAL(track.parameters(), startParametersFit.parameters());
0306 BOOST_CHECK_EQUAL(track.covariance(), BoundMatrix::Identity());
0307
0308
0309 BOOST_CHECK_EQUAL(
0310 (track.template component<
0311 std::uint32_t, hashString(Gx2fConstants::gx2fnUpdateColumn)>()),
0312 0);
0313
0314 ACTS_INFO("*** Test: NoFit -- Finish");
0315 }
0316
0317 BOOST_AUTO_TEST_CASE(Fit5Iterations) {
0318 ACTS_INFO("*** Test: Fit5Iterations -- Start");
0319
0320 std::default_random_engine rng(42);
0321
0322 ACTS_DEBUG("Create the detector");
0323 const std::size_t nSurfaces = 5;
0324 Detector detector;
0325 detector.geometry = makeToyDetector(geoCtx, nSurfaces);
0326
0327 ACTS_DEBUG("Set the start parameters for measurement creation and fit");
0328 const auto parametersMeasurements = makeParameters();
0329 const auto startParametersFit = makeParameters(
0330 7_mm, 11_mm, 15_mm, 42_ns, 10_degree, 80_degree, 1_GeV, 1_e);
0331
0332 ACTS_DEBUG("Create the measurements");
0333 using SimPropagator = Propagator<StraightLineStepper, Navigator>;
0334 const SimPropagator simPropagator = makeStraightPropagator(detector.geometry);
0335 const auto measurements =
0336 createMeasurements(simPropagator, geoCtx, magCtx, parametersMeasurements,
0337 resMapAllPixel, rng);
0338 const auto sourceLinks = prepareSourceLinks(measurements.sourceLinks);
0339 ACTS_VERBOSE("sourceLinks.size() = " << sourceLinks.size());
0340
0341 BOOST_REQUIRE_EQUAL(sourceLinks.size(), nSurfaces);
0342
0343 ACTS_DEBUG("Set up the fitter");
0344 const Surface* rSurface = ¶metersMeasurements.referenceSurface();
0345
0346 using RecoStepper = EigenStepper<>;
0347 const auto recoPropagator =
0348 makeConstantFieldPropagator<RecoStepper>(detector.geometry, 0_T);
0349
0350 using RecoPropagator = decltype(recoPropagator);
0351 using Gx2Fitter = Gx2Fitter<RecoPropagator, VectorMultiTrajectory>;
0352 const Gx2Fitter fitter(recoPropagator, gx2fLogger->clone());
0353
0354 Gx2FitterExtensions<VectorMultiTrajectory> extensions;
0355 extensions.calibrator
0356 .connect<&testSourceLinkCalibratorStrict<VectorMultiTrajectory>>();
0357 TestSourceLink::SurfaceAccessor surfaceAccessor{*detector.geometry};
0358 extensions.surfaceAccessor
0359 .connect<&TestSourceLink::SurfaceAccessor::operator()>(&surfaceAccessor);
0360
0361 const Gx2FitterOptions gx2fOptions(geoCtx, magCtx, calCtx, extensions,
0362 PropagatorPlainOptions(geoCtx, magCtx),
0363 rSurface, false, false,
0364 FreeToBoundCorrection(false), 5, 0);
0365
0366 TrackContainer tracks{VectorTrackContainer{}, VectorMultiTrajectory{}};
0367
0368 ACTS_DEBUG("Fit the track");
0369 ACTS_VERBOSE("startParameter unsmeared:\n" << parametersMeasurements);
0370 ACTS_VERBOSE("startParameter fit:\n" << startParametersFit);
0371 const auto res = fitter.fit(sourceLinks.begin(), sourceLinks.end(),
0372 startParametersFit, gx2fOptions, tracks);
0373
0374 BOOST_REQUIRE(res.ok());
0375
0376 const auto& track = *res;
0377
0378 BOOST_CHECK_EQUAL(track.tipIndex(), nSurfaces - 1);
0379 BOOST_CHECK(track.hasReferenceSurface());
0380
0381
0382 CHECK_CLOSE_ABS(track.chi2(), 8., 2.);
0383 BOOST_CHECK_EQUAL(track.nDoF(), nSurfaces * 2);
0384 BOOST_CHECK_EQUAL(track.nHoles(), 0u);
0385 BOOST_CHECK_EQUAL(track.nMeasurements(), nSurfaces);
0386 BOOST_CHECK_EQUAL(track.nSharedHits(), 0u);
0387 BOOST_CHECK_EQUAL(track.nOutliers(), 0u);
0388
0389
0390
0391
0392 BOOST_CHECK_CLOSE(track.parameters()[eBoundLoc0], -11., 7e0);
0393 BOOST_CHECK_CLOSE(track.parameters()[eBoundLoc1], -15., 6e0);
0394 BOOST_CHECK_CLOSE(track.parameters()[eBoundPhi], 1e-5, 1e3);
0395 BOOST_CHECK_CLOSE(track.parameters()[eBoundTheta], std::numbers::pi / 2,
0396 1e-3);
0397 BOOST_CHECK_EQUAL(track.parameters()[eBoundQOverP], 1);
0398 BOOST_CHECK_CLOSE(track.parameters()[eBoundTime],
0399 startParametersFit.parameters()[eBoundTime], 1e-6);
0400 BOOST_CHECK_CLOSE(track.covariance().determinant(), 1e-27, 4e0);
0401
0402
0403 BOOST_CHECK_EQUAL(
0404 (track.template component<
0405 std::uint32_t, hashString(Gx2fConstants::gx2fnUpdateColumn)>()),
0406 4);
0407
0408 ACTS_INFO("*** Test: Fit5Iterations -- Finish");
0409 }
0410
0411
0412
0413 BOOST_AUTO_TEST_CASE(FreeMeasurementSurface) {
0414 ACTS_INFO("*** Test: FreeMeasurementSurface -- Start");
0415
0416 std::default_random_engine rng(42);
0417
0418 ACTS_DEBUG("Create the detector");
0419 const std::size_t nSurfaces = 5;
0420 Detector detector;
0421 detector.geometry = makeToyDetector(geoCtx, nSurfaces);
0422
0423 ACTS_DEBUG("Set the start parameters for measurement creation and fit");
0424 const auto parametersMeasurements = makeParameters();
0425 const auto startParametersFit = makeParameters(
0426 7_mm, 11_mm, 15_mm, 42_ns, 10_degree, 80_degree, 1_GeV, 1_e);
0427
0428 ACTS_DEBUG("Create the measurements");
0429 using SimPropagator = Propagator<StraightLineStepper, Navigator>;
0430 const SimPropagator simPropagator = makeStraightPropagator(detector.geometry);
0431 const auto measurements =
0432 createMeasurements(simPropagator, geoCtx, magCtx, parametersMeasurements,
0433 resMapAllPixel, rng);
0434 auto sourceLinks = prepareSourceLinks(measurements.sourceLinks);
0435 BOOST_REQUIRE_EQUAL(sourceLinks.size(), nSurfaces);
0436
0437 ACTS_DEBUG("Add a measurement on a free surface between two layers");
0438 const Surface* firstSurface = detector.geometry->findSurface(
0439 measurements.sourceLinks.front().m_geometryId);
0440 BOOST_REQUIRE(firstSurface != nullptr);
0441 Transform3 freeTransform = Transform3::Identity();
0442 freeTransform.linear() =
0443 firstSurface->localToGlobalTransform(geoCtx).linear();
0444 freeTransform.translation() = Vector3(2.5_m, 0., 0.);
0445 const auto freeSurface = Surface::makeShared<PlaneSurface>(
0446 freeTransform, std::make_shared<RectangleBounds>(1_m, 1_m));
0447 BOOST_REQUIRE_EQUAL(freeSurface->geometryId(), GeometryIdentifier{});
0448 sourceLinks.emplace_back(
0449 TestSourceLink(eBoundLoc0, eBoundLoc1, Vector2::Zero(),
0450 Vector2(25_um * 25_um, 50_um * 50_um).asDiagonal()));
0451
0452
0453 struct FreeSurfaceAccessor {
0454 const TrackingGeometry* geometry{};
0455 const Surface* freeSurface{};
0456
0457 const Surface* operator()(const SourceLink& sourceLink) const {
0458 const GeometryIdentifier geoId =
0459 sourceLink.get<TestSourceLink>().m_geometryId;
0460 return geoId == GeometryIdentifier{} ? freeSurface
0461 : geometry->findSurface(geoId);
0462 }
0463 };
0464 FreeSurfaceAccessor surfaceAccessor{detector.geometry.get(),
0465 freeSurface.get()};
0466
0467 ACTS_DEBUG("Set up the fitter");
0468 const Surface* rSurface = ¶metersMeasurements.referenceSurface();
0469
0470 using RecoStepper = EigenStepper<>;
0471 const auto recoPropagator =
0472 makeConstantFieldPropagator<RecoStepper>(detector.geometry, 0_T);
0473
0474 using RecoPropagator = decltype(recoPropagator);
0475 using Gx2Fitter = Gx2Fitter<RecoPropagator, VectorMultiTrajectory>;
0476 const Gx2Fitter fitter(recoPropagator, gx2fLogger->clone());
0477
0478 Gx2FitterExtensions<VectorMultiTrajectory> extensions;
0479 extensions.calibrator
0480 .connect<&testSourceLinkCalibratorStrict<VectorMultiTrajectory>>();
0481 extensions.surfaceAccessor.connect<&FreeSurfaceAccessor::operator()>(
0482 &surfaceAccessor);
0483
0484 const Gx2FitterOptions gx2fOptions(geoCtx, magCtx, calCtx, extensions,
0485 PropagatorPlainOptions(geoCtx, magCtx),
0486 rSurface, false, false,
0487 FreeToBoundCorrection(false), 5, 0);
0488
0489 TrackContainer tracks{VectorTrackContainer{}, VectorMultiTrajectory{}};
0490
0491 ACTS_DEBUG("Fit the track");
0492 const auto res = fitter.fit(sourceLinks.begin(), sourceLinks.end(),
0493 startParametersFit, gx2fOptions, tracks);
0494
0495 BOOST_REQUIRE(res.ok());
0496
0497 const auto& track = *res;
0498 BOOST_CHECK_EQUAL(track.nMeasurements(), nSurfaces + 1);
0499 BOOST_CHECK_EQUAL(track.nDoF(), (nSurfaces + 1) * 2);
0500 BOOST_CHECK_EQUAL(track.nHoles(), 0u);
0501 BOOST_CHECK_EQUAL(track.nOutliers(), 0u);
0502
0503
0504 bool freeSurfaceMeasured = false;
0505 for (const auto trackState : track.trackStatesReversed()) {
0506 if (&trackState.referenceSurface() == freeSurface.get()) {
0507 freeSurfaceMeasured = trackState.typeFlags().isMeasurement();
0508 }
0509 }
0510 BOOST_CHECK(freeSurfaceMeasured);
0511
0512 ACTS_INFO("*** Test: FreeMeasurementSurface -- Finish");
0513 }
0514
0515 BOOST_AUTO_TEST_CASE(MixedDetector) {
0516 ACTS_INFO("*** Test: MixedDetector -- Start");
0517
0518 std::default_random_engine rng(42);
0519
0520 ACTS_DEBUG("Create the detector");
0521 const std::size_t nSurfaces = 7;
0522 Detector detector;
0523 detector.geometry = makeToyDetector(geoCtx, nSurfaces);
0524
0525 ACTS_DEBUG("Set the start parameters for measurement creation and fit");
0526 const auto parametersMeasurements = makeParameters();
0527 const auto startParametersFit = makeParameters(
0528 7_mm, 11_mm, 15_mm, 42_ns, 10_degree, 80_degree, 1_GeV, 1_e);
0529
0530 ACTS_DEBUG("Create the measurements");
0531 const MeasurementResolutionMap resMap = {
0532 {GeometryIdentifier().withVolume(2).withLayer(2), resPixel},
0533 {GeometryIdentifier().withVolume(2).withLayer(4), resStrip0},
0534 {GeometryIdentifier().withVolume(2).withLayer(6), resStrip1},
0535 {GeometryIdentifier().withVolume(2).withLayer(8), resPixel},
0536 {GeometryIdentifier().withVolume(2).withLayer(10), resStrip0},
0537 {GeometryIdentifier().withVolume(2).withLayer(12), resStrip1},
0538 {GeometryIdentifier().withVolume(2).withLayer(14), resPixel},
0539 };
0540
0541 using SimPropagator = Propagator<StraightLineStepper, Navigator>;
0542 const SimPropagator simPropagator = makeStraightPropagator(detector.geometry);
0543 const auto measurements = createMeasurements(
0544 simPropagator, geoCtx, magCtx, parametersMeasurements, resMap, rng);
0545 const auto sourceLinks = prepareSourceLinks(measurements.sourceLinks);
0546 ACTS_VERBOSE("sourceLinks.size() = " << sourceLinks.size());
0547
0548 BOOST_REQUIRE_EQUAL(sourceLinks.size(), nSurfaces);
0549
0550 ACTS_DEBUG("Set up the fitter");
0551 const Surface* rSurface = ¶metersMeasurements.referenceSurface();
0552
0553 using RecoStepper = EigenStepper<>;
0554 const auto recoPropagator =
0555 makeConstantFieldPropagator<RecoStepper>(detector.geometry, 0_T);
0556
0557 using RecoPropagator = decltype(recoPropagator);
0558 using Gx2Fitter = Gx2Fitter<RecoPropagator, VectorMultiTrajectory>;
0559 const Gx2Fitter fitter(recoPropagator, gx2fLogger->clone());
0560
0561 Gx2FitterExtensions<VectorMultiTrajectory> extensions;
0562 extensions.calibrator
0563 .connect<&testSourceLinkCalibratorStrict<VectorMultiTrajectory>>();
0564 TestSourceLink::SurfaceAccessor surfaceAccessor{*detector.geometry};
0565 extensions.surfaceAccessor
0566 .connect<&TestSourceLink::SurfaceAccessor::operator()>(&surfaceAccessor);
0567
0568 const Gx2FitterOptions gx2fOptions(geoCtx, magCtx, calCtx, extensions,
0569 PropagatorPlainOptions(geoCtx, magCtx),
0570 rSurface, false, false,
0571 FreeToBoundCorrection(false), 5, 0);
0572
0573 TrackContainer tracks{VectorTrackContainer{}, VectorMultiTrajectory{}};
0574
0575 ACTS_DEBUG("Fit the track");
0576 ACTS_VERBOSE("startParameter unsmeared:\n" << parametersMeasurements);
0577 ACTS_VERBOSE("startParameter fit:\n" << startParametersFit);
0578 const auto res = fitter.fit(sourceLinks.begin(), sourceLinks.end(),
0579 startParametersFit, gx2fOptions, tracks);
0580
0581 BOOST_REQUIRE(res.ok());
0582
0583 const auto& track = *res;
0584 BOOST_CHECK_EQUAL(track.tipIndex(), nSurfaces - 1);
0585 BOOST_CHECK(track.hasReferenceSurface());
0586
0587
0588 CHECK_CLOSE_ABS(track.chi2(), 8.5, 4.);
0589 BOOST_CHECK_EQUAL(track.nDoF(), 10u);
0590 BOOST_CHECK_EQUAL(track.nHoles(), 0u);
0591 BOOST_CHECK_EQUAL(track.nMeasurements(), nSurfaces);
0592 BOOST_CHECK_EQUAL(track.nSharedHits(), 0u);
0593 BOOST_CHECK_EQUAL(track.nOutliers(), 0u);
0594
0595
0596
0597
0598 BOOST_CHECK_CLOSE(track.parameters()[eBoundLoc0], -11., 7e0);
0599 BOOST_CHECK_CLOSE(track.parameters()[eBoundLoc1], -15., 6e0);
0600 BOOST_CHECK_CLOSE(track.parameters()[eBoundPhi], 1e-5, 1e3);
0601 BOOST_CHECK_CLOSE(track.parameters()[eBoundTheta], std::numbers::pi / 2,
0602 1e-3);
0603 BOOST_CHECK_EQUAL(track.parameters()[eBoundQOverP], 1);
0604 BOOST_CHECK_CLOSE(track.parameters()[eBoundTime],
0605 startParametersFit.parameters()[eBoundTime], 1e-6);
0606 BOOST_CHECK_CLOSE(track.covariance().determinant(), 2e-28, 1e0);
0607
0608
0609 BOOST_CHECK_EQUAL(
0610 (track.template component<
0611 std::uint32_t, hashString(Gx2fConstants::gx2fnUpdateColumn)>()),
0612 4);
0613
0614 ACTS_INFO("*** Test: MixedDetector -- Finish");
0615 }
0616
0617
0618 BOOST_AUTO_TEST_CASE(FitWithBfield) {
0619 ACTS_INFO("*** Test: FitWithBfield -- Start");
0620
0621 std::default_random_engine rng(42);
0622
0623 ACTS_DEBUG("Create the detector");
0624 const std::size_t nSurfaces = 5;
0625 Detector detector;
0626 detector.geometry = makeToyDetector(geoCtx, nSurfaces);
0627
0628 ACTS_DEBUG("Set the start parameters for measurement creation and fit");
0629 const auto parametersMeasurements = makeParameters();
0630 const auto startParametersFit = makeParameters(
0631 7_mm, 11_mm, 15_mm, 42_ns, 10_degree, 80_degree, 1_GeV, 1_e);
0632
0633 ACTS_DEBUG("Create the measurements");
0634 using SimStepper = EigenStepper<>;
0635 const auto simPropagator =
0636 makeConstantFieldPropagator<SimStepper>(detector.geometry, 0.3_T);
0637
0638 const auto measurements =
0639 createMeasurements(simPropagator, geoCtx, magCtx, parametersMeasurements,
0640 resMapAllPixel, rng);
0641
0642 const auto sourceLinks = prepareSourceLinks(measurements.sourceLinks);
0643 ACTS_VERBOSE("sourceLinks.size() = " << sourceLinks.size());
0644
0645 BOOST_REQUIRE_EQUAL(sourceLinks.size(), nSurfaces);
0646
0647 ACTS_DEBUG("Set up the fitter");
0648 const Surface* rSurface = ¶metersMeasurements.referenceSurface();
0649
0650
0651 using SimPropagator = decltype(simPropagator);
0652 using Gx2Fitter = Gx2Fitter<SimPropagator, VectorMultiTrajectory>;
0653 const Gx2Fitter fitter(simPropagator, gx2fLogger->clone());
0654
0655 Gx2FitterExtensions<VectorMultiTrajectory> extensions;
0656 extensions.calibrator
0657 .connect<&testSourceLinkCalibratorStrict<VectorMultiTrajectory>>();
0658 TestSourceLink::SurfaceAccessor surfaceAccessor{*detector.geometry};
0659 extensions.surfaceAccessor
0660 .connect<&TestSourceLink::SurfaceAccessor::operator()>(&surfaceAccessor);
0661
0662 const Gx2FitterOptions gx2fOptions(geoCtx, magCtx, calCtx, extensions,
0663 PropagatorPlainOptions(geoCtx, magCtx),
0664 rSurface, false, false,
0665 FreeToBoundCorrection(false), 5, 0);
0666
0667 TrackContainer tracks{VectorTrackContainer{}, VectorMultiTrajectory{}};
0668
0669 ACTS_DEBUG("Fit the track");
0670 ACTS_VERBOSE("startParameter unsmeared:\n" << parametersMeasurements);
0671 ACTS_VERBOSE("startParameter fit:\n" << startParametersFit);
0672 const auto res = fitter.fit(sourceLinks.begin(), sourceLinks.end(),
0673 startParametersFit, gx2fOptions, tracks);
0674
0675 BOOST_REQUIRE(res.ok());
0676
0677 const auto& track = *res;
0678 BOOST_CHECK_EQUAL(track.tipIndex(), nSurfaces - 1);
0679 BOOST_CHECK(track.hasReferenceSurface());
0680
0681
0682 CHECK_CLOSE_ABS(track.chi2(), 7.5, 1.5);
0683 BOOST_CHECK_EQUAL(track.nDoF(), nSurfaces * 2);
0684 BOOST_CHECK_EQUAL(track.nHoles(), 0u);
0685 BOOST_CHECK_EQUAL(track.nMeasurements(), nSurfaces);
0686 BOOST_CHECK_EQUAL(track.nSharedHits(), 0u);
0687 BOOST_CHECK_EQUAL(track.nOutliers(), 0u);
0688
0689
0690
0691
0692
0693 BOOST_CHECK_CLOSE(track.parameters()[eBoundLoc0], -11., 8e0);
0694 BOOST_CHECK_CLOSE(track.parameters()[eBoundLoc1], -15., 6e0);
0695 BOOST_CHECK_CLOSE(track.parameters()[eBoundPhi], 1e-4, 1e3);
0696 BOOST_CHECK_CLOSE(track.parameters()[eBoundTheta], std::numbers::pi / 2,
0697 1e-3);
0698 BOOST_CHECK_CLOSE(track.parameters()[eBoundQOverP], 0.5, 2e-1);
0699 BOOST_CHECK_CLOSE(track.parameters()[eBoundTime],
0700 startParametersFit.parameters()[eBoundTime], 1e-6);
0701 BOOST_CHECK_CLOSE(track.covariance().determinant(), 8e-35, 4e0);
0702
0703
0704 BOOST_CHECK_EQUAL(
0705 (track.template component<
0706 std::uint32_t, hashString(Gx2fConstants::gx2fnUpdateColumn)>()),
0707 4);
0708
0709 ACTS_INFO("*** Test: FitWithBfield -- Finish");
0710 }
0711
0712 BOOST_AUTO_TEST_CASE(relChi2changeCutOff) {
0713 ACTS_INFO("*** Test: relChi2changeCutOff -- Start");
0714
0715 std::default_random_engine rng(42);
0716
0717 ACTS_DEBUG("Create the detector");
0718 const std::size_t nSurfaces = 5;
0719 Detector detector;
0720 detector.geometry = makeToyDetector(geoCtx, nSurfaces);
0721
0722 ACTS_DEBUG("Set the start parameters for measurement creation and fit");
0723 const auto parametersMeasurements = makeParameters();
0724 const auto startParametersFit = makeParameters(
0725 7_mm, 11_mm, 15_mm, 42_ns, 10_degree, 80_degree, 1_GeV, 1_e);
0726
0727 ACTS_DEBUG("Create the measurements");
0728
0729 using SimPropagator = Propagator<StraightLineStepper, Navigator>;
0730 const SimPropagator simPropagator = makeStraightPropagator(detector.geometry);
0731 const auto measurements =
0732 createMeasurements(simPropagator, geoCtx, magCtx, parametersMeasurements,
0733 resMapAllPixel, rng);
0734 const auto sourceLinks = prepareSourceLinks(measurements.sourceLinks);
0735 ACTS_VERBOSE("sourceLinks.size() = " << sourceLinks.size());
0736
0737 BOOST_REQUIRE_EQUAL(sourceLinks.size(), nSurfaces);
0738
0739 ACTS_DEBUG("Set up the fitter");
0740 const Surface* rSurface = ¶metersMeasurements.referenceSurface();
0741
0742 using RecoStepper = EigenStepper<>;
0743 const auto recoPropagator =
0744 makeConstantFieldPropagator<RecoStepper>(detector.geometry, 0_T);
0745
0746 using RecoPropagator = decltype(recoPropagator);
0747 using Gx2Fitter = Gx2Fitter<RecoPropagator, VectorMultiTrajectory>;
0748 const Gx2Fitter fitter(recoPropagator, gx2fLogger->clone());
0749
0750 Gx2FitterExtensions<VectorMultiTrajectory> extensions;
0751 extensions.calibrator
0752 .connect<&testSourceLinkCalibratorStrict<VectorMultiTrajectory>>();
0753 TestSourceLink::SurfaceAccessor surfaceAccessor{*detector.geometry};
0754 extensions.surfaceAccessor
0755 .connect<&TestSourceLink::SurfaceAccessor::operator()>(&surfaceAccessor);
0756
0757 const Gx2FitterOptions gx2fOptions(geoCtx, magCtx, calCtx, extensions,
0758 PropagatorPlainOptions(geoCtx, magCtx),
0759 rSurface, false, false,
0760 FreeToBoundCorrection(false), 500, 1e-5);
0761
0762 TrackContainer tracks{VectorTrackContainer{}, VectorMultiTrajectory{}};
0763
0764 ACTS_DEBUG("Fit the track");
0765 ACTS_VERBOSE("startParameter unsmeared:\n" << parametersMeasurements);
0766 ACTS_VERBOSE("startParameter fit:\n" << startParametersFit);
0767 const auto res = fitter.fit(sourceLinks.begin(), sourceLinks.end(),
0768 startParametersFit, gx2fOptions, tracks);
0769
0770 BOOST_REQUIRE(res.ok());
0771
0772 const auto& track = *res;
0773 BOOST_CHECK_EQUAL(track.tipIndex(), nSurfaces - 1);
0774 BOOST_CHECK(track.hasReferenceSurface());
0775
0776
0777 CHECK_CLOSE_ABS(track.chi2(), 8., 2.);
0778 BOOST_CHECK_EQUAL(track.nDoF(), nSurfaces * 2);
0779 BOOST_CHECK_EQUAL(track.nHoles(), 0u);
0780 BOOST_CHECK_EQUAL(track.nMeasurements(), nSurfaces);
0781 BOOST_CHECK_EQUAL(track.nSharedHits(), 0u);
0782 BOOST_CHECK_EQUAL(track.nOutliers(), 0u);
0783
0784
0785
0786
0787 BOOST_CHECK_CLOSE(track.parameters()[eBoundLoc0], -11., 7e0);
0788 BOOST_CHECK_CLOSE(track.parameters()[eBoundLoc1], -15., 6e0);
0789 BOOST_CHECK_CLOSE(track.parameters()[eBoundPhi], 1e-5, 1e3);
0790 BOOST_CHECK_CLOSE(track.parameters()[eBoundTheta], std::numbers::pi / 2,
0791 1e-3);
0792 BOOST_CHECK_EQUAL(track.parameters()[eBoundQOverP], 1);
0793 BOOST_CHECK_CLOSE(track.parameters()[eBoundTime],
0794 startParametersFit.parameters()[eBoundTime], 1e-6);
0795 BOOST_CHECK_CLOSE(track.covariance().determinant(), 1e-27, 4e0);
0796
0797
0798 BOOST_CHECK_LT(
0799 (track.template component<
0800 std::uint32_t, hashString(Gx2fConstants::gx2fnUpdateColumn)>()),
0801 10);
0802
0803 ACTS_INFO("*** Test: relChi2changeCutOff -- Finish");
0804 }
0805
0806 BOOST_AUTO_TEST_CASE(DidNotConverge) {
0807 ACTS_INFO("*** Test: DidNotConverge -- Start");
0808
0809 std::default_random_engine rng(42);
0810
0811 ACTS_DEBUG("Create the detector");
0812 const std::size_t nSurfaces = 5;
0813 Detector detector;
0814 detector.geometry = makeToyDetector(geoCtx, nSurfaces);
0815
0816 ACTS_DEBUG("Set the start parameters for measurement creation and fit");
0817 const auto parametersMeasurements = makeParameters();
0818 const auto startParametersFit = makeParameters(
0819 7_mm, 11_mm, 15_mm, 42_ns, 10_degree, 80_degree, 1_GeV, 1_e);
0820
0821 ACTS_DEBUG("Create the measurements");
0822
0823 using SimPropagator = Propagator<StraightLineStepper, Navigator>;
0824 const SimPropagator simPropagator = makeStraightPropagator(detector.geometry);
0825 const auto measurements =
0826 createMeasurements(simPropagator, geoCtx, magCtx, parametersMeasurements,
0827 resMapAllPixel, rng);
0828 const auto sourceLinks = prepareSourceLinks(measurements.sourceLinks);
0829 ACTS_VERBOSE("sourceLinks.size() = " << sourceLinks.size());
0830
0831 BOOST_REQUIRE_EQUAL(sourceLinks.size(), nSurfaces);
0832
0833 ACTS_DEBUG("Set up the fitter");
0834 const Surface* rSurface = ¶metersMeasurements.referenceSurface();
0835
0836 using RecoStepper = EigenStepper<>;
0837 const auto recoPropagator =
0838 makeConstantFieldPropagator<RecoStepper>(detector.geometry, 0_T);
0839
0840 using RecoPropagator = decltype(recoPropagator);
0841 using Gx2Fitter = Gx2Fitter<RecoPropagator, VectorMultiTrajectory>;
0842 const Gx2Fitter fitter(recoPropagator, gx2fLogger->clone());
0843
0844 Gx2FitterExtensions<VectorMultiTrajectory> extensions;
0845 extensions.calibrator
0846 .connect<&testSourceLinkCalibratorStrict<VectorMultiTrajectory>>();
0847 TestSourceLink::SurfaceAccessor surfaceAccessor{*detector.geometry};
0848 extensions.surfaceAccessor
0849 .connect<&TestSourceLink::SurfaceAccessor::operator()>(&surfaceAccessor);
0850
0851
0852
0853
0854
0855 const Gx2FitterOptions gx2fOptions(geoCtx, magCtx, calCtx, extensions,
0856 PropagatorPlainOptions(geoCtx, magCtx),
0857 rSurface, false, false,
0858 FreeToBoundCorrection(false), 6, 0);
0859
0860 TrackContainer tracks{VectorTrackContainer{}, VectorMultiTrajectory{}};
0861
0862 ACTS_DEBUG("Fit the track");
0863 ACTS_VERBOSE("startParameter unsmeared:\n" << parametersMeasurements);
0864 ACTS_VERBOSE("startParameter fit:\n" << startParametersFit);
0865 const auto res = fitter.fit(sourceLinks.begin(), sourceLinks.end(),
0866 startParametersFit, gx2fOptions, tracks);
0867
0868 BOOST_REQUIRE(!res.ok());
0869 BOOST_CHECK_EQUAL(res.error(), GlobalChiSquareFitterError::DidNotConverge);
0870
0871 ACTS_INFO("*** Test: DidNotConverge -- Finish");
0872 }
0873
0874 BOOST_AUTO_TEST_CASE(NotEnoughMeasurements) {
0875 ACTS_INFO("*** Test: NotEnoughMeasurements -- Start");
0876
0877 std::default_random_engine rng(42);
0878
0879 ACTS_DEBUG("Create the detector");
0880 const std::size_t nSurfaces = 2;
0881 Detector detector;
0882 detector.geometry = makeToyDetector(geoCtx, nSurfaces);
0883
0884 ACTS_DEBUG("Set the start parameters for measurement creation and fit");
0885 const auto parametersMeasurements = makeParameters();
0886 const auto startParametersFit = makeParameters(
0887 7_mm, 11_mm, 15_mm, 42_ns, 10_degree, 80_degree, 1_GeV, 1_e);
0888
0889 ACTS_DEBUG("Create the measurements");
0890
0891 using SimPropagator = Propagator<StraightLineStepper, Navigator>;
0892 const SimPropagator simPropagator = makeStraightPropagator(detector.geometry);
0893 const auto measurements =
0894 createMeasurements(simPropagator, geoCtx, magCtx, parametersMeasurements,
0895 resMapAllPixel, rng);
0896 const auto sourceLinks = prepareSourceLinks(measurements.sourceLinks);
0897 ACTS_VERBOSE("sourceLinks.size() = " << sourceLinks.size());
0898
0899 BOOST_REQUIRE_EQUAL(sourceLinks.size(), nSurfaces);
0900
0901 ACTS_DEBUG("Set up the fitter");
0902 const Surface* rSurface = ¶metersMeasurements.referenceSurface();
0903
0904 using RecoStepper = EigenStepper<>;
0905 const auto recoPropagator =
0906 makeConstantFieldPropagator<RecoStepper>(detector.geometry, 0_T);
0907
0908 using RecoPropagator = decltype(recoPropagator);
0909 using Gx2Fitter = Gx2Fitter<RecoPropagator, VectorMultiTrajectory>;
0910 const Gx2Fitter fitter(recoPropagator, gx2fLogger->clone());
0911
0912 Gx2FitterExtensions<VectorMultiTrajectory> extensions;
0913 extensions.calibrator
0914 .connect<&testSourceLinkCalibratorStrict<VectorMultiTrajectory>>();
0915 TestSourceLink::SurfaceAccessor surfaceAccessor{*detector.geometry};
0916 extensions.surfaceAccessor
0917 .connect<&TestSourceLink::SurfaceAccessor::operator()>(&surfaceAccessor);
0918
0919 const Gx2FitterOptions gx2fOptions(geoCtx, magCtx, calCtx, extensions,
0920 PropagatorPlainOptions(geoCtx, magCtx),
0921 rSurface, false, false,
0922 FreeToBoundCorrection(false), 6, 0);
0923
0924 TrackContainer tracks{VectorTrackContainer{}, VectorMultiTrajectory{}};
0925
0926 ACTS_DEBUG("Fit the track");
0927 ACTS_VERBOSE("startParameter unsmeared:\n" << parametersMeasurements);
0928 ACTS_VERBOSE("startParameter fit:\n" << startParametersFit);
0929 const auto res = fitter.fit(sourceLinks.begin(), sourceLinks.end(),
0930 startParametersFit, gx2fOptions, tracks);
0931
0932 BOOST_REQUIRE(!res.ok());
0933 BOOST_CHECK_EQUAL(res.error(),
0934 GlobalChiSquareFitterError::NotEnoughMeasurements);
0935
0936 ACTS_INFO("*** Test: NotEnoughMeasurements -- Finish");
0937 }
0938
0939 BOOST_AUTO_TEST_CASE(FindHoles) {
0940 ACTS_INFO("*** Test: FindHoles -- Start");
0941
0942 std::default_random_engine rng(42);
0943
0944 ACTS_DEBUG("Create the detector");
0945
0946 const std::size_t nSurfaces = 8;
0947 Detector detector;
0948 detector.geometry = makeToyDetector(geoCtx, nSurfaces);
0949
0950 ACTS_DEBUG("Set the start parameters for measurement creation and fit");
0951 const auto parametersMeasurements = makeParameters();
0952 const auto startParametersFit = makeParameters(
0953 7_mm, 11_mm, 15_mm, 42_ns, 10_degree, 80_degree, 1_GeV, 1_e);
0954
0955 ACTS_DEBUG("Create the measurements");
0956 using SimPropagator = Propagator<StraightLineStepper, Navigator>;
0957 const SimPropagator simPropagator = makeStraightPropagator(detector.geometry);
0958 const auto measurements =
0959 createMeasurements(simPropagator, geoCtx, magCtx, parametersMeasurements,
0960 resMapAllPixel, rng);
0961 auto sourceLinks = prepareSourceLinks(measurements.sourceLinks);
0962 ACTS_VERBOSE("sourceLinks.size() [before] = " << sourceLinks.size());
0963
0964
0965 sourceLinks.erase(std::next(sourceLinks.begin(), 0));
0966 ACTS_VERBOSE(
0967 "sourceLinks.size() [after first erase] = " << sourceLinks.size());
0968
0969
0970 sourceLinks.pop_back();
0971 ACTS_VERBOSE("sourceLinks.size() [after pop] = " << sourceLinks.size());
0972
0973
0974
0975 const std::size_t indexHole = sourceLinks.size() - 2;
0976 ACTS_VERBOSE("Remove measurement " << indexHole);
0977 sourceLinks.erase(std::next(sourceLinks.begin(), indexHole));
0978 ACTS_VERBOSE("sourceLinks.size() [after second-to-last erase]= "
0979 << sourceLinks.size());
0980
0981
0982
0983 const std::size_t nMeasurements = nSurfaces - 3;
0984 BOOST_REQUIRE_EQUAL(sourceLinks.size(), nMeasurements);
0985
0986 ACTS_DEBUG("Set up the fitter");
0987 const Surface* rSurface = ¶metersMeasurements.referenceSurface();
0988
0989 using RecoStepper = EigenStepper<>;
0990 const auto recoPropagator =
0991 makeConstantFieldPropagator<RecoStepper>(detector.geometry, 0_T);
0992
0993 using RecoPropagator = decltype(recoPropagator);
0994 using Gx2Fitter = Gx2Fitter<RecoPropagator, VectorMultiTrajectory>;
0995 const Gx2Fitter fitter(recoPropagator, gx2fLogger->clone());
0996
0997 Gx2FitterExtensions<VectorMultiTrajectory> extensions;
0998 extensions.calibrator
0999 .connect<&testSourceLinkCalibratorStrict<VectorMultiTrajectory>>();
1000 TestSourceLink::SurfaceAccessor surfaceAccessor{*detector.geometry};
1001 extensions.surfaceAccessor
1002 .connect<&TestSourceLink::SurfaceAccessor::operator()>(&surfaceAccessor);
1003
1004 const Gx2FitterOptions gx2fOptions(geoCtx, magCtx, calCtx, extensions,
1005 PropagatorPlainOptions(geoCtx, magCtx),
1006 rSurface, false, false,
1007 FreeToBoundCorrection(false), 20, 1e-5);
1008
1009 TrackContainer tracks{VectorTrackContainer{}, VectorMultiTrajectory{}};
1010
1011 ACTS_DEBUG("Fit the track");
1012 ACTS_VERBOSE("startParameter unsmeared:\n" << parametersMeasurements);
1013 ACTS_VERBOSE("startParameter fit:\n" << startParametersFit);
1014 const auto res = fitter.fit(sourceLinks.begin(), sourceLinks.end(),
1015 startParametersFit, gx2fOptions, tracks);
1016
1017 BOOST_REQUIRE(res.ok());
1018
1019 const auto& track = *res;
1020
1021
1022
1023 BOOST_CHECK_EQUAL(track.tipIndex(), nSurfaces - 1 - 2);
1024 BOOST_CHECK(track.hasReferenceSurface());
1025
1026
1027 CHECK_CLOSE_ABS(track.chi2(), 6.5, 2.);
1028 BOOST_CHECK_EQUAL(track.nDoF(), 10u);
1029 BOOST_CHECK_EQUAL(track.nHoles(), 1u);
1030 BOOST_CHECK_EQUAL(track.nMeasurements(), nMeasurements);
1031 BOOST_CHECK_EQUAL(track.nSharedHits(), 0u);
1032 BOOST_CHECK_EQUAL(track.nOutliers(), 0u);
1033
1034
1035
1036
1037 BOOST_CHECK_CLOSE(track.parameters()[eBoundLoc0], -11., 7e0);
1038 BOOST_CHECK_CLOSE(track.parameters()[eBoundLoc1], -15., 6e0);
1039 BOOST_CHECK_CLOSE(track.parameters()[eBoundPhi], 1e-5, 1e3);
1040 BOOST_CHECK_CLOSE(track.parameters()[eBoundTheta], std::numbers::pi / 2,
1041 1e-3);
1042 BOOST_CHECK_EQUAL(track.parameters()[eBoundQOverP], 1);
1043 BOOST_CHECK_CLOSE(track.parameters()[eBoundTime],
1044 startParametersFit.parameters()[eBoundTime], 1e-6);
1045 BOOST_CHECK_CLOSE(track.covariance().determinant(), 4.7e-28, 2e0);
1046
1047 ACTS_INFO("*** Test: FindHoles -- Finish");
1048 }
1049
1050 BOOST_AUTO_TEST_CASE(Material) {
1051 ACTS_INFO("*** Test: Material -- Start");
1052
1053 std::default_random_engine rng(42);
1054
1055 ACTS_DEBUG("Create the detector");
1056 const std::size_t nSurfaces = 7;
1057 const std::set<std::size_t> surfaceIndexWithMaterial = {4};
1058 Detector detector;
1059 detector.geometry =
1060 makeToyDetector(geoCtx, nSurfaces, surfaceIndexWithMaterial);
1061
1062 ACTS_DEBUG("Set the start parameters for measurement creation and fit");
1063 const auto parametersMeasurements = makeParameters();
1064 const auto startParametersFit = makeParameters(
1065 7_mm, 11_mm, 15_mm, 42_ns, 10_degree, 80_degree, 1_GeV, 1_e);
1066
1067 ACTS_DEBUG("Create the measurements");
1068 using SimPropagator = Propagator<StraightLineStepper, Navigator>;
1069 const SimPropagator simPropagator = makeStraightPropagator(detector.geometry);
1070 auto measurements =
1071 createMeasurements(simPropagator, geoCtx, magCtx, parametersMeasurements,
1072 resMapAllPixel, rng);
1073
1074 const Vector2 scatterOffset = {100_mm, 100_mm};
1075 const std::size_t indexMaterialSurface = 3;
1076 for (std::size_t iMeas = indexMaterialSurface; iMeas < nSurfaces; iMeas++) {
1077
1078 const std::size_t offsetFactor = iMeas - indexMaterialSurface;
1079
1080 auto& sl = measurements.sourceLinks[iMeas];
1081 sl.parameters[0] += scatterOffset[0] * offsetFactor;
1082 sl.parameters[1] += scatterOffset[1] * offsetFactor;
1083 }
1084
1085 const auto sourceLinks = prepareSourceLinks(measurements.sourceLinks);
1086 ACTS_VERBOSE("sourceLinks.size() = " << sourceLinks.size());
1087
1088 BOOST_REQUIRE_EQUAL(sourceLinks.size(), nSurfaces);
1089
1090 ACTS_DEBUG("Set up the fitter");
1091 const Surface* rSurface = ¶metersMeasurements.referenceSurface();
1092
1093 using RecoStepper = EigenStepper<>;
1094 const auto recoPropagator =
1095 makeConstantFieldPropagator<RecoStepper>(detector.geometry, 0_T);
1096
1097 using RecoPropagator = decltype(recoPropagator);
1098 using Gx2Fitter = Gx2Fitter<RecoPropagator, VectorMultiTrajectory>;
1099 const Gx2Fitter fitter(recoPropagator, gx2fLogger->clone());
1100
1101 Gx2FitterExtensions<VectorMultiTrajectory> extensions;
1102 extensions.calibrator
1103 .connect<&testSourceLinkCalibratorStrict<VectorMultiTrajectory>>();
1104 TestSourceLink::SurfaceAccessor surfaceAccessor{*detector.geometry};
1105 extensions.surfaceAccessor
1106 .connect<&TestSourceLink::SurfaceAccessor::operator()>(&surfaceAccessor);
1107
1108 const Gx2FitterOptions gx2fOptions(geoCtx, magCtx, calCtx, extensions,
1109 PropagatorPlainOptions(geoCtx, magCtx),
1110 rSurface, true, false,
1111 FreeToBoundCorrection(false), 5, 0);
1112
1113 TrackContainer tracks{VectorTrackContainer{}, VectorMultiTrajectory{}};
1114
1115 ACTS_DEBUG("Fit the track");
1116 ACTS_VERBOSE("startParameter unsmeared:\n" << parametersMeasurements);
1117 ACTS_VERBOSE("startParameter fit:\n" << startParametersFit);
1118 const auto res = fitter.fit(sourceLinks.begin(), sourceLinks.end(),
1119 startParametersFit, gx2fOptions, tracks);
1120
1121
1122 {
1123 std::cout << "\n*** Create .obj of Detector ***\n" << std::endl;
1124
1125 ObjVisualization3D obj;
1126
1127 bool triangulate = true;
1128 ViewConfig viewSensitive = {.color = {0, 180, 240}};
1129 viewSensitive.triangulate = triangulate;
1130 ViewConfig viewPassive = {.color = {240, 280, 0}};
1131 viewPassive.triangulate = triangulate;
1132 ViewConfig viewVolume = {.color = {220, 220, 0}};
1133 viewVolume.triangulate = triangulate;
1134 ViewConfig viewContainer = {.color = {220, 220, 0}};
1135 viewContainer.triangulate = triangulate;
1136 ViewConfig viewGrid = {.color = {220, 0, 0}};
1137 viewGrid.quarterSegments = 8;
1138 viewGrid.offset = 3.;
1139 viewGrid.triangulate = triangulate;
1140
1141 std::string tag = "gx2f_toydet";
1142
1143 const TrackingVolume& tgVolume =
1144 *(detector.geometry->highestTrackingVolume());
1145
1146 GeometryView3D::drawTrackingVolume(obj, tgVolume, geoCtx, viewContainer,
1147 viewVolume, viewPassive, viewSensitive,
1148 viewGrid, true, tag);
1149 }
1150
1151 {
1152 std::cout << "\n*** Create .obj of measurements ***\n" << std::endl;
1153 ObjVisualization3D obj;
1154
1155 double localErrorScale = 10000000.;
1156 ViewConfig mcolor{.color = {255, 145, 48}};
1157 mcolor.offset = 2;
1158
1159
1160 drawMeasurements(obj, measurements, detector.geometry, geoCtx,
1161 localErrorScale, mcolor);
1162
1163 obj.write("meas");
1164 }
1165
1166 BOOST_REQUIRE(res.ok());
1167
1168 const auto& track = *res;
1169
1170 BOOST_CHECK_EQUAL(track.tipIndex(), nSurfaces - 1);
1171 BOOST_CHECK(track.hasReferenceSurface());
1172
1173
1174
1175
1176 BOOST_CHECK_EQUAL(track.nDoF(), nSurfaces * 2);
1177 BOOST_CHECK_EQUAL(track.nHoles(), 0u);
1178 BOOST_CHECK_EQUAL(track.nMeasurements(), nSurfaces);
1179 BOOST_CHECK_EQUAL(track.nSharedHits(), 0u);
1180 BOOST_CHECK_EQUAL(track.nOutliers(), 0u);
1181
1182
1183
1184
1185 BOOST_CHECK_CLOSE(track.parameters()[eBoundLoc0], -11., 26e0);
1186 BOOST_CHECK_CLOSE(track.parameters()[eBoundLoc1], -15., 15e0);
1187 BOOST_CHECK_CLOSE(track.parameters()[eBoundPhi], 1e-5, 1.1e3);
1188 BOOST_CHECK_CLOSE(track.parameters()[eBoundTheta], std::numbers::pi / 2,
1189 2e-2);
1190 BOOST_CHECK_EQUAL(track.parameters()[eBoundQOverP], 1);
1191 BOOST_CHECK_CLOSE(track.parameters()[eBoundTime],
1192 startParametersFit.parameters()[eBoundTime], 1e-6);
1193 BOOST_CHECK_CLOSE(track.covariance().determinant(), 3.5e-27, 1e1);
1194
1195
1196 BOOST_CHECK_EQUAL(
1197 (track.template component<
1198 std::uint32_t, hashString(Gx2fConstants::gx2fnUpdateColumn)>()),
1199 4);
1200
1201 ACTS_INFO("*** Test: Material -- Finish");
1202 }
1203 BOOST_AUTO_TEST_SUITE_END()
1204
1205 }