Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
FullBilloirVertexFitterTests.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file FullBilloirVertexFitterTests.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 
33 
34 #include <algorithm>
35 #include <array>
36 #include <cmath>
37 #include <fstream>
38 #include <functional>
39 #include <iostream>
40 #include <memory>
41 #include <random>
42 #include <tuple>
43 #include <type_traits>
44 #include <utility>
45 #include <vector>
46 
47 namespace bdata = boost::unit_test::data;
48 using namespace Acts::UnitLiterals;
49 
50 namespace Acts {
51 namespace Test {
52 
54 using Linearizer = HelicalTrackLinearizer<Propagator<EigenStepper<>>>;
55 
56 // Create a test context
59 
60 // 4D vertex distributions
61 // x-/y-position
62 std::uniform_real_distribution<> vXYDist(-0.1_mm, 0.1_mm);
63 // z-position
64 std::uniform_real_distribution<> vZDist(-20_mm, 20_mm);
65 // time
66 std::uniform_real_distribution<> vTDist(-1_ns, 1_ns);
67 
68 // Track parameter distributions
69 // d0
70 std::uniform_real_distribution<> d0Dist(-0.01_mm, 0.01_mm);
71 // z0
72 std::uniform_real_distribution<> z0Dist(-0.2_mm, 0.2_mm);
73 // pT
74 std::uniform_real_distribution<> pTDist(0.4_GeV, 10_GeV);
75 // phi
76 std::uniform_real_distribution<> phiDist(-M_PI, M_PI);
77 // theta
78 std::uniform_real_distribution<> thetaDist(1.0, M_PI - 1.0);
79 // charge helper
80 std::uniform_real_distribution<> qDist(-1, 1);
81 // time
82 std::uniform_real_distribution<> tDist(-0.002_ns, 0.002_ns);
83 
84 // Track parameter resolution distributions
85 // impact parameters
86 std::uniform_real_distribution<> resIPDist(0., 100_um);
87 // angles
88 std::uniform_real_distribution<> resAngDist(0., 0.1);
89 // q/p
90 std::uniform_real_distribution<> resQoPDist(-0.1, 0.1);
91 // Track time resolution distribution
92 std::uniform_real_distribution<> resTDist(0.1_ns, 0.2_ns);
93 
94 // Number of tracks distritbution
95 std::uniform_int_distribution<> nTracksDist(3, 10);
96 
97 // Dummy user-defined InputTrack type
98 struct InputTrack {
99  InputTrack(const BoundTrackParameters& params) : m_parameters(params) {}
100 
101  const BoundTrackParameters& parameters() const { return m_parameters; }
102 
103  // store e.g. link to original objects here
104 
105  private:
106  BoundTrackParameters m_parameters;
107 };
108 
113 BOOST_AUTO_TEST_CASE(billoir_vertex_fitter_defaulttrack_test) {
114  // Set up RNG
115  int seed = 31415;
116  std::mt19937 gen(seed);
117  // Set up constant B-Field
118  auto bField = std::make_shared<ConstantBField>(Vector3{0.0, 0.0, 1_T});
119 
120  // Set up Eigenstepper
122  // Set up propagator with void navigator
123  auto propagator = std::make_shared<Propagator<EigenStepper<>>>(stepper);
124 
125  Linearizer::Config ltConfig(bField, propagator);
126  Linearizer linearizer(ltConfig);
127 
128  // Constraint for vertex fit
129  Vertex<BoundTrackParameters> constraint;
130  Vertex<InputTrack> customConstraint;
131  // Some arbitrary values
132  SquareMatrix4 covMatVtx = SquareMatrix4::Zero();
134  covMatVtx(0, 0) = 30_mm2;
135  covMatVtx(1, 1) = 30_mm2;
136  covMatVtx(2, 2) = 30_mm2;
137  covMatVtx(3, 3) = 30 * ns2;
138  constraint.setFullCovariance(covMatVtx);
139  constraint.setFullPosition(Vector4(0, 0, 0, 0));
140  customConstraint.setFullCovariance(covMatVtx);
141  customConstraint.setFullPosition(Vector4(0, 0, 0, 0));
142 
143  // Set up Billoir vertex fitter with default tracks
144  using VertexFitter =
146  VertexFitter::Config vertexFitterCfg;
147  VertexFitter billoirFitter(vertexFitterCfg);
148  VertexFitter::State state(bField->makeCache(magFieldContext));
149  // Vertexing options for default tracks
152  geoContext, magFieldContext, constraint);
153 
154  // Create a custom std::function to extract BoundTrackParameters from
155  // user-defined InputTrack
156  std::function<BoundTrackParameters(InputTrack)> extractParameters =
157  [](const InputTrack& params) { return params.parameters(); };
158 
159  // Set up Billoir vertex fitter with user-defined input tracks
160  using CustomVertexFitter = FullBilloirVertexFitter<InputTrack, Linearizer>;
161  CustomVertexFitter::Config customVertexFitterCfg;
162  CustomVertexFitter customBilloirFitter(customVertexFitterCfg,
163  extractParameters);
164  CustomVertexFitter::State customState(bField->makeCache(magFieldContext));
165  // Vertexing options for custom tracks
167  VertexingOptions<InputTrack> customVfOptionsConstr(
168  geoContext, magFieldContext, customConstraint);
169 
170  BOOST_TEST_CONTEXT(
171  "Testing FullBilloirVertexFitter when input track vector is empty.") {
172  const std::vector<const BoundTrackParameters*> emptyVector;
173 
174  // Without constraint
175  Vertex<BoundTrackParameters> fittedVertex =
176  billoirFitter.fit(emptyVector, linearizer, vfOptions, state).value();
177 
178  Vector3 origin(0., 0., 0.);
179  SquareMatrix4 zeroMat = SquareMatrix4::Zero();
180  BOOST_CHECK_EQUAL(fittedVertex.position(), origin);
181  BOOST_CHECK_EQUAL(fittedVertex.fullCovariance(), zeroMat);
182 
183  // With constraint
184  fittedVertex =
185  billoirFitter.fit(emptyVector, linearizer, vfOptionsConstr, state)
186  .value();
187 
188  BOOST_CHECK_EQUAL(fittedVertex.position(), origin);
189  BOOST_CHECK_EQUAL(fittedVertex.fullCovariance(), zeroMat);
190  }
191 
192  // Number of events
193  const int nEvents = 100;
194  for (int eventIdx = 0; eventIdx < nEvents; ++eventIdx) {
195  // Number of tracks
196  unsigned int nTracks = nTracksDist(gen);
197 
198  // Create position of vertex and perigee surface
199  double x = vXYDist(gen);
200  double y = vXYDist(gen);
201  double z = vZDist(gen);
202  double t = vTDist(gen);
203 
204  Vector4 trueVertex(x, y, z, t);
205  std::shared_ptr<PerigeeSurface> perigeeSurface =
206  Surface::makeShared<PerigeeSurface>(Vector3(0., 0., 0.));
207 
208  // Calculate d0 and z0 corresponding to the vertex position
209  double d0V = std::hypot(x, y);
210  double z0V = z;
211 
212  // Vector to store track objects used for vertex fit
213  std::vector<BoundTrackParameters> tracks;
214  std::vector<InputTrack> customTracks;
215 
216  // Calculate random track emerging from vicinity of vertex position
217  for (unsigned int iTrack = 0; iTrack < nTracks; iTrack++) {
218  // Charge
219  double q = qDist(gen) < 0 ? -1. : 1.;
220 
221  // Track parameters
222  BoundVector paramVec;
223  paramVec << d0V + d0Dist(gen), z0V + z0Dist(gen), phiDist(gen),
224  thetaDist(gen), q / pTDist(gen), t + tDist(gen);
225 
226  // Resolutions
227  double resD0 = resIPDist(gen);
228  double resZ0 = resIPDist(gen);
229  double resPh = resAngDist(gen);
230  double resTh = resAngDist(gen);
231  double resQp = resQoPDist(gen);
232  double resT = resTDist(gen);
233 
234  // Fill vector of track objects with simple covariance matrix
235  Covariance covMat;
236 
237  covMat << resD0 * resD0, 0., 0., 0., 0., 0., 0., resZ0 * resZ0, 0., 0.,
238  0., 0., 0., 0., resPh * resPh, 0., 0., 0., 0., 0., 0., resTh * resTh,
239  0., 0., 0., 0., 0., 0., resQp * resQp, 0., 0., 0., 0., 0., 0.,
240  resT * resT;
241  tracks.emplace_back(BoundTrackParameters(perigeeSurface, paramVec, covMat,
243  customTracks.emplace_back(
244  BoundTrackParameters(perigeeSurface, paramVec, std::move(covMat),
246  }
247 
248  std::vector<const BoundTrackParameters*> tracksPtr;
249  for (const auto& trk : tracks) {
250  tracksPtr.push_back(&trk);
251  }
252 
253  std::vector<const InputTrack*> customTracksPtr;
254  for (const auto& trk : customTracks) {
255  customTracksPtr.push_back(&trk);
256  }
257 
258  auto fit = [&trueVertex, &nTracks](const auto& fitter, const auto& trksPtr,
259  const auto& lin, const auto& vfOpts,
260  auto& vfState) {
261  auto fittedVertex = fitter.fit(trksPtr, lin, vfOpts, vfState).value();
262  if (!fittedVertex.tracks().empty()) {
263  CHECK_CLOSE_ABS(fittedVertex.position(), trueVertex.head(3), 1_mm);
264  auto tracksAtVtx = fittedVertex.tracks();
265  auto trackAtVtx = tracksAtVtx[0];
266  CHECK_CLOSE_ABS(fittedVertex.time(), trueVertex[3], 1_ns);
267  }
268 
269  std::cout << "\nFitting " << nTracks << " tracks" << std::endl;
270  std::cout << "True Vertex:\n" << trueVertex << std::endl;
271  std::cout << "Fitted Vertex:\n"
272  << fittedVertex.fullPosition() << std::endl;
273  };
274 
275  BOOST_TEST_CONTEXT(
276  "Testing FullBilloirVertexFitter without vertex constraint.") {
277  fit(billoirFitter, tracksPtr, linearizer, vfOptions, state);
278  }
279  BOOST_TEST_CONTEXT(
280  "Testing FullBilloirVertexFitter with vertex constraint.") {
281  fit(billoirFitter, tracksPtr, linearizer, vfOptionsConstr, state);
282  }
283  BOOST_TEST_CONTEXT(
284  "Testing FullBilloirVertexFitter with custom tracks (no vertex "
285  "constraint).") {
286  fit(customBilloirFitter, customTracksPtr, linearizer, customVfOptions,
287  customState);
288  }
289  BOOST_TEST_CONTEXT(
290  "Testing FullBilloirVertexFitter with custom tracks (with vertex "
291  "constraint).") {
292  fit(customBilloirFitter, customTracksPtr, linearizer,
293  customVfOptionsConstr, customState);
294  }
295  }
296 }
297 } // namespace Test
298 } // namespace Acts