Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Portal.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file Portal.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 
16 
17 #include <cstddef>
18 #include <stdexcept>
19 #include <utility>
20 
21 namespace Acts {
22 namespace Experimental {
23 class DetectorVolume;
24 } // namespace Experimental
25 } // namespace Acts
26 
28  : m_surface(std::move(surface)) {
29  throw_assert(m_surface, "Portal surface is nullptr");
30 }
31 
32 std::shared_ptr<Acts::Experimental::Portal>
34  return std::shared_ptr<Portal>(new Portal(std::move(surface)));
35 }
36 
38  return *m_surface.get();
39 }
40 
42  return *m_surface.get();
43 }
44 
47  return m_volumeUpdators;
48 }
49 
52  return m_attachedVolumes;
53 }
54 
55 std::shared_ptr<Acts::Experimental::Portal>
57  return shared_from_this();
58 }
59 
60 std::shared_ptr<const Acts::Experimental::Portal>
62  return shared_from_this();
63 }
64 
66  const GeometryIdentifier& geometryId) {
67  m_surface->assignGeometryId(geometryId);
68 }
69 
70 void Acts::Experimental::Portal::fuse(std::shared_ptr<Portal>& other) {
72 
73  // Determine this directioon
74  Direction tDir = (not m_volumeUpdators[bDir.index()].connected())
77 
78  if (not m_volumeUpdators[tDir.index()].connected()) {
79  throw std::invalid_argument(
80  "Portal: trying to fuse portal (keep) with no links.");
81  }
82  // And now check other direction
83  Direction oDir = tDir.invert();
84  if (not other->m_volumeUpdators[oDir.index()].connected()) {
85  throw std::runtime_error(
86  "Portal: trying to fuse portal (waste) with no links.");
87  }
88 
89  auto odx = oDir.index();
90  m_volumeUpdators[odx] = std::move(other->m_volumeUpdators[odx]);
91  m_attachedVolumes[odx] = other->m_attachedVolumes[odx];
92  // And finally overwrite the original portal
93  other = getSharedPtr();
94 }
95 
97  Direction dir, DetectorVolumeUpdator dVolumeUpdator,
98  std::vector<std::shared_ptr<DetectorVolume>> attachedVolumes) {
99  auto idx = dir.index();
100  m_volumeUpdators[idx] = std::move(dVolumeUpdator);
101  m_attachedVolumes[idx] = std::move(attachedVolumes);
102 }
103 
105  DetectorVolumeUpdator dVolumeUpdator,
106  std::vector<std::shared_ptr<DetectorVolume>> attachedVolumes) {
107  // Check and throw exceptions
108  if (not m_volumeUpdators[0u].connected() and
109  not m_volumeUpdators[1u].connected()) {
110  throw std::runtime_error("Portal: portal has no link on either side.");
111  }
112  if (m_volumeUpdators[0u].connected() and m_volumeUpdators[1u].connected()) {
113  throw std::runtime_error("Portal: portal already has links on both sides.");
114  }
115  size_t idx = m_volumeUpdators[0u].connected() ? 1u : 0u;
116  m_volumeUpdators[idx] = std::move(dVolumeUpdator);
117  m_attachedVolumes[idx] = std::move(attachedVolumes);
118 }
119 
121  const GeometryContext& gctx, NavigationState& nState) const {
122  const auto& position = nState.position;
123  const auto& direction = nState.direction;
124  const Vector3 normal = surface().normal(gctx, position);
125  Direction dir = Direction::fromScalar(normal.dot(direction));
126  const auto& vUpdator = m_volumeUpdators[dir.index()];
127  if (vUpdator.connected()) {
128  vUpdator(gctx, nState);
129  } else {
130  nState.currentVolume = nullptr;
131  }
132 }