Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Detector.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file Detector.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 
15 
16 #include <iterator>
17 #include <sstream>
18 #include <stdexcept>
19 #include <unordered_map>
20 #include <utility>
21 
23  std::string name, std::vector<std::shared_ptr<DetectorVolume>> rootVolumes,
24  DetectorVolumeUpdator detectorVolumeUpdator)
25  : m_name(std::move(name)),
26  m_rootVolumes(std::move(rootVolumes)),
27  m_detectorVolumeUpdator(std::move(detectorVolumeUpdator)) {
28  if (m_rootVolumes.internal.empty()) {
29  throw std::invalid_argument("Detector: no volume were given.");
30  }
31  if (not m_detectorVolumeUpdator.connected()) {
32  throw std::invalid_argument(
33  "Detector: volume finder delegate is not connected.");
34  }
35 
36  // Fill volumes
37  auto collectVolumes = [&]() {
38  std::vector<std::shared_ptr<DetectorVolume>> volumes;
39  auto recurse = [&volumes](const std::shared_ptr<DetectorVolume>& volume,
40  auto& callback) -> void {
41  volumes.push_back(volume);
42  for (const auto& v : volume->volumePtrs()) {
43  callback(v, callback);
44  }
45  };
46  for (const auto& root : m_rootVolumes.internal) {
47  recurse(root, recurse);
48  }
49  return volumes;
50  };
52  collectVolumes());
53 
54  // Fill the surface map
55  std::unordered_map<GeometryIdentifier, const Surface*> surfaceGeoIdMap;
56  // Check for unique names and fill the volume name / index map
57  for (auto [iv, v] : enumerate(m_volumes.internal)) {
58  // Assign this detector
59  v->assignDetector(*this);
60  // Close the portals
61  v->closePortals();
62  // Store the name
63  const std::string vName = v->name();
64  if (m_volumeNameIndex.find(vName) != m_volumeNameIndex.end()) {
65  throw std::invalid_argument("Detector: duplicate volume name " + vName +
66  " detected.");
67  }
68  m_volumeNameIndex[vName] = iv;
69 
70  for (const auto* s : v->surfaces()) {
71  auto sgeoID = s->geometryId();
72  if (surfaceGeoIdMap.find(sgeoID) != surfaceGeoIdMap.end()) {
73  std::stringstream ss;
74  ss << sgeoID;
75  throw std::invalid_argument(
76  "Detector: duplicate sensitive surface geometry id '" + ss.str() +
77  "' detected. Make sure a GeometryIdGenerator is used.");
78  }
79  surfaceGeoIdMap.emplace(sgeoID, s);
80  }
81  }
82  // Let us transfer the surfaces into the hierarchy map
83  std::vector<std::pair<GeometryIdentifier, const Surface*>> surfaceGeoIdVec;
84  surfaceGeoIdVec.reserve(surfaceGeoIdMap.size());
85  for (auto [geoID, surface] : surfaceGeoIdMap) {
86  surfaceGeoIdVec.emplace_back(geoID, surface);
87  }
90 }
91 
92 std::shared_ptr<Acts::Experimental::Detector>
94  std::string name, std::vector<std::shared_ptr<DetectorVolume>> rootVolumes,
95  DetectorVolumeUpdator detectorVolumeUpdator) {
96  return std::shared_ptr<Detector>(
97  new Detector(std::move(name), std::move(rootVolumes),
98  std::move(detectorVolumeUpdator)));
99 }
100 
101 std::vector<std::shared_ptr<Acts::Experimental::DetectorVolume>>&
103  return m_rootVolumes.internal;
104 }
105 
106 const std::vector<const Acts::Experimental::DetectorVolume*>&
108  return m_rootVolumes.external;
109 }
110 
111 std::vector<std::shared_ptr<Acts::Experimental::DetectorVolume>>&
113  return m_volumes.internal;
114 }
115 
116 const std::vector<const Acts::Experimental::DetectorVolume*>&
118  return m_volumes.external;
119 }
120 
122  DetectorVolumeUpdator detectorVolumeUpdator) {
123  m_detectorVolumeUpdator = std::move(detectorVolumeUpdator);
124 }
125 
128  return m_detectorVolumeUpdator;
129 }
130 
132  return m_name;
133 }
134 
135 std::shared_ptr<Acts::Experimental::Detector>
137  return shared_from_this();
138 }
139 
140 std::shared_ptr<const Acts::Experimental::Detector>
142  return shared_from_this();
143 }
144 
146  const GeometryContext& gctx, NavigationState& nState) const {
147  m_detectorVolumeUpdator(gctx, nState);
148 }
149 
152  const GeometryContext& gctx, const Vector3& position) const {
154  nState.currentDetector = this;
155  nState.position = position;
156  m_detectorVolumeUpdator(gctx, nState);
157  return nState.currentVolume;
158 }
159 
162  const std::string& name) const {
163  auto vCandidate = m_volumeNameIndex.find(name);
164  if (vCandidate != m_volumeNameIndex.end()) {
165  return m_volumes.external[vCandidate->second];
166  }
167  return nullptr;
168 }
169 
172  return m_sensitiveHierarchyMap;
173 }