File indexing completed on 2026-07-13 07:37:53
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/TrackParametrization.hpp"
0013 #include "Acts/Definitions/Units.hpp"
0014 #include "Acts/EventData/BoundTrackParameters.hpp"
0015 #include "Acts/Geometry/GeometryContext.hpp"
0016 #include "Acts/MagneticField/ConstantBField.hpp"
0017 #include "Acts/MagneticField/MagneticFieldContext.hpp"
0018 #include "Acts/Propagator/EigenStepper.hpp"
0019 #include "Acts/Propagator/Propagator.hpp"
0020 #include "Acts/Utilities/AnnealingUtility.hpp"
0021 #include "Acts/Utilities/Result.hpp"
0022 #include "Acts/Vertexing/AdaptiveGridDensityVertexFinder.hpp"
0023 #include "Acts/Vertexing/AdaptiveMultiVertexFinder.hpp"
0024 #include "Acts/Vertexing/AdaptiveMultiVertexFitter.hpp"
0025 #include "Acts/Vertexing/GaussianTrackDensity.hpp"
0026 #include "Acts/Vertexing/GridDensityVertexFinder.hpp"
0027 #include "Acts/Vertexing/HelicalTrackLinearizer.hpp"
0028 #include "Acts/Vertexing/IVertexFinder.hpp"
0029 #include "Acts/Vertexing/ImpactPointEstimator.hpp"
0030 #include "Acts/Vertexing/TrackAtVertex.hpp"
0031 #include "Acts/Vertexing/TrackDensityVertexFinder.hpp"
0032 #include "Acts/Vertexing/Vertex.hpp"
0033 #include "Acts/Vertexing/VertexingOptions.hpp"
0034 #include "ActsTests/CommonHelpers/FloatComparisons.hpp"
0035
0036 #include <array>
0037 #include <chrono>
0038 #include <cmath>
0039 #include <iostream>
0040 #include <memory>
0041 #include <numbers>
0042 #include <string>
0043 #include <system_error>
0044 #include <tuple>
0045 #include <utility>
0046 #include <vector>
0047
0048 #include "VertexingDataHelper.hpp"
0049
0050 using namespace Acts;
0051 using namespace Acts::UnitLiterals;
0052
0053 namespace ActsTests {
0054
0055 using Covariance = BoundMatrix;
0056 using Propagator = Acts::Propagator<EigenStepper<>>;
0057 using Linearizer = HelicalTrackLinearizer;
0058
0059
0060 GeometryContext geoContext = GeometryContext::dangerouslyDefaultConstruct();
0061 MagneticFieldContext magFieldContext = MagneticFieldContext();
0062
0063 const std::string toolString = "AMVF";
0064
0065 class FixedVertexSeedFinder final : public IVertexFinder {
0066 public:
0067 struct State {};
0068
0069 explicit FixedVertexSeedFinder(std::vector<Vertex> seeds)
0070 : m_seeds(std::move(seeds)) {}
0071
0072 Result<std::vector<Vertex>> find(
0073 const std::vector<InputTrack>& ,
0074 const VertexingOptions& ,
0075 IVertexFinder::State& ) const override {
0076 return m_seeds;
0077 }
0078
0079 IVertexFinder::State makeState(
0080 const MagneticFieldContext& ) const override {
0081 return IVertexFinder::State{State{}};
0082 }
0083
0084 void setTracksToRemove(
0085 IVertexFinder::State& ,
0086 const std::vector<InputTrack>& ) const override {}
0087
0088 private:
0089 std::vector<Vertex> m_seeds;
0090 };
0091
0092 BOOST_AUTO_TEST_SUITE(VertexingSuite)
0093
0094
0095 BOOST_AUTO_TEST_CASE(adaptive_multi_vertex_finder_test) {
0096
0097 bool debugMode = false;
0098
0099 auto bField = std::make_shared<ConstantBField>(Vector3(0., 0., 2_T));
0100
0101
0102
0103 EigenStepper<> stepper(bField);
0104
0105
0106 auto propagator = std::make_shared<Propagator>(stepper);
0107
0108
0109 ImpactPointEstimator::Config ipEstimatorCfg(bField, propagator);
0110 ImpactPointEstimator ipEstimator(ipEstimatorCfg);
0111
0112 std::vector<double> temperatures{
0113 8., 4., 2., std::numbers::sqrt2, std::sqrt(3. / 2.), 1.};
0114 AnnealingUtility::Config annealingConfig;
0115 annealingConfig.setOfTemperatures = temperatures;
0116 AnnealingUtility annealingUtility(annealingConfig);
0117
0118 using Fitter = AdaptiveMultiVertexFitter;
0119
0120 Fitter::Config fitterCfg(ipEstimator);
0121
0122 fitterCfg.annealingTool = annealingUtility;
0123
0124
0125 Linearizer::Config ltConfig;
0126 ltConfig.bField = bField;
0127 ltConfig.propagator = propagator;
0128 Linearizer linearizer(ltConfig);
0129
0130
0131 fitterCfg.doSmoothing = true;
0132 fitterCfg.extractParameters.connect<&InputTrack::extractParameters>();
0133 fitterCfg.trackLinearizer.connect<&Linearizer::linearizeTrack>(&linearizer);
0134
0135 Fitter fitter(fitterCfg);
0136
0137 GaussianTrackDensity::Config densityCfg;
0138 densityCfg.extractParameters.connect<&InputTrack::extractParameters>();
0139 auto seedFinder = std::make_shared<TrackDensityVertexFinder>(
0140 TrackDensityVertexFinder::Config{Acts::GaussianTrackDensity(densityCfg)});
0141
0142 AdaptiveMultiVertexFinder::Config finderConfig(std::move(fitter), seedFinder,
0143 ipEstimator, bField);
0144 finderConfig.extractParameters.connect<&InputTrack::extractParameters>();
0145
0146 AdaptiveMultiVertexFinder finder(std::move(finderConfig));
0147 IVertexFinder::State state = finder.makeState(magFieldContext);
0148
0149 auto csvData = readTracksAndVertexCSV(toolString);
0150 std::vector<BoundTrackParameters> tracks = std::get<TracksData>(csvData);
0151
0152 if (debugMode) {
0153 std::cout << "Number of tracks in event: " << tracks.size() << std::endl;
0154 int maxCout = 10;
0155 int count = 0;
0156 for (const auto& trk : tracks) {
0157 std::cout << count << ". track: " << std::endl;
0158 std::cout << "params: " << trk << std::endl;
0159 count++;
0160 if (count == maxCout) {
0161 break;
0162 }
0163 }
0164 }
0165
0166 std::vector<InputTrack> inputTracks;
0167 for (const auto& trk : tracks) {
0168 inputTracks.emplace_back(&trk);
0169 }
0170
0171
0172 Vertex bsConstr = std::get<BeamSpotData>(csvData);
0173 VertexingOptions vertexingOptions(geoContext, magFieldContext, bsConstr);
0174
0175 auto t1 = std::chrono::system_clock::now();
0176 auto findResult = finder.find(inputTracks, vertexingOptions, state);
0177 auto t2 = std::chrono::system_clock::now();
0178
0179 auto timediff =
0180 std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count();
0181
0182 if (!findResult.ok()) {
0183 std::cout << findResult.error().message() << std::endl;
0184 }
0185
0186 BOOST_CHECK(findResult.ok());
0187
0188 std::vector<Vertex> allVertices = *findResult;
0189
0190 if (debugMode) {
0191 std::cout << "Time needed: " << timediff << " ms." << std::endl;
0192 std::cout << "Number of vertices reconstructed: " << allVertices.size()
0193 << std::endl;
0194
0195 int count = 0;
0196 for (const auto& vtx : allVertices) {
0197 count++;
0198 std::cout << count << ". Vertex at position: " << vtx.position()[0]
0199 << ", " << vtx.position()[1] << ", " << vtx.position()[2]
0200 << std::endl;
0201 std::cout << count << ". Vertex with cov: " << vtx.covariance()
0202 << std::endl;
0203 std::cout << "\t with n tracks: " << vtx.tracks().size() << std::endl;
0204 }
0205 }
0206
0207
0208
0209 auto verticesInfo = std::get<VerticesData>(csvData);
0210 const int expNRecoVertices = verticesInfo.size();
0211
0212 BOOST_CHECK_EQUAL(allVertices.size(), expNRecoVertices);
0213
0214 double relTol = 1e-2;
0215 double small = 1e-3;
0216 for (int i = 0; i < expNRecoVertices; i++) {
0217 auto recoVtx = allVertices[i];
0218 auto expVtx = verticesInfo[i];
0219 CHECK_CLOSE_OR_SMALL(recoVtx.position(), expVtx.position, relTol, small);
0220 CHECK_CLOSE_OR_SMALL(recoVtx.covariance(), expVtx.covariance, relTol,
0221 small);
0222 BOOST_CHECK_EQUAL(recoVtx.tracks().size(), expVtx.nTracks);
0223 CHECK_CLOSE_OR_SMALL(recoVtx.tracks()[0].trackWeight, expVtx.trk1Weight,
0224 relTol, small);
0225 CHECK_CLOSE_OR_SMALL(recoVtx.tracks()[0].vertexCompatibility,
0226 expVtx.trk1Comp, relTol, small);
0227 }
0228 }
0229
0230
0231 struct InputTrackStub {
0232 InputTrackStub(const BoundTrackParameters& params, int id)
0233 : m_parameters(params), m_id(id) {}
0234
0235 const BoundTrackParameters& parameters() const { return m_parameters; }
0236
0237
0238 int id() const { return m_id; }
0239
0240 private:
0241 BoundTrackParameters m_parameters;
0242
0243
0244 int m_id;
0245 };
0246
0247
0248 BOOST_AUTO_TEST_CASE(adaptive_multi_vertex_finder_usertype_test) {
0249
0250 bool debugMode = false;
0251
0252 auto bField = std::make_shared<ConstantBField>(Vector3(0., 0., 2_T));
0253
0254
0255
0256 EigenStepper<> stepper(bField);
0257
0258
0259 auto propagator = std::make_shared<Propagator>(stepper);
0260
0261
0262
0263 auto extractParameters = [](const InputTrack& track) {
0264 return track.as<InputTrackStub>()->parameters();
0265 };
0266
0267
0268 ImpactPointEstimator::Config ipEstimatorCfg(bField, propagator);
0269 ImpactPointEstimator ipEstimator(ipEstimatorCfg);
0270
0271 std::vector<double> temperatures{
0272 8., 4., 2., std::numbers::sqrt2, std::sqrt(3. / 2.), 1.};
0273 AnnealingUtility::Config annealingConfig;
0274 annealingConfig.setOfTemperatures = temperatures;
0275 AnnealingUtility annealingUtility(annealingConfig);
0276
0277 using Fitter = AdaptiveMultiVertexFitter;
0278
0279 Fitter::Config fitterCfg(ipEstimator);
0280
0281 fitterCfg.annealingTool = annealingUtility;
0282
0283
0284 Linearizer::Config ltConfig;
0285 ltConfig.bField = bField;
0286 ltConfig.propagator = propagator;
0287 Linearizer linearizer(ltConfig);
0288
0289
0290 fitterCfg.doSmoothing = true;
0291 fitterCfg.extractParameters.connect(extractParameters);
0292 fitterCfg.trackLinearizer.connect<&Linearizer::linearizeTrack>(&linearizer);
0293
0294 Fitter fitter(fitterCfg);
0295
0296 GaussianTrackDensity::Config densityCfg;
0297 densityCfg.extractParameters.connect(extractParameters);
0298 auto seedFinder = std::make_shared<TrackDensityVertexFinder>(
0299 TrackDensityVertexFinder::Config{Acts::GaussianTrackDensity(densityCfg)});
0300
0301 AdaptiveMultiVertexFinder::Config finderConfig(
0302 std::move(fitter), std::move(seedFinder), ipEstimator, bField);
0303 finderConfig.extractParameters.connect(extractParameters);
0304
0305 AdaptiveMultiVertexFinder finder(std::move(finderConfig));
0306 IVertexFinder::State state = finder.makeState(magFieldContext);
0307
0308 auto csvData = readTracksAndVertexCSV(toolString);
0309 auto tracks = std::get<TracksData>(csvData);
0310
0311 std::vector<InputTrackStub> userTracks;
0312 int idCount = 0;
0313 for (const auto& trk : tracks) {
0314 userTracks.push_back(InputTrackStub(trk, idCount));
0315 idCount++;
0316 }
0317
0318 if (debugMode) {
0319 std::cout << "Number of tracks in event: " << tracks.size() << std::endl;
0320 int maxCout = 10;
0321 int count = 0;
0322 for (const auto& trk : tracks) {
0323 std::cout << count << ". track: " << std::endl;
0324 std::cout << "params: " << trk << std::endl;
0325 count++;
0326 if (count == maxCout) {
0327 break;
0328 }
0329 }
0330 }
0331
0332 std::vector<InputTrack> userInputTracks;
0333 for (const auto& trk : userTracks) {
0334 userInputTracks.emplace_back(&trk);
0335 }
0336
0337 Vertex constraintVtx;
0338 constraintVtx.setPosition(std::get<BeamSpotData>(csvData).position());
0339 constraintVtx.setCovariance(std::get<BeamSpotData>(csvData).covariance());
0340
0341 VertexingOptions vertexingOptions(geoContext, magFieldContext, constraintVtx);
0342
0343 auto findResult = finder.find(userInputTracks, vertexingOptions, state);
0344
0345 if (!findResult.ok()) {
0346 std::cout << findResult.error().message() << std::endl;
0347 }
0348
0349 BOOST_CHECK(findResult.ok());
0350
0351 std::vector<Vertex> allVertices = *findResult;
0352
0353 if (debugMode) {
0354 std::cout << "Number of vertices reconstructed: " << allVertices.size()
0355 << std::endl;
0356
0357 int count = 0;
0358 for (const auto& vtx : allVertices) {
0359 count++;
0360 std::cout << count << ". Vertex at position: " << vtx.position()[0]
0361 << ", " << vtx.position()[1] << ", " << vtx.position()[2]
0362 << std::endl;
0363 std::cout << count << ". Vertex with cov: " << vtx.covariance()
0364 << std::endl;
0365 std::cout << "\t with n tracks: " << vtx.tracks().size() << std::endl;
0366 }
0367 for (auto& trk : allVertices[0].tracks()) {
0368 std::cout << "Track ID at first vertex: "
0369 << trk.originalParams.as<InputTrackStub>()->id() << std::endl;
0370 }
0371 }
0372
0373 auto verticesInfo = std::get<VerticesData>(csvData);
0374 const int expNRecoVertices = verticesInfo.size();
0375
0376 BOOST_CHECK_EQUAL(allVertices.size(), expNRecoVertices);
0377
0378 double relTol = 1e-2;
0379 double small = 1e-3;
0380 for (int i = 0; i < expNRecoVertices; i++) {
0381 auto recoVtx = allVertices[i];
0382 auto expVtx = verticesInfo[i];
0383 CHECK_CLOSE_OR_SMALL(recoVtx.position(), expVtx.position, relTol, small);
0384 CHECK_CLOSE_OR_SMALL(recoVtx.covariance(), expVtx.covariance, relTol,
0385 small);
0386 BOOST_CHECK_EQUAL(recoVtx.tracks().size(), expVtx.nTracks);
0387 CHECK_CLOSE_OR_SMALL(recoVtx.tracks()[0].trackWeight, expVtx.trk1Weight,
0388 relTol, small);
0389 CHECK_CLOSE_OR_SMALL(recoVtx.tracks()[0].vertexCompatibility,
0390 expVtx.trk1Comp, relTol, small);
0391 }
0392 }
0393
0394
0395 BOOST_AUTO_TEST_CASE(adaptive_multi_vertex_finder_grid_seed_finder_test) {
0396
0397 bool debugMode = false;
0398 if (debugMode) {
0399 std::cout << "Starting AMVF test with grid seed finder..." << std::endl;
0400 }
0401
0402 auto bField = std::make_shared<ConstantBField>(Vector3(0., 0., 2_T));
0403
0404
0405
0406 EigenStepper<> stepper(bField);
0407
0408
0409 auto propagator = std::make_shared<Propagator>(stepper);
0410
0411
0412 ImpactPointEstimator::Config ipEstCfg(bField, propagator);
0413 ImpactPointEstimator ipEst(ipEstCfg);
0414
0415 std::vector<double> temperatures{
0416 8., 4., 2., std::numbers::sqrt2, std::sqrt(3. / 2.), 1.};
0417 AnnealingUtility::Config annealingConfig;
0418 annealingConfig.setOfTemperatures = temperatures;
0419 AnnealingUtility annealingUtility(annealingConfig);
0420
0421 using Fitter = AdaptiveMultiVertexFitter;
0422
0423 Fitter::Config fitterCfg(ipEst);
0424
0425 fitterCfg.annealingTool = annealingUtility;
0426
0427
0428 Linearizer::Config ltConfig;
0429 ltConfig.bField = bField;
0430 ltConfig.propagator = propagator;
0431 Linearizer linearizer(ltConfig);
0432
0433
0434 fitterCfg.doSmoothing = true;
0435 fitterCfg.extractParameters.connect<&InputTrack::extractParameters>();
0436 fitterCfg.trackLinearizer.connect<&Linearizer::linearizeTrack>(&linearizer);
0437
0438 Fitter fitter(fitterCfg);
0439
0440 using SeedFinder = GridDensityVertexFinder;
0441 GaussianGridTrackDensity::Config gDensityConfig(250, 4000, 55);
0442 GaussianGridTrackDensity gDensity(gDensityConfig);
0443 SeedFinder::Config seedFinderCfg(gDensity);
0444 seedFinderCfg.cacheGridStateForTrackRemoval = true;
0445 seedFinderCfg.extractParameters.connect<&InputTrack::extractParameters>();
0446
0447 auto seedFinder = std::make_shared<SeedFinder>(seedFinderCfg);
0448
0449 AdaptiveMultiVertexFinder::Config finderConfig(
0450 std::move(fitter), std::move(seedFinder), ipEst, bField);
0451 finderConfig.extractParameters.connect<&InputTrack::extractParameters>();
0452
0453 AdaptiveMultiVertexFinder finder(std::move(finderConfig));
0454 IVertexFinder::State state = finder.makeState(magFieldContext);
0455
0456 auto csvData = readTracksAndVertexCSV(toolString);
0457 auto tracks = std::get<TracksData>(csvData);
0458
0459 if (debugMode) {
0460 std::cout << "Number of tracks in event: " << tracks.size() << std::endl;
0461 int maxCout = 10;
0462 int count = 0;
0463 for (const auto& trk : tracks) {
0464 std::cout << count << ". track: " << std::endl;
0465 std::cout << "params: " << trk << std::endl;
0466 count++;
0467 if (count == maxCout) {
0468 break;
0469 }
0470 }
0471 }
0472
0473 std::vector<InputTrack> inputTracks;
0474 for (const auto& trk : tracks) {
0475 inputTracks.emplace_back(&trk);
0476 }
0477
0478
0479 Vertex bsConstr = std::get<BeamSpotData>(csvData);
0480 VertexingOptions vertexingOptions(geoContext, magFieldContext, bsConstr);
0481
0482 auto t1 = std::chrono::system_clock::now();
0483 auto findResult = finder.find(inputTracks, vertexingOptions, state);
0484 auto t2 = std::chrono::system_clock::now();
0485
0486 auto timediff =
0487 std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count();
0488
0489 if (!findResult.ok()) {
0490 std::cout << findResult.error().message() << std::endl;
0491 }
0492
0493 BOOST_CHECK(findResult.ok());
0494
0495 std::vector<Vertex> allVertices = *findResult;
0496
0497 if (debugMode) {
0498 std::cout << "Time needed: " << timediff << " ms." << std::endl;
0499 std::cout << "Number of vertices reconstructed: " << allVertices.size()
0500 << std::endl;
0501
0502 int count = 0;
0503 for (const auto& vtx : allVertices) {
0504 count++;
0505 std::cout << count << ". Vertex at position: " << vtx.position()[0]
0506 << ", " << vtx.position()[1] << ", " << vtx.position()[2]
0507 << std::endl;
0508 std::cout << count << ". Vertex with cov: " << vtx.covariance()
0509 << std::endl;
0510 std::cout << "\t with n tracks: " << vtx.tracks().size() << std::endl;
0511 }
0512 }
0513
0514
0515 auto verticesInfo = std::get<VerticesData>(csvData);
0516 const int expNRecoVertices = verticesInfo.size();
0517
0518 BOOST_CHECK_EQUAL(allVertices.size(), expNRecoVertices);
0519 std::vector<bool> vtxFound(expNRecoVertices, false);
0520
0521 for (const auto& vtx : allVertices) {
0522 double vtxZ = vtx.position()[2];
0523 double diffZ = 1e5;
0524 int foundVtxIdx = -1;
0525 for (int i = 0; i < expNRecoVertices; i++) {
0526 if (!vtxFound[i]) {
0527 if (std::abs(vtxZ - verticesInfo[i].position[2]) < diffZ) {
0528 diffZ = std::abs(vtxZ - verticesInfo[i].position[2]);
0529 foundVtxIdx = i;
0530 }
0531 }
0532 }
0533 if (diffZ < 0.5_mm) {
0534 vtxFound[foundVtxIdx] = true;
0535 CHECK_CLOSE_ABS(vtx.tracks().size(), verticesInfo[foundVtxIdx].nTracks,
0536 1);
0537 }
0538 }
0539 for (bool found : vtxFound) {
0540 BOOST_CHECK_EQUAL(found, true);
0541 }
0542 }
0543
0544
0545 BOOST_AUTO_TEST_CASE(
0546 adaptive_multi_vertex_finder_adaptive_grid_seed_finder_test) {
0547
0548 bool debugMode = false;
0549 if (debugMode) {
0550 std::cout << "Starting AMVF test with adaptive grid seed finder..."
0551 << std::endl;
0552 }
0553
0554 auto bField = std::make_shared<ConstantBField>(Vector3(0., 0., 2_T));
0555
0556
0557
0558 EigenStepper<> stepper(bField);
0559
0560
0561 auto propagator = std::make_shared<Propagator>(stepper);
0562
0563
0564 ImpactPointEstimator::Config ipEstCfg(bField, propagator);
0565 ImpactPointEstimator ipEst(ipEstCfg);
0566
0567 std::vector<double> temperatures{
0568 8., 4., 2., std::numbers::sqrt2, std::sqrt(3. / 2.), 1.};
0569 AnnealingUtility::Config annealingConfig;
0570 annealingConfig.setOfTemperatures = temperatures;
0571 AnnealingUtility annealingUtility(annealingConfig);
0572
0573 using Fitter = AdaptiveMultiVertexFitter;
0574
0575 Fitter::Config fitterCfg(ipEst);
0576
0577 fitterCfg.annealingTool = annealingUtility;
0578
0579
0580 Linearizer::Config ltConfig;
0581 ltConfig.bField = bField;
0582 ltConfig.propagator = propagator;
0583 Linearizer linearizer(ltConfig);
0584
0585
0586 fitterCfg.doSmoothing = true;
0587 fitterCfg.extractParameters.connect<&InputTrack::extractParameters>();
0588 fitterCfg.trackLinearizer.connect<&Linearizer::linearizeTrack>(&linearizer);
0589
0590 Fitter fitter(fitterCfg);
0591
0592
0593 AdaptiveGridTrackDensity::Config gridDensityCfg;
0594
0595
0596 gridDensityCfg.spatialTrkGridSizeRange = {55, 55};
0597 gridDensityCfg.spatialBinExtent = 0.05;
0598 AdaptiveGridTrackDensity gridDensity(gridDensityCfg);
0599
0600 using SeedFinder = AdaptiveGridDensityVertexFinder;
0601 SeedFinder::Config seedFinderCfg(gridDensity);
0602 seedFinderCfg.cacheGridStateForTrackRemoval = true;
0603 seedFinderCfg.extractParameters.connect<&InputTrack::extractParameters>();
0604
0605 auto seedFinder = std::make_shared<SeedFinder>(seedFinderCfg);
0606
0607 AdaptiveMultiVertexFinder::Config finderConfig(
0608 std::move(fitter), std::move(seedFinder), ipEst, bField);
0609 finderConfig.extractParameters.connect<&InputTrack::extractParameters>();
0610
0611 AdaptiveMultiVertexFinder finder(std::move(finderConfig));
0612 IVertexFinder::State state = finder.makeState(magFieldContext);
0613
0614 auto csvData = readTracksAndVertexCSV(toolString);
0615 auto tracks = std::get<TracksData>(csvData);
0616
0617 if (debugMode) {
0618 std::cout << "Number of tracks in event: " << tracks.size() << std::endl;
0619 int maxCout = 10;
0620 int count = 0;
0621 for (const auto& trk : tracks) {
0622 std::cout << count << ". track: " << std::endl;
0623 std::cout << "params: " << trk << std::endl;
0624 count++;
0625 if (count == maxCout) {
0626 break;
0627 }
0628 }
0629 }
0630
0631 std::vector<InputTrack> inputTracks;
0632 for (const auto& trk : tracks) {
0633 inputTracks.emplace_back(&trk);
0634 }
0635
0636 Vertex bsConstr = std::get<BeamSpotData>(csvData);
0637 VertexingOptions vertexingOptions(geoContext, magFieldContext, bsConstr);
0638
0639 auto t1 = std::chrono::system_clock::now();
0640 auto findResult = finder.find(inputTracks, vertexingOptions, state);
0641 auto t2 = std::chrono::system_clock::now();
0642
0643 auto timediff =
0644 std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count();
0645
0646 if (!findResult.ok()) {
0647 std::cout << findResult.error().message() << std::endl;
0648 }
0649
0650 BOOST_CHECK(findResult.ok());
0651
0652 std::vector<Vertex> allVertices = *findResult;
0653
0654 if (debugMode) {
0655 std::cout << "Time needed: " << timediff << " ms." << std::endl;
0656 std::cout << "Number of vertices reconstructed: " << allVertices.size()
0657 << std::endl;
0658
0659 int count = 0;
0660 for (const auto& vtx : allVertices) {
0661 count++;
0662 std::cout << count << ". Vertex at position: " << vtx.position()[0]
0663 << ", " << vtx.position()[1] << ", " << vtx.position()[2]
0664 << std::endl;
0665 std::cout << count << ". Vertex with cov: " << vtx.covariance()
0666 << std::endl;
0667 std::cout << "\t with n tracks: " << vtx.tracks().size() << std::endl;
0668 }
0669 }
0670
0671
0672 auto verticesInfo = std::get<VerticesData>(csvData);
0673 const int expNRecoVertices = verticesInfo.size();
0674
0675 BOOST_CHECK_EQUAL(allVertices.size(), expNRecoVertices);
0676 std::vector<bool> vtxFound(expNRecoVertices, false);
0677
0678 for (const auto& vtx : allVertices) {
0679 double vtxZ = vtx.position()[2];
0680 double diffZ = 1e5;
0681 int foundVtxIdx = -1;
0682 for (int i = 0; i < expNRecoVertices; i++) {
0683 if (!vtxFound[i]) {
0684 if (std::abs(vtxZ - verticesInfo[i].position[2]) < diffZ) {
0685 diffZ = std::abs(vtxZ - verticesInfo[i].position[2]);
0686 foundVtxIdx = i;
0687 }
0688 }
0689 }
0690 if (diffZ < 0.5_mm) {
0691 vtxFound[foundVtxIdx] = true;
0692 CHECK_CLOSE_ABS(vtx.tracks().size(), verticesInfo[foundVtxIdx].nTracks,
0693 2);
0694 }
0695 }
0696 for (bool found : vtxFound) {
0697 BOOST_CHECK_EQUAL(found, true);
0698 }
0699 }
0700
0701 BOOST_AUTO_TEST_CASE(adaptive_multi_vertex_finder_removes_rejected_seed) {
0702 auto bField = std::make_shared<ConstantBField>(Vector3(0., 0., 2_T));
0703
0704 EigenStepper<> stepper(bField);
0705 auto propagator = std::make_shared<Propagator>(stepper);
0706
0707 ImpactPointEstimator::Config ipEstCfg(bField, propagator);
0708 ImpactPointEstimator ipEst(ipEstCfg);
0709
0710 std::vector<double> temperatures{
0711 8., 4., 2., std::numbers::sqrt2, std::sqrt(3. / 2.), 1.};
0712 AnnealingUtility::Config annealingConfig;
0713 annealingConfig.setOfTemperatures = temperatures;
0714 AnnealingUtility annealingUtility(annealingConfig);
0715
0716 using Fitter = AdaptiveMultiVertexFitter;
0717
0718 Fitter::Config fitterCfg(ipEst);
0719 fitterCfg.annealingTool = annealingUtility;
0720
0721 Linearizer::Config ltConfig;
0722 ltConfig.bField = bField;
0723 ltConfig.propagator = propagator;
0724 Linearizer linearizer(ltConfig);
0725
0726 fitterCfg.doSmoothing = true;
0727 fitterCfg.extractParameters.connect<&InputTrack::extractParameters>();
0728 fitterCfg.trackLinearizer.connect<&Linearizer::linearizeTrack>(&linearizer);
0729
0730 Fitter fitter(fitterCfg);
0731
0732 auto csvData = readTracksAndVertexCSV(toolString);
0733 auto tracks = std::get<TracksData>(csvData);
0734 auto verticesInfo = std::get<VerticesData>(csvData);
0735 BOOST_REQUIRE_GE(verticesInfo.size(), 2u);
0736
0737 std::vector<Vertex> seeds;
0738 seeds.emplace_back(verticesInfo[0].position);
0739 seeds.back().setCovariance(verticesInfo[0].covariance);
0740 seeds.emplace_back(verticesInfo[1].position);
0741 seeds.back().setCovariance(verticesInfo[1].covariance);
0742
0743 auto seedFinder = std::make_shared<FixedVertexSeedFinder>(std::move(seeds));
0744
0745 AdaptiveMultiVertexFinder::Config finderConfig(
0746 std::move(fitter), std::move(seedFinder), ipEst, bField);
0747 finderConfig.extractParameters.connect<&InputTrack::extractParameters>();
0748 finderConfig.maxMergeVertexSignificance = 1e9;
0749 finderConfig.maxIterations = 1;
0750
0751 AdaptiveMultiVertexFinder finder(std::move(finderConfig));
0752 IVertexFinder::State state = finder.makeState(magFieldContext);
0753
0754 std::vector<InputTrack> inputTracks;
0755 for (const auto& trk : tracks) {
0756 inputTracks.emplace_back(&trk);
0757 }
0758
0759 VertexingOptions vertexingOptions(geoContext, magFieldContext,
0760 std::get<BeamSpotData>(csvData));
0761
0762 auto findResult = finder.find(inputTracks, vertexingOptions, state);
0763
0764 if (!findResult.ok()) {
0765 std::cout << findResult.error().message() << std::endl;
0766 }
0767
0768 BOOST_REQUIRE(findResult.ok());
0769
0770 std::vector<Vertex> allVertices = *findResult;
0771 BOOST_CHECK_EQUAL(allVertices.size(), 1u);
0772 BOOST_CHECK_GT(allVertices.front().tracks().size(), 1u);
0773 }
0774
0775 BOOST_AUTO_TEST_SUITE_END()
0776
0777 }