Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TrackingGeometryClosureTests.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file TrackingGeometryClosureTests.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/unit_test.hpp>
10 
16 #include "Acts/Geometry/Layer.hpp"
22 
23 #include <cstddef>
24 #include <memory>
25 #include <unordered_map>
26 #include <vector>
27 
29 
30 using namespace Acts::UnitLiterals;
31 
32 namespace Acts {
33 namespace Test {
34 
35 // Create a test context
37 
47 
48  // sensitive surface definitions
49  double surfaceHalfLengthZ = 50_mm;
50  double surfaceRstagger = 5_mm;
51  double surfaceZoverlap = 10_mm;
52  double layerEnvelope = 0.5_mm;
53  double volumeEnvelope = 10_mm;
54 
55  // inner inner volume definitions
56  double iiv_surfaceR = 25_mm;
57  double iiv_volumeR =
58  iiv_surfaceR + 0.5 * surfaceRstagger + layerEnvelope + volumeEnvelope;
59 
61  double iov_surfaceR = 100_mm;
62  double iov_volumeR =
63  iov_surfaceR + 0.5 * surfaceRstagger + layerEnvelope + volumeEnvelope;
64 
66  auto iiVolume = constructCylinderVolume(
67  tgContext, surfaceHalfLengthZ, iiv_surfaceR, surfaceRstagger,
68  surfaceZoverlap, layerEnvelope, volumeEnvelope, 0., iiv_volumeR,
69  "InnerInnerVolume");
71  auto ioVolume = constructCylinderVolume(
72  tgContext, surfaceHalfLengthZ, iov_surfaceR, surfaceRstagger,
73  surfaceZoverlap, layerEnvelope, volumeEnvelope, iiv_volumeR, iov_volumeR,
74  "InnerOuterVolume");
75 
76  // now create the Inner Container volume
77  double volumeHalfZ =
78  (4 * surfaceHalfLengthZ - surfaceZoverlap) + volumeEnvelope;
81  tgContext, iiVolume, ioVolume, iov_volumeR, volumeHalfZ, "InnerVolume");
82 
83  // outer volume definitions
84  double ov_surfaceR = 150_mm;
85  double ov_volumeR =
86  ov_surfaceR + 0.5 * surfaceRstagger + layerEnvelope + volumeEnvelope;
87 
90  tgContext, surfaceHalfLengthZ, ov_surfaceR, surfaceRstagger,
91  surfaceZoverlap, layerEnvelope, volumeEnvelope, iov_volumeR, ov_volumeR,
92  "OuterVolume");
94  auto volume = constructContainerVolume(
95  tgContext, iVolume, oVolume, ov_volumeR, volumeHalfZ, "WorldVolume");
96 
97  // creating a TrackingGeometry
98  // -> close the geometry, this should set the GeometryIdentifier
99  TrackingGeometry tGeometry(volume, nullptr, hook);
100  return tGeometry;
101 }
102 
103 BOOST_AUTO_TEST_CASE(GeometryIdentifier_closeGeometry_test) {
104  GeometryIdentifierHook hook{};
106  auto world = tGeometry.highestTrackingVolume();
107 
108  // the lambda for checking
109  auto check_vol = [](const TrackingVolume& vol,
111  // check the geometry id of the volume
112  BOOST_CHECK_EQUAL(geoid, vol.geometryId().volume());
113  // check the geometry id of all boundary surfaces of the volume
114  // - this is strictly only possible when glueing is OFF
115  GeometryIdentifier::Value bsurface_id = 0;
116  for (const auto& bSf : vol.boundarySurfaces()) {
117  // check the bsurface volume id
118  auto bs_vol_id = bSf->surfaceRepresentation().geometryId().volume();
119  BOOST_CHECK_EQUAL(geoid, bs_vol_id);
120  // check the bsurface boundary id
121  auto bs_bsf_id = bSf->surfaceRepresentation().geometryId().boundary();
122  auto bs_ext_id = bSf->surfaceRepresentation().geometryId().extra();
123  BOOST_CHECK_EQUAL(++bsurface_id, bs_bsf_id);
124  BOOST_CHECK_EQUAL(bs_ext_id, 0);
125  }
126  // testing the layer and its approach surfaces
127  if (vol.confinedLayers() != nullptr) {
128  // layers start are counted from 1 - n
129  GeometryIdentifier::Value layer_id = 0;
130  for (const auto& lay : vol.confinedLayers()->arrayObjects()) {
131  // check the layer volume id and layer id
132  auto lay_vol_id = lay->geometryId().volume();
133  auto lay_lay_id = lay->geometryId().layer();
134  BOOST_CHECK_EQUAL(++layer_id, lay_lay_id);
135  BOOST_CHECK_EQUAL(geoid, lay_vol_id);
136  // test the layer approach surfaces
137  if (lay->approachDescriptor() != nullptr) {
138  // approach surfaces are counted from 1 - n
139  GeometryIdentifier::Value asurface_id = 0;
140  for (const auto& asf :
141  lay->approachDescriptor()->containedSurfaces()) {
142  // check the approach volume id, approach layer id
143  auto asf_vol_id = asf->geometryId().volume();
144  auto asf_lay_id = asf->geometryId().layer();
145  auto asf_asf_id = asf->geometryId().approach();
146  auto ssf_ext_id = asf->geometryId().extra();
147  BOOST_CHECK_EQUAL(layer_id, asf_lay_id);
148  BOOST_CHECK_EQUAL(geoid, asf_vol_id);
149  BOOST_CHECK_EQUAL(++asurface_id, asf_asf_id);
150  BOOST_CHECK_EQUAL(0, ssf_ext_id);
151  }
152  }
153  // test the sensitive surfaces
154  if (lay->surfaceArray() != nullptr) {
155  // sensitive surfaces are counted from 1 - n
156  GeometryIdentifier::Value ssurface_id = 0;
157  for (const auto& ssf : lay->surfaceArray()->surfaces()) {
158  // check the approach volume id, approach layer id
159  auto ssf_vol_id = ssf->geometryId().volume();
160  auto ssf_lay_id = ssf->geometryId().layer();
161  auto ssf_ssf_id = ssf->geometryId().sensitive();
162  auto ssf_ext_id = ssf->geometryId().extra();
163  BOOST_CHECK_EQUAL(layer_id, ssf_lay_id);
164  BOOST_CHECK_EQUAL(geoid, ssf_vol_id);
165  BOOST_CHECK_EQUAL(++ssurface_id, ssf_ssf_id);
166  BOOST_CHECK_EQUAL(0, ssf_ext_id);
167  }
168  }
169  }
170  }
171  };
172 
173  // get the two volumes the world is built of
174  auto ioVolumes = world->confinedVolumes()->arrayObjects();
175  // check the size - has to be two volumes
176  BOOST_CHECK_EQUAL(2ul, ioVolumes.size());
177  // get the innermost volumes
178  auto iioVolumes = ioVolumes[0]->confinedVolumes()->arrayObjects();
179  // check the size - has to be two volumes
180  BOOST_CHECK_EQUAL(2ul, iioVolumes.size());
181 
182  // check the world
183  check_vol(*world, 1);
184  // - check InnerVolume
185  check_vol(*ioVolumes[0], 2);
186  // -- check the InnerInnerVolume
187  check_vol(*iioVolumes[0], 3);
188  // -- check the InenerOuterVolume
189  check_vol(*iioVolumes[1], 4);
190  // - check the OuterVolume
191  check_vol(*ioVolumes[1], 5);
192 }
193 
194 template <typename Callable>
196  Callable callable;
197 
198  CallableHook(const Callable& c) : callable(c) {}
199 
200  Acts::GeometryIdentifier decorateIdentifier(
202  const Acts::Surface& surface) const override {
203  return callable(identifier, surface);
204  }
205 };
206 
207 BOOST_AUTO_TEST_CASE(GeometryIdentifier_closeGeometry_test_extra) {
208  size_t extra = 0;
209  std::unordered_map<const Surface*, size_t> extraMap;
210  auto hookImpl = [&](GeometryIdentifier orig, const Surface& srf) {
211  ++extra;
212  extraMap[&srf] = extra;
213  orig.setExtra(extra);
214  return orig;
215  };
216  CallableHook<decltype(hookImpl)> hook{hookImpl};
217 
219  auto world = tGeometry.highestTrackingVolume();
220 
221  // the lambda for checking
222  auto check_vol = [&extraMap](const TrackingVolume& vol,
224  // check the geometry id of the volume
225  BOOST_CHECK_EQUAL(geoid, vol.geometryId().volume());
226  // check the geometry id of all boundary surfaces of the volume
227  // - this is strictly only possible when glueing is OFF
228  GeometryIdentifier::Value bsurface_id = 0;
229  for (const auto& bSf : vol.boundarySurfaces()) {
230  // check the bsurface volume id
231  auto bs_vol_id = bSf->surfaceRepresentation().geometryId().volume();
232  BOOST_CHECK_EQUAL(geoid, bs_vol_id);
233  // check the bsurface boundary id
234  auto bs_bsf_id = bSf->surfaceRepresentation().geometryId().boundary();
235  auto bs_ext_id = bSf->surfaceRepresentation().geometryId().extra();
236  BOOST_CHECK_EQUAL(++bsurface_id, bs_bsf_id);
237  BOOST_CHECK_EQUAL(bs_ext_id, 0);
238  }
239  // testing the layer and its approach surfaces
240  if (vol.confinedLayers() != nullptr) {
241  // layers start are counted from 1 - n
242  GeometryIdentifier::Value layer_id = 0;
243  for (const auto& lay : vol.confinedLayers()->arrayObjects()) {
244  // check the layer volume id and layer id
245  auto lay_vol_id = lay->geometryId().volume();
246  auto lay_lay_id = lay->geometryId().layer();
247  BOOST_CHECK_EQUAL(++layer_id, lay_lay_id);
248  BOOST_CHECK_EQUAL(geoid, lay_vol_id);
249  // test the layer approach surfaces
250  if (lay->approachDescriptor() != nullptr) {
251  // approach surfaces are counted from 1 - n
252  GeometryIdentifier::Value asurface_id = 0;
253  for (const auto& asf :
254  lay->approachDescriptor()->containedSurfaces()) {
255  // check the approach volume id, approach layer id
256  auto asf_vol_id = asf->geometryId().volume();
257  auto asf_lay_id = asf->geometryId().layer();
258  auto asf_asf_id = asf->geometryId().approach();
259  auto ssf_ext_id = asf->geometryId().extra();
260  BOOST_CHECK_EQUAL(layer_id, asf_lay_id);
261  BOOST_CHECK_EQUAL(geoid, asf_vol_id);
262  BOOST_CHECK_EQUAL(++asurface_id, asf_asf_id);
263  BOOST_CHECK_EQUAL(0, ssf_ext_id);
264  }
265  }
266  // test the sensitive surfaces
267  if (lay->surfaceArray() != nullptr) {
268  // sensitive surfaces are counted from 1 - n
269  GeometryIdentifier::Value ssurface_id = 0;
270  for (const auto& ssf : lay->surfaceArray()->surfaces()) {
271  // check the approach volume id, approach layer id
272  auto ssf_vol_id = ssf->geometryId().volume();
273  auto ssf_lay_id = ssf->geometryId().layer();
274  auto ssf_ssf_id = ssf->geometryId().sensitive();
275  auto ssf_ext_id = ssf->geometryId().extra();
276  BOOST_CHECK_EQUAL(layer_id, ssf_lay_id);
277  BOOST_CHECK_EQUAL(geoid, ssf_vol_id);
278  BOOST_CHECK_EQUAL(++ssurface_id, ssf_ssf_id);
279  BOOST_CHECK_EQUAL(extraMap[ssf], ssf_ext_id);
280  }
281  }
282  }
283  }
284  };
285 
286  // get the two volumes the world is built of
287  auto ioVolumes = world->confinedVolumes()->arrayObjects();
288  // check the size - has to be two volumes
289  BOOST_CHECK_EQUAL(2ul, ioVolumes.size());
290  // get the innermost volumes
291  auto iioVolumes = ioVolumes[0]->confinedVolumes()->arrayObjects();
292  // check the size - has to be two volumes
293  BOOST_CHECK_EQUAL(2ul, iioVolumes.size());
294 
295  // check the world
296  check_vol(*world, 1);
297  // - check InnerVolume
298  check_vol(*ioVolumes[0], 2);
299  // -- check the InnerInnerVolume
300  check_vol(*iioVolumes[0], 3);
301  // -- check the InenerOuterVolume
302  check_vol(*iioVolumes[1], 4);
303  // - check the OuterVolume
304  check_vol(*ioVolumes[1], 5);
305 }
306 
307 BOOST_AUTO_TEST_CASE(TrackingGeometry_testVisitSurfaces) {
308  GeometryIdentifierHook hook{};
310 
311  // this will also cover TrackingVolume::visitSurfaces
312  // it's a pretty bare-bones test, and only asserts that the
313  // method is called on the expected number of surfaces
314  size_t nSurfaces = 0;
315  tGeometry.visitSurfaces([&nSurfaces](const auto*) { nSurfaces++; });
316 
317  BOOST_CHECK_EQUAL(nSurfaces, 9u);
318 }
319 
320 } // end of namespace Test
321 } // end of namespace Acts