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