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