Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DetectorVolume.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file DetectorVolume.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2022-2023 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 
10 
12 #include "Acts/Detector/Portal.hpp"
21 
22 #include <cassert>
23 #include <iterator>
24 
25 namespace Acts {
26 class IVolumeMaterial;
27 } // namespace Acts
28 
31  std::shared_ptr<VolumeBounds> bounds,
32  std::vector<std::shared_ptr<Surface>> surfaces,
33  std::vector<std::shared_ptr<DetectorVolume>> volumes,
34  DetectorVolumeUpdator detectorVolumeUpdator,
35  SurfaceCandidatesUpdator surfaceCandidateUpdator)
36  : m_name(std::move(name)),
37  m_transform(transform),
38  m_bounds(std::move(bounds)),
39  m_surfaces(std::move(surfaces)),
40  m_volumes(std::move(volumes)),
41  m_detectorVolumeUpdator(std::move(detectorVolumeUpdator)),
42  m_surfaceCandidatesUpdator(std::move(surfaceCandidateUpdator)),
43  m_volumeMaterial(nullptr) {
44  if (m_bounds == nullptr) {
45  throw std::invalid_argument(
46  "DetectorVolume: construction with nullptr bounds.");
47  }
48  if (not m_detectorVolumeUpdator.connected()) {
49  throw std::invalid_argument(
50  "DetectorVolume: navigation state updator delegate is not connected.");
51  }
52  if (not m_surfaceCandidatesUpdator.connected()) {
53  throw std::invalid_argument(
54  "DetectorVolume: navigation state updator delegate is not connected.");
55  }
56 
57  [[maybe_unused]] const auto& gctx_ref = gctx;
58  assert(checkContainment(gctx) && "Objects are not contained by volume.");
59 }
60 
63  std::shared_ptr<VolumeBounds> bounds,
64  SurfaceCandidatesUpdator surfaceCandidateUpdator)
65  : DetectorVolume(gctx, std::move(name), transform, std::move(bounds), {},
66  {}, tryNoVolumes(), std::move(surfaceCandidateUpdator)) {}
67 
68 std::shared_ptr<Acts::Experimental::DetectorVolume>
71  std::shared_ptr<VolumeBounds> bounds,
72  std::vector<std::shared_ptr<Surface>> surfaces,
73  std::vector<std::shared_ptr<DetectorVolume>> volumes,
74  DetectorVolumeUpdator detectorVolumeUpdator,
75  SurfaceCandidatesUpdator surfaceCandidateUpdator) {
76  return std::shared_ptr<DetectorVolume>(new DetectorVolume(
77  gctx, std::move(name), transform, std::move(bounds), std::move(surfaces),
78  std::move(volumes), std::move(detectorVolumeUpdator),
79  std::move(surfaceCandidateUpdator)));
80 }
81 
82 std::shared_ptr<Acts::Experimental::DetectorVolume>
85  std::shared_ptr<VolumeBounds> bounds,
86  SurfaceCandidatesUpdator surfaceCandidateUpdator) {
87  return std::shared_ptr<DetectorVolume>(
88  new DetectorVolume(gctx, std::move(name), transform, std::move(bounds),
89  std::move(surfaceCandidateUpdator)));
90 }
91 
93  const GeometryContext& /*gctx*/) const {
94  return m_transform;
95 }
96 
98  const GeometryContext& gctx) const {
99  return transform(gctx).translation();
100 }
101 
103  const {
104  return (*m_bounds.get());
105 }
106 
107 std::vector<std::shared_ptr<Acts::Experimental::Portal>>&
109  return m_portals.internal;
110 }
111 
112 std::vector<std::shared_ptr<Acts::Surface>>&
114  return m_surfaces.internal;
115 }
116 
117 std::vector<std::shared_ptr<Acts::Experimental::DetectorVolume>>&
119  return m_volumes.internal;
120 }
121 
122 const std::vector<const Acts::Experimental::Portal*>&
124  return m_portals.external;
125 }
126 
127 const std::vector<const Acts::Surface*>&
129  return m_surfaces.external;
130 }
131 
132 const std::vector<const Acts::Experimental::DetectorVolume*>&
134  return m_volumes.external;
135 }
136 
139  return m_detectorVolumeUpdator;
140 }
141 
144  return m_surfaceCandidatesUpdator;
145 }
146 
148  std::shared_ptr<IVolumeMaterial> material) {
149  m_volumeMaterial = std::move(material);
150 }
151 
152 std::shared_ptr<Acts::IVolumeMaterial>
154  return m_volumeMaterial;
155 }
156 
159  return m_volumeMaterial.get();
160 }
161 
163  const {
164  return m_geometryId;
165 }
166 
168  const GeometryIdentifier& geoID) {
169  m_geometryId = geoID;
170 }
171 
173  return m_name;
174 }
175 
177  const Detector& detector) {
178  m_detector = &detector;
179 
180  for (auto& v : m_volumes.internal) {
181  v->assignDetector(detector);
182  }
183 }
184 
187  return m_detector;
188 }
189 
191  std::shared_ptr<Portal> portal, unsigned int pIndex) {
192  if (pIndex >= m_portals.internal.size()) {
193  throw std::invalid_argument(
194  "DetectorVolume: trying to update a portal that does not exist.");
195  }
196  m_portals.internal[pIndex] = std::move(portal);
197  m_portals = ObjectStore<std::shared_ptr<Portal>>(m_portals.internal);
198 }
199 
202  // Create portals with the given generator
203  auto portalSurfaces =
204  portalGenerator(transform(gctx), *(m_bounds.get()), getSharedPtr());
205  m_portals = ObjectStore<std::shared_ptr<Portal>>(portalSurfaces);
206  createBoundingBox(gctx);
207 }
208 
209 std::shared_ptr<Acts::Experimental::DetectorVolume>
211  return shared_from_this();
212 }
213 
214 std::shared_ptr<const Acts::Experimental::DetectorVolume>
216  return shared_from_this();
217 }
218 
220  const Vector3& position) const {
221  Vector3 posInVolFrame(transform(gctx).inverse() * position);
222  return volumeBounds().inside(posInVolFrame);
223 }
224 
226  const GeometryContext& gctx, const Vector3& position) const {
227  if (!inside(gctx, position)) {
228  return false;
229  }
230  // Check exclusion through subvolume
231  for (const auto& v : volumes()) {
232  if (v->inside(gctx, position)) {
233  return false;
234  }
235  }
236  return true;
237 }
238 
240  const GeometryContext& gctx, NavigationState& nState) const {
241  nState.currentVolume = this;
242  m_surfaceCandidatesUpdator(gctx, nState);
243  nState.surfaceCandidate = nState.surfaceCandidates.begin();
244 }
245 
247  SurfaceCandidatesUpdator surfaceCandidateUpdator,
248  const std::vector<std::shared_ptr<Surface>>& surfaces,
249  const std::vector<std::shared_ptr<DetectorVolume>>& volumes) {
250  m_surfaceCandidatesUpdator = std::move(surfaceCandidateUpdator);
251  m_surfaces = ObjectStore<std::shared_ptr<Surface>>(surfaces);
253 }
254 
256  const GeometryContext& gctx, size_t nseg) const {
257  Extent volumeExtent;
258  for (const auto* p : portals()) {
259  volumeExtent.extend(
260  p->surface().polyhedronRepresentation(gctx, nseg).extent());
261  }
262  return volumeExtent;
263 }
264 
266  const GeometryContext& gctx, size_t nseg) const {
267  // Create the volume extent
268  auto volumeExtent = extent(gctx, nseg);
269  // Check surfaces
270  for (const auto* s : surfaces()) {
271  auto sExtent = s->polyhedronRepresentation(gctx, nseg).extent();
272  if (not volumeExtent.contains(sExtent)) {
273  return false;
274  }
275  }
276  // Check volumes
277  for (const auto* v : volumes()) {
278  auto vExtent = v->extent(gctx, nseg);
279  if (not volumeExtent.contains(vExtent)) {
280  return false;
281  }
282  }
283  // All contained
284  return true;
285 }
286 
288  for (auto& p : m_portals.internal) {
289  // Create a null link
290  for (auto [ivu, vu] : enumerate(p->detectorVolumeUpdators())) {
291  if (not vu.connected()) {
292  auto eowDir = Direction::fromIndex(ivu);
293  auto eow = std::make_unique<const EndOfWorldImpl>();
295  eowLink.connect<&EndOfWorldImpl::update>(std::move(eow));
296  p->assignDetectorVolumeUpdator(eowDir, std::move(eowLink), {});
297  }
298  }
299  }
300 
301  for (auto& v : m_volumes.internal) {
302  v->closePortals();
303  }
304 }
305 
307  const GeometryContext& gctx) {
308  std::vector<Vector3> vertices;
309  for (auto p : m_portals.external) {
310  auto surface = p->surface().polyhedronRepresentation(gctx, 1);
311  auto pVertices = surface.vertices;
312  for (const auto& v : pVertices) {
313  vertices.push_back(v);
314  }
315  }
316  Acts::Vector3 vmin = Acts::Vector3::Zero();
317  Acts::Vector3 vmax = Acts::Vector3::Zero();
318  for (const auto& v : vertices) {
319  vmin = vmin.cwiseMin(v);
320  vmax = vmax.cwiseMax(v);
321  }
322  std::shared_ptr<Acts::Experimental::DetectorVolume::BoundingBox> box =
323  std::make_shared<Acts::Experimental::DetectorVolume::BoundingBox>(
324  this, vmin, vmax);
325  m_boundingBox = box;
326 }
327 
330  return *m_boundingBox;
331 }