Back to home page

EIC code displayed by LXR

 
 

    


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 // 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/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 }  // namespace
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     // Skip volumes that were already in the parent before the subtree
0175     // was processed
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 }  // namespace Acts::Experimental