Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SurfaceArrayTests.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file SurfaceArrayTests.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2017-2018 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 
27 
28 #include <cmath>
29 #include <cstddef>
30 #include <fstream>
31 #include <iomanip>
32 #include <iostream>
33 #include <memory>
34 #include <string>
35 #include <tuple>
36 #include <utility>
37 #include <vector>
38 
39 #include <boost/format.hpp>
40 
43 
44 namespace bdata = boost::unit_test::data;
45 namespace tt = boost::test_tools;
46 
47 namespace Acts {
48 
49 namespace Test {
50 
51 // Create a test context
53 
54 using SrfVec = std::vector<std::shared_ptr<const Surface>>;
56  std::vector<std::shared_ptr<const Surface>> m_surfaces;
57 
58  SurfaceArrayFixture() { BOOST_TEST_MESSAGE("setup fixture"); }
59  ~SurfaceArrayFixture() { BOOST_TEST_MESSAGE("teardown fixture"); }
60 
61  SrfVec fullPhiTestSurfacesEC(size_t n = 10, double shift = 0,
62  double zbase = 0, double r = 10) {
63  SrfVec res;
64 
65  double phiStep = 2 * M_PI / n;
66  for (size_t i = 0; i < n; ++i) {
67  double z = zbase + ((i % 2 == 0) ? 1 : -1) * 0.2;
68 
69  Transform3 trans;
70  trans.setIdentity();
71  trans.rotate(Eigen::AngleAxisd(i * phiStep + shift, Vector3(0, 0, 1)));
72  trans.translate(Vector3(r, 0, z));
73 
74  auto bounds = std::make_shared<const RectangleBounds>(2, 1);
75  std::shared_ptr<const Surface> srf =
76  Surface::makeShared<PlaneSurface>(trans, bounds);
77 
78  res.push_back(srf);
79  m_surfaces.push_back(
80  std::move(srf)); // keep shared, will get destroyed at the end
81  }
82 
83  return res;
84  }
85 
86  SrfVec fullPhiTestSurfacesBRL(int n = 10, double shift = 0, double zbase = 0,
87  double incl = M_PI / 9., double w = 2,
88  double h = 1.5) {
89  SrfVec res;
90 
91  double phiStep = 2 * M_PI / n;
92  for (int i = 0; i < n; ++i) {
93  double z = zbase;
94 
95  Transform3 trans;
96  trans.setIdentity();
97  trans.rotate(Eigen::AngleAxisd(i * phiStep + shift, Vector3(0, 0, 1)));
98  trans.translate(Vector3(10, 0, z));
99  trans.rotate(Eigen::AngleAxisd(incl, Vector3(0, 0, 1)));
100  trans.rotate(Eigen::AngleAxisd(M_PI / 2., Vector3(0, 1, 0)));
101 
102  auto bounds = std::make_shared<const RectangleBounds>(w, h);
103  std::shared_ptr<const Surface> srf =
104  Surface::makeShared<PlaneSurface>(trans, bounds);
105 
106  res.push_back(srf);
107  m_surfaces.push_back(
108  std::move(srf)); // keep shared, will get destroyed at the end
109  }
110 
111  return res;
112  }
113 
115  size_t n = 10., double step = 3, const Vector3& origin = {0, 0, 1.5},
116  const Transform3& pretrans = Transform3::Identity(),
117  const Vector3& dir = {0, 0, 1}) {
118  SrfVec res;
119  for (size_t i = 0; i < n; ++i) {
120  Transform3 trans;
121  trans.setIdentity();
122  trans.translate(origin + dir * step * i);
123  // trans.rotate(AngleAxis3(M_PI/9., Vector3(0, 0, 1)));
124  trans.rotate(AngleAxis3(M_PI / 2., Vector3(1, 0, 0)));
125  trans = trans * pretrans;
126 
127  auto bounds = std::make_shared<const RectangleBounds>(2, 1.5);
128 
129  std::shared_ptr<const Surface> srf =
130  Surface::makeShared<PlaneSurface>(trans, bounds);
131 
132  res.push_back(srf);
133  m_surfaces.push_back(
134  std::move(srf)); // keep shared, will get destroyed at the end
135  }
136 
137  return res;
138  }
139 
140  SrfVec makeBarrel(int nPhi, int nZ, double w, double h) {
141  double z0 = -(nZ - 1) * w;
142  SrfVec res;
143 
144  for (int i = 0; i < nZ; i++) {
145  double z = i * w * 2 + z0;
146  // std::cout << "z=" << z << std::endl;
147  SrfVec ring = fullPhiTestSurfacesBRL(nPhi, 0, z, M_PI / 9., w, h);
148  res.insert(res.end(), ring.begin(), ring.end());
149  }
150 
151  return res;
152  }
153 
154  void draw_surfaces(const SrfVec& surfaces, const std::string& fname) {
155  std::ofstream os;
156  os.open(fname);
157 
158  os << std::fixed << std::setprecision(4);
159 
160  size_t nVtx = 0;
161  for (const auto& srfx : surfaces) {
162  std::shared_ptr<const PlaneSurface> srf =
164  const PlanarBounds* bounds =
165  dynamic_cast<const PlanarBounds*>(&srf->bounds());
166 
167  for (const auto& vtxloc : bounds->vertices()) {
168  Vector3 vtx =
169  srf->transform(tgContext) * Vector3(vtxloc.x(), vtxloc.y(), 0);
170  os << "v " << vtx.x() << " " << vtx.y() << " " << vtx.z() << "\n";
171  }
172 
173  // connect them
174  os << "f";
175  for (size_t i = 1; i <= bounds->vertices().size(); ++i) {
176  os << " " << nVtx + i;
177  }
178  os << "\n";
179 
180  nVtx += bounds->vertices().size();
181  }
182 
183  os.close();
184  }
185 };
186 
187 BOOST_AUTO_TEST_SUITE(Surfaces)
188 
191 
192  SrfVec brl = makeBarrel(30, 7, 2, 1);
193  std::vector<const Surface*> brlRaw = unpack_shared_vector(brl);
194  draw_surfaces(brl, "SurfaceArray_create_BRL_1.obj");
195 
196  detail::Axis<detail::AxisType::Equidistant, detail::AxisBoundaryType::Closed>
197  phiAxis(-M_PI, M_PI, 30u);
198  detail::Axis<detail::AxisType::Equidistant, detail::AxisBoundaryType::Bound>
199  zAxis(-14, 14, 7u);
200 
201  double angleShift = 2 * M_PI / 30. / 2.;
202  auto transform = [angleShift](const Vector3& pos) {
203  return Vector2(phi(pos) + angleShift, pos.z());
204  };
205  double R = 10;
206  auto itransform = [angleShift, R](const Vector2& loc) {
207  return Vector3(R * std::cos(loc[0] - angleShift),
208  R * std::sin(loc[0] - angleShift), loc[1]);
209  };
210 
211  auto sl = std::make_unique<
213  transform, itransform,
214  std::make_tuple(std::move(phiAxis), std::move(zAxis)));
215  sl->fill(tgContext, brlRaw);
216  SurfaceArray sa(std::move(sl), brl);
217 
218  // let's see if we can access all surfaces
219  sa.toStream(tgContext, std::cout);
220 
221  for (const auto& srf : brl) {
222  Vector3 ctr = srf->binningPosition(tgContext, binR);
223  std::vector<const Surface*> binContent = sa.at(ctr);
224 
225  BOOST_CHECK_EQUAL(binContent.size(), 1u);
226  BOOST_CHECK_EQUAL(srf.get(), binContent.at(0));
227  }
228 
229  std::vector<const Surface*> neighbors =
230  sa.neighbors(itransform(Vector2(0, 0)));
231  BOOST_CHECK_EQUAL(neighbors.size(), 9u);
232 
233  auto sl2 = std::make_unique<
235  transform, itransform,
236  std::make_tuple(std::move(phiAxis), std::move(zAxis)));
237  // do NOT fill, only completebinning
238  sl2->completeBinning(tgContext, brlRaw);
239  SurfaceArray sa2(std::move(sl2), brl);
240  sa.toStream(tgContext, std::cout);
241  for (const auto& srf : brl) {
242  Vector3 ctr = srf->binningPosition(tgContext, binR);
243  std::vector<const Surface*> binContent = sa2.at(ctr);
244 
245  BOOST_CHECK_EQUAL(binContent.size(), 1u);
246  BOOST_CHECK_EQUAL(srf.get(), binContent.at(0));
247  }
248 }
249 
250 BOOST_AUTO_TEST_CASE(SurfaceArray_singleElement) {
251  double w = 3, h = 4;
252  auto bounds = std::make_shared<const RectangleBounds>(w, h);
253  auto srf = Surface::makeShared<PlaneSurface>(Transform3::Identity(), bounds);
254 
255  SurfaceArray sa(srf);
256 
257  auto binContent = sa.at(Vector3(42, 42, 42));
258  BOOST_CHECK_EQUAL(binContent.size(), 1u);
259  BOOST_CHECK_EQUAL(binContent.at(0), srf.get());
260  BOOST_CHECK_EQUAL(sa.surfaces().size(), 1u);
261  BOOST_CHECK_EQUAL(sa.surfaces().at(0), srf.get());
262 }
263 
264 BOOST_AUTO_TEST_CASE(SurfaceArray_manyElementsSingleLookup) {
265  double w = 3, h = 4;
266  auto bounds = std::make_shared<const RectangleBounds>(w, h);
267  auto srf0 = Surface::makeShared<PlaneSurface>(Transform3::Identity(), bounds);
268  auto srf1 = Surface::makeShared<PlaneSurface>(Transform3::Identity(), bounds);
269 
270  std::vector<const Surface*> sfPointers = {srf0.get(), srf1.get()};
271  std::vector<std::shared_ptr<const Surface>> surfaces = {srf0, srf1};
272 
273  auto singleLookUp =
274  std::make_unique<Acts::SurfaceArray::SingleElementLookup>(sfPointers);
275 
276  SurfaceArray sa(std::move(singleLookUp), surfaces);
277 
278  auto binContent = sa.at(Vector3(42, 42, 42));
279  BOOST_CHECK_EQUAL(binContent.size(), 2u);
280  BOOST_CHECK_EQUAL(sa.surfaces().size(), 2u);
281 }
282 
283 BOOST_AUTO_TEST_SUITE_END()
284 } // namespace Test
285 
286 } // namespace Acts