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