Warning, file /acts/Core/src/Geometry/GeometryIdentifierBlueprintNode.cpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Geometry/GeometryIdentifierBlueprintNode.hpp"
0010
0011 #include "Acts/Geometry/BlueprintOptions.hpp"
0012 #include "Acts/Geometry/GeometryIdentifier.hpp"
0013 #include "Acts/Geometry/TrackingVolume.hpp"
0014 #include "Acts/Utilities/Logger.hpp"
0015
0016 #include <algorithm>
0017
0018 #include <boost/algorithm/string/join.hpp>
0019
0020 namespace Acts::Experimental {
0021
0022 namespace {
0023 class Configuration {
0024 public:
0025 virtual ~Configuration() = default;
0026
0027 virtual void apply(const std::string& prefix, TrackingVolume& volume,
0028 const Logger& logger) = 0;
0029 virtual const std::string& name() const = 0;
0030 };
0031
0032 struct FixedLayerConfiguration : public Configuration {
0033 explicit FixedLayerConfiguration(GeometryIdentifier::Value layer)
0034 : m_layer(layer) {
0035 m_name = "GeoIdFixLayer(lay=" + std::to_string(m_layer) + ")";
0036 }
0037
0038 void apply(const std::string& prefix, TrackingVolume& volume,
0039 const Logger& logger) override {
0040 ACTS_DEBUG(prefix << "~> Setting layer to " << m_layer
0041 << " for volume with ID " << volume.geometryId());
0042 volume.assignGeometryId(volume.geometryId().withLayer(m_layer));
0043 }
0044
0045 const std::string& name() const override { return m_name; }
0046
0047 private:
0048 GeometryIdentifier::Value m_layer;
0049 std::string m_name;
0050 };
0051
0052 struct IncrementLayerConfiguration : public Configuration {
0053 explicit IncrementLayerConfiguration(GeometryIdentifier::Value start)
0054 : m_value(start) {
0055 m_name = "GeoIdIncLay(start=" + std::to_string(m_value) + ")";
0056 }
0057
0058 void apply(const std::string& prefix, TrackingVolume& volume,
0059 const Logger& logger) override {
0060 ACTS_DEBUG(prefix << "Incrementing layer component for volume with ID "
0061 << volume.geometryId());
0062 if (volume.geometryId().layer() != 0) {
0063 ACTS_ERROR("Volume " << volume.volumeName() << " already has layer ID "
0064 << volume.geometryId().layer() << ". Please check "
0065 << "your geometry configuration.");
0066 throw std::logic_error("Volume already has a layer ID");
0067 }
0068 GeometryIdentifier id = volume.geometryId().withLayer(m_value);
0069 ACTS_DEBUG(prefix << "~> Setting layer to " << m_value
0070 << " for volume with ID " << id);
0071 volume.assignGeometryId(id);
0072 m_value++;
0073 }
0074
0075 const std::string& name() const override { return m_name; }
0076
0077 private:
0078 GeometryIdentifier::Value m_value;
0079 std::string m_name;
0080 };
0081
0082 struct FixedVolumeConfiguration : public Configuration {
0083 explicit FixedVolumeConfiguration(GeometryIdentifier::Value volumeId)
0084 : m_volumeId(volumeId) {
0085 m_name = "GeoIdFixVol(vol=" + std::to_string(m_volumeId) + ")";
0086 }
0087
0088 void apply(const std::string& prefix, TrackingVolume& volume,
0089 const Logger& logger) override {
0090 ACTS_DEBUG(prefix << "~> Setting volume ID to " << m_volumeId
0091 << " for volume " << volume.volumeName()
0092 << " and all descendents");
0093 volume.apply([&](TrackingVolume& v) {
0094 if (v.geometryId().volume() != 0) {
0095 ACTS_ERROR("Volume " << v.volumeName() << " already has volume ID "
0096 << v.geometryId().volume()
0097 << ". Please check your geometry configuration.");
0098 throw std::logic_error("Volume already has a volume ID");
0099 }
0100 ACTS_DEBUG(prefix << "~> Setting volume ID to " << m_volumeId
0101 << " for volume " << v.volumeName());
0102 v.assignGeometryId(v.geometryId().withVolume(m_volumeId));
0103 });
0104 }
0105
0106 const std::string& name() const override { return m_name; }
0107
0108 private:
0109 GeometryIdentifier::Value m_volumeId;
0110 std::string m_name;
0111 };
0112
0113 }
0114
0115 struct GeometryIdentifierBlueprintNodeImpl {
0116 void add(std::unique_ptr<Configuration> configuration) {
0117 m_configurations.push_back(std::move(configuration));
0118
0119 std::vector<std::string> names;
0120 for (auto& conf : m_configurations) {
0121 names.push_back(conf->name());
0122 }
0123
0124 m_name = boost::algorithm::join(names, ", ");
0125 }
0126
0127 std::vector<std::unique_ptr<Configuration>> m_configurations;
0128 std::string m_name;
0129
0130 GeometryIdentifierBlueprintNode::CompareVolumes m_sortBy;
0131 };
0132
0133 GeometryIdentifierBlueprintNode::GeometryIdentifierBlueprintNode()
0134 : m_impl(std::make_unique<GeometryIdentifierBlueprintNodeImpl>()) {}
0135
0136 GeometryIdentifierBlueprintNode::~GeometryIdentifierBlueprintNode() = default;
0137
0138 Volume& GeometryIdentifierBlueprintNode::build(const BlueprintOptions& options,
0139 const GeometryContext& gctx,
0140 const Logger& logger) {
0141 if (children().size() != 1) {
0142 throw std::invalid_argument(
0143 "GeometryIdentifierBlueprintNode must have exactly one child");
0144 }
0145
0146 if (m_impl->m_configurations.empty()) {
0147 throw std::invalid_argument(
0148 "GeometryIdentifierBlueprintNode has no configuration");
0149 }
0150
0151 return children().at(0).build(options, gctx, logger);
0152 }
0153
0154 PortalShellBase& GeometryIdentifierBlueprintNode::connect(
0155 const BlueprintOptions& options, const GeometryContext& gctx,
0156 const Logger& logger) {
0157 return children().at(0).connect(options, gctx, logger);
0158 }
0159
0160 void GeometryIdentifierBlueprintNode::finalize(const BlueprintOptions& options,
0161 const GeometryContext& gctx,
0162 TrackingVolume& parent,
0163 const Logger& logger) {
0164 ACTS_DEBUG(prefix() << "Finalizing geo id " << name() << " with parent "
0165 << parent.volumeName());
0166 std::set<const TrackingVolume*> previous;
0167 std::ranges::for_each(parent.volumes(),
0168 [&](const auto& v) { previous.insert(&v); });
0169
0170 children().at(0).finalize(options, gctx, parent, logger);
0171
0172 std::vector<TrackingVolume*> volumes;
0173 for (auto& v : parent.volumes()) {
0174
0175
0176 if (previous.contains(&v)) {
0177 continue;
0178 }
0179
0180 volumes.push_back(&v);
0181 }
0182
0183 if (m_impl->m_sortBy) {
0184 std::ranges::sort(volumes, m_impl->m_sortBy,
0185 [](TrackingVolume* v) -> TrackingVolume& { return *v; });
0186 }
0187
0188 for (auto* volumePtr : volumes) {
0189 auto& volume = *volumePtr;
0190 ACTS_VERBOSE(
0191 prefix() << " Applying " << m_impl->m_configurations.size()
0192 << " geometry ID configuration(s) on subtree starting from "
0193 << volume.volumeName());
0194 for (auto& configuration : m_impl->m_configurations) {
0195 ACTS_VERBOSE(prefix()
0196 << "~> Applying configuration " << configuration->name());
0197 configuration->apply(prefix(), volume, logger);
0198 }
0199 ACTS_DEBUG(prefix() << "~> Final volume ID for " << volume.volumeName()
0200 << ": " << volume.geometryId());
0201 }
0202 }
0203
0204 const std::string& GeometryIdentifierBlueprintNode::name() const {
0205 return m_impl->m_name;
0206 }
0207
0208 GeometryIdentifierBlueprintNode& GeometryIdentifierBlueprintNode::setLayerIdTo(
0209 GeometryIdentifier::Value layer) {
0210 m_impl->add(std::make_unique<FixedLayerConfiguration>(layer));
0211 return *this;
0212 }
0213
0214 GeometryIdentifierBlueprintNode&
0215 GeometryIdentifierBlueprintNode::incrementLayerIds(
0216 GeometryIdentifier::Value start) {
0217 m_impl->add(std::make_unique<IncrementLayerConfiguration>(start));
0218 return *this;
0219 }
0220
0221 GeometryIdentifierBlueprintNode&
0222 GeometryIdentifierBlueprintNode::setAllVolumeIdsTo(
0223 GeometryIdentifier::Value volumeId) {
0224 m_impl->add(std::make_unique<FixedVolumeConfiguration>(volumeId));
0225 return *this;
0226 }
0227
0228 GeometryIdentifierBlueprintNode& GeometryIdentifierBlueprintNode::sortBy(
0229 const CompareVolumes& compare) {
0230 if (!compare) {
0231 throw std::invalid_argument("Invalid sorting function");
0232 }
0233 m_impl->m_sortBy = compare;
0234 return *this;
0235 }
0236
0237 }