Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GsfTests.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file GsfTests.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2022 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/unit_test.hpp>
10 
47 #include "Acts/Utilities/Zip.hpp"
48 
49 #include <algorithm>
50 #include <array>
51 #include <functional>
52 #include <map>
53 #include <memory>
54 #include <optional>
55 #include <random>
56 #include <string>
57 #include <string_view>
58 #include <tuple>
59 #include <vector>
60 
61 #include "FitterTestsCommon.hpp"
62 
63 namespace {
64 
65 using namespace Acts;
66 using namespace Acts::Test;
67 using namespace Acts::UnitLiterals;
68 
69 static const auto electron = ParticleHypothesis::electron();
70 
71 Acts::GainMatrixUpdater kfUpdater;
72 
73 FitterTester tester;
74 
77  extensions.calibrator
78  .connect<&testSourceLinkCalibrator<VectorMultiTrajectory>>();
79  extensions.updater
80  .connect<&Acts::GainMatrixUpdater::operator()<VectorMultiTrajectory>>(
81  &kfUpdater);
82  extensions.surfaceAccessor
83  .connect<&TestSourceLink::SurfaceAccessor::operator()>(
84  &tester.surfaceAccessor);
86  return extensions;
87 }
88 
92 using GSF =
94 
95 const GSF gsfZero(makeConstantFieldPropagator<Stepper>(tester.geometry, 0_T),
97 
98 std::default_random_engine rng(42);
99 
100 auto makeDefaultGsfOptions() {
101  return GsfOptions<VectorMultiTrajectory>{tester.geoCtx, tester.magCtx,
102  tester.calCtx, getExtensions(),
104 }
105 
106 // A Helper type to allow us to put the MultiComponentBoundTrackParameters into
107 // the function so that it can also be used as GenericBoundTrackParameters for
108 // the MeasurementsCreator
109 struct MultiCmpsParsInterface : public BoundTrackParameters {
111 
112  MultiCmpsParsInterface(const MultiComponentBoundTrackParameters &p)
113  : BoundTrackParameters(p.referenceSurface().getSharedPtr(),
114  p.parameters(), p.covariance(), electron),
115  multi_pars(p) {}
116 
117  operator MultiComponentBoundTrackParameters() const { return multi_pars; }
118 };
119 
120 auto makeParameters() {
121  // create covariance matrix from reasonable standard deviations
122  Acts::BoundVector stddev;
123  stddev[Acts::eBoundLoc0] = 100_um;
124  stddev[Acts::eBoundLoc1] = 100_um;
125  stddev[Acts::eBoundTime] = 25_ns;
126  stddev[Acts::eBoundPhi] = 2_degree;
127  stddev[Acts::eBoundTheta] = 2_degree;
128  stddev[Acts::eBoundQOverP] = 1 / 100_GeV;
129  Acts::BoundSquareMatrix cov = stddev.cwiseProduct(stddev).asDiagonal();
130 
131  // define a track in the transverse plane along x
132  Acts::Vector4 mPos4(-3_m, 0., 0., 42_ns);
133  Acts::CurvilinearTrackParameters cp(mPos4, 0_degree, 90_degree, 1_e / 1_GeV,
134  cov, electron);
135 
136  // Construct bound multi component parameters from curvilinear ones
137  Acts::BoundVector deltaLOC0 = Acts::BoundVector::Zero();
138  deltaLOC0[eBoundLoc0] = 0.5_mm;
139 
140  Acts::BoundVector deltaLOC1 = Acts::BoundVector::Zero();
141  deltaLOC1[eBoundLoc1] = 0.5_mm;
142 
143  Acts::BoundVector deltaQOP = Acts::BoundVector::Zero();
144  deltaQOP[eBoundQOverP] = 0.01_GeV;
145 
146  std::vector<std::tuple<double, BoundVector, BoundSquareMatrix>> cmps = {
147  {0.2, cp.parameters(), cov},
148  {0.2, cp.parameters() + deltaLOC0 + deltaLOC1 + deltaQOP, cov},
149  {0.2, cp.parameters() + deltaLOC0 - deltaLOC1 - deltaQOP, cov},
150  {0.2, cp.parameters() - deltaLOC0 + deltaLOC1 + deltaQOP, cov},
151  {0.2, cp.parameters() - deltaLOC0 - deltaLOC1 - deltaQOP, cov}};
152 
153  return MultiCmpsParsInterface(MultiComponentBoundTrackParameters(
154  cp.referenceSurface().getSharedPtr(), cmps, electron));
155 }
156 
157 } // namespace
158 
159 BOOST_AUTO_TEST_SUITE(TrackFittingGsf)
160 
161 BOOST_AUTO_TEST_CASE(ZeroFieldNoSurfaceForward) {
162  auto multi_pars = makeParameters();
163  auto options = makeDefaultGsfOptions();
164 
165  tester.test_ZeroFieldNoSurfaceForward(gsfZero, options, multi_pars, rng, true,
166  false, false);
167 }
168 
169 BOOST_AUTO_TEST_CASE(ZeroFieldWithSurfaceForward) {
170  auto multi_pars = makeParameters();
171  auto options = makeDefaultGsfOptions();
172 
173  tester.test_ZeroFieldWithSurfaceForward(gsfZero, options, multi_pars, rng,
174  true, false, false);
175 }
176 
177 BOOST_AUTO_TEST_CASE(ZeroFieldWithSurfaceBackward) {
178  auto multi_pars = makeParameters();
179  auto options = makeDefaultGsfOptions();
180 
181  tester.test_ZeroFieldWithSurfaceBackward(gsfZero, options, multi_pars, rng,
182  true, false, false);
183 }
184 
185 BOOST_AUTO_TEST_CASE(ZeroFieldWithSurfaceAtExit) {
186  auto multi_pars = makeParameters();
187  auto options = makeDefaultGsfOptions();
188 
189  tester.test_ZeroFieldWithSurfaceBackward(gsfZero, options, multi_pars, rng,
190  true, false, false);
191 }
192 
193 BOOST_AUTO_TEST_CASE(ZeroFieldShuffled) {
194  auto multi_pars = makeParameters();
195  auto options = makeDefaultGsfOptions();
196 
197  tester.test_ZeroFieldShuffled(gsfZero, options, multi_pars, rng, true, false,
198  false);
199 }
200 
201 BOOST_AUTO_TEST_CASE(ZeroFieldWithHole) {
202  auto options = makeDefaultGsfOptions();
203  auto multi_pars = makeParameters();
204 
205  tester.test_ZeroFieldWithHole(gsfZero, options, multi_pars, rng, true, false,
206  false);
207 }
208 
209 BOOST_AUTO_TEST_CASE(ZeroFieldWithOutliers) {
210  // fitter options w/o target surface. outlier distance is set to be below the
211  // default outlier distance in the `MeasurementsCreator`
212  TestOutlierFinder tof{5_mm};
213  auto options = makeDefaultGsfOptions();
214  options.extensions.outlierFinder
215  .connect<&TestOutlierFinder::operator()<VectorMultiTrajectory>>(&tof);
216 
217  auto multi_pars = makeParameters();
218 
219  tester.test_ZeroFieldWithOutliers(gsfZero, options, multi_pars, rng, true,
220  false, false);
221 }
222 
223 BOOST_AUTO_TEST_CASE(WithFinalMultiComponentState) {
226  using namespace Acts::GsfConstants;
228  tracks.template addColumn<FinalMultiComponentState>(key);
229 
230  auto multi_pars = makeParameters();
231  auto measurements =
232  createMeasurements(tester.simPropagator, tester.geoCtx, tester.magCtx,
233  multi_pars, tester.resolutions, rng);
234  auto sourceLinks = tester.prepareSourceLinks(measurements.sourceLinks);
235  auto options = makeDefaultGsfOptions();
236 
237  // create a boundless target surface near the tracker exit
238  Acts::Vector3 center(-3._m, 0., 0.);
239  Acts::Vector3 normal(1., 0., 0.);
240  auto targetSurface =
241  Acts::Surface::makeShared<Acts::PlaneSurface>(center, normal);
242 
243  options.referenceSurface = targetSurface.get();
244 
245  auto res = gsfZero.fit(sourceLinks.begin(), sourceLinks.end(), multi_pars,
246  options, tracks);
247 
248  BOOST_REQUIRE(res.ok());
249  BOOST_CHECK(res->template component<FinalMultiComponentState>(
251  .has_value());
252 }
253 
254 BOOST_AUTO_TEST_SUITE_END()