File indexing completed on 2025-01-18 09:11:18
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Detector/Detector.hpp"
0010
0011 #include "Acts/Navigation/NavigationState.hpp"
0012 #include "Acts/Surfaces/Surface.hpp"
0013 #include "Acts/Utilities/Delegate.hpp"
0014 #include "Acts/Utilities/Enumerate.hpp"
0015
0016 #include <iterator>
0017 #include <sstream>
0018 #include <stdexcept>
0019 #include <unordered_map>
0020 #include <utility>
0021
0022 Acts::Experimental::Detector::Detector(
0023 std::string name, std::vector<std::shared_ptr<DetectorVolume>> rootVolumes,
0024 ExternalNavigationDelegate detectorVolumeFinder)
0025 : m_name(std::move(name)),
0026 m_rootVolumes(std::move(rootVolumes)),
0027 m_volumeFinder(std::move(detectorVolumeFinder)) {
0028 if (m_rootVolumes.internal.empty()) {
0029 throw std::invalid_argument("Detector: no volume were given.");
0030 }
0031 if (!m_volumeFinder.connected()) {
0032 throw std::invalid_argument(
0033 "Detector: volume finder delegate is not connected.");
0034 }
0035
0036
0037 auto collectVolumes = [&]() {
0038 std::vector<std::shared_ptr<DetectorVolume>> volumes;
0039 auto recurse = [&volumes](const std::shared_ptr<DetectorVolume>& volume,
0040 auto& callback) -> void {
0041 volumes.push_back(volume);
0042 for (const auto& v : volume->volumePtrs()) {
0043 callback(v, callback);
0044 }
0045 };
0046 for (const auto& root : m_rootVolumes.internal) {
0047 recurse(root, recurse);
0048 }
0049 return volumes;
0050 };
0051 m_volumes = DetectorVolume::ObjectStore<std::shared_ptr<DetectorVolume>>(
0052 collectVolumes());
0053
0054
0055 std::unordered_map<GeometryIdentifier, const Surface*> surfaceGeoIdMap;
0056
0057 std::unordered_map<GeometryIdentifier, const DetectorVolume*> volumeGeoIdMap;
0058
0059
0060 for (auto [iv, v] : enumerate(m_volumes.internal)) {
0061
0062 v->assignDetector(*this);
0063
0064 v->closePortals();
0065
0066 const std::string vName = v->name();
0067 if (m_volumeNameIndex.contains(vName)) {
0068 throw std::invalid_argument("Detector: duplicate volume name " + vName +
0069 " detected.");
0070 }
0071 m_volumeNameIndex[vName] = iv;
0072
0073
0074
0075 auto vgeoID = v->geometryId();
0076
0077 if (vgeoID.value() == 0u) {
0078 throw std::invalid_argument("Detector: volume '" + v->name() +
0079 "' with undefined geometry id detected" +
0080 ". Make sure a GeometryIdGenerator is used.");
0081 }
0082 if (volumeGeoIdMap.contains(vgeoID)) {
0083 std::stringstream ss;
0084 ss << vgeoID;
0085 throw std::invalid_argument("Detector: duplicate volume geometry id '" +
0086 ss.str() + "' detected" +
0087 ". Make sure a GeometryIdGenerator is used.");
0088 }
0089 volumeGeoIdMap.emplace(vgeoID, v.get());
0090
0091
0092 for (const auto* s : v->surfaces()) {
0093 auto sgeoID = s->geometryId();
0094
0095
0096
0097 if (sgeoID.value() == 0u) {
0098 std::stringstream ss;
0099 ss << s->name();
0100 throw std::invalid_argument(
0101 "Detector: surface '" + ss.str() + "' with undefined geometry id " +
0102 "detected in volume '" + v->name() +
0103 "'. Make sure a GeometryIdGenerator is used.");
0104 }
0105
0106
0107 if (surfaceGeoIdMap.contains(sgeoID)) {
0108 std::stringstream ss;
0109 ss << sgeoID;
0110 throw std::invalid_argument(
0111 "Detector: duplicate sensitive surface geometry id '" + ss.str() +
0112 "' detected in volume '" + v->name() +
0113 "'. Make sure a GeometryIdGenerator is used.");
0114 }
0115 surfaceGeoIdMap.emplace(sgeoID, s);
0116 }
0117 }
0118
0119 std::vector<std::pair<GeometryIdentifier, const Surface*>> surfaceGeoIdVec;
0120 surfaceGeoIdVec.reserve(surfaceGeoIdMap.size());
0121 for (auto [geoID, surface] : surfaceGeoIdMap) {
0122 surfaceGeoIdVec.emplace_back(geoID, surface);
0123 }
0124 m_sensitiveHierarchyMap =
0125 GeometryHierarchyMap<const Surface*>(std::move(surfaceGeoIdVec));
0126 }
0127
0128 std::shared_ptr<Acts::Experimental::Detector>
0129 Acts::Experimental::Detector::makeShared(
0130 std::string name, std::vector<std::shared_ptr<DetectorVolume>> rootVolumes,
0131 ExternalNavigationDelegate detectorVolumeFinder) {
0132 return std::shared_ptr<Detector>(
0133 new Detector(std::move(name), std::move(rootVolumes),
0134 std::move(detectorVolumeFinder)));
0135 }
0136
0137 std::vector<std::shared_ptr<Acts::Experimental::DetectorVolume>>&
0138 Acts::Experimental::Detector::rootVolumePtrs() {
0139 return m_rootVolumes.internal;
0140 }
0141
0142 const std::vector<const Acts::Experimental::DetectorVolume*>&
0143 Acts::Experimental::Detector::rootVolumes() const {
0144 return m_rootVolumes.external;
0145 }
0146
0147 std::vector<std::shared_ptr<Acts::Experimental::DetectorVolume>>&
0148 Acts::Experimental::Detector::volumePtrs() {
0149 return m_volumes.internal;
0150 }
0151
0152 const std::vector<const Acts::Experimental::DetectorVolume*>&
0153 Acts::Experimental::Detector::volumes() const {
0154 return m_volumes.external;
0155 }
0156
0157 void Acts::Experimental::Detector::updateDetectorVolumeFinder(
0158 ExternalNavigationDelegate detectorVolumeFinder) {
0159 m_volumeFinder = std::move(detectorVolumeFinder);
0160 }
0161
0162 const Acts::Experimental::ExternalNavigationDelegate&
0163 Acts::Experimental::Detector::detectorVolumeFinder() const {
0164 return m_volumeFinder;
0165 }
0166
0167 const std::string& Acts::Experimental::Detector::name() const {
0168 return m_name;
0169 }
0170
0171 std::shared_ptr<Acts::Experimental::Detector>
0172 Acts::Experimental::Detector::getSharedPtr() {
0173 return shared_from_this();
0174 }
0175
0176 std::shared_ptr<const Acts::Experimental::Detector>
0177 Acts::Experimental::Detector::getSharedPtr() const {
0178 return shared_from_this();
0179 }
0180
0181 void Acts::Experimental::Detector::updateDetectorVolume(
0182 const GeometryContext& gctx, NavigationState& nState) const {
0183 m_volumeFinder(gctx, nState);
0184 }
0185
0186 const Acts::Experimental::DetectorVolume*
0187 Acts::Experimental::Detector::findDetectorVolume(
0188 const GeometryContext& gctx, const Vector3& position) const {
0189 NavigationState nState;
0190 nState.currentDetector = this;
0191 nState.position = position;
0192 m_volumeFinder(gctx, nState);
0193 return nState.currentVolume;
0194 }
0195
0196 const Acts::Experimental::DetectorVolume*
0197 Acts::Experimental::Detector::findDetectorVolume(
0198 const std::string& name) const {
0199 auto vCandidate = m_volumeNameIndex.find(name);
0200 if (vCandidate != m_volumeNameIndex.end()) {
0201 return m_volumes.external[vCandidate->second];
0202 }
0203 return nullptr;
0204 }
0205
0206 const Acts::GeometryHierarchyMap<const Acts::Surface*>&
0207 Acts::Experimental::Detector::sensitiveHierarchyMap() const {
0208 return m_sensitiveHierarchyMap;
0209 }
0210
0211 const Acts::Surface* Acts::Experimental::Detector::findSurface(
0212 GeometryIdentifier geoID) const {
0213 return *m_sensitiveHierarchyMap.find(geoID);
0214 }