8 #include "Acts/Geometry/BlueprintNode.hpp"
9 #include "Acts/Geometry/StaticBlueprintNode.hpp"
10 #include "Acts/Geometry/CylinderVolumeBounds.hpp"
11 #include <Acts/Geometry/ContainerBlueprintNode.hpp>
12 #include "Acts/Geometry/MultiWireVolumeBuilder.hpp"
13 #include "Acts/Surfaces/TrapezoidBounds.hpp"
14 #include "Acts/Material/HomogeneousSurfaceMaterial.hpp"
15 #include <Acts/Geometry/MaterialDesignatorBlueprintNode.hpp>
16 #include <Acts/Geometry/GeometryIdentifierBlueprintNode.hpp>
17 #include <Acts/Geometry/VolumeAttachmentStrategy.hpp>
18 #include "Acts/Geometry/VolumeResizeStrategy.hpp"
19 #include <Acts/Geometry/TrackingVolume.hpp>
20 #include <Acts/Geometry/TrapezoidVolumeBounds.hpp>
21 #include <Acts/Surfaces/PlaneSurface.hpp>
22 #include <Acts/Plugins/GeoModel/GeoModelMaterialConverter.hpp>
23 #include <Acts/Visualization/ObjVisualization3D.hpp>
29 #include "GeoModelValidation/GeoMaterialHelper.h"
33 constexpr std::size_t s_muonBarrelId = 30;
34 constexpr std::size_t s_muonEndcapAId = 31;
35 constexpr std::size_t s_muonEndcapCId = 32;
42 return StatusCode::SUCCESS;
60 endcapAStations.insert(
chamber);
62 endcapCStations.insert(
chamber);
67 auto muonNode = std::make_shared<Acts::Experimental::CylinderContainerBlueprintNode>(
"MuonNode", Acts::AxisDirection::AxisZ);
69 Acts::VolumeBoundFactory boundsFactory{};
71 auto barrelNode =
buildMuonNode(gctx, barrelStations,
"BI_BM_BO_EE_EI",Acts::GeometryIdentifier().withVolume(s_muonBarrelId), boundsFactory);
72 auto endcapANode =
buildMuonNode(gctx, endcapAStations,
"EM_EO_A", Acts::GeometryIdentifier().withVolume(s_muonEndcapAId), boundsFactory);
73 auto endcapCNode =
buildMuonNode(gctx, endcapCStations,
"EM_EO_C", Acts::GeometryIdentifier().withVolume(s_muonEndcapCId), boundsFactory);
77 barrelNode->addChild(std::move(childNode));
80 muonNode->addChild(std::move(barrelNode));
81 muonNode->addChild(std::move(endcapANode));
82 muonNode->addChild(std::move(endcapCNode));
88 std::shared_ptr<Acts::Experimental::StaticBlueprintNode>
90 const Acts::GeometryContext& gctx,
92 const std::string&
name,
93 const Acts::GeometryIdentifier&
id,
94 Acts::VolumeBoundFactory& boundsFactory)
const {
97 std::vector<std::string> stationNames;
99 std::vector<std::shared_ptr<Acts::Experimental::StaticBlueprintNode>> nodes;
101 double innerRadius = 0.0;
102 double outerRadius = std::numeric_limits<double>::lowest();
103 double maxZ = std::numeric_limits<double>::lowest();
111 auto vol = std::make_unique<Acts::TrackingVolume>(
118 vol->addSurface(std::move(material));
120 Acts::GeometryIdentifier chId =
id.withLayer(chamberId++);
121 vol->assignGeometryId(chId);
123 std::pair<std::vector<volumePtr>,std::vector<surfacePtr>> innerStructure =
getSensitiveElements(*context, *
chamber, chId, boundsFactory);
125 for(
auto& surface: innerStructure.second){
126 vol->addSurface(surface);
130 for(
const auto& surface: vol->boundarySurfaces()){
131 const auto& surfaceRepr = surface->surfaceRepresentation();
132 const Acts::Polyhedron& polyhedron = surfaceRepr.polyhedronRepresentation(gctx);
145 Acts::ObjVisualization3D
helper;
146 vol->visualize(
helper, gctx, {.visible =
true},
147 {.visible =
false}, {.visible =
true});
152 auto node = std::make_shared<Acts::Experimental::StaticBlueprintNode>(std::move(vol));
153 for(
auto& readoutVol : innerStructure.first){
154 node->addStaticVolume(std::move(readoutVol));
158 nodes.emplace_back(std::move(
node));
161 double halfLengthZ = 0.5 * std::abs(maxZ - minZ);
170 auto bounds = boundsFactory.makeBounds<Acts::CylinderVolumeBounds>(innerRadius, outerRadius, halfLengthZ);
171 auto volume = std::make_unique<Acts::TrackingVolume>(
trf, bounds,
name);
172 volume->assignGeometryId(
id);
173 auto muonNode = std::make_shared<Acts::Experimental::StaticBlueprintNode>(std::move(volume));
176 std::ranges::for_each(nodes, [&muonNode](
auto&
node) {
177 muonNode->addChild(std::move(
node));
183 std::pair<std::vector<volumePtr>, std::vector<surfacePtr>>
187 const Acts::GeometryIdentifier& chId,
188 Acts::VolumeBoundFactory& boundsFactory)
const {
190 std::vector<volumePtr> readoutVolumes;
191 std::vector<surfacePtr> readoutSurfaces;
192 Acts::GeometryIdentifier::Value mdtId{1};
196 std::vector<surfacePtr> detSurfaces = readoutEle->getSurfaces();
197 switch(readoutEle->detectorType()){
207 Acts::Experimental::MultiWireVolumeBuilder::Config mwCfg;
209 mwCfg.mlSurfaces = detSurfaces;
210 mwCfg.transform = mdtTransform;
212 auto mdtBounds = boundsFactory.makeBounds<Acts::TrapezoidVolumeBounds>(
parameters.shortHalfX,
215 mwCfg.bounds = mdtBounds;
216 using BoundsV = Acts::TrapezoidVolumeBounds::BoundValues;
217 mwCfg.binning = {{{Acts::AxisDirection::AxisY, Acts::AxisBoundaryType::Bound,
218 -mdtBounds->get(BoundsV::eHalfLengthY),
219 mdtBounds->get(BoundsV::eHalfLengthY),
220 static_cast<std::size_t
>(std::lround(2 * mdtBounds->get(BoundsV::eHalfLengthY) /
parameters.tubePitch))}, 2
u},
221 {{Acts::AxisDirection::AxisZ, Acts::AxisBoundaryType::Bound,
222 -mdtBounds->get(BoundsV::eHalfLengthZ),
223 mdtBounds->get(BoundsV::eHalfLengthZ),
224 static_cast<std::size_t
>(std::lround(2 * mdtBounds->get(BoundsV::eHalfLengthZ) /
parameters.tubePitch))}, 1
u}};
225 Acts::Experimental::MultiWireVolumeBuilder mdtBuilder{mwCfg};
226 std::unique_ptr<Acts::TrackingVolume> mdtVolume = mdtBuilder.buildVolume(gctx.
context());
228 mdtVolume->assignGeometryId(chId.withExtra(mdtId++));
229 readoutVolumes.push_back(std::move(mdtVolume));
237 readoutSurfaces.insert(readoutSurfaces.end(), std::make_move_iterator(detSurfaces.begin()),
238 std::make_move_iterator(detSurfaces.end()));
249 return std::make_pair(std::move(readoutVolumes), std::move(readoutSurfaces));
254 std::shared_ptr<Acts::Surface>
258 const float thickness =
chamber.halfZ() * 2;
259 PVConstLink parentVolume =
chamber.readoutEles().front()->getMaterialGeom()->getParent();
260 GeoModelTools::GeoMaterialHelper geoMaterialHelper;
261 std::pair<GeoModelTools::GeoMaterialPtr, double> geoMaterials = geoMaterialHelper.collectMaterial(parentVolume);
263 const Acts::Material aMat = Acts::GeoModel::geoMaterialConverter(*geoMaterials.first);
265 auto constPtr =
chamber.surface().getSharedPtr();
267 auto ptr = std::const_pointer_cast<Acts::Surface>(constPtr);
268 Acts::MaterialSlab slab{aMat, thickness};
269 std::shared_ptr<Acts::HomogeneousSurfaceMaterial> material = std::make_shared<Acts::HomogeneousSurfaceMaterial>(slab);
270 ptr->assignSurfaceMaterial(material);
277 bool matchesName = std::ranges::any_of(stationIndex.begin(), stationIndex.end(), [&](
const auto&
n){
278 return stationIdx == n;
280 const int stationEta =
chamber.stationEta();
282 return matchesName && etaSignCorrect;