53std::variant<MuonChamberSet, MuonSectorSet> elements;
54std::variant<MuonChamberSet, MuonSectorSet> barrelStations, endcapAStations, endcapCStations, endcapMiddleAStations, endcapMiddleCStations;
57 elements =
m_detMgr->getAllSectors();
59 elements =
m_detMgr->getAllChambers();
62std::visit([&](
auto& elems) {
63 using SetType = std::decay_t<
decltype(elems)>;
66 SetType
barrel, endcapA, endcapC, endcapMiddleA, endcapMiddleC;
68 for (
const auto& element : elems) {
70 {StIdx::BI, StIdx::BM, StIdx::BO, StIdx::BE, StIdx::EE, StIdx::EI},
74 endcapA.push_back(element);
76 endcapC.push_back(element);
78 endcapMiddleA.push_back(element);
80 endcapMiddleC.push_back(element);
83 <<
" not assigned to any station!");
88 barrelStations = std::move(
barrel);
89 endcapAStations = std::move(endcapA);
90 endcapCStations = std::move(endcapC);
91 endcapMiddleAStations= std::move(endcapMiddleA);
92 endcapMiddleCStations= std::move(endcapMiddleC);
97auto muonNode = std::make_shared<Acts::Experimental::CylinderContainerBlueprintNode>(
"MuonNode", Acts::AxisDirection::AxisZ);
99Acts::VolumeBoundFactory boundsFactory{};
101auto barrelNode =
buildMuonNode(gctx, barrelStations,
"BI_BM_BO_EE_EI",Acts::GeometryIdentifier().withVolume(s_muonBarrelId), boundsFactory);
102auto endcapANode =
buildMuonNode(gctx, endcapAStations,
"EO_A", Acts::GeometryIdentifier().withVolume(s_muonEndcapAId), boundsFactory);
103auto endcapCNode =
buildMuonNode(gctx, endcapCStations,
"EO_C", Acts::GeometryIdentifier().withVolume(s_muonEndcapCId), boundsFactory);
104auto endcapMiddleANode =
buildMuonNode(gctx, endcapMiddleAStations,
"EM_A", Acts::GeometryIdentifier().withVolume(s_muonEndcapMiddleAId), boundsFactory);
105auto endcapMiddleCNode =
buildMuonNode(gctx, endcapMiddleCStations,
"EM_C", Acts::GeometryIdentifier().withVolume(s_muonEndcapMiddleCId), boundsFactory);
109 barrelNode->addChild(std::move(childNode));
112muonNode->addChild(std::move(barrelNode));
113muonNode->addChild(std::move(endcapANode));
114muonNode->addChild(std::move(endcapCNode));
115muonNode->addChild(std::move(endcapMiddleANode));
116muonNode->addChild(std::move(endcapMiddleCNode));
125 const Acts::GeometryContext& gctx,
126 const MuonElementsSet& elements,
127 const std::string& name,
128 const Acts::GeometryIdentifier&
id,
129 Acts::VolumeBoundFactory& boundsFactory)
const {
132 std::vector<std::string> stationNames;
134 std::vector<std::shared_ptr<Acts::Experimental::StaticBlueprintNode>> nodes;
136 double innerRadius = 0.0;
137 double outerRadius = std::numeric_limits<double>::lowest();
138 double maxZ = std::numeric_limits<double>::lowest();
139 double minZ = std::numeric_limits<double>::max();
143 std::visit([&](
const auto& elems){
145 for(
const auto& element : elems){
147 std::string volName = element->identString();
149 auto vol = std::make_unique<Acts::TrackingVolume>(
156 vol->addSurface(std::move(material));
158 Acts::GeometryIdentifier chId =
id.withLayer(chamberId++);
159 vol->assignGeometryId(chId);
161 std::pair<std::vector<staticNodePtr>,std::vector<surfacePtr>> innerStructure =
getSensitiveElements(*context, *element, chId, boundsFactory);
163 for(
auto& surface: innerStructure.second){
164 vol->addSurface(surface);
168 for(
const auto& surface: vol->boundarySurfaces()){
169 const auto& surfaceRepr = surface->surfaceRepresentation();
170 const Acts::Polyhedron& polyhedron = surfaceRepr.polyhedronRepresentation(gctx);
173 maxZ = std::max(maxZ, center.z());
174 minZ = std::min(minZ, center.z());
178 outerRadius = std::max(outerRadius, vertex.perp());
183 Acts::ObjVisualization3D helper;
184 vol->visualize(helper, gctx, {.visible =
true},
185 {.visible =
true}, {.visible =
true});
186 helper.write(volName +
".obj");
190 std::shared_ptr<Acts::Experimental::StaticBlueprintNode>
node;
192 const bool isSingleMdt =
193 (element->readoutEles().size() == 1 &&
198 node = std::move(innerStructure.first.front());
199 innerStructure.first.clear();
201 node = std::make_shared<Acts::Experimental::StaticBlueprintNode>(std::move(vol));
203 for (
auto& childNode : innerStructure.first) {
204 node->addChild(std::move(childNode));
206 innerStructure.first.clear();
213 nodes.emplace_back(std::move(
node));
219 double halfLengthZ = 0.5 * std::abs(maxZ - minZ);
228 auto bounds = boundsFactory.makeBounds<Acts::CylinderVolumeBounds>(innerRadius, outerRadius, halfLengthZ);
229 auto volume = std::make_unique<Acts::TrackingVolume>(trf, bounds, name);
230 volume->assignGeometryId(
id);
231 auto muonNode = std::make_shared<Acts::Experimental::StaticBlueprintNode>(std::move(volume));
234 std::ranges::for_each(nodes, [&muonNode](
auto&
node) {
235 muonNode->addChild(std::move(
node));
245 const Acts::GeometryIdentifier& chId,
246 Acts::VolumeBoundFactory& boundsFactory)
const {
248 std::vector<staticNodePtr> readoutVolumes;
249 std::vector<surfacePtr> readoutSurfaces;
250 Acts::GeometryIdentifier::Value mdtId{1};
254 std::vector<surfacePtr> detSurfaces = readoutEle->getSurfaces();
255 switch(readoutEle->detectorType()){
261 const Amg::Vector3D toChamber = element.globalToLocalTrans(gctx)*mdtReadoutEle->center(gctx);
262 const Acts::Transform3 mdtTransform = element.localToGlobalTrans(gctx) *
Amg::getTranslate3D(toChamber);
265 Acts::Experimental::MultiWireVolumeBuilder::Config mwCfg;
266 mwCfg.name =
m_detMgr->idHelperSvc()->toStringDetEl(mdtReadoutEle->identify());
267 mwCfg.mlSurfaces = detSurfaces;
268 mwCfg.transform = mdtTransform;
271 std::shared_ptr<Acts::VolumeBounds> mdtBounds{
nullptr};
273 if(std::abs(parameters.shortHalfX - parameters.longHalfX) < Acts::s_epsilon){
275 mdtBounds = boundsFactory.makeBounds<Acts::CuboidVolumeBounds>(parameters.shortHalfX, parameters.halfY, parameters.halfHeight);
279 mdtBounds = boundsFactory.makeBounds<Acts::TrapezoidVolumeBounds>(parameters.shortHalfX,
280 parameters.longHalfX, parameters.halfY, parameters.halfHeight);
283 mwCfg.bounds = mdtBounds;
284 using BoundsV = Acts::TrapezoidVolumeBounds::BoundValues;
285 mwCfg.binning = {{{Acts::AxisDirection::AxisY, Acts::AxisBoundaryType::Bound,
288 static_cast<std::size_t
>(std::lround(2 * parameters.halfY / parameters.tubePitch))}, 2u},
289 {{Acts::AxisDirection::AxisZ, Acts::AxisBoundaryType::Bound,
290 -parameters.halfHeight,
291 parameters.halfHeight,
292 static_cast<std::size_t
>(std::lround(2 * parameters.halfHeight / parameters.tubePitch))}, 1u}};
293 Acts::Experimental::MultiWireVolumeBuilder mdtBuilder{mwCfg};
294 std::unique_ptr<Acts::TrackingVolume> mdtVolume = mdtBuilder.buildVolume();
296 mdtVolume->assignGeometryId(chId.withExtra(mdtId++));
298 std::shared_ptr<Acts::Experimental::StaticBlueprintNode> mdtNode = std::make_shared<Acts::Experimental::StaticBlueprintNode>(std::move(mdtVolume));
299 mdtNode->setNavigationPolicyFactory(mdtBuilder.createNavigationPolicyFactory());
300 readoutVolumes.push_back(std::move(mdtNode));
309 readoutSurfaces.insert(readoutSurfaces.end(), std::make_move_iterator(detSurfaces.begin()),
310 std::make_move_iterator(detSurfaces.end()));
321 return std::make_pair(std::move(readoutVolumes), std::move(readoutSurfaces));
328 const T& element)
const {
330 const float thickness = element.halfZ() * 2;
331 PVConstLink parentVolume = element.readoutEles().front()->getMaterialGeom()->getParent();
332 GeoModelTools::GeoMaterialHelper geoMaterialHelper;
333 std::pair<GeoModelTools::GeoMaterialPtr, double> geoMaterials = geoMaterialHelper.collectMaterial(parentVolume);
335 const Acts::Material aMat = ActsPlugins::GeoModel::geoMaterialConverter(*geoMaterials.first);
337 auto constPtr = element.surface().getSharedPtr();
339 auto ptr = std::const_pointer_cast<Acts::Surface>(constPtr);
341 Acts::MaterialSlab slab{aMat, thickness};
342 std::shared_ptr<Acts::HomogeneousSurfaceMaterial> material = std::make_shared<Acts::HomogeneousSurfaceMaterial>(slab);
343 ptr->assignSurfaceMaterial(material);
std::shared_ptr< Acts::Experimental::StaticBlueprintNode > buildMuonNode(const Acts::GeometryContext &gctx, const MuonElementsSet &elements, const std::string &name, const Acts::GeometryIdentifier &id, Acts::VolumeBoundFactory &boundsFactory) const
Build subnodes for the muon system node.