ATLAS Offline Software
Loading...
Searching...
No Matches
BeamPipeBlueprintNodeBuilder.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5// This absolutely needs to go first to ensure Eigen plugin is loaded
7//
8#include <GeoModelKernel/GeoTube.h>
9#include <GeoModelKernel/GeoVPhysVol.h>
10
11#include <Acts/Definitions/Units.hpp>
12#include <Acts/Geometry/ContainerBlueprintNode.hpp>
13#include <Acts/Geometry/CylinderVolumeBounds.hpp>
14#include <Acts/Geometry/GeometryIdentifierBlueprintNode.hpp>
15#include <Acts/Geometry/MaterialDesignatorBlueprintNode.hpp>
16#include <Acts/Geometry/StaticBlueprintNode.hpp>
17#include <Acts/Geometry/VolumeAttachmentStrategy.hpp>
18#include <Acts/Geometry/VolumeResizeStrategy.hpp>
19#include <Acts/Utilities/AxisDefinitions.hpp>
20
26
27using namespace Acts::UnitLiterals;
28
29namespace {
30using namespace ActsTrk::detail::GeoVolIds;
31
32using enum Acts::CylinderVolumeBounds::Face;
33using enum Acts::AxisDirection;
34using enum Acts::AxisBoundaryType;
35using AttachmentStrategy = Acts::VolumeAttachmentStrategy;
36using ResizeStrategy = Acts::VolumeResizeStrategy;
37
38} // namespace
39
40namespace ActsTrk {
41
44 ATH_CHECK(detStore()->retrieve(m_beamPipeMgr, "BeamPipe"));
45 }
46 return StatusCode::SUCCESS;
47}
48
49std::shared_ptr<Acts::Experimental::BlueprintNode>
51 const Acts::GeometryContext& /*gctx*/,
52 std::shared_ptr<Acts::Experimental::BlueprintNode>&& child) {
53
54 // Beam pipe is the innermost element and has no child to wrap
55 if (child) {
56 ATH_MSG_ERROR("BeamPipeBlueprintNodeBuilder expects no child node");
57 throw std::runtime_error("Child node is not null");
58 }
59
60 // If the manager is available, use it to construct the beam pipe geometry,
61 // and retrieve the beampipe radius from the geometry database.
62 // Otherwise, use default parameters to construct a simple tube.
63 double beamPipeRadius = m_defaultInnerRadius; // mm
64 Amg::Transform3D beamPipeTransform = Amg::Transform3D::Identity();
65
67
68 // Navigate the GeoModel tree to reach the actual beam pipe volume.
69 // When there is a single tree top, the real tube sits two levels down
70 // (envelope → envelope → tube).
71 PVConstLink beamPipeTopVolume = m_beamPipeMgr->getTreeTop(0);
72 if (m_beamPipeMgr->getNumTreeTops() == 1) {
73 beamPipeTopVolume =
74 m_beamPipeMgr->getTreeTop(0)->getChildVol(0)->getChildVol(0);
75 }
76
77 // Extract the translation so the volume is placed at the same
78 // position as the GeoModel volume.
79 beamPipeTransform =
80 Amg::getTranslate3D(beamPipeTopVolume->getX().translation());
81
82 // If SectionC03 is found, then overwrite the default radius
83 const GeoLogVol* beamPipeLogVolume = beamPipeTopVolume->getLogVol();
84 if (beamPipeLogVolume == nullptr) {
85 ATH_MSG_ERROR("Beam pipe volume has no log volume");
86 throw std::runtime_error("Beam pipe volume has no log volume");
87 }
88
89 const GeoTube* beamPipeTube =
90 dynamic_cast<const GeoTube*>(beamPipeLogVolume->getShape());
91 if (beamPipeTube == nullptr) {
92 ATH_MSG_ERROR("BeamPipeLogVolume was not of type GeoTube");
93 throw std::runtime_error{"BeamPipeLogVolume was not of type GeoTube"};
94 }
95
96 // SectionC03 is the central beam-pipe section at η≈0 whose mid-radius is
97 // used as the representative beam pipe radius for the Acts cylinder.
98 for (unsigned int i = 0; i < beamPipeTopVolume->getNChildVols(); i++) {
99 if (beamPipeTopVolume->getNameOfChildVol(i) != "SectionC03") {
100 continue;
101 }
102 PVConstLink childTopVolume = beamPipeTopVolume->getChildVol(i);
103 const GeoLogVol* childLogVolume = childTopVolume->getLogVol();
104 const GeoTube* childTube =
105 dynamic_cast<const GeoTube*>(childLogVolume->getShape());
106 if (childTube) {
107 beamPipeRadius = 0.5 * (childTube->getRMax() + childTube->getRMin());
108 break;
109 }
110 }
111
113 "BeamPipe constructed from database with radius = " << beamPipeRadius);
115 "BeamPipe shift : " << beamPipeTransform.translation().transpose());
116 } else {
118 "BeamPipe constructed from default parameters with radius = "
119 << beamPipeRadius);
121 "BeamPipe shift : " << beamPipeTransform.translation().transpose());
122 }
123
124 // Build the blueprint subtree:
125 // GeometryIdentifierNode (assigns volume ID s_beamPipeVolumeId)
126 // └── MaterialDesignator "BeamPipe_Material" (material on outer
127 // cylinder)
128 // └── StaticVolume "BeamPipe" (the actual cylinder)
129 auto beamPipeNode =
130 std::make_shared<Acts::Experimental::GeometryIdentifierBlueprintNode>();
131 beamPipeNode->setAllVolumeIdsTo(s_beamPipeVolumeId).incrementLayerIds(1);
132
133 auto& beamPipeContainer =
134 beamPipeNode->addCylinderContainer("BeamPipeContainer", AxisR);
135 beamPipeContainer.setAttachmentStrategy(AttachmentStrategy::Gap);
136 beamPipeContainer.setResizeStrategy(ResizeStrategy::Gap);
137
138 beamPipeContainer.addMaterial("BeamPipe_Material", [&](auto& mat) {
139 // Place material on the outer cylindrical surface facing outward
140 mat.configureFace(OuterCylinder, {AxisRPhi, Closed, 20},
141 {AxisZ, Bound, 20});
142 // A solid cylinder from r=0 to beamPipeRadius, extending ±3 m in z
143 mat.addStaticVolume(beamPipeTransform,
144 std::make_shared<Acts::CylinderVolumeBounds>(
145 0, beamPipeRadius * 1_mm, 3. * 1_m),
146 "BeamPipeVolume");
147 });
148
149 return beamPipeNode;
150}
151
152} // namespace ActsTrk
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_VERBOSE(x)
Acts::VolumeResizeStrategy ResizeStrategy
Acts::VolumeAttachmentStrategy AttachmentStrategy
std::shared_ptr< Acts::Experimental::BlueprintNode > buildBlueprintNode(const Acts::GeometryContext &gctx, std::shared_ptr< Acts::Experimental::BlueprintNode > &&child) override
Build the BeamPipe Blueprint Node.
Define the volume parts of the GeometryIdentifier for each ATLAS subsystem centrally.
constexpr std::size_t s_beamPipeVolumeId
The AlignStoreProviderAlg loads the rigid alignment corrections and pipes them through the readout ge...
Amg::Transform3D getTranslate3D(const double X, const double Y, const double Z)
: Returns a shift transformation along an arbitrary axis
Eigen::Affine3d Transform3D