Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-08 08:00:33

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 "ActsPlugins/Root/BlueprintBuilder.hpp"
0010 
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Geometry/detail/BlueprintBuilder_impl.hpp"
0013 #include "Acts/Surfaces/Surface.hpp"
0014 #include "ActsPlugins/Root/TGeoSurfaceConverter.hpp"
0015 
0016 #include <cstddef>
0017 #include <functional>
0018 #include <iterator>
0019 #include <optional>
0020 #include <stdexcept>
0021 #include <string>
0022 #include <utility>
0023 #include <vector>
0024 
0025 #include "TGeoNode.h"
0026 #include "TGeoShape.h"
0027 #include "TGeoVolume.h"
0028 
0029 namespace ActsPlugins {
0030 
0031 TGeoBlueprintBuilderBackend::DetectorElementPtr
0032 TGeoBlueprintBuilderBackend::defaultElementFactory(
0033     const TGeoDetectorElement::Identifier& identifier, const TGeoNode& tGeoNode,
0034     const TGeoMatrix& tGeoMatrix, AxisDefinition axes, double lengthScale,
0035     std::shared_ptr<const Acts::ISurfaceMaterial> material) {
0036   return std::make_shared<TGeoDetectorElement>(
0037       identifier, tGeoNode, tGeoMatrix, axes, lengthScale, std::move(material));
0038 }
0039 
0040 TGeoBlueprintBuilderBackend::TGeoBlueprintBuilderBackend(
0041     const Config& cfg, const Acts::Logger& logger)
0042     : m_cfg(cfg), m_logger(&logger) {
0043   if (m_cfg.root == nullptr) {
0044     throw std::invalid_argument(
0045         "TGeoBlueprintBuilderBackend: root node is null");
0046   }
0047   m_world = makeElement(*m_cfg.root, nullptr);
0048 }
0049 
0050 auto TGeoBlueprintBuilderBackend::makeElement(
0051     const TGeoNode& node, std::shared_ptr<const NodeContext> parent) const
0052     -> Element {
0053   return Element{std::make_shared<NodeContext>(
0054       NodeContext{.node = &node, .parent = std::move(parent)})};
0055 }
0056 
0057 const TGeoBlueprintBuilderBackend::NodeContext&
0058 TGeoBlueprintBuilderBackend::contextOf(const Element& element) const {
0059   if (element.context == nullptr) {
0060     throw std::invalid_argument(
0061         "TGeoBlueprintBuilderBackend: invalid element handle");
0062   }
0063   return *element.context;
0064 }
0065 
0066 TGeoDetectorElement::Identifier
0067 TGeoBlueprintBuilderBackend::defaultIdentifierFor(
0068     const Element& element) const {
0069   const auto path = pathOf(element);
0070   return static_cast<TGeoDetectorElement::Identifier>(
0071       std::hash<std::string>{}(path));
0072 }
0073 
0074 TGeoBlueprintBuilderBackend::DetectorElementPtr
0075 TGeoBlueprintBuilderBackend::createDetectorElement(const Element& element,
0076                                                    AxisDefinition axes) const {
0077   const auto& context = contextOf(element);
0078   const auto identifier = m_cfg.identifierProvider != nullptr
0079                               ? m_cfg.identifierProvider(element)
0080                               : defaultIdentifierFor(element);
0081   const auto transform = transformOf(element);
0082 
0083   auto detectorElement = m_cfg.elementFactory(
0084       identifier, *context.node, transform, axes, m_cfg.lengthScale, nullptr);
0085   m_detectorElementStore.push_back(detectorElement);
0086   return detectorElement;
0087 }
0088 
0089 std::vector<std::shared_ptr<Acts::Surface>>
0090 TGeoBlueprintBuilderBackend::makeSurfaces(std::span<const Element> sensitives,
0091                                           const LayerSpec& layerSpec) const {
0092   if (!layerSpec.axes.has_value()) {
0093     throw std::runtime_error(
0094         "TGeoBlueprintBuilderBackend::makeSurfaces: axes not set");
0095   }
0096 
0097   std::vector<std::shared_ptr<Acts::Surface>> surfaces;
0098   surfaces.reserve(sensitives.size());
0099 
0100   for (const auto& sensitive : sensitives) {
0101     auto detectorElement =
0102         createDetectorElement(sensitive, layerSpec.axes.value());
0103     surfaces.push_back(detectorElement->surface().getSharedPtr());
0104   }
0105 
0106   return surfaces;
0107 }
0108 
0109 std::optional<Acts::Transform3>
0110 TGeoBlueprintBuilderBackend::lookupLayerTransform(
0111     const Element& element, const LayerSpec& layerSpec) const {
0112   if (!layerSpec.layerAxes.has_value()) {
0113     return std::nullopt;
0114   }
0115 
0116   const auto& context = contextOf(element);
0117   return TGeoSurfaceConverter::transformFromShape(
0118       *context.node->GetVolume()->GetShape(), transformOf(element),
0119       layerSpec.layerAxes.value(), m_cfg.lengthScale);
0120 }
0121 
0122 TGeoBlueprintBuilderBackend::Element TGeoBlueprintBuilderBackend::world()
0123     const {
0124   return m_world;
0125 }
0126 
0127 std::string TGeoBlueprintBuilderBackend::nameOf(const Element& element) const {
0128   const auto& context = contextOf(element);
0129   if (const auto* volume = context.node->GetVolume();
0130       volume != nullptr && volume->GetName() != nullptr) {
0131     return volume->GetName();
0132   }
0133   if (context.node->GetName() != nullptr) {
0134     return context.node->GetName();
0135   }
0136   return {};
0137 }
0138 
0139 std::vector<TGeoBlueprintBuilderBackend::Element>
0140 TGeoBlueprintBuilderBackend::children(const Element& parent) const {
0141   const auto& context = contextOf(parent);
0142   std::vector<Element> result;
0143   result.reserve(context.node->GetNdaughters());
0144   for (int i = 0; i < context.node->GetNdaughters(); ++i) {
0145     const TGeoNode* child = context.node->GetDaughter(i);
0146     if (child == nullptr) {
0147       continue;
0148     }
0149     result.push_back(makeElement(*child, parent.context));
0150   }
0151   return result;
0152 }
0153 
0154 TGeoBlueprintBuilderBackend::Element TGeoBlueprintBuilderBackend::parent(
0155     const Element& element) const {
0156   return Element{contextOf(element).parent};
0157 }
0158 
0159 bool TGeoBlueprintBuilderBackend::isSensitive(const Element& element) const {
0160   return m_cfg.sensitivePredicate != nullptr &&
0161          m_cfg.sensitivePredicate(element);
0162 }
0163 
0164 const TGeoNode& TGeoBlueprintBuilderBackend::nodeOf(
0165     const Element& element) const {
0166   return *contextOf(element).node;
0167 }
0168 
0169 TGeoHMatrix TGeoBlueprintBuilderBackend::transformOf(
0170     const Element& element) const {
0171   std::vector<const NodeContext*> chain;
0172   for (const NodeContext* current = element.context.get(); current != nullptr;
0173        current = current->parent.get()) {
0174     chain.push_back(current);
0175   }
0176 
0177   std::optional<TGeoHMatrix> transform = std::nullopt;
0178   for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
0179     const TGeoMatrix* localMatrix = (*it)->node->GetMatrix();
0180     if (localMatrix == nullptr) {
0181       continue;
0182     }
0183     if (!transform.has_value()) {
0184       transform.emplace(*localMatrix);
0185       continue;
0186     }
0187     transform = TGeoCombiTrans(*transform) * TGeoCombiTrans(*localMatrix);
0188   }
0189   return transform.value_or(TGeoHMatrix{});
0190 }
0191 
0192 std::string TGeoBlueprintBuilderBackend::pathOf(const Element& element) const {
0193   std::vector<std::string> names;
0194   for (const NodeContext* current = element.context.get(); current != nullptr;
0195        current = current->parent.get()) {
0196     if (current->node->GetName() != nullptr) {
0197       names.emplace_back(current->node->GetName());
0198     } else {
0199       names.emplace_back(current->node->GetVolume()->GetName());
0200     }
0201   }
0202 
0203   if (names.empty()) {
0204     return {};
0205   }
0206 
0207   std::string path = names.back();
0208   for (auto it = std::next(names.rbegin()); it != names.rend(); ++it) {
0209     path += "|";
0210     path += *it;
0211   }
0212   return path;
0213 }
0214 
0215 }  // namespace ActsPlugins
0216 
0217 namespace Acts::Experimental {
0218 template class BlueprintBuilder<ActsPlugins::TGeoBlueprintBuilderBackend>;
0219 template class ElementLayerAssembler<ActsPlugins::TGeoBlueprintBuilderBackend>;
0220 template class SensorLayerAssembler<ActsPlugins::TGeoBlueprintBuilderBackend>;
0221 template class SensorLayer<ActsPlugins::TGeoBlueprintBuilderBackend>;
0222 }  // namespace Acts::Experimental