Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:11:18

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
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   // Fill volumes
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   // Fill the surface map
0055   std::unordered_map<GeometryIdentifier, const Surface*> surfaceGeoIdMap;
0056   // Map for the volume geometry id
0057   std::unordered_map<GeometryIdentifier, const DetectorVolume*> volumeGeoIdMap;
0058 
0059   // Check for unique names and fill the volume name / index map
0060   for (auto [iv, v] : enumerate(m_volumes.internal)) {
0061     // Assign this detector
0062     v->assignDetector(*this);
0063     // Close the portals
0064     v->closePortals();
0065     // Store the name
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     // Check volume geometry id
0075     auto vgeoID = v->geometryId();
0076     // Check for undefined geometry id
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       // Check for undefined geometry id
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   // Let us transfer the surfaces into the hierarchy map
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 }