Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SpacePointBuilderTests.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file SpacePointBuilderTests.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/data/test_case.hpp>
10 #include <boost/test/unit_test.hpp>
11 
38 
39 #include <algorithm>
40 #include <iostream>
41 #include <iterator>
42 #include <map>
43 #include <memory>
44 #include <optional>
45 #include <random>
46 #include <utility>
47 #include <vector>
48 
49 namespace bdata = boost::unit_test::data;
50 namespace tt = boost::test_tools;
51 
52 namespace Acts {
53 namespace Test {
54 
55 using namespace UnitLiterals;
56 
58 
62 // Construct initial track parameters.
64  double q) {
65  // create covariance matrix from reasonable standard deviations
66  BoundVector stddev;
67  stddev[eBoundLoc0] = 100_um;
68  stddev[eBoundLoc1] = 100_um;
69  stddev[eBoundTime] = 25_ns;
70  stddev[eBoundPhi] = 2_degree;
71  stddev[eBoundTheta] = 2_degree;
72  stddev[eBoundQOverP] = 1 / 100_GeV;
73  BoundSquareMatrix cov = stddev.cwiseProduct(stddev).asDiagonal();
74  // Let the particle start from the origin
75  Vector4 mPos4(-3_m, 0., 0., 0.);
76  return CurvilinearTrackParameters(mPos4, phi, theta, q / p, cov,
78 }
79 
80 std::pair<Vector3, Vector3> stripEnds(
81  const std::shared_ptr<const TrackingGeometry>& geo,
82  const GeometryContext& gctx, const SourceLink& slink,
83  const double stripFrac = 0.4) {
84  auto testslink = slink.get<TestSourceLink>();
85  const auto lpos = testslink.parameters;
86 
87  Vector3 globalFakeMom(1, 1, 1);
88  const auto geoId = testslink.m_geometryId;
89  const Surface* surface = geo->findSurface(geoId);
90 
91  const double stripLength = 40.;
92  const double end1x = lpos[0] + stripLength * stripFrac;
93  const double end1y = lpos[1];
94  const double end2x = lpos[0] - stripLength * (1 - stripFrac);
95  const double end2y = lpos[1];
96  const Vector2 lpos1(end1x, end1y);
97  const Vector2 lpos2(end2x, end2y);
98 
99  auto gPos1 = surface->localToGlobal(gctx, lpos1, globalFakeMom);
100  auto gPos2 = surface->localToGlobal(gctx, lpos2, globalFakeMom);
101 
102  return std::make_pair(gPos1, gPos2);
103 }
104 
105 // Create a test context
107 
108 const GeometryContext geoCtx;
111 
112 // detector geometry
114 const auto geometry = geometryStore();
115 
116 // detector resolutions
117 const MeasurementResolution resPixel = {MeasurementType::eLoc01,
118  {25_um, 50_um}};
119 const MeasurementResolution resStrip = {MeasurementType::eLoc01,
120  {100_um, 100_um}};
127 };
128 
129 // Construct a straight-line propagator.
131  std::shared_ptr<const TrackingGeometry> geo) {
133  cfg.resolvePassive = false;
134  cfg.resolveMaterial = true;
135  cfg.resolveSensitive = true;
138  return StraightPropagator(stepper, std::move(navigator));
139 }
140 
141 // simulation propagator
143 
144 std::default_random_engine rng(42);
145 
146 BOOST_DATA_TEST_CASE(SpacePointBuilder_basic, bdata::xrange(1), index) {
147  (void)index;
148 
149  double phi = 5._degree;
150  double theta = 95._degree;
151  double p = 50._GeV;
152  double q = 1;
153 
155  geometry,
156  true, // sensitive
157  true, // material
158  false // passive
159  });
160  auto field = std::make_shared<ConstantBField>(Vector3(0.0, 0.0, 2._T));
162 
163  ConstantFieldPropagator propagator(std::move(stepper), std::move(navigator));
164  auto start = makeParameters(phi, theta, p, q);
165 
166  auto measurements =
168 
169  const auto sourceLinks = measurements.sourceLinks;
170 
171  std::vector<SourceLink> frontSourceLinks;
172  std::vector<SourceLink> backSourceLinks;
173  std::vector<SourceLink> singleHitSourceLinks;
174 
175  std::vector<const Vector3*> frontStripEnds;
176  std::vector<const Vector3*> backStripEnds;
177 
178  for (auto& sl : sourceLinks) {
179  const auto geoId = sl.m_geometryId;
180  const auto volumeId = geoId.volume();
181  if (volumeId == 2) { // pixel type detector
182  singleHitSourceLinks.emplace_back(SourceLink{sl});
183  } else if (volumeId == 3) { // strip type detector
184 
185  const auto layerId = geoId.layer();
186 
187  if (layerId == 2 || layerId == 6) {
188  frontSourceLinks.emplace_back(SourceLink{sl});
189  } else if (layerId == 4 || layerId == 8) {
190  backSourceLinks.emplace_back(SourceLink{sl});
191  }
192  } // volume 3 (strip detector)
193  }
194 
195  BOOST_CHECK_EQUAL(frontSourceLinks.size(), 2);
196  BOOST_CHECK_EQUAL(backSourceLinks.size(), 2);
197 
198  Vector3 vertex = Vector3(-3_m, 0., 0.);
199 
200  auto spConstructor = [](const Vector3& pos, const Vector2& cov,
201  boost::container::static_vector<SourceLink, 2> slinks)
202  -> TestSpacePoint {
203  return TestSpacePoint(pos, cov[0], cov[1], std::move(slinks));
204  };
205 
206  auto spBuilderConfig = SpacePointBuilderConfig();
207  spBuilderConfig.trackingGeometry = geometry;
208 
209  TestSourceLink::SurfaceAccessor surfaceAccessor{*geometry};
210  spBuilderConfig.slSurfaceAccessor
211  .connect<&TestSourceLink::SurfaceAccessor::operator()>(&surfaceAccessor);
212 
213  auto spBuilder =
214  SpacePointBuilder<TestSpacePoint>(spBuilderConfig, spConstructor);
215 
216  // for cosmic without vertex constraint, usePerpProj = true
217  auto spBuilderConfig_perp = SpacePointBuilderConfig();
218  spBuilderConfig_perp.trackingGeometry = geometry;
219  spBuilderConfig_perp.slSurfaceAccessor
220  .connect<&TestSourceLink::SurfaceAccessor::operator()>(&surfaceAccessor);
221 
222  spBuilderConfig_perp.usePerpProj = true;
223 
224  auto spBuilder_perp =
225  SpacePointBuilder<TestSpacePoint>(spBuilderConfig_perp, spConstructor);
226 
227  TestSpacePointContainer spacePoints;
228  TestSpacePointContainer spacePoints_extra;
229 
230  auto accessor = [](const SourceLink& slink) {
231  auto testslink = slink.get<TestSourceLink>();
232  BoundVector param;
233  param.setZero();
234  param[eBoundLoc0] = testslink.parameters[eBoundLoc0];
235  param[eBoundLoc1] = testslink.parameters[eBoundLoc1];
236 
237  BoundSquareMatrix cov = BoundSquareMatrix::Zero();
238  cov.topLeftCorner<2, 2>() = testslink.covariance;
239 
240  return std::make_pair(param, cov);
241  };
242 
243  for (auto& sl : singleHitSourceLinks) {
244  std::vector<SourceLink> slinks;
245  slinks.emplace_back(sl);
247  spOpt.vertex = vertex;
248  spOpt.paramCovAccessor = accessor;
249  spBuilder.buildSpacePoint(geoCtx, slinks, spOpt,
250  std::back_inserter(spacePoints));
251  }
252  BOOST_CHECK_EQUAL(spacePoints.size(), 2);
253  std::vector<std::pair<SourceLink, SourceLink>> slinkPairs;
254 
255  // strip SP building
256 
257  StripPairOptions pairOpt;
258  pairOpt.paramCovAccessor = accessor;
259 
260  spBuilder.makeSourceLinkPairs(tgContext, frontSourceLinks, backSourceLinks,
261  slinkPairs, pairOpt);
262 
263  BOOST_CHECK_EQUAL(slinkPairs.size(), 2);
264 
265  for (auto& slinkPair : slinkPairs) {
266  const std::pair<Vector3, Vector3> end1 =
267  stripEnds(geometry, geoCtx, slinkPair.first);
268  const std::pair<Vector3, Vector3> end2 =
269  stripEnds(geometry, geoCtx, slinkPair.second);
270 
271  std::shared_ptr<const TestSpacePoint> spacePoint = nullptr;
272 
273  auto strippair = std::make_pair(end1, end2);
274  std::vector<SourceLink> slinks;
275  slinks.emplace_back(slinkPair.first);
276  slinks.emplace_back(slinkPair.second);
277 
278  SpacePointBuilderOptions spOpt{strippair, accessor};
279 
280  // nominal strip sp building
281  spBuilder.buildSpacePoint(geoCtx, slinks, spOpt,
282  std::back_inserter(spacePoints));
283 
284  // sp building without vertex constraint
285  spBuilder_perp.buildSpacePoint(geoCtx, slinks, spOpt,
286  std::back_inserter(spacePoints));
287 
288  // put measurements slightly outside strips to test recovery
289  const std::pair<Vector3, Vector3> end3 =
290  stripEnds(geometry, geoCtx, slinkPair.first, 1.01);
291  const std::pair<Vector3, Vector3> end4 =
292  stripEnds(geometry, geoCtx, slinkPair.second, 1.02);
293  // the other side of the strips
294  const std::pair<Vector3, Vector3> end5 =
295  stripEnds(geometry, geoCtx, slinkPair.first, -0.01);
296  const std::pair<Vector3, Vector3> end6 =
297  stripEnds(geometry, geoCtx, slinkPair.second, -0.02);
298 
299  auto spBuilderConfig_badStrips = SpacePointBuilderConfig();
300 
301  spBuilderConfig_badStrips.trackingGeometry = geometry;
302  spBuilderConfig_badStrips.slSurfaceAccessor
303  .connect<&TestSourceLink::SurfaceAccessor::operator()>(
304  &surfaceAccessor);
305 
306  auto spBuilder_badStrips = SpacePointBuilder<TestSpacePoint>(
307  spBuilderConfig_badStrips, spConstructor);
308  // sp building with the recovery method
309  SpacePointBuilderOptions spOpt_badStrips1{std::make_pair(end3, end4),
310  accessor};
311  spOpt_badStrips1.vertex = vertex;
312  spOpt_badStrips1.stripLengthTolerance = 0.0001;
313  spOpt_badStrips1.stripLengthGapTolerance = 50.;
314  spBuilder_badStrips.buildSpacePoint(geoCtx, slinks, spOpt_badStrips1,
315  std::back_inserter(spacePoints_extra));
316 
317  SpacePointBuilderOptions spOpt_badStrips2{std::make_pair(end5, end6),
318  accessor};
319  spOpt_badStrips2.vertex = vertex;
320  spOpt_badStrips2.stripLengthTolerance = 0.0001;
321  spOpt_badStrips2.stripLengthGapTolerance = 50.;
322  spBuilder_badStrips.buildSpacePoint(geoCtx, slinks, spOpt_badStrips2,
323  std::back_inserter(spacePoints_extra));
324  }
325 
326  for (auto& sp : spacePoints) {
327  std::cout << "space point (" << sp.x() << " " << sp.y() << " " << sp.z()
328  << ") var (r,z): " << sp.varianceR() << " " << sp.varianceZ()
329  << std::endl;
330  }
331  std::cout << "space points produced with bad strips:" << std::endl;
332  for (auto& sp : spacePoints_extra) {
333  std::cout << "space point (" << sp.x() << " " << sp.y() << " " << sp.z()
334  << ") var (r,z): " << sp.varianceR() << " " << sp.varianceZ()
335  << std::endl;
336  }
337 
338  BOOST_CHECK_EQUAL(spacePoints.size(), 6);
339 }
340 
341 } // end of namespace Test
342 } // namespace Acts