EIC 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 
25 
26 #include <fstream>
27 
28 #include <boost/format.hpp>
29 
32 
33 namespace bdata = boost::unit_test::data;
34 namespace tt = boost::test_tools;
35 
36 namespace Acts {
37 
38 namespace Test {
39 
40 // Create a test context
42 
43 using SrfVec = std::vector<std::shared_ptr<const Surface>>;
45  std::vector<std::shared_ptr<const Surface>> m_surfaces;
46 
47  SurfaceArrayFixture() { BOOST_TEST_MESSAGE("setup fixture"); }
48  ~SurfaceArrayFixture() { BOOST_TEST_MESSAGE("teardown fixture"); }
49 
50  SrfVec fullPhiTestSurfacesEC(size_t n = 10, double shift = 0,
51  double zbase = 0, double r = 10) {
52  SrfVec res;
53 
54  double phiStep = 2 * M_PI / n;
55  for (size_t i = 0; i < n; ++i) {
56  double z = zbase + ((i % 2 == 0) ? 1 : -1) * 0.2;
57 
58  Transform3D trans;
59  trans.setIdentity();
60  trans.rotate(Eigen::AngleAxisd(i * phiStep + shift, Vector3D(0, 0, 1)));
61  trans.translate(Vector3D(r, 0, z));
62 
63  auto bounds = std::make_shared<const RectangleBounds>(2, 1);
64  std::shared_ptr<const Surface> srf =
65  Surface::makeShared<PlaneSurface>(trans, bounds);
66 
67  res.push_back(srf);
68  m_surfaces.push_back(
69  std::move(srf)); // keep shared, will get destroyed at the end
70  }
71 
72  return res;
73  }
74 
75  SrfVec fullPhiTestSurfacesBRL(int n = 10, double shift = 0, double zbase = 0,
76  double incl = M_PI / 9., double w = 2,
77  double h = 1.5) {
78  SrfVec res;
79 
80  double phiStep = 2 * M_PI / n;
81  for (int i = 0; i < n; ++i) {
82  double z = zbase;
83 
84  Transform3D trans;
85  trans.setIdentity();
86  trans.rotate(Eigen::AngleAxisd(i * phiStep + shift, Vector3D(0, 0, 1)));
87  trans.translate(Vector3D(10, 0, z));
88  trans.rotate(Eigen::AngleAxisd(incl, Vector3D(0, 0, 1)));
89  trans.rotate(Eigen::AngleAxisd(M_PI / 2., Vector3D(0, 1, 0)));
90 
91  auto bounds = std::make_shared<const RectangleBounds>(w, h);
92  std::shared_ptr<const Surface> srf =
93  Surface::makeShared<PlaneSurface>(trans, bounds);
94 
95  res.push_back(srf);
96  m_surfaces.push_back(
97  std::move(srf)); // keep shared, will get destroyed at the end
98  }
99 
100  return res;
101  }
102 
104  size_t n = 10., double step = 3, const Vector3D& origin = {0, 0, 1.5},
105  const Transform3D& pretrans = Transform3D::Identity(),
106  const Vector3D& dir = {0, 0, 1}) {
107  SrfVec res;
108  for (size_t i = 0; i < n; ++i) {
109  Transform3D trans;
110  trans.setIdentity();
111  trans.translate(origin + dir * step * i);
112  // trans.rotate(AngleAxis3D(M_PI/9., Vector3D(0, 0, 1)));
113  trans.rotate(AngleAxis3D(M_PI / 2., Vector3D(1, 0, 0)));
114  trans = trans * pretrans;
115 
116  auto bounds = std::make_shared<const RectangleBounds>(2, 1.5);
117 
118  std::shared_ptr<const Surface> srf =
119  Surface::makeShared<PlaneSurface>(trans, bounds);
120 
121  res.push_back(srf);
122  m_surfaces.push_back(
123  std::move(srf)); // keep shared, will get destroyed at the end
124  }
125 
126  return res;
127  }
128 
129  SrfVec makeBarrel(int nPhi, int nZ, double w, double h) {
130  double z0 = -(nZ - 1) * w;
131  SrfVec res;
132 
133  for (int i = 0; i < nZ; i++) {
134  double z = i * w * 2 + z0;
135  // std::cout << "z=" << z << std::endl;
136  SrfVec ring = fullPhiTestSurfacesBRL(nPhi, 0, z, M_PI / 9., w, h);
137  res.insert(res.end(), ring.begin(), ring.end());
138  }
139 
140  return res;
141  }
142 
143  void draw_surfaces(const SrfVec& surfaces, const std::string& fname) {
144  std::ofstream os;
145  os.open(fname);
146 
147  os << std::fixed << std::setprecision(4);
148 
149  size_t nVtx = 0;
150  for (const auto& srfx : surfaces) {
151  std::shared_ptr<const PlaneSurface> srf =
153  const PlanarBounds* bounds =
154  dynamic_cast<const PlanarBounds*>(&srf->bounds());
155 
156  for (const auto& vtxloc : bounds->vertices()) {
157  Vector3D vtx =
158  srf->transform(tgContext) * Vector3D(vtxloc.x(), vtxloc.y(), 0);
159  os << "v " << vtx.x() << " " << vtx.y() << " " << vtx.z() << "\n";
160  }
161 
162  // connect them
163  os << "f";
164  for (size_t i = 1; i <= bounds->vertices().size(); ++i) {
165  os << " " << nVtx + i;
166  }
167  os << "\n";
168 
169  nVtx += bounds->vertices().size();
170  }
171 
172  os.close();
173  }
174 };
175 
176 BOOST_AUTO_TEST_SUITE(Surfaces)
177 
180 
181  SrfVec brl = makeBarrel(30, 7, 2, 1);
182  std::vector<const Surface*> brlRaw = unpack_shared_vector(brl);
183  draw_surfaces(brl, "SurfaceArray_create_BRL_1.obj");
184 
185  detail::Axis<detail::AxisType::Equidistant, detail::AxisBoundaryType::Closed>
186  phiAxis(-M_PI, M_PI, 30u);
187  detail::Axis<detail::AxisType::Equidistant, detail::AxisBoundaryType::Bound>
188  zAxis(-14, 14, 7u);
189 
190  double angleShift = 2 * M_PI / 30. / 2.;
191  auto transform = [angleShift](const Vector3D& pos) {
192  return Vector2D(phi(pos) + angleShift, pos.z());
193  };
194  double R = 10;
195  auto itransform = [angleShift, R](const Vector2D& loc) {
196  return Vector3D(R * std::cos(loc[0] - angleShift),
197  R * std::sin(loc[0] - angleShift), loc[1]);
198  };
199 
200  auto sl = std::make_unique<
202  transform, itransform,
203  std::make_tuple(std::move(phiAxis), std::move(zAxis)));
204  sl->fill(tgContext, brlRaw);
205  SurfaceArray sa(std::move(sl), brl);
206 
207  // let's see if we can access all surfaces
208  sa.toStream(tgContext, std::cout);
209 
210  for (const auto& srf : brl) {
211  Vector3D ctr = srf->binningPosition(tgContext, binR);
212  std::vector<const Surface*> binContent = sa.at(ctr);
213 
214  BOOST_CHECK_EQUAL(binContent.size(), 1u);
215  BOOST_CHECK_EQUAL(srf.get(), binContent.at(0));
216  }
217 
218  std::vector<const Surface*> neighbors =
219  sa.neighbors(itransform(Vector2D(0, 0)));
220  BOOST_CHECK_EQUAL(neighbors.size(), 9u);
221 
222  auto sl2 = std::make_unique<
224  transform, itransform,
225  std::make_tuple(std::move(phiAxis), std::move(zAxis)));
226  // do NOT fill, only completebinning
227  sl2->completeBinning(tgContext, brlRaw);
228  SurfaceArray sa2(std::move(sl2), brl);
229  sa.toStream(tgContext, std::cout);
230  for (const auto& srf : brl) {
231  Vector3D ctr = srf->binningPosition(tgContext, binR);
232  std::vector<const Surface*> binContent = sa2.at(ctr);
233 
234  BOOST_CHECK_EQUAL(binContent.size(), 1u);
235  BOOST_CHECK_EQUAL(srf.get(), binContent.at(0));
236  }
237 }
238 
239 BOOST_AUTO_TEST_CASE(SurfaceArray_singleElement) {
240  double w = 3, h = 4;
241  auto bounds = std::make_shared<const RectangleBounds>(w, h);
242  auto srf = Surface::makeShared<PlaneSurface>(Transform3D::Identity(), bounds);
243 
244  SurfaceArray sa(srf);
245 
246  auto binContent = sa.at(Vector3D(42, 42, 42));
247  BOOST_CHECK_EQUAL(binContent.size(), 1u);
248  BOOST_CHECK_EQUAL(binContent.at(0), srf.get());
249  BOOST_CHECK_EQUAL(sa.surfaces().size(), 1u);
250  BOOST_CHECK_EQUAL(sa.surfaces().at(0), srf.get());
251 }
252 
253 BOOST_AUTO_TEST_SUITE_END()
254 } // namespace Test
255 
256 } // namespace Acts