File indexing completed on 2025-08-06 08:11:31
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/Layer.hpp"
0018 #include "Acts/Geometry/TrackingGeometry.hpp"
0019 #include "Acts/Geometry/TrackingGeometryBuilder.hpp"
0020 #include "Acts/MagneticField/ConstantBField.hpp"
0021 #include "Acts/Material/HomogeneousSurfaceMaterial.hpp"
0022 #include "Acts/Material/HomogeneousVolumeMaterial.hpp"
0023 #include "Acts/Material/MaterialSlab.hpp"
0024 #include "Acts/Propagator/EigenStepper.hpp"
0025 #include "Acts/Propagator/Navigator.hpp"
0026 #include "Acts/Propagator/Propagator.hpp"
0027 #include "Acts/Propagator/StraightLineStepper.hpp"
0028 #include "Acts/Surfaces/RectangleBounds.hpp"
0029 #include "Acts/Tests/CommonHelpers/DetectorElementStub.hpp"
0030 #include "Acts/Tests/CommonHelpers/MeasurementsCreator.hpp"
0031 #include "Acts/Tests/CommonHelpers/PredefinedMaterials.hpp"
0032 #include "Acts/TrackFitting/GlobalChiSquareFitter.hpp"
0033 #include "Acts/Utilities/Logger.hpp"
0034
0035 #include <vector>
0036
0037 #include "FitterTestsCommon.hpp"
0038
0039 using namespace Acts::UnitLiterals;
0040 using namespace Acts::detail::Test;
0041
0042 Acts::Logging::Level logLevel = Acts::Logging::VERBOSE;
0043 const auto gx2fLogger = Acts::getDefaultLogger("Gx2f", logLevel);
0044
0045 namespace Acts::Test {
0046
0047
0048 Acts::CurvilinearTrackParameters makeParameters(
0049 const ActsScalar x = 0.0_m, const ActsScalar y = 0.0_m,
0050 const ActsScalar z = 0.0_m, const ActsScalar w = 42_ns,
0051 const ActsScalar phi = 0_degree, const ActsScalar theta = 90_degree,
0052 const ActsScalar p = 2_GeV, const ActsScalar q = 1_e) {
0053
0054 Acts::BoundVector stddev;
0055 stddev[Acts::eBoundLoc0] = 100_um;
0056 stddev[Acts::eBoundLoc1] = 100_um;
0057 stddev[Acts::eBoundTime] = 25_ns;
0058 stddev[Acts::eBoundPhi] = 2_degree;
0059 stddev[Acts::eBoundTheta] = 2_degree;
0060 stddev[Acts::eBoundQOverP] = 1 / 100_GeV;
0061 const Acts::BoundSquareMatrix cov = stddev.cwiseProduct(stddev).asDiagonal();
0062
0063 const Acts::Vector4 mPos4(x, y, z, w);
0064 return Acts::CurvilinearTrackParameters(mPos4, phi, theta, q / p, cov,
0065 Acts::ParticleHypothesis::pion());
0066 }
0067
0068 static std::vector<Acts::SourceLink> prepareSourceLinks(
0069 const std::vector<TestSourceLink>& sourceLinks) {
0070 std::vector<Acts::SourceLink> result;
0071 std::transform(sourceLinks.begin(), sourceLinks.end(),
0072 std::back_inserter(result),
0073 [](const auto& sl) { return Acts::SourceLink{sl}; });
0074 return result;
0075 }
0076
0077
0078
0079
0080
0081 std::shared_ptr<const TrackingGeometry> makeToyDetector(
0082 const Acts::GeometryContext& geoCtx, const std::size_t nSurfaces = 5) {
0083 if (nSurfaces < 1) {
0084 throw std::invalid_argument("At least 1 surfaces needs to be created.");
0085 }
0086
0087
0088 const double halfSizeSurface = 1_m;
0089
0090
0091 const double rotationAngle = M_PI * 0.5;
0092 const Vector3 xPos(cos(rotationAngle), 0., sin(rotationAngle));
0093 const Vector3 yPos(0., 1., 0.);
0094 const Vector3 zPos(-sin(rotationAngle), 0., cos(rotationAngle));
0095
0096
0097 CuboidVolumeBuilder cvb;
0098
0099
0100 std::vector<CuboidVolumeBuilder::SurfaceConfig> surfaceConfig;
0101 for (unsigned int surfPos = 1; surfPos <= nSurfaces; surfPos++) {
0102
0103 CuboidVolumeBuilder::SurfaceConfig cfg;
0104 cfg.position = {surfPos * UnitConstants::m, 0., 0.};
0105
0106
0107 cfg.rotation.col(0) = xPos;
0108 cfg.rotation.col(1) = yPos;
0109 cfg.rotation.col(2) = zPos;
0110
0111
0112 cfg.rBounds = std::make_shared<const RectangleBounds>(
0113 RectangleBounds(halfSizeSurface, halfSizeSurface));
0114
0115
0116 MaterialSlab matProp(makeBeryllium(), 0.5_mm);
0117 cfg.surMat = std::make_shared<HomogeneousSurfaceMaterial>(matProp);
0118
0119
0120 cfg.thickness = 1_um;
0121
0122 cfg.detElementConstructor =
0123 [](const Transform3& trans,
0124 const std::shared_ptr<const RectangleBounds>& bounds,
0125 double thickness) {
0126 return new DetectorElementStub(trans, bounds, thickness);
0127 };
0128 surfaceConfig.push_back(cfg);
0129 }
0130
0131
0132 std::vector<CuboidVolumeBuilder::LayerConfig> layerConfig;
0133 for (auto& sCfg : surfaceConfig) {
0134 CuboidVolumeBuilder::LayerConfig cfg;
0135 cfg.surfaceCfg = {sCfg};
0136 cfg.active = true;
0137 cfg.envelopeX = {-0.1_mm, 0.1_mm};
0138 cfg.envelopeY = {-0.1_mm, 0.1_mm};
0139 cfg.envelopeZ = {-0.1_mm, 0.1_mm};
0140 layerConfig.push_back(cfg);
0141 }
0142
0143
0144 CuboidVolumeBuilder::VolumeConfig volumeConfig;
0145 volumeConfig.length = {(nSurfaces + 1) * 1_m, 2 * halfSizeSurface,
0146 2 * halfSizeSurface};
0147 volumeConfig.position = {volumeConfig.length.x() / 2, 0., 0.};
0148 volumeConfig.layerCfg = layerConfig;
0149 volumeConfig.name = "Test volume";
0150
0151
0152 CuboidVolumeBuilder::Config config;
0153 config.length = {(nSurfaces + 1) * 1_m, 2 * halfSizeSurface,
0154 2 * halfSizeSurface};
0155 config.position = {volumeConfig.length.x() / 2, 0., 0.};
0156 config.volumeCfg = {volumeConfig};
0157
0158 cvb.setConfig(config);
0159
0160 TrackingGeometryBuilder::Config tgbCfg;
0161
0162 tgbCfg.trackingVolumeBuilders.push_back(
0163 [=](const auto& context, const auto& inner, const auto&) {
0164 return cvb.trackingVolume(context, inner, nullptr);
0165 });
0166
0167 TrackingGeometryBuilder tgb(tgbCfg);
0168
0169 std::unique_ptr<const TrackingGeometry> detector =
0170 tgb.trackingGeometry(geoCtx);
0171 return detector;
0172 }
0173
0174 struct Detector {
0175
0176 std::shared_ptr<const TrackingGeometry> geometry;
0177 };
0178
0179 BOOST_AUTO_TEST_SUITE(Gx2fTest)
0180 ACTS_LOCAL_LOGGER(Acts::getDefaultLogger("Gx2fTests", logLevel))
0181
0182
0183 const Acts::GeometryContext geoCtx;
0184 const Acts::MagneticFieldContext magCtx;
0185 const Acts::CalibrationContext calCtx;
0186
0187
0188 const MeasurementResolution resPixel = {MeasurementType::eLoc01,
0189 {25_um, 50_um}};
0190 const MeasurementResolution resStrip0 = {MeasurementType::eLoc0, {25_um}};
0191 const MeasurementResolution resStrip1 = {MeasurementType::eLoc1, {50_um}};
0192 const MeasurementResolutionMap resMapAllPixel = {
0193 {Acts::GeometryIdentifier().setVolume(0), resPixel}};
0194
0195
0196
0197 BOOST_AUTO_TEST_CASE(NoFit) {
0198 ACTS_INFO("*** Test: NoFit -- Start");
0199
0200 std::default_random_engine rng(42);
0201
0202 ACTS_DEBUG("Create the detector");
0203 const std::size_t nSurfaces = 5;
0204 Detector detector;
0205 detector.geometry = makeToyDetector(geoCtx, nSurfaces);
0206
0207 ACTS_DEBUG("Set the start parameters for measurement creation and fit");
0208 const auto parametersMeasurements = makeParameters();
0209 const auto startParametersFit = makeParameters(
0210 7_mm, 11_mm, 15_mm, 42_ns, 10_degree, 80_degree, 1_GeV, 1_e);
0211
0212 ACTS_DEBUG("Create the measurements");
0213 using SimPropagator =
0214 Acts::Propagator<Acts::StraightLineStepper, Acts::Navigator>;
0215 const SimPropagator simPropagator = makeStraightPropagator(detector.geometry);
0216 const auto measurements =
0217 createMeasurements(simPropagator, geoCtx, magCtx, parametersMeasurements,
0218 resMapAllPixel, rng);
0219 const auto sourceLinks = prepareSourceLinks(measurements.sourceLinks);
0220 ACTS_VERBOSE("sourceLinks.size() = " << sourceLinks.size());
0221
0222 ACTS_DEBUG("Set up the fitter");
0223
0224 using Gx2Fitter =
0225 Experimental::Gx2Fitter<SimPropagator, VectorMultiTrajectory>;
0226 const Gx2Fitter fitter(simPropagator, gx2fLogger->clone());
0227
0228 const Surface* rSurface = ¶metersMeasurements.referenceSurface();
0229
0230 Experimental::Gx2FitterExtensions<VectorMultiTrajectory> extensions;
0231 extensions.calibrator
0232 .connect<&testSourceLinkCalibrator<VectorMultiTrajectory>>();
0233 TestSourceLink::SurfaceAccessor surfaceAccessor{*detector.geometry};
0234 extensions.surfaceAccessor
0235 .connect<&TestSourceLink::SurfaceAccessor::operator()>(&surfaceAccessor);
0236
0237 Experimental::Gx2FitterOptions gx2fOptions(
0238 geoCtx, magCtx, calCtx, extensions, PropagatorPlainOptions(), rSurface,
0239 false, false, FreeToBoundCorrection(false), 0, true, 0);
0240
0241 Acts::TrackContainer tracks{Acts::VectorTrackContainer{},
0242 Acts::VectorMultiTrajectory{}};
0243
0244 ACTS_DEBUG("Fit the track");
0245 ACTS_VERBOSE("startParameter unsmeared:\n" << parametersMeasurements);
0246 ACTS_VERBOSE("startParameter fit:\n" << startParametersFit);
0247 const auto res = fitter.fit(sourceLinks.begin(), sourceLinks.end(),
0248 startParametersFit, gx2fOptions, tracks);
0249
0250 BOOST_REQUIRE(res.ok());
0251
0252 const auto& track = *res;
0253 BOOST_CHECK_EQUAL(track.tipIndex(), Acts::MultiTrajectoryTraits::kInvalid);
0254 BOOST_CHECK(track.hasReferenceSurface());
0255
0256
0257 BOOST_CHECK_EQUAL(track.chi2(), 0.);
0258 BOOST_CHECK_EQUAL(track.nDoF(), 0u);
0259 BOOST_CHECK_EQUAL(track.nHoles(), 0u);
0260 BOOST_CHECK_EQUAL(track.nMeasurements(), 0u);
0261 BOOST_CHECK_EQUAL(track.nSharedHits(), 0u);
0262 BOOST_CHECK_EQUAL(track.nOutliers(), 0u);
0263
0264
0265 BOOST_CHECK_EQUAL(track.parameters(), startParametersFit.parameters());
0266 BOOST_CHECK_EQUAL(track.covariance(), BoundMatrix::Identity());
0267
0268
0269 BOOST_CHECK_EQUAL(
0270 (track.template component<
0271 std::size_t,
0272 hashString(Experimental::Gx2fConstants::gx2fnUpdateColumn)>()),
0273 0);
0274
0275 ACTS_INFO("*** Test: NoFit -- Finish");
0276 }
0277
0278 BOOST_AUTO_TEST_CASE(Fit5Iterations) {
0279 ACTS_INFO("*** Test: Fit5Iterations -- Start");
0280
0281 std::default_random_engine rng(42);
0282
0283 ACTS_DEBUG("Create the detector");
0284 const std::size_t nSurfaces = 5;
0285 Detector detector;
0286 detector.geometry = makeToyDetector(geoCtx, nSurfaces);
0287
0288 ACTS_DEBUG("Set the start parameters for measurement creation and fit");
0289 const auto parametersMeasurements = makeParameters();
0290 const auto startParametersFit = makeParameters(
0291 7_mm, 11_mm, 15_mm, 42_ns, 10_degree, 80_degree, 1_GeV, 1_e);
0292
0293 ACTS_DEBUG("Create the measurements");
0294 using SimPropagator =
0295 Acts::Propagator<Acts::StraightLineStepper, Acts::Navigator>;
0296 const SimPropagator simPropagator = makeStraightPropagator(detector.geometry);
0297 const auto measurements =
0298 createMeasurements(simPropagator, geoCtx, magCtx, parametersMeasurements,
0299 resMapAllPixel, rng);
0300 const auto sourceLinks = prepareSourceLinks(measurements.sourceLinks);
0301 ACTS_VERBOSE("sourceLinks.size() = " << sourceLinks.size());
0302
0303 BOOST_REQUIRE_EQUAL(sourceLinks.size(), nSurfaces);
0304
0305 ACTS_DEBUG("Set up the fitter");
0306 const Surface* rSurface = ¶metersMeasurements.referenceSurface();
0307
0308 using RecoStepper = EigenStepper<>;
0309 const auto recoPropagator =
0310 makeConstantFieldPropagator<RecoStepper>(detector.geometry, 0_T);
0311
0312 using RecoPropagator = decltype(recoPropagator);
0313 using Gx2Fitter =
0314 Experimental::Gx2Fitter<RecoPropagator, VectorMultiTrajectory>;
0315 const Gx2Fitter fitter(recoPropagator, gx2fLogger->clone());
0316
0317 Experimental::Gx2FitterExtensions<VectorMultiTrajectory> extensions;
0318 extensions.calibrator
0319 .connect<&testSourceLinkCalibrator<VectorMultiTrajectory>>();
0320 TestSourceLink::SurfaceAccessor surfaceAccessor{*detector.geometry};
0321 extensions.surfaceAccessor
0322 .connect<&TestSourceLink::SurfaceAccessor::operator()>(&surfaceAccessor);
0323
0324 const Experimental::Gx2FitterOptions gx2fOptions(
0325 geoCtx, magCtx, calCtx, extensions, PropagatorPlainOptions(), rSurface,
0326 false, false, FreeToBoundCorrection(false), 5, true, 0);
0327
0328 Acts::TrackContainer tracks{Acts::VectorTrackContainer{},
0329 Acts::VectorMultiTrajectory{}};
0330
0331 ACTS_DEBUG("Fit the track");
0332 ACTS_VERBOSE("startParameter unsmeared:\n" << parametersMeasurements);
0333 ACTS_VERBOSE("startParameter fit:\n" << startParametersFit);
0334 const auto res = fitter.fit(sourceLinks.begin(), sourceLinks.end(),
0335 startParametersFit, gx2fOptions, tracks);
0336
0337 BOOST_REQUIRE(res.ok());
0338
0339 const auto& track = *res;
0340
0341 BOOST_CHECK_EQUAL(track.tipIndex(), nSurfaces - 1);
0342 BOOST_CHECK(track.hasReferenceSurface());
0343
0344
0345 CHECK_CLOSE_ABS(track.chi2(), 8., 2.);
0346 BOOST_CHECK_EQUAL(track.nDoF(), 10u);
0347 BOOST_CHECK_EQUAL(track.nHoles(), 0u);
0348 BOOST_CHECK_EQUAL(track.nMeasurements(), nSurfaces);
0349 BOOST_CHECK_EQUAL(track.nSharedHits(), 0u);
0350 BOOST_CHECK_EQUAL(track.nOutliers(), 0u);
0351
0352
0353
0354
0355 BOOST_CHECK_CLOSE(track.parameters()[eBoundLoc0], -11., 7e0);
0356 BOOST_CHECK_CLOSE(track.parameters()[eBoundLoc1], -15., 6e0);
0357 BOOST_CHECK_CLOSE(track.parameters()[eBoundPhi], 1e-5, 1e3);
0358 BOOST_CHECK_CLOSE(track.parameters()[eBoundTheta], M_PI / 2, 1e-3);
0359 BOOST_CHECK_EQUAL(track.parameters()[eBoundQOverP], 1);
0360 BOOST_CHECK_CLOSE(track.parameters()[eBoundTime], 12591.2832360000, 1e-6);
0361 BOOST_CHECK_CLOSE(track.covariance().determinant(), 1e-27, 4e0);
0362
0363
0364 BOOST_CHECK_EQUAL(
0365 (track.template component<
0366 std::size_t,
0367 hashString(Experimental::Gx2fConstants::gx2fnUpdateColumn)>()),
0368 5);
0369
0370 ACTS_INFO("*** Test: Fit5Iterations -- Finish");
0371 }
0372
0373 BOOST_AUTO_TEST_CASE(MixedDetector) {
0374 ACTS_INFO("*** Test: MixedDetector -- Start");
0375
0376 std::default_random_engine rng(42);
0377
0378 ACTS_DEBUG("Create the detector");
0379 const std::size_t nSurfaces = 7;
0380 Detector detector;
0381 detector.geometry = makeToyDetector(geoCtx, nSurfaces);
0382
0383 ACTS_DEBUG("Set the start parameters for measurement creation and fit");
0384 const auto parametersMeasurements = makeParameters();
0385 const auto startParametersFit = makeParameters(
0386 7_mm, 11_mm, 15_mm, 42_ns, 10_degree, 80_degree, 1_GeV, 1_e);
0387
0388 ACTS_DEBUG("Create the measurements");
0389 const MeasurementResolutionMap resMap = {
0390 {Acts::GeometryIdentifier().setVolume(2).setLayer(2), resPixel},
0391 {Acts::GeometryIdentifier().setVolume(2).setLayer(4), resStrip0},
0392 {Acts::GeometryIdentifier().setVolume(2).setLayer(6), resStrip1},
0393 {Acts::GeometryIdentifier().setVolume(2).setLayer(8), resPixel},
0394 {Acts::GeometryIdentifier().setVolume(2).setLayer(10), resStrip0},
0395 {Acts::GeometryIdentifier().setVolume(2).setLayer(12), resStrip1},
0396 {Acts::GeometryIdentifier().setVolume(2).setLayer(14), resPixel},
0397 };
0398
0399 using SimPropagator =
0400 Acts::Propagator<Acts::StraightLineStepper, Acts::Navigator>;
0401 const SimPropagator simPropagator = makeStraightPropagator(detector.geometry);
0402 const auto measurements = createMeasurements(
0403 simPropagator, geoCtx, magCtx, parametersMeasurements, resMap, rng);
0404 const auto sourceLinks = prepareSourceLinks(measurements.sourceLinks);
0405 ACTS_VERBOSE("sourceLinks.size() = " << sourceLinks.size());
0406
0407 BOOST_REQUIRE_EQUAL(sourceLinks.size(), nSurfaces);
0408
0409 ACTS_DEBUG("Set up the fitter");
0410 const Surface* rSurface = ¶metersMeasurements.referenceSurface();
0411
0412 using RecoStepper = EigenStepper<>;
0413 const auto recoPropagator =
0414 makeConstantFieldPropagator<RecoStepper>(detector.geometry, 0_T);
0415
0416 using RecoPropagator = decltype(recoPropagator);
0417 using Gx2Fitter =
0418 Experimental::Gx2Fitter<RecoPropagator, VectorMultiTrajectory>;
0419 const Gx2Fitter fitter(recoPropagator, gx2fLogger->clone());
0420
0421 Experimental::Gx2FitterExtensions<VectorMultiTrajectory> extensions;
0422 extensions.calibrator
0423 .connect<&testSourceLinkCalibrator<VectorMultiTrajectory>>();
0424 TestSourceLink::SurfaceAccessor surfaceAccessor{*detector.geometry};
0425 extensions.surfaceAccessor
0426 .connect<&TestSourceLink::SurfaceAccessor::operator()>(&surfaceAccessor);
0427
0428 const Experimental::Gx2FitterOptions gx2fOptions(
0429 geoCtx, magCtx, calCtx, extensions, PropagatorPlainOptions(), rSurface,
0430 false, false, FreeToBoundCorrection(false), 5, true, 0);
0431
0432 Acts::TrackContainer tracks{Acts::VectorTrackContainer{},
0433 Acts::VectorMultiTrajectory{}};
0434
0435 ACTS_DEBUG("Fit the track");
0436 ACTS_VERBOSE("startParameter unsmeared:\n" << parametersMeasurements);
0437 ACTS_VERBOSE("startParameter fit:\n" << startParametersFit);
0438 const auto res = fitter.fit(sourceLinks.begin(), sourceLinks.end(),
0439 startParametersFit, gx2fOptions, tracks);
0440
0441 BOOST_REQUIRE(res.ok());
0442
0443 const auto& track = *res;
0444 BOOST_CHECK_EQUAL(track.tipIndex(), nSurfaces - 1);
0445 BOOST_CHECK(track.hasReferenceSurface());
0446
0447
0448 CHECK_CLOSE_ABS(track.chi2(), 8.5, 4.);
0449 BOOST_CHECK_EQUAL(track.nDoF(), 10u);
0450 BOOST_CHECK_EQUAL(track.nHoles(), 0u);
0451 BOOST_CHECK_EQUAL(track.nMeasurements(), nSurfaces);
0452 BOOST_CHECK_EQUAL(track.nSharedHits(), 0u);
0453 BOOST_CHECK_EQUAL(track.nOutliers(), 0u);
0454
0455
0456
0457
0458 BOOST_CHECK_CLOSE(track.parameters()[eBoundLoc0], -11., 7e0);
0459 BOOST_CHECK_CLOSE(track.parameters()[eBoundLoc1], -15., 6e0);
0460 BOOST_CHECK_CLOSE(track.parameters()[eBoundPhi], 1e-5, 1e3);
0461 BOOST_CHECK_CLOSE(track.parameters()[eBoundTheta], M_PI / 2, 1e-3);
0462 BOOST_CHECK_EQUAL(track.parameters()[eBoundQOverP], 1);
0463 BOOST_CHECK_CLOSE(track.parameters()[eBoundTime], 12591.2832360000, 1e-6);
0464 BOOST_CHECK_CLOSE(track.covariance().determinant(), 2e-28, 1e0);
0465
0466
0467 BOOST_CHECK_EQUAL(
0468 (track.template component<
0469 std::size_t,
0470 hashString(Experimental::Gx2fConstants::gx2fnUpdateColumn)>()),
0471 5);
0472
0473 ACTS_INFO("*** Test: MixedDetector -- Finish");
0474 }
0475
0476
0477 BOOST_AUTO_TEST_CASE(FitWithBfield) {
0478 ACTS_INFO("*** Test: FitWithBfield -- Start");
0479
0480 std::default_random_engine rng(42);
0481
0482 ACTS_DEBUG("Create the detector");
0483 const std::size_t nSurfaces = 5;
0484 Detector detector;
0485 detector.geometry = makeToyDetector(geoCtx, nSurfaces);
0486
0487 ACTS_DEBUG("Set the start parameters for measurement creation and fit");
0488 const auto parametersMeasurements = makeParameters();
0489 const auto startParametersFit = makeParameters(
0490 7_mm, 11_mm, 15_mm, 42_ns, 10_degree, 80_degree, 1_GeV, 1_e);
0491
0492 ACTS_DEBUG("Create the measurements");
0493 using SimStepper = EigenStepper<>;
0494 const auto simPropagator =
0495 makeConstantFieldPropagator<SimStepper>(detector.geometry, 0.3_T);
0496
0497 const auto measurements =
0498 createMeasurements(simPropagator, geoCtx, magCtx, parametersMeasurements,
0499 resMapAllPixel, rng);
0500
0501 const auto sourceLinks = prepareSourceLinks(measurements.sourceLinks);
0502 ACTS_VERBOSE("sourceLinks.size() = " << sourceLinks.size());
0503
0504 BOOST_REQUIRE_EQUAL(sourceLinks.size(), nSurfaces);
0505
0506 ACTS_DEBUG("Set up the fitter");
0507 const Surface* rSurface = ¶metersMeasurements.referenceSurface();
0508
0509
0510 using SimPropagator = decltype(simPropagator);
0511 using Gx2Fitter =
0512 Experimental::Gx2Fitter<SimPropagator, VectorMultiTrajectory>;
0513 const Gx2Fitter fitter(simPropagator, gx2fLogger->clone());
0514
0515 Experimental::Gx2FitterExtensions<VectorMultiTrajectory> extensions;
0516 extensions.calibrator
0517 .connect<&testSourceLinkCalibrator<VectorMultiTrajectory>>();
0518 TestSourceLink::SurfaceAccessor surfaceAccessor{*detector.geometry};
0519 extensions.surfaceAccessor
0520 .connect<&TestSourceLink::SurfaceAccessor::operator()>(&surfaceAccessor);
0521
0522 const Experimental::Gx2FitterOptions gx2fOptions(
0523 geoCtx, magCtx, calCtx, extensions, PropagatorPlainOptions(), rSurface,
0524 false, false, FreeToBoundCorrection(false), 5, false, 0);
0525
0526 Acts::TrackContainer tracks{Acts::VectorTrackContainer{},
0527 Acts::VectorMultiTrajectory{}};
0528
0529 ACTS_DEBUG("Fit the track");
0530 ACTS_VERBOSE("startParameter unsmeared:\n" << parametersMeasurements);
0531 ACTS_VERBOSE("startParameter fit:\n" << startParametersFit);
0532 const auto res = fitter.fit(sourceLinks.begin(), sourceLinks.end(),
0533 startParametersFit, gx2fOptions, tracks);
0534
0535 BOOST_REQUIRE(res.ok());
0536
0537 const auto& track = *res;
0538 BOOST_CHECK_EQUAL(track.tipIndex(), nSurfaces - 1);
0539 BOOST_CHECK(track.hasReferenceSurface());
0540
0541
0542 CHECK_CLOSE_ABS(track.chi2(), 7.5, 1.5);
0543 BOOST_CHECK_EQUAL(track.nDoF(), 10u);
0544 BOOST_CHECK_EQUAL(track.nHoles(), 0u);
0545 BOOST_CHECK_EQUAL(track.nMeasurements(), nSurfaces);
0546 BOOST_CHECK_EQUAL(track.nSharedHits(), 0u);
0547 BOOST_CHECK_EQUAL(track.nOutliers(), 0u);
0548
0549
0550
0551
0552
0553 BOOST_CHECK_CLOSE(track.parameters()[eBoundLoc0], -11., 8e0);
0554 BOOST_CHECK_CLOSE(track.parameters()[eBoundLoc1], -15., 6e0);
0555 BOOST_CHECK_CLOSE(track.parameters()[eBoundPhi], 1e-4, 1e3);
0556 BOOST_CHECK_CLOSE(track.parameters()[eBoundTheta], M_PI / 2, 1e-3);
0557 BOOST_CHECK_CLOSE(track.parameters()[eBoundQOverP], 0.5, 2e-1);
0558 BOOST_CHECK_CLOSE(track.parameters()[eBoundTime], 12591.2832360000, 1e-6);
0559 BOOST_CHECK_CLOSE(track.covariance().determinant(), 8e-35, 4e0);
0560
0561
0562 BOOST_CHECK_EQUAL(
0563 (track.template component<
0564 std::size_t,
0565 hashString(Experimental::Gx2fConstants::gx2fnUpdateColumn)>()),
0566 5);
0567
0568 ACTS_INFO("*** Test: FitWithBfield -- Finish");
0569 }
0570
0571 BOOST_AUTO_TEST_CASE(relChi2changeCutOff) {
0572 ACTS_INFO("*** Test: relChi2changeCutOff -- Start");
0573
0574 std::default_random_engine rng(42);
0575
0576 ACTS_DEBUG("Create the detector");
0577 const std::size_t nSurfaces = 5;
0578 Detector detector;
0579 detector.geometry = makeToyDetector(geoCtx, nSurfaces);
0580
0581 ACTS_DEBUG("Set the start parameters for measurement creation and fit");
0582 const auto parametersMeasurements = makeParameters();
0583 const auto startParametersFit = makeParameters(
0584 7_mm, 11_mm, 15_mm, 42_ns, 10_degree, 80_degree, 1_GeV, 1_e);
0585
0586 ACTS_DEBUG("Create the measurements");
0587
0588 using SimPropagator =
0589 Acts::Propagator<Acts::StraightLineStepper, Acts::Navigator>;
0590 const SimPropagator simPropagator = makeStraightPropagator(detector.geometry);
0591 const auto measurements =
0592 createMeasurements(simPropagator, geoCtx, magCtx, parametersMeasurements,
0593 resMapAllPixel, rng);
0594 const auto sourceLinks = prepareSourceLinks(measurements.sourceLinks);
0595 ACTS_VERBOSE("sourceLinks.size() = " << sourceLinks.size());
0596
0597 BOOST_REQUIRE_EQUAL(sourceLinks.size(), nSurfaces);
0598
0599 ACTS_DEBUG("Set up the fitter");
0600 const Surface* rSurface = ¶metersMeasurements.referenceSurface();
0601
0602 using RecoStepper = EigenStepper<>;
0603 const auto recoPropagator =
0604 makeConstantFieldPropagator<RecoStepper>(detector.geometry, 0_T);
0605
0606 using RecoPropagator = decltype(recoPropagator);
0607 using Gx2Fitter =
0608 Experimental::Gx2Fitter<RecoPropagator, VectorMultiTrajectory>;
0609 const Gx2Fitter fitter(recoPropagator, gx2fLogger->clone());
0610
0611 Experimental::Gx2FitterExtensions<VectorMultiTrajectory> extensions;
0612 extensions.calibrator
0613 .connect<&testSourceLinkCalibrator<VectorMultiTrajectory>>();
0614 TestSourceLink::SurfaceAccessor surfaceAccessor{*detector.geometry};
0615 extensions.surfaceAccessor
0616 .connect<&TestSourceLink::SurfaceAccessor::operator()>(&surfaceAccessor);
0617
0618 const Experimental::Gx2FitterOptions gx2fOptions(
0619 geoCtx, magCtx, calCtx, extensions, PropagatorPlainOptions(), rSurface,
0620 false, false, FreeToBoundCorrection(false), 500, true, 1e-5);
0621
0622 Acts::TrackContainer tracks{Acts::VectorTrackContainer{},
0623 Acts::VectorMultiTrajectory{}};
0624
0625 ACTS_DEBUG("Fit the track");
0626 ACTS_VERBOSE("startParameter unsmeared:\n" << parametersMeasurements);
0627 ACTS_VERBOSE("startParameter fit:\n" << startParametersFit);
0628 const auto res = fitter.fit(sourceLinks.begin(), sourceLinks.end(),
0629 startParametersFit, gx2fOptions, tracks);
0630
0631 BOOST_REQUIRE(res.ok());
0632
0633 const auto& track = *res;
0634 BOOST_CHECK_EQUAL(track.tipIndex(), nSurfaces - 1);
0635 BOOST_CHECK(track.hasReferenceSurface());
0636
0637
0638 CHECK_CLOSE_ABS(track.chi2(), 8., 2.);
0639 BOOST_CHECK_EQUAL(track.nDoF(), 10u);
0640 BOOST_CHECK_EQUAL(track.nHoles(), 0u);
0641 BOOST_CHECK_EQUAL(track.nMeasurements(), nSurfaces);
0642 BOOST_CHECK_EQUAL(track.nSharedHits(), 0u);
0643 BOOST_CHECK_EQUAL(track.nOutliers(), 0u);
0644
0645
0646
0647
0648 BOOST_CHECK_CLOSE(track.parameters()[eBoundLoc0], -11., 7e0);
0649 BOOST_CHECK_CLOSE(track.parameters()[eBoundLoc1], -15., 6e0);
0650 BOOST_CHECK_CLOSE(track.parameters()[eBoundPhi], 1e-5, 1e3);
0651 BOOST_CHECK_CLOSE(track.parameters()[eBoundTheta], M_PI / 2, 1e-3);
0652 BOOST_CHECK_EQUAL(track.parameters()[eBoundQOverP], 1);
0653 BOOST_CHECK_CLOSE(track.parameters()[eBoundTime], 12591.2832360000, 1e-6);
0654 BOOST_CHECK_CLOSE(track.covariance().determinant(), 1e-27, 4e0);
0655
0656
0657 BOOST_CHECK_LT(
0658 (track.template component<
0659 std::size_t,
0660 hashString(Experimental::Gx2fConstants::gx2fnUpdateColumn)>()),
0661 10);
0662
0663 ACTS_INFO("*** Test: relChi2changeCutOff -- Finish");
0664 }
0665
0666 BOOST_AUTO_TEST_CASE(DidNotConverge) {
0667 ACTS_INFO("*** Test: DidNotConverge -- Start");
0668
0669 std::default_random_engine rng(42);
0670
0671 ACTS_DEBUG("Create the detector");
0672 const std::size_t nSurfaces = 5;
0673 Detector detector;
0674 detector.geometry = makeToyDetector(geoCtx, nSurfaces);
0675
0676 ACTS_DEBUG("Set the start parameters for measurement creation and fit");
0677 const auto parametersMeasurements = makeParameters();
0678 const auto startParametersFit = makeParameters(
0679 7_mm, 11_mm, 15_mm, 42_ns, 10_degree, 80_degree, 1_GeV, 1_e);
0680
0681 ACTS_DEBUG("Create the measurements");
0682
0683 using SimPropagator =
0684 Acts::Propagator<Acts::StraightLineStepper, Acts::Navigator>;
0685 const SimPropagator simPropagator = makeStraightPropagator(detector.geometry);
0686 const auto measurements =
0687 createMeasurements(simPropagator, geoCtx, magCtx, parametersMeasurements,
0688 resMapAllPixel, rng);
0689 const auto sourceLinks = prepareSourceLinks(measurements.sourceLinks);
0690 ACTS_VERBOSE("sourceLinks.size() = " << sourceLinks.size());
0691
0692 BOOST_REQUIRE_EQUAL(sourceLinks.size(), nSurfaces);
0693
0694 ACTS_DEBUG("Set up the fitter");
0695 const Surface* rSurface = ¶metersMeasurements.referenceSurface();
0696
0697 using RecoStepper = EigenStepper<>;
0698 const auto recoPropagator =
0699 makeConstantFieldPropagator<RecoStepper>(detector.geometry, 0_T);
0700
0701 using RecoPropagator = decltype(recoPropagator);
0702 using Gx2Fitter =
0703 Experimental::Gx2Fitter<RecoPropagator, VectorMultiTrajectory>;
0704 const Gx2Fitter fitter(recoPropagator, gx2fLogger->clone());
0705
0706 Experimental::Gx2FitterExtensions<VectorMultiTrajectory> extensions;
0707 extensions.calibrator
0708 .connect<&testSourceLinkCalibrator<VectorMultiTrajectory>>();
0709 TestSourceLink::SurfaceAccessor surfaceAccessor{*detector.geometry};
0710 extensions.surfaceAccessor
0711 .connect<&TestSourceLink::SurfaceAccessor::operator()>(&surfaceAccessor);
0712
0713
0714
0715
0716
0717 const Experimental::Gx2FitterOptions gx2fOptions(
0718 geoCtx, magCtx, calCtx, extensions, PropagatorPlainOptions(), rSurface,
0719 false, false, FreeToBoundCorrection(false), 6, true, 0);
0720
0721 Acts::TrackContainer tracks{Acts::VectorTrackContainer{},
0722 Acts::VectorMultiTrajectory{}};
0723
0724 ACTS_DEBUG("Fit the track");
0725 ACTS_VERBOSE("startParameter unsmeared:\n" << parametersMeasurements);
0726 ACTS_VERBOSE("startParameter fit:\n" << startParametersFit);
0727 const auto res = fitter.fit(sourceLinks.begin(), sourceLinks.end(),
0728 startParametersFit, gx2fOptions, tracks);
0729
0730 BOOST_REQUIRE(!res.ok());
0731 BOOST_CHECK_EQUAL(
0732 res.error(),
0733 Acts::Experimental::GlobalChiSquareFitterError::DidNotConverge);
0734
0735 ACTS_INFO("*** Test: DidNotConverge -- Finish");
0736 }
0737
0738 BOOST_AUTO_TEST_CASE(NotEnoughMeasurements) {
0739 ACTS_INFO("*** Test: NotEnoughMeasurements -- Start");
0740
0741 std::default_random_engine rng(42);
0742
0743 ACTS_DEBUG("Create the detector");
0744 const std::size_t nSurfaces = 2;
0745 Detector detector;
0746 detector.geometry = makeToyDetector(geoCtx, nSurfaces);
0747
0748 ACTS_DEBUG("Set the start parameters for measurement creation and fit");
0749 const auto parametersMeasurements = makeParameters();
0750 const auto startParametersFit = makeParameters(
0751 7_mm, 11_mm, 15_mm, 42_ns, 10_degree, 80_degree, 1_GeV, 1_e);
0752
0753 ACTS_DEBUG("Create the measurements");
0754
0755 using SimPropagator =
0756 Acts::Propagator<Acts::StraightLineStepper, Acts::Navigator>;
0757 const SimPropagator simPropagator = makeStraightPropagator(detector.geometry);
0758 const auto measurements =
0759 createMeasurements(simPropagator, geoCtx, magCtx, parametersMeasurements,
0760 resMapAllPixel, rng);
0761 const auto sourceLinks = prepareSourceLinks(measurements.sourceLinks);
0762 ACTS_VERBOSE("sourceLinks.size() = " << sourceLinks.size());
0763
0764 BOOST_REQUIRE_EQUAL(sourceLinks.size(), nSurfaces);
0765
0766 ACTS_DEBUG("Set up the fitter");
0767 const Surface* rSurface = ¶metersMeasurements.referenceSurface();
0768
0769 using RecoStepper = EigenStepper<>;
0770 const auto recoPropagator =
0771 makeConstantFieldPropagator<RecoStepper>(detector.geometry, 0_T);
0772
0773 using RecoPropagator = decltype(recoPropagator);
0774 using Gx2Fitter =
0775 Experimental::Gx2Fitter<RecoPropagator, VectorMultiTrajectory>;
0776 const Gx2Fitter fitter(recoPropagator, gx2fLogger->clone());
0777
0778 Experimental::Gx2FitterExtensions<VectorMultiTrajectory> extensions;
0779 extensions.calibrator
0780 .connect<&testSourceLinkCalibrator<VectorMultiTrajectory>>();
0781 TestSourceLink::SurfaceAccessor surfaceAccessor{*detector.geometry};
0782 extensions.surfaceAccessor
0783 .connect<&TestSourceLink::SurfaceAccessor::operator()>(&surfaceAccessor);
0784
0785 const Experimental::Gx2FitterOptions gx2fOptions(
0786 geoCtx, magCtx, calCtx, extensions, PropagatorPlainOptions(), rSurface,
0787 false, false, FreeToBoundCorrection(false), 6, true, 0);
0788
0789 Acts::TrackContainer tracks{Acts::VectorTrackContainer{},
0790 Acts::VectorMultiTrajectory{}};
0791
0792 ACTS_DEBUG("Fit the track");
0793 ACTS_VERBOSE("startParameter unsmeared:\n" << parametersMeasurements);
0794 ACTS_VERBOSE("startParameter fit:\n" << startParametersFit);
0795 const auto res = fitter.fit(sourceLinks.begin(), sourceLinks.end(),
0796 startParametersFit, gx2fOptions, tracks);
0797
0798 BOOST_REQUIRE(!res.ok());
0799 BOOST_CHECK_EQUAL(
0800 res.error(),
0801 Acts::Experimental::GlobalChiSquareFitterError::NotEnoughMeasurements);
0802
0803 ACTS_INFO("*** Test: NotEnoughMeasurements -- Finish");
0804 }
0805
0806 BOOST_AUTO_TEST_CASE(FindHoles) {
0807 ACTS_INFO("*** Test: FindHoles -- Start");
0808
0809 std::default_random_engine rng(42);
0810
0811 ACTS_DEBUG("Create the detector");
0812
0813 const std::size_t nSurfaces = 8;
0814 Detector detector;
0815 detector.geometry = makeToyDetector(geoCtx, nSurfaces);
0816
0817 ACTS_DEBUG("Set the start parameters for measurement creation and fit");
0818 const auto parametersMeasurements = makeParameters();
0819 const auto startParametersFit = makeParameters(
0820 7_mm, 11_mm, 15_mm, 42_ns, 10_degree, 80_degree, 1_GeV, 1_e);
0821
0822 ACTS_DEBUG("Create the measurements");
0823 using SimPropagator =
0824 Acts::Propagator<Acts::StraightLineStepper, Acts::Navigator>;
0825 const SimPropagator simPropagator = makeStraightPropagator(detector.geometry);
0826 const auto measurements =
0827 createMeasurements(simPropagator, geoCtx, magCtx, parametersMeasurements,
0828 resMapAllPixel, rng);
0829 auto sourceLinks = prepareSourceLinks(measurements.sourceLinks);
0830 ACTS_VERBOSE("sourceLinks.size() [before] = " << sourceLinks.size());
0831
0832
0833 sourceLinks.erase(std::next(sourceLinks.begin(), 0));
0834 ACTS_VERBOSE(
0835 "sourceLinks.size() [after first erase] = " << sourceLinks.size());
0836
0837
0838 sourceLinks.pop_back();
0839 ACTS_VERBOSE("sourceLinks.size() [after pop] = " << sourceLinks.size());
0840
0841
0842
0843 const std::size_t indexHole = sourceLinks.size() - 2;
0844 ACTS_VERBOSE("Remove measurement " << indexHole);
0845 sourceLinks.erase(std::next(sourceLinks.begin(), indexHole));
0846 ACTS_VERBOSE("sourceLinks.size() [after second-to-last erase]= "
0847 << sourceLinks.size());
0848
0849
0850
0851 const std::size_t nMeasurements = nSurfaces - 3;
0852 BOOST_REQUIRE_EQUAL(sourceLinks.size(), nMeasurements);
0853
0854 ACTS_DEBUG("Set up the fitter");
0855 const Surface* rSurface = ¶metersMeasurements.referenceSurface();
0856
0857 using RecoStepper = EigenStepper<>;
0858 const auto recoPropagator =
0859 makeConstantFieldPropagator<RecoStepper>(detector.geometry, 0_T);
0860
0861 using RecoPropagator = decltype(recoPropagator);
0862 using Gx2Fitter =
0863 Experimental::Gx2Fitter<RecoPropagator, VectorMultiTrajectory>;
0864 const Gx2Fitter fitter(recoPropagator, gx2fLogger->clone());
0865
0866 Experimental::Gx2FitterExtensions<VectorMultiTrajectory> extensions;
0867 extensions.calibrator
0868 .connect<&testSourceLinkCalibrator<VectorMultiTrajectory>>();
0869 TestSourceLink::SurfaceAccessor surfaceAccessor{*detector.geometry};
0870 extensions.surfaceAccessor
0871 .connect<&TestSourceLink::SurfaceAccessor::operator()>(&surfaceAccessor);
0872
0873 const Experimental::Gx2FitterOptions gx2fOptions(
0874 geoCtx, magCtx, calCtx, extensions, PropagatorPlainOptions(), rSurface,
0875 false, false, FreeToBoundCorrection(false), 20, true, 1e-5);
0876
0877 Acts::TrackContainer tracks{Acts::VectorTrackContainer{},
0878 Acts::VectorMultiTrajectory{}};
0879
0880 ACTS_DEBUG("Fit the track");
0881 ACTS_VERBOSE("startParameter unsmeared:\n" << parametersMeasurements);
0882 ACTS_VERBOSE("startParameter fit:\n" << startParametersFit);
0883 const auto res = fitter.fit(sourceLinks.begin(), sourceLinks.end(),
0884 startParametersFit, gx2fOptions, tracks);
0885
0886 BOOST_REQUIRE(res.ok());
0887
0888 const auto& track = *res;
0889
0890
0891
0892 BOOST_CHECK_EQUAL(track.tipIndex(), nSurfaces - 1 - 2);
0893 BOOST_CHECK(track.hasReferenceSurface());
0894
0895
0896 CHECK_CLOSE_ABS(track.chi2(), 6.5, 2.);
0897 BOOST_CHECK_EQUAL(track.nDoF(), 10u);
0898 BOOST_CHECK_EQUAL(track.nHoles(), 1u);
0899 BOOST_CHECK_EQUAL(track.nMeasurements(), nMeasurements);
0900 BOOST_CHECK_EQUAL(track.nSharedHits(), 0u);
0901 BOOST_CHECK_EQUAL(track.nOutliers(), 0u);
0902
0903
0904
0905
0906 BOOST_CHECK_CLOSE(track.parameters()[eBoundLoc0], -11., 7e0);
0907 BOOST_CHECK_CLOSE(track.parameters()[eBoundLoc1], -15., 6e0);
0908 BOOST_CHECK_CLOSE(track.parameters()[eBoundPhi], 1e-5, 1e3);
0909 BOOST_CHECK_CLOSE(track.parameters()[eBoundTheta], M_PI / 2, 1e-3);
0910 BOOST_CHECK_EQUAL(track.parameters()[eBoundQOverP], 1);
0911 BOOST_CHECK_CLOSE(track.parameters()[eBoundTime], 12591.2832360000, 1e-6);
0912 BOOST_CHECK_CLOSE(track.covariance().determinant(), 4.7e-28, 2e0);
0913
0914 ACTS_INFO("*** Test: FindHoles -- Finish");
0915 }
0916 BOOST_AUTO_TEST_SUITE_END()
0917 }