EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
AdaptiveMultiVertexFinderTests.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file AdaptiveMultiVertexFinderTests.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2019-2020 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 
18 #include "Acts/Utilities/Units.hpp"
26 
27 #include <chrono>
28 
29 #include "VertexingDataHelper.hpp"
30 
31 namespace Acts {
32 namespace Test {
33 
34 using namespace Acts::UnitLiterals;
35 
39 
40 // Create a test context
43 
44 const std::string toolString = "AMVF";
45 
47 BOOST_AUTO_TEST_CASE(adaptive_multi_vertex_finder_test) {
48  // Set debug mode
49  bool debugMode = false;
50  // Set up constant B-Field
51  ConstantBField bField(Vector3D(0., 0., 2_T));
52 
53  // Set up EigenStepper
54  // EigenStepper<ConstantBField> stepper(bField);
56 
57  // Set up propagator with void navigator
58  auto propagator = std::make_shared<Propagator>(stepper);
59 
60  // IP 3D Estimator
62 
63  IPEstimator::Config ipEstimatorCfg(bField, propagator);
64  IPEstimator ipEstimator(ipEstimatorCfg);
65 
66  std::vector<double> temperatures{8.0, 4.0, 2.0, 1.4142136, 1.2247449, 1.0};
67  AnnealingUtility::Config annealingConfig(temperatures);
68  AnnealingUtility annealingUtility(annealingConfig);
69 
71 
72  Fitter::Config fitterCfg(ipEstimator);
73 
74  fitterCfg.annealingTool = annealingUtility;
75 
76  // Linearizer for BoundTrackParameters type test
77  Linearizer::Config ltConfig(bField, propagator);
78  Linearizer linearizer(ltConfig);
79 
80  // Test smoothing
81  fitterCfg.doSmoothing = true;
82 
83  Fitter fitter(fitterCfg);
84 
85  using SeedFinder =
88 
89  SeedFinder seedFinder;
90 
92 
93  Finder::Config finderConfig(std::move(fitter), seedFinder, ipEstimator,
94  linearizer);
95 
96  // TODO: test this as well!
97  // finderConfig.useBeamSpotConstraint = false;
98 
99  Finder finder(finderConfig);
100  Finder::State state;
101 
102  auto csvData = readTracksAndVertexCSV(toolString);
103  auto tracks = std::get<TracksData>(csvData);
104 
105  if (debugMode) {
106  std::cout << "Number of tracks in event: " << tracks.size() << std::endl;
107  int maxCout = 10;
108  int count = 0;
109  for (const auto& trk : tracks) {
110  std::cout << count << ". track: " << std::endl;
111  std::cout << "params: " << trk << std::endl;
112  count++;
113  if (count == maxCout) {
114  break;
115  }
116  }
117  }
118 
119  std::vector<const BoundTrackParameters*> tracksPtr;
120  for (const auto& trk : tracks) {
121  tracksPtr.push_back(&trk);
122  }
123 
126 
127  vertexingOptions.vertexConstraint = std::get<BeamSpotData>(csvData);
128 
129  auto t1 = std::chrono::system_clock::now();
130  auto findResult = finder.find(tracksPtr, vertexingOptions, state);
131  auto t2 = std::chrono::system_clock::now();
132 
133  auto timediff =
134  std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count();
135 
136  if (!findResult.ok()) {
137  std::cout << findResult.error().message() << std::endl;
138  }
139 
140  BOOST_CHECK(findResult.ok());
141 
142  std::vector<Vertex<BoundTrackParameters>> allVertices = *findResult;
143 
144  if (debugMode) {
145  std::cout << "Time needed: " << timediff << " ms." << std::endl;
146  std::cout << "Number of vertices reconstructed: " << allVertices.size()
147  << std::endl;
148 
149  int count = 0;
150  for (const auto& vtx : allVertices) {
151  count++;
152  std::cout << count << ". Vertex at position: " << vtx.position()[0]
153  << ", " << vtx.position()[1] << ", " << vtx.position()[2]
154  << std::endl;
155  std::cout << count << ". Vertex with cov: " << vtx.covariance()
156  << std::endl;
157  std::cout << "\t with n tracks: " << vtx.tracks().size() << std::endl;
158  }
159  }
160 
161  // Test expected outcomes from athena implementation
162  // Number of reconstructed vertices
163  auto verticesInfo = std::get<VerticesData>(csvData);
164  const int expNRecoVertices = verticesInfo.size();
165 
166  BOOST_CHECK_EQUAL(allVertices.size(), expNRecoVertices);
167 
168  for (int i = 0; i < expNRecoVertices; i++) {
169  auto recoVtx = allVertices[i];
170  auto expVtx = verticesInfo[i];
171  CHECK_CLOSE_ABS(recoVtx.position(), expVtx.position, 0.001_mm);
172  CHECK_CLOSE_ABS(recoVtx.covariance(), expVtx.covariance, 0.001_mm);
173  BOOST_CHECK_EQUAL(recoVtx.tracks().size(), expVtx.nTracks);
174  CHECK_CLOSE_ABS(recoVtx.tracks()[0].trackWeight, expVtx.trk1Weight, 0.003);
175  CHECK_CLOSE_ABS(recoVtx.tracks()[0].vertexCompatibility, expVtx.trk1Comp,
176  0.003);
177  }
178 }
179 
180 // Dummy user-defined InputTrack type
181 struct InputTrack {
182  InputTrack(const BoundTrackParameters& params, int id)
183  : m_parameters(params), m_id(id) {}
184 
185  const BoundTrackParameters& parameters() const { return m_parameters; }
186  // store e.g. link to original objects here
187 
188  int id() const { return m_id; }
189 
190  private:
192 
193  // Some test track ID
194  int m_id;
195 };
196 
198 BOOST_AUTO_TEST_CASE(adaptive_multi_vertex_finder_usertype_test) {
199  // Set debug mode
200  bool debugMode = false;
201  // Set up constant B-Field
202  ConstantBField bField(Vector3D(0., 0., 2_T));
203 
204  // Set up EigenStepper
205  // EigenStepper<ConstantBField> stepper(bField);
207 
208  // Set up propagator with void navigator
209  auto propagator = std::make_shared<Propagator>(stepper);
210 
211  // Create a custom std::function to extract BoundTrackParameters from
212  // user-defined InputTrack
213  std::function<BoundTrackParameters(InputTrack)> extractParameters =
214  [](InputTrack params) { return params.parameters(); };
215 
216  // IP 3D Estimator
218 
219  IPEstimator::Config ipEstimatorCfg(bField, propagator);
220  IPEstimator ipEstimator(ipEstimatorCfg);
221 
222  std::vector<double> temperatures{8.0, 4.0, 2.0, 1.4142136, 1.2247449, 1.0};
223  AnnealingUtility::Config annealingConfig(temperatures);
224  AnnealingUtility annealingUtility(annealingConfig);
225 
227 
228  Fitter::Config fitterCfg(ipEstimator);
229 
230  fitterCfg.annealingTool = annealingUtility;
231 
232  // Linearizer
233  Linearizer::Config ltConfig(bField, propagator);
234  Linearizer linearizer(ltConfig);
235 
236  // Test smoothing
237  fitterCfg.doSmoothing = true;
238 
239  Fitter fitter(fitterCfg, extractParameters);
240 
241  using SeedFinder =
243 
244  SeedFinder seedFinder(extractParameters);
245 
247 
248  Finder::Config finderConfig(std::move(fitter), seedFinder, ipEstimator,
249  linearizer);
250  Finder::State state;
251 
252  Finder finder(finderConfig, extractParameters);
253 
254  auto csvData = readTracksAndVertexCSV(toolString);
255  auto tracks = std::get<TracksData>(csvData);
256 
257  std::vector<InputTrack> userTracks;
258  int idCount = 0;
259  for (const auto& trk : tracks) {
260  userTracks.push_back(InputTrack(trk, idCount));
261  idCount++;
262  }
263 
264  if (debugMode) {
265  std::cout << "Number of tracks in event: " << tracks.size() << std::endl;
266  int maxCout = 10;
267  int count = 0;
268  for (const auto& trk : tracks) {
269  std::cout << count << ". track: " << std::endl;
270  std::cout << "params: " << trk << std::endl;
271  count++;
272  if (count == maxCout) {
273  break;
274  }
275  }
276  }
277 
278  std::vector<const InputTrack*> userTracksPtr;
279  for (const auto& trk : userTracks) {
280  userTracksPtr.push_back(&trk);
281  }
282 
284 
285  Vertex<InputTrack> constraintVtx;
286  constraintVtx.setPosition(std::get<BeamSpotData>(csvData).position());
287  constraintVtx.setCovariance(std::get<BeamSpotData>(csvData).covariance());
288 
289  vertexingOptions.vertexConstraint = constraintVtx;
290 
291  auto findResult = finder.find(userTracksPtr, vertexingOptions, state);
292 
293  if (!findResult.ok()) {
294  std::cout << findResult.error().message() << std::endl;
295  }
296 
297  BOOST_CHECK(findResult.ok());
298 
299  std::vector<Vertex<InputTrack>> allVertices = *findResult;
300 
301  if (debugMode) {
302  std::cout << "Number of vertices reconstructed: " << allVertices.size()
303  << std::endl;
304 
305  int count = 0;
306  for (const auto& vtx : allVertices) {
307  count++;
308  std::cout << count << ". Vertex at position: " << vtx.position()[0]
309  << ", " << vtx.position()[1] << ", " << vtx.position()[2]
310  << std::endl;
311  std::cout << count << ". Vertex with cov: " << vtx.covariance()
312  << std::endl;
313  std::cout << "\t with n tracks: " << vtx.tracks().size() << std::endl;
314  }
315  for (auto& trk : allVertices[0].tracks()) {
316  std::cout << "Track ID at first vertex: " << trk.originalParams->id()
317  << std::endl;
318  }
319  }
320 
321  auto verticesInfo = std::get<VerticesData>(csvData);
322  const int expNRecoVertices = verticesInfo.size();
323 
324  BOOST_CHECK_EQUAL(allVertices.size(), expNRecoVertices);
325 
326  for (int i = 0; i < expNRecoVertices; i++) {
327  auto recoVtx = allVertices[i];
328  auto expVtx = verticesInfo[i];
329  CHECK_CLOSE_ABS(recoVtx.position(), expVtx.position, 0.001_mm);
330  CHECK_CLOSE_ABS(recoVtx.covariance(), expVtx.covariance, 0.001_mm);
331  BOOST_CHECK_EQUAL(recoVtx.tracks().size(), expVtx.nTracks);
332  CHECK_CLOSE_ABS(recoVtx.tracks()[0].trackWeight, expVtx.trk1Weight, 0.003);
333  CHECK_CLOSE_ABS(recoVtx.tracks()[0].vertexCompatibility, expVtx.trk1Comp,
334  0.003);
335  }
336 }
337 
339 BOOST_AUTO_TEST_CASE(adaptive_multi_vertex_finder_grid_seed_finder_test) {
340  // Set debug mode
341  bool debugMode = false;
342  if (debugMode) {
343  std::cout << "Starting AMVF test with grid seed finder..." << std::endl;
344  }
345  // Set up constant B-Field
346  ConstantBField bField(Vector3D(0., 0., 2_T));
347 
348  // Set up EigenStepper
349  // EigenStepper<ConstantBField> stepper(bField);
351 
352  // Set up propagator with void navigator
353  auto propagator = std::make_shared<Propagator>(stepper);
354 
355  // IP Estimator
357 
358  IPEstimator::Config ipEstCfg(bField, propagator);
359  IPEstimator ipEst(ipEstCfg);
360 
361  std::vector<double> temperatures{8.0, 4.0, 2.0, 1.4142136, 1.2247449, 1.0};
362  AnnealingUtility::Config annealingConfig(temperatures);
363  AnnealingUtility annealingUtility(annealingConfig);
364 
366 
367  Fitter::Config fitterCfg(ipEst);
368 
369  fitterCfg.annealingTool = annealingUtility;
370 
371  // Linearizer for BoundTrackParameters type test
372  Linearizer::Config ltConfig(bField, propagator);
373  Linearizer linearizer(ltConfig);
374 
375  // Test smoothing
376  fitterCfg.doSmoothing = true;
377 
378  Fitter fitter(fitterCfg);
379 
380  using SeedFinder = GridDensityVertexFinder<4000, 55>;
381  SeedFinder::Config seedFinderCfg(250);
382  seedFinderCfg.cacheGridStateForTrackRemoval = true;
383 
384  SeedFinder seedFinder(seedFinderCfg);
385 
387 
388  Finder::Config finderConfig(std::move(fitter), seedFinder, ipEst, linearizer);
389 
390  // TODO: test this as well!
391  // finderConfig.useBeamSpotConstraint = false;
392 
393  Finder finder(finderConfig);
394  Finder::State state;
395 
396  auto csvData = readTracksAndVertexCSV(toolString);
397  auto tracks = std::get<TracksData>(csvData);
398 
399  if (debugMode) {
400  std::cout << "Number of tracks in event: " << tracks.size() << std::endl;
401  int maxCout = 10;
402  int count = 0;
403  for (const auto& trk : tracks) {
404  std::cout << count << ". track: " << std::endl;
405  std::cout << "params: " << trk << std::endl;
406  count++;
407  if (count == maxCout) {
408  break;
409  }
410  }
411  }
412 
413  std::vector<const BoundTrackParameters*> tracksPtr;
414  for (const auto& trk : tracks) {
415  tracksPtr.push_back(&trk);
416  }
417 
420 
421  vertexingOptions.vertexConstraint = std::get<BeamSpotData>(csvData);
422 
423  auto t1 = std::chrono::system_clock::now();
424  auto findResult = finder.find(tracksPtr, vertexingOptions, state);
425  auto t2 = std::chrono::system_clock::now();
426 
427  auto timediff =
428  std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count();
429 
430  if (!findResult.ok()) {
431  std::cout << findResult.error().message() << std::endl;
432  }
433 
434  BOOST_CHECK(findResult.ok());
435 
436  std::vector<Vertex<BoundTrackParameters>> allVertices = *findResult;
437 
438  if (debugMode) {
439  std::cout << "Time needed: " << timediff << " ms." << std::endl;
440  std::cout << "Number of vertices reconstructed: " << allVertices.size()
441  << std::endl;
442 
443  int count = 0;
444  for (const auto& vtx : allVertices) {
445  count++;
446  std::cout << count << ". Vertex at position: " << vtx.position()[0]
447  << ", " << vtx.position()[1] << ", " << vtx.position()[2]
448  << std::endl;
449  std::cout << count << ". Vertex with cov: " << vtx.covariance()
450  << std::endl;
451  std::cout << "\t with n tracks: " << vtx.tracks().size() << std::endl;
452  }
453  }
454  // Test expected outcomes from athena implementation
455  // Number of reconstructed vertices
456  auto verticesInfo = std::get<VerticesData>(csvData);
457  const int expNRecoVertices = verticesInfo.size();
458 
459  BOOST_CHECK_EQUAL(allVertices.size(), expNRecoVertices);
460  std::vector<bool> vtxFound(expNRecoVertices, false);
461 
462  for (auto vtx : allVertices) {
463  double vtxZ = vtx.position()[2];
464  double diffZ = 1e5;
465  int foundVtxIdx = -1;
466  for (int i = 0; i < expNRecoVertices; i++) {
467  if (not vtxFound[i]) {
468  if (std::abs(vtxZ - verticesInfo[i].position[2]) < diffZ) {
469  diffZ = std::abs(vtxZ - verticesInfo[i].position[2]);
470  foundVtxIdx = i;
471  }
472  }
473  }
474  if (diffZ < 0.5_mm) {
475  vtxFound[foundVtxIdx] = true;
476  CHECK_CLOSE_ABS(vtx.tracks().size(), verticesInfo[foundVtxIdx].nTracks,
477  1);
478  }
479  }
480  for (bool found : vtxFound) {
481  BOOST_CHECK_EQUAL(found, true);
482  }
483 }
484 
485 } // namespace Test
486 } // namespace Acts