Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
AdaptiveMultiVertexFitterTests.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file AdaptiveMultiVertexFitterTests.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2019 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
9 #include <boost/test/data/test_case.hpp>
10 #include <boost/test/tools/output_test_stream.hpp>
11 #include <boost/test/unit_test.hpp>
12 
38 
39 #include <algorithm>
40 #include <array>
41 #include <cmath>
42 #include <iostream>
43 #include <map>
44 #include <memory>
45 #include <random>
46 #include <tuple>
47 #include <type_traits>
48 #include <utility>
49 #include <vector>
50 
51 namespace Acts {
52 namespace Test {
53 
54 using namespace Acts::UnitLiterals;
56 
59 using Linearizer = HelicalTrackLinearizer<Propagator>;
60 
61 // Create a test context
64 
65 // Vertex x/y position distribution
66 std::uniform_real_distribution<> vXYDist(-0.1_mm, 0.1_mm);
67 // Vertex z position distribution
68 std::uniform_real_distribution<> vZDist(-20_mm, 20_mm);
69 // Track d0 distribution
70 std::uniform_real_distribution<> d0Dist(-0.01_mm, 0.01_mm);
71 // Track z0 distribution
72 std::uniform_real_distribution<> z0Dist(-0.2_mm, 0.2_mm);
73 // Track pT distribution
74 std::uniform_real_distribution<> pTDist(1._GeV, 30._GeV);
75 // Track phi distribution
76 std::uniform_real_distribution<> phiDist(-M_PI, M_PI);
77 // Track theta distribution
78 std::uniform_real_distribution<> thetaDist(1.0, M_PI - 1.0);
79 // Track charge helper distribution
80 std::uniform_real_distribution<> qDist(-1, 1);
81 // Track IP resolution distribution
82 std::uniform_real_distribution<> resIPDist(0., 100._um);
83 // Track angular distribution
84 std::uniform_real_distribution<> resAngDist(0., 0.1);
85 // Track q/p resolution distribution
86 std::uniform_real_distribution<> resQoPDist(-0.1, 0.1);
87 // Number of tracks distritbution
88 std::uniform_int_distribution<> nTracksDist(3, 10);
89 
92 BOOST_AUTO_TEST_CASE(adaptive_multi_vertex_fitter_test) {
93  bool debugMode = false;
94 
95  // Set up RNG
96  int mySeed = 31415;
97  std::mt19937 gen(mySeed);
98 
99  // Set up constant B-Field
100  auto bField = std::make_shared<ConstantBField>(Vector3{0.0, 0.0, 1_T});
101 
102  // Set up EigenStepper
104 
105  // Set up propagator with void navigator
106  auto propagator = std::make_shared<Propagator>(stepper);
107 
110 
111  // IP 3D Estimator
113 
114  IPEstimator::Config ip3dEstCfg(bField, propagator);
115  IPEstimator ip3dEst(ip3dEstCfg);
116 
118  ip3dEst);
119 
120  // Linearizer for BoundTrackParameters type test
121  Linearizer::Config ltConfig(bField, propagator);
122  Linearizer linearizer(ltConfig);
123 
124  // Test smoothing
125  fitterCfg.doSmoothing = true;
126 
128 
129  // Create positions of three vertices, two of which (1 and 2) are
130  // close to one another and will share a common track later
131  Vector3 vtxPos1(-0.15_mm, -0.1_mm, -1.5_mm);
132  Vector3 vtxPos2(-0.1_mm, -0.15_mm, -3._mm);
133  Vector3 vtxPos3(0.2_mm, 0.2_mm, 10._mm);
134 
135  std::vector<Vector3> vtxPosVec{vtxPos1, vtxPos2, vtxPos3};
136 
137  // Resolutions, use the same for all tracks
138  double resD0 = resIPDist(gen);
139  double resZ0 = resIPDist(gen);
140  double resPh = resAngDist(gen);
141  double resTh = resAngDist(gen);
142  double resQp = resQoPDist(gen);
143 
144  std::vector<Vertex<BoundTrackParameters>> vtxList;
145  for (auto& vtxPos : vtxPosVec) {
146  Vertex<BoundTrackParameters> vtx(vtxPos);
147  // Set some vertex covariance
148  SquareMatrix4 posCovariance(SquareMatrix4::Identity());
149  vtx.setFullCovariance(posCovariance);
150  // Add to vertex list
151  vtxList.push_back(vtx);
152  }
153 
154  std::vector<Vertex<BoundTrackParameters>*> vtxPtrList;
155  int cv = 0;
156  if (debugMode) {
157  std::cout << "All vertices in test case: " << std::endl;
158  }
159  for (auto& vtx : vtxList) {
160  if (debugMode) {
161  cv++;
162  std::cout << "\t" << cv << ". vertex ptr: " << &vtx << std::endl;
163  }
164  vtxPtrList.push_back(&vtx);
165  }
166 
167  std::vector<BoundTrackParameters> allTracks;
168 
169  unsigned int nTracksPerVtx = 4;
170  // Construct nTracksPerVtx * 3 (3 vertices) random track emerging
171  // from vicinity of vertex positions
172  for (unsigned int iTrack = 0; iTrack < nTracksPerVtx * vtxPosVec.size();
173  iTrack++) {
174  // Construct positive or negative charge randomly
175  double q = qDist(gen) < 0 ? -1. : 1.;
176 
177  // Fill vector of track objects with simple covariance matrix
178  Covariance covMat;
179 
180  covMat << resD0 * resD0, 0., 0., 0., 0., 0., 0., resZ0 * resZ0, 0., 0., 0.,
181  0., 0., 0., resPh * resPh, 0., 0., 0., 0., 0., 0., resTh * resTh, 0.,
182  0., 0., 0., 0., 0., resQp * resQp, 0., 0., 0., 0., 0., 0., 1.;
183 
184  // Index of current vertex
185  int vtxIdx = (int)(iTrack / nTracksPerVtx);
186 
187  // Construct random track parameters
189  paramVec << d0Dist(gen), z0Dist(gen), phiDist(gen), thetaDist(gen),
190  q / pTDist(gen), 0.;
191 
192  std::shared_ptr<PerigeeSurface> perigeeSurface =
193  Surface::makeShared<PerigeeSurface>(vtxPosVec[vtxIdx]);
194 
195  allTracks.emplace_back(perigeeSurface, paramVec, std::move(covMat),
197  }
198 
199  if (debugMode) {
200  int ct = 0;
201  std::cout << "All tracks in test case: " << std::endl;
202  for (auto& trk : allTracks) {
203  ct++;
204  std::cout << "\t" << ct << ". track ptr: " << &trk << std::endl;
205  }
206  }
207 
210 
211  for (unsigned int iTrack = 0; iTrack < nTracksPerVtx * vtxPosVec.size();
212  iTrack++) {
213  // Index of current vertex
214  int vtxIdx = (int)(iTrack / nTracksPerVtx);
215  state.vtxInfoMap[&(vtxList[vtxIdx])].trackLinks.push_back(
216  &(allTracks[iTrack]));
217  state.tracksAtVerticesMap.insert(
218  std::make_pair(std::make_pair(&(allTracks[iTrack]), &(vtxList[vtxIdx])),
220  1., allTracks[iTrack], &(allTracks[iTrack]))));
221 
222  // Use first track also for second vertex to let vtx1 and vtx2
223  // share this track
224  if (iTrack == 0) {
225  state.vtxInfoMap[&(vtxList.at(1))].trackLinks.push_back(
226  &(allTracks[iTrack]));
227  state.tracksAtVerticesMap.insert(
228  std::make_pair(std::make_pair(&(allTracks[iTrack]), &(vtxList.at(1))),
230  1., allTracks[iTrack], &(allTracks[iTrack]))));
231  }
232  }
233 
234  for (auto& vtx : vtxPtrList) {
235  state.addVertexToMultiMap(*vtx);
236  if (debugMode) {
237  std::cout << "Vertex, with ptr: " << vtx << std::endl;
238  for (auto& trk : state.vtxInfoMap[vtx].trackLinks) {
239  std::cout << "\t track ptr: " << trk << std::endl;
240  }
241  }
242  }
243 
244  if (debugMode) {
245  std::cout << "Checking all vertices linked to a single track: "
246  << std::endl;
247  for (auto& trk : allTracks) {
248  std::cout << "Track with ptr: " << &trk << std::endl;
249  auto range = state.trackToVerticesMultiMap.equal_range(&trk);
250  for (auto vtxIter = range.first; vtxIter != range.second; ++vtxIter) {
251  std::cout << "\t used by vertex: " << vtxIter->second << std::endl;
252  }
253  }
254  }
255 
256  // Copy vertex seeds from state.vertexCollection to new
257  // list in order to be able to compare later
258  std::vector<Vertex<BoundTrackParameters>> seedListCopy = vtxList;
259 
260  auto res1 =
261  fitter.addVtxToFit(state, vtxList.at(0), linearizer, vertexingOptions);
262  if (debugMode) {
263  std::cout << "Tracks linked to each vertex AFTER fit: " << std::endl;
264  int c = 0;
265  for (auto& vtx : vtxPtrList) {
266  c++;
267  std::cout << c << ". vertex, with ptr: " << vtx << std::endl;
268  for (auto& trk : state.vtxInfoMap[vtx].trackLinks) {
269  std::cout << "\t track ptr: " << trk << std::endl;
270  }
271  }
272  }
273 
274  if (debugMode) {
275  std::cout << "Checking all vertices linked to a single track AFTER fit: "
276  << std::endl;
277  for (auto& trk : allTracks) {
278  std::cout << "Track with ptr: " << &trk << std::endl;
279  auto range = state.trackToVerticesMultiMap.equal_range(&trk);
280  for (auto vtxIter = range.first; vtxIter != range.second; ++vtxIter) {
281  std::cout << "\t used by vertex: " << vtxIter->second << std::endl;
282  }
283  }
284  }
285 
286  BOOST_CHECK(res1.ok());
287 
288  if (debugMode) {
289  std::cout << "Vertex positions after fit of vertex 1 and 2:" << std::endl;
290  std::cout << "Vtx 1, seed position:\n " << seedListCopy.at(0).fullPosition()
291  << "\nFitted position:\n " << vtxList.at(0).fullPosition()
292  << std::endl;
293  std::cout << "Vtx 2, seed position:\n " << seedListCopy.at(1).fullPosition()
294  << "\nFitted position:\n " << vtxList.at(1).fullPosition()
295  << std::endl;
296  std::cout << "Vtx 3, seed position:\n " << seedListCopy.at(2).fullPosition()
297  << "\nFitted position:\n " << vtxList.at(2).fullPosition()
298  << std::endl;
299  }
300 
301  // After fit of first vertex, only first and second vertex seed
302  // should have been modified while third vertex should remain untouched
303  BOOST_CHECK_NE(vtxList.at(0).fullPosition(),
304  seedListCopy.at(0).fullPosition());
305  BOOST_CHECK_NE(vtxList.at(1).fullPosition(),
306  seedListCopy.at(1).fullPosition());
307  BOOST_CHECK_EQUAL(vtxList.at(2).fullPosition(),
308  seedListCopy.at(2).fullPosition());
309 
310  CHECK_CLOSE_ABS(vtxList.at(0).fullPosition(),
311  seedListCopy.at(0).fullPosition(), 1_mm);
312  CHECK_CLOSE_ABS(vtxList.at(1).fullPosition(),
313  seedListCopy.at(1).fullPosition(), 1_mm);
314 
315  auto res2 =
316  fitter.addVtxToFit(state, vtxList.at(2), linearizer, vertexingOptions);
317  BOOST_CHECK(res2.ok());
318 
319  // Now also the third vertex should have been modified and fitted
320  BOOST_CHECK_NE(vtxList.at(2).fullPosition(),
321  seedListCopy.at(2).fullPosition());
322  CHECK_CLOSE_ABS(vtxList.at(2).fullPosition(),
323  seedListCopy.at(2).fullPosition(), 1_mm);
324 
325  if (debugMode) {
326  std::cout << "Vertex positions after fit of vertex 3:" << std::endl;
327  std::cout << "Vtx 1, seed position:\n " << seedListCopy.at(0).fullPosition()
328  << "\nFitted position:\n " << vtxList.at(0).fullPosition()
329  << std::endl;
330  std::cout << "Vtx 2, seed position:\n " << seedListCopy.at(1).fullPosition()
331  << "\nFitted position:\n " << vtxList.at(1).fullPosition()
332  << std::endl;
333  std::cout << "Vtx 3, seed position:\n " << seedListCopy.at(2).fullPosition()
334  << "\nFitted position:\n " << vtxList.at(2).fullPosition()
335  << std::endl;
336  }
337 }
338 
342 BOOST_AUTO_TEST_CASE(adaptive_multi_vertex_fitter_test_athena) {
343  // Set debug mode
344  bool debugMode = false;
345  // Set up constant B-Field
346  auto bField = std::make_shared<ConstantBField>(Vector3{0.0, 0.0, 2_T});
347 
348  // Set up EigenStepper
349  // EigenStepper<> stepper(bField);
351 
352  // Set up propagator with void navigator
353  auto propagator = std::make_shared<Propagator>(stepper);
354 
357 
358  // IP 3D Estimator
360 
361  IPEstimator::Config ip3dEstCfg(bField, propagator);
362  IPEstimator ip3dEst(ip3dEstCfg);
363 
364  std::vector<double> temperatures(1, 3.);
365  AnnealingUtility::Config annealingConfig;
366  annealingConfig.setOfTemperatures = temperatures;
367  AnnealingUtility annealingUtility(annealingConfig);
368 
370  ip3dEst);
371 
372  fitterCfg.annealingTool = annealingUtility;
373 
374  // Linearizer for BoundTrackParameters type test
375  Linearizer::Config ltConfig(bField, propagator);
376  Linearizer linearizer(ltConfig);
377 
378  // Test smoothing
379  // fitterCfg.doSmoothing = true;
380 
382 
383  // Create first vector of tracks
384  Vector3 pos1a(0.5_mm, -0.5_mm, 2.4_mm);
385  Vector3 mom1a(1000_MeV, 0_MeV, -500_MeV);
386  Vector3 pos1b(0.5_mm, -0.5_mm, 3.5_mm);
387  Vector3 mom1b(0_MeV, 1000_MeV, 500_MeV);
388  Vector3 pos1c(-0.2_mm, 0.1_mm, 3.4_mm);
389  Vector3 mom1c(-50_MeV, 180_MeV, 300_MeV);
390 
391  Vector3 pos1d(-0.1_mm, 0.3_mm, 3.0_mm);
392  Vector3 mom1d(-80_MeV, 480_MeV, -100_MeV);
393  Vector3 pos1e(-0.01_mm, 0.01_mm, 2.9_mm);
394  Vector3 mom1e(-600_MeV, 10_MeV, 210_MeV);
395 
396  Vector3 pos1f(-0.07_mm, 0.03_mm, 2.5_mm);
397  Vector3 mom1f(240_MeV, 110_MeV, 150_MeV);
398 
399  // Start creating some track parameters
400  Covariance covMat1;
401  covMat1 << 1_mm * 1_mm, 0, 0., 0, 0., 0, 0, 1_mm * 1_mm, 0, 0., 0, 0, 0., 0,
402  0.1, 0, 0, 0, 0, 0., 0, 0.1, 0, 0, 0., 0, 0, 0, 1. / (10_GeV * 10_GeV), 0,
403  0, 0, 0, 0, 0, 1_ns;
404 
405  std::vector<BoundTrackParameters> params1 = {
406  BoundTrackParameters::create(Surface::makeShared<PerigeeSurface>(pos1a),
407  geoContext, makeVector4(pos1a, 0),
408  mom1a.normalized(), 1_e / mom1a.norm(),
409  covMat1, ParticleHypothesis::pion())
410  .value(),
411  BoundTrackParameters::create(Surface::makeShared<PerigeeSurface>(pos1b),
412  geoContext, makeVector4(pos1b, 0),
413  mom1b.normalized(), -1_e / mom1b.norm(),
414  covMat1, ParticleHypothesis::pion())
415  .value(),
416  BoundTrackParameters::create(Surface::makeShared<PerigeeSurface>(pos1c),
417  geoContext, makeVector4(pos1c, 0),
418  mom1c.normalized(), 1_e / mom1c.norm(),
419  covMat1, ParticleHypothesis::pion())
420  .value(),
421  BoundTrackParameters::create(Surface::makeShared<PerigeeSurface>(pos1d),
422  geoContext, makeVector4(pos1d, 0),
423  mom1d.normalized(), -1_e / mom1d.norm(),
424  covMat1, ParticleHypothesis::pion())
425  .value(),
426  BoundTrackParameters::create(Surface::makeShared<PerigeeSurface>(pos1e),
427  geoContext, makeVector4(pos1e, 0),
428  mom1e.normalized(), 1_e / mom1e.norm(),
429  covMat1, ParticleHypothesis::pion())
430  .value(),
431  BoundTrackParameters::create(Surface::makeShared<PerigeeSurface>(pos1f),
432  geoContext, makeVector4(pos1f, 0),
433  mom1f.normalized(), -1_e / mom1f.norm(),
434  covMat1, ParticleHypothesis::pion())
435  .value(),
436  };
437 
438  // Create second vector of tracks
439  Vector3 pos2a(0.2_mm, 0_mm, -4.9_mm);
440  Vector3 mom2a(5000_MeV, 30_MeV, 200_MeV);
441  Vector3 pos2b(-0.5_mm, 0.1_mm, -5.1_mm);
442  Vector3 mom2b(800_MeV, 1200_MeV, 200_MeV);
443  Vector3 pos2c(0.05_mm, -0.5_mm, -4.7_mm);
444  Vector3 mom2c(400_MeV, -300_MeV, -200_MeV);
445 
446  // Define covariance as used in athena unit test
447  Covariance covMat2 = covMat1;
448 
449  std::vector<BoundTrackParameters> params2 = {
450  BoundTrackParameters::create(Surface::makeShared<PerigeeSurface>(pos2a),
451  geoContext, makeVector4(pos2a, 0),
452  mom2a.normalized(), 1_e / mom2a.norm(),
453  covMat2, ParticleHypothesis::pion())
454  .value(),
455  BoundTrackParameters::create(Surface::makeShared<PerigeeSurface>(pos2b),
456  geoContext, makeVector4(pos2b, 0),
457  mom2b.normalized(), -1_e / mom2b.norm(),
458  covMat2, ParticleHypothesis::pion())
459  .value(),
460  BoundTrackParameters::create(Surface::makeShared<PerigeeSurface>(pos2c),
461  geoContext, makeVector4(pos2c, 0),
462  mom2c.normalized(), -1_e / mom2c.norm(),
463  covMat2, ParticleHypothesis::pion())
464  .value(),
465  };
466  std::vector<Vertex<BoundTrackParameters>*> vtxList;
467 
470 
471  // The constraint vertex position covariance
472  SquareMatrix4 covConstr(SquareMatrix4::Identity());
473  covConstr = covConstr * 1e+8;
474  covConstr(3, 3) = 0.;
475 
476  // Prepare first vertex
477  Vector3 vtxPos1(0.15_mm, 0.15_mm, 2.9_mm);
478  Vertex<BoundTrackParameters> vtx1(vtxPos1);
479 
480  // Add to vertex list
481  vtxList.push_back(&vtx1);
482 
483  // The constraint vtx for vtx1
484  Vertex<BoundTrackParameters> vtx1Constr(vtxPos1);
485  vtx1Constr.setFullCovariance(covConstr);
486  vtx1Constr.setFitQuality(0, -3);
487 
488  // Prepare vtx info for fitter
490  vtxInfo1.linPoint.setZero();
491  vtxInfo1.linPoint.head<3>() = vtxPos1;
492  vtxInfo1.constraint = vtx1Constr;
493  vtxInfo1.oldPosition = vtxInfo1.linPoint;
494  vtxInfo1.seedPosition = vtxInfo1.linPoint;
495 
496  for (const auto& trk : params1) {
497  vtxInfo1.trackLinks.push_back(&trk);
498  state.tracksAtVerticesMap.insert(
499  std::make_pair(std::make_pair(&trk, &vtx1),
500  TrackAtVertex<BoundTrackParameters>(1.5, trk, &trk)));
501  }
502 
503  // Prepare second vertex
504  Vector3 vtxPos2(0.3_mm, -0.2_mm, -4.8_mm);
505  Vertex<BoundTrackParameters> vtx2(vtxPos2);
506 
507  // Add to vertex list
508  vtxList.push_back(&vtx2);
509 
510  // The constraint vtx for vtx2
511  Vertex<BoundTrackParameters> vtx2Constr(vtxPos2);
512  vtx2Constr.setFullCovariance(covConstr);
513  vtx2Constr.setFitQuality(0, -3);
514 
515  // Prepare vtx info for fitter
517  vtxInfo2.linPoint.setZero();
518  vtxInfo2.linPoint.head<3>() = vtxPos2;
519  vtxInfo2.constraint = vtx2Constr;
520  vtxInfo2.oldPosition = vtxInfo2.linPoint;
521  vtxInfo2.seedPosition = vtxInfo2.linPoint;
522 
523  for (const auto& trk : params2) {
524  vtxInfo2.trackLinks.push_back(&trk);
525  state.tracksAtVerticesMap.insert(
526  std::make_pair(std::make_pair(&trk, &vtx2),
527  TrackAtVertex<BoundTrackParameters>(1.5, trk, &trk)));
528  }
529 
530  state.vtxInfoMap[&vtx1] = std::move(vtxInfo1);
531  state.vtxInfoMap[&vtx2] = std::move(vtxInfo2);
532 
533  state.addVertexToMultiMap(vtx1);
534  state.addVertexToMultiMap(vtx2);
535 
536  // Fit vertices
537  fitter.fit(state, vtxList, linearizer, vertexingOptions);
538 
539  auto vtx1Pos = state.vertexCollection.at(0)->position();
540  auto vtx1Cov = state.vertexCollection.at(0)->covariance();
541  // auto vtx1Trks = state.vertexCollection.at(0)->tracks();
542  auto vtx1FQ = state.vertexCollection.at(0)->fitQuality();
543 
544  auto vtx2Pos = state.vertexCollection.at(1)->position();
545  auto vtx2Cov = state.vertexCollection.at(1)->covariance();
546  // auto vtx2Trks = state.vertexCollection.at(1)->tracks();
547  auto vtx2FQ = state.vertexCollection.at(1)->fitQuality();
548 
549  if (debugMode) {
550  // Vertex 1
551  std::cout << "Vertex 1, position: " << vtx1Pos << std::endl;
552  std::cout << "Vertex 1, covariance: " << vtx1Cov << std::endl;
553  // for (auto t : vtx1Trks) {
554  // std::cout << "\tTrackWeight:" << t.trackWeight << std::endl;
555  // }
556  std::cout << "Vertex 1, chi2: " << vtx1FQ.first << std::endl;
557  std::cout << "Vertex 1, ndf: " << vtx1FQ.second << std::endl;
558 
559  // Vertex 2
560  std::cout << "Vertex 2, position: " << vtx2Pos << std::endl;
561  std::cout << "Vertex 2, covariance: " << vtx2Cov << std::endl;
562  // for (auto t : vtx2Trks) {
563  // std::cout << "\tTrackWeight:" << t.trackWeight << std::endl;
564  // }
565  std::cout << "Vertex 2, chi2: " << vtx2FQ.first << std::endl;
566  std::cout << "Vertex 2, ndf: " << vtx2FQ.second << std::endl;
567  }
568 
569  // Expected values from Athena implementation
570  // Vertex 1
571  const Vector3 expVtx1Pos(0.077_mm, -0.189_mm, 2.924_mm);
572 
573  // Helper matrix to create const expVtx1Cov below
574  SquareMatrix3 expVtx1Cov;
575  expVtx1Cov << 0.329, 0.016, -0.035, 0.016, 0.250, 0.085, -0.035, 0.085, 0.242;
576 
577  ActsVector<6> expVtx1TrkWeights;
578  expVtx1TrkWeights << 0.8128, 0.7994, 0.8164, 0.8165, 0.8165, 0.8119;
579  const double expVtx1chi2 = 0.9812;
580  const double expVtx1ndf = 6.7474;
581 
582  // Vertex 2
583  const Vector3 expVtx2Pos(-0.443_mm, -0.044_mm, -4.829_mm);
584  // Helper matrix to create const expVtx2Cov below
585  SquareMatrix3 expVtx2Cov;
586  expVtx2Cov << 1.088, 0.028, -0.066, 0.028, 0.643, 0.073, -0.066, 0.073, 0.435;
587 
588  const Vector3 expVtx2TrkWeights(0.8172, 0.8150, 0.8137);
589  const double expVtx2chi2 = 0.2114;
590  const double expVtx2ndf = 1.8920;
591 
592  // Compare the results
593  // Vertex 1
594  CHECK_CLOSE_ABS(vtx1Pos, expVtx1Pos, 0.001_mm);
595  CHECK_CLOSE_ABS(vtx1Cov, expVtx1Cov, 0.001_mm);
596  for (int i = 0; i < expVtx1TrkWeights.size(); i++) {
597  // CHECK_CLOSE_ABS(vtx1Trks[i].trackWeight, expVtx1TrkWeights[i], 0.001);
598  }
599  CHECK_CLOSE_ABS(vtx1FQ.first, expVtx1chi2, 0.001);
600  CHECK_CLOSE_ABS(vtx1FQ.second, expVtx1ndf, 0.001);
601 
602  // Vertex 2
603  CHECK_CLOSE_ABS(vtx2Pos, expVtx2Pos, 0.001_mm);
604  CHECK_CLOSE_ABS(vtx2Cov, expVtx2Cov, 0.001_mm);
605  for (int i = 0; i < expVtx2TrkWeights.size(); i++) {
606  // CHECK_CLOSE_ABS(vtx2Trks[i].trackWeight, expVtx2TrkWeights[i], 0.001);
607  }
608  CHECK_CLOSE_ABS(vtx2FQ.first, expVtx2chi2, 0.001);
609  CHECK_CLOSE_ABS(vtx2FQ.second, expVtx2ndf, 0.001);
610 }
611 
612 } // namespace Test
613 } // namespace Acts