ATLAS Offline Software
Loading...
Searching...
No Matches
ActsTrk::MuonBlueprintNodeBuilder Class Reference

Helper class to build a Blueprint node of the muon system. More...

#include <MuonBlueprintNodeBuilder.h>

Inheritance diagram for ActsTrk::MuonBlueprintNodeBuilder:
Collaboration diagram for ActsTrk::MuonBlueprintNodeBuilder:

Public Types

enum class  EndcapSide : std::uint8_t { A , C , Both }
using blueprintNodePtr = std::shared_ptr<Acts::BlueprintNode>
 Abrivation of the blueprint node ptr base class.
using staticNodePtr = std::shared_ptr<Acts::StaticBlueprintNode>
 Abrivation of the blue print node pointer.
using materialNodePtr = std::shared_ptr<Acts::MaterialDesignatorBlueprintNode>
 Abrivation of the material node pointer.
using surfacePtr = std::shared_ptr<Acts::Surface>
 Abrivation of the surface pointer.
using BluePrintSurfPairs_t = std::pair<std::vector<blueprintNodePtr>, std::vector<surfacePtr>>
 Abrivate the vector pair of blue print nodes and associated active surfaces.
using MuonChamberSet = MuonGMR4::MuonDetectorManager::MuonChamberSet
 Abrivation of the container holding all chambers.
using MuonSectorSet = MuonGMR4::MuonDetectorManager::MuonSectorSet
 Abrivation of the container holding all ms sectors.
using StIdx = Muon::MuonStationIndex::StIndex
 Abrivation of the station index.
using DetIdx = Muon::MuonStationIndex::DetectorRegionIndex
 Abrivatin for the detector region index.
using LayIdx = Muon::MuonStationIndex::LayerIndex
 Abrivation for the layer index.
using ChIdx = Muon::MuonStationIndex::ChIndex
 Abrivation for the chamber index.
using DetLayIdx_t = std::pair<DetIdx, LayIdx>
 Abrivation for the stations indices.
using EnvelopeSet_t = std::variant<MuonChamberSet, MuonSectorSet>
 Hide the flexibility to build the tracking geometry from sectors or chambers behind a variant.
using EnvelopesPerStIdx_t = std::unordered_map<StIdx, EnvelopeSet_t>

Public Member Functions

StatusCode initialize () override
std::shared_ptr< Acts::BlueprintNode > buildBlueprintNode (const Acts::GeometryContext &gctx, std::shared_ptr< Acts::BlueprintNode > &&childNode) override
 Build the Muon Blueprint Node.
template<typename ElementSet_t>
std::vector< std::shared_ptr< Acts::Surface > > getPassiveMaterialSurfaces (const Acts::GeometryContext &gctx, const std::unordered_map< unsigned int, ElementSet_t > &elementsPerStation) const

Private Member Functions

std::shared_ptr< Acts::ISurfaceMaterial > preparePassiveMaterial (const Acts::SurfaceBounds &bounds, const std::size_t nBins1, const std::size_t nBins2) const
 Prepare a binned material which is associated to the surface.
std::pair< std::size_t, std::size_t > getMaterialBins (const Muon::MuonStationIndex::ChIndex chIdx) const
template<typename T>
requires (std::is_same_v<T, MuonGMR4::Chamber> || std::is_same_v<T, MuonGMR4::SpectrometerSector>)
BluePrintSurfPairs_t getSensitiveElements (const ActsTrk::GeometryContext &gctx, const T &element, const Acts::GeometryIdentifier &chId, Acts::VolumeBoundFactory &boundsFactory) const
 Get the chamber's sensitive elements.
template<typename ElementSet_t>
std::vector< surfacePtr > getPassiveMaterialSurfaces (const Acts::GeometryContext &gctx, const std::unordered_map< unsigned int, ElementSet_t > &elementsPerStation) const
 Construct and return the surfaces for the passive material description (e.g cylinders for barrel/ discs for endcaps).
template<typename T>
requires (std::is_same_v<T, MuonGMR4::Chamber> || std::is_same_v<T, MuonGMR4::SpectrometerSector>)
std::shared_ptr< const Acts::ISurfaceMaterial > getActiveMaterial (const T &element) const
 Get the active material for a given element representing the chamber/sector.
template<typename T>
requires (std::is_same_v<T, MuonGMR4::Chamber> || std::is_same_v<T, MuonGMR4::SpectrometerSector>)
bool isElementInTheStation (const T &element, const std::vector< StIdx > &stationNames, const EndcapSide side) const
 Check if the chamber is in this node.
staticNodePtr buildMuonNode (const Acts::GeometryContext &gctx, const EnvelopeSet_t &elements, const std::string &name, const Acts::GeometryIdentifier &id, Acts::VolumeBoundFactory &boundsFactory, const std::vector< ChIdx > &passiveStationIds={}) const
 Build subnodes for the muon system node.
std::variant< staticNodePtr, materialNodePtr > buildChamberNode (const blueprintNodePtr &chamberNode) const
 Build a static or a material node for a chamber that corresponds to a single blueprint node (e.g for a single MDT multilayer).
template<typename T>
std::variant< staticNodePtr, materialNodePtr > buildChamberNode (const T &element, std::unique_ptr< Acts::TrackingVolume > &vol, const std::vector< blueprintNodePtr > &innerStructure) const
 Build a static or a material node for a chamber that corresponds to a single blueprint node (e.g for a single MDT multilayer).
bool isBIS78 (const MuonGMR4::MuonReadoutElement *element) const
 Helper function determining whether a readout element is BIS78.

Private Attributes

const MuonGMR4::MuonDetectorManager * m_detMgr {nullptr}
 the Detector manager
Gaudi::Property< bool > m_useSectors {this, "UseSectors", false}
 Flag to control if we want to build the muon node from sectors or chambers.
Gaudi::Property< bool > m_alignableVolumes {this, "AlignableVolumes", true}
 Flag to control if the volumes should be alignable or not.
Gaudi::Property< bool > m_isRun4 {this, "run4Layout", false}
 Flag to control if we use run4 geometry or not.
Gaudi::Property< bool > m_assignActiveMaterial {this, "AssignActiveMaterial", true}
 Flag to assign active material on the chambers.
Gaudi::Property< bool > m_buildPassiveVolumes {this, "BuildPassiveVolumes", false}
 Flag to construct the passive material surfaces.
Gaudi::Property< bool > m_assignEmptyMaterial {this, "AssignEmptyPassiveMaterial", false}
 Assign empty material slabs for the passive surfaces.
Gaudi::Property< std::size_t > m_nPhiBinsBI {this, "nPhiBinsBI", 16}
 Number of bins in phi direction on the BI cylinder surface.
Gaudi::Property< std::size_t > m_nZBinsBI {this, "nZBinsBI", 12}
 Number of bins in Z direction on the BI cylinder surface.
Gaudi::Property< std::size_t > m_nPhiBinsBM {this, "nPhiBinsBM", 16}
 Number of bins in phi direction on the BM cylinder surface.
Gaudi::Property< std::size_t > m_nZBinsBM {this, "nZBinsBM", 12}
 Number of bins in Z direction on the BM cylinder surface.
Gaudi::Property< std::size_t > m_nPhiBinsBO {this, "nPhiBinsBO", 16}
 Number of bins in phi direction on the BM cylinder surface.
Gaudi::Property< std::size_t > m_nZBinsBO {this, "nZBinsBO", 12}
 Number of bins in Z direction on the BM cylinder surface.
Gaudi::Property< std::size_t > m_nRBinsEI1 {this, "nRBinsEIbNSW", 4}
 Number of bins in R direction on the disc before the NSW.
Gaudi::Property< std::size_t > m_nPhiBinsEI1 {this, "nPhiBinsEIbNSW", 16}
 Number of bins in phi direction on the disc before the NSW.
Gaudi::Property< std::size_t > m_nRBinsEI2 {this, "nRBinsEIaNSW", 4}
 Number of bins in R direction on the disc after the NSW.
Gaudi::Property< std::size_t > m_nPhiBinsEI2 {this, "nPhiBinsEIaNSW", 16}
 Number of bins in phi direction on the disc after the NSW.
Gaudi::Property< std::size_t > m_nRBinsEM1 {this, "nRBinsEMbBW", 16}
 Number of bins in R direction on the disc before the middle big wheel.
Gaudi::Property< std::size_t > m_nPhiBinsEM1 {this, "nPhiBinsEMbBW", 16}
 Number of bins in phi direction on the disc before the middle big wheel.
Gaudi::Property< std::size_t > m_nRBinsEM2 {this, "nRBinsEMaBW", 5}
 Number of bins in R direction on the disc after the middle big wheel.
Gaudi::Property< std::size_t > m_nPhiBinsEM2 {this, "nPhiBinsEMaBW", 16}
 Number of bins in phi direction on the disc after the NSW.
Gaudi::Property< bool > m_useFrustumNav {this, "UseFrustumNav", false}
 Flag to use frustum navigation.

Detailed Description

Helper class to build a Blueprint node of the muon system.

It builds the whole muon system for PhaseII adding it to the Blueprint as a node.

Definition at line 39 of file MuonBlueprintNodeBuilder.h.

Member Typedef Documentation

◆ blueprintNodePtr

using ActsTrk::MuonBlueprintNodeBuilder::blueprintNodePtr = std::shared_ptr<Acts::BlueprintNode>

Abrivation of the blueprint node ptr base class.

Definition at line 42 of file MuonBlueprintNodeBuilder.h.

◆ BluePrintSurfPairs_t

Abrivate the vector pair of blue print nodes and associated active surfaces.

Definition at line 50 of file MuonBlueprintNodeBuilder.h.

◆ ChIdx

Abrivation for the chamber index.

Definition at line 62 of file MuonBlueprintNodeBuilder.h.

◆ DetIdx

Abrivatin for the detector region index.

Definition at line 58 of file MuonBlueprintNodeBuilder.h.

◆ DetLayIdx_t

Abrivation for the stations indices.

Definition at line 64 of file MuonBlueprintNodeBuilder.h.

◆ EnvelopeSet_t

Hide the flexibility to build the tracking geometry from sectors or chambers behind a variant.

Definition at line 67 of file MuonBlueprintNodeBuilder.h.

◆ EnvelopesPerStIdx_t

◆ LayIdx

Abrivation for the layer index.

Definition at line 60 of file MuonBlueprintNodeBuilder.h.

◆ materialNodePtr

using ActsTrk::MuonBlueprintNodeBuilder::materialNodePtr = std::shared_ptr<Acts::MaterialDesignatorBlueprintNode>

Abrivation of the material node pointer.

Definition at line 46 of file MuonBlueprintNodeBuilder.h.

◆ MuonChamberSet

Abrivation of the container holding all chambers.

Definition at line 52 of file MuonBlueprintNodeBuilder.h.

◆ MuonSectorSet

Abrivation of the container holding all ms sectors.

Definition at line 54 of file MuonBlueprintNodeBuilder.h.

◆ staticNodePtr

using ActsTrk::MuonBlueprintNodeBuilder::staticNodePtr = std::shared_ptr<Acts::StaticBlueprintNode>

Abrivation of the blue print node pointer.

Definition at line 44 of file MuonBlueprintNodeBuilder.h.

◆ StIdx

Abrivation of the station index.

Definition at line 56 of file MuonBlueprintNodeBuilder.h.

◆ surfacePtr

using ActsTrk::MuonBlueprintNodeBuilder::surfacePtr = std::shared_ptr<Acts::Surface>

Abrivation of the surface pointer.

Definition at line 48 of file MuonBlueprintNodeBuilder.h.

Member Enumeration Documentation

◆ EndcapSide

enum class ActsTrk::MuonBlueprintNodeBuilder::EndcapSide : std::uint8_t
strong
Enumerator
A 
C 
Both 

Definition at line 71 of file MuonBlueprintNodeBuilder.h.

71 : std::uint8_t {
72 A,
73 C,
74 Both
75 };
struct color C

Member Function Documentation

◆ buildBlueprintNode()

std::shared_ptr< Acts::BlueprintNode > ActsTrk::MuonBlueprintNodeBuilder::buildBlueprintNode ( const Acts::GeometryContext & gctx,
std::shared_ptr< Acts::BlueprintNode > && childNode )
override

Build the Muon Blueprint Node.

Parameters
gctxGeometry context
childNodeThe blueprint node as child of this node (for Muon System it should be Calo or Itk).

Definition at line 100 of file MuonBlueprintNodeBuilder.cxx.

100 {
101
102EnvelopeSet_t elements;
103EnvelopeSet_t barrelStations, endcapOuterAStations, endcapOuterCStations,
104 endcapMiddleAStations, endcapMiddleCStations;
105
106if (m_useSectors) {
107 elements = m_detMgr->getAllSectors();
108} else {
109 elements = m_detMgr->getAllChambers();
110}
111
112std::visit([&](auto& elems) {
113 using SetType = std::decay_t<decltype(elems)>;
114
115 // Initialize station containers of the same type
116 SetType barrel, endcapA, endcapC, endcapMiddleA, endcapMiddleC;
117
118 for (const auto& element : elems) {
119 if (isElementInTheStation(*element,
120 {StIdx::BI, StIdx::BM, StIdx::BO, StIdx::BE, StIdx::EE, StIdx::EI},
122 barrel.push_back(element);
123 } else if (isElementInTheStation(*element, {StIdx::EO}, EndcapSide::A)) {
124 endcapA.push_back(element);
125 } else if (isElementInTheStation(*element, {StIdx::EO}, EndcapSide::C)) {
126 endcapC.push_back(element);
127 } else if (isElementInTheStation(*element, {StIdx::EM}, EndcapSide::A)) {
128 endcapMiddleA.push_back(element);
129 } else if (isElementInTheStation(*element, {StIdx::EM}, EndcapSide::C)) {
130 endcapMiddleC.push_back(element);
131 } else {
132 ATH_MSG_WARNING("Element " << element->identString()
133 << " not assigned to any station!");
134 }
135 }
136
137 // Assign back into the outer variants
138 barrelStations = std::move(barrel);
139 endcapOuterAStations = std::move(endcapA);
140 endcapOuterCStations = std::move(endcapC);
141 endcapMiddleAStations = std::move(endcapMiddleA);
142 endcapMiddleCStations = std::move(endcapMiddleC);
143}, elements);
144
145 // Top level node for the Muon system
146auto muonNode = std::make_shared<Acts::CylinderContainerBlueprintNode>("MuonNode", Acts::AxisDirection::AxisZ);
147
148Acts::VolumeBoundFactory boundsFactory{};
149using namespace ActsTrk::detail::GeoVolIds;
150auto barrelNode = buildMuonNode(gctx, barrelStations, "BI_BM_BO_EE_EI", Acts::GeometryIdentifier().withVolume(s_muonBarrelId), boundsFactory, {ChIdx::BIS, ChIdx::BML, ChIdx::BOL,
151 ChIdx::EIS, ChIdx::EIL});
152auto endcapANode = buildMuonNode(gctx, endcapOuterAStations, "EO_A", Acts::GeometryIdentifier().withVolume(s_muonEndcapAId), boundsFactory);
153auto endcapCNode = buildMuonNode(gctx, endcapOuterCStations, "EO_C", Acts::GeometryIdentifier().withVolume(s_muonEndcapCId), boundsFactory);
154auto endcapMiddleANode = buildMuonNode(gctx, endcapMiddleAStations, "EM_A", Acts::GeometryIdentifier().withVolume(s_muonEndcapMiddleAId), boundsFactory, {ChIdx::EML, ChIdx::EMS});
155auto endcapMiddleCNode = buildMuonNode(gctx, endcapMiddleCStations, "EM_C", Acts::GeometryIdentifier().withVolume(s_muonEndcapMiddleCId), boundsFactory, {ChIdx::EML, ChIdx::EMS});
157 ATH_MSG_INFO("Using Frustum Navigation Policy");
158 Acts::Experimental::FrustumNavigationPolicy::Config frustumConfig;
159 auto factory = std::make_shared<Acts::NavigationPolicyFactory>(Acts::NavigationPolicyFactory{}.add<Acts::Experimental::FrustumNavigationPolicy>(frustumConfig));
160 for (auto& node: {barrelNode, endcapANode, endcapCNode, endcapMiddleANode, endcapMiddleCNode}){
161 node->setNavigationPolicyFactory(factory);
162 }
163}
164//Add to the muon barrel child node (e.g calo or Itk) - if existed
165if(childNode){
166 barrelNode->addChild(std::move(childNode));
167}
168muonNode->addChild(std::move(barrelNode));
169muonNode->addChild(std::move(endcapANode));
170muonNode->addChild(std::move(endcapCNode));
171muonNode->addChild(std::move(endcapMiddleANode));
172muonNode->addChild(std::move(endcapMiddleCNode));
173
174return muonNode;
175
176}
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_INFO(x,...)
bool isElementInTheStation(const T &element, const std::vector< StIdx > &stationNames, const EndcapSide side) const
Check if the chamber is in this node.
Gaudi::Property< bool > m_useSectors
Flag to control if we want to build the muon node from sectors or chambers.
std::variant< MuonChamberSet, MuonSectorSet > EnvelopeSet_t
Hide the flexibility to build the tracking geometry from sectors or chambers behind a variant.
const MuonGMR4::MuonDetectorManager * m_detMgr
the Detector manager
Gaudi::Property< bool > m_useFrustumNav
Flag to use frustum navigation.
staticNodePtr buildMuonNode(const Acts::GeometryContext &gctx, const EnvelopeSet_t &elements, const std::string &name, const Acts::GeometryIdentifier &id, Acts::VolumeBoundFactory &boundsFactory, const std::vector< ChIdx > &passiveStationIds={}) const
Build subnodes for the muon system node.

◆ buildChamberNode() [1/2]

std::variant< MuonBlueprintNodeBuilder::staticNodePtr, MuonBlueprintNodeBuilder::materialNodePtr > ActsTrk::MuonBlueprintNodeBuilder::buildChamberNode ( const blueprintNodePtr & chamberNode) const
private

Build a static or a material node for a chamber that corresponds to a single blueprint node (e.g for a single MDT multilayer).

Parameters
chamberNodeThe blueprint node out of which the variant node will be built
Returns
A variant holding either a static node or material node depending on wether the assignment of active material is enabled

Definition at line 301 of file MuonBlueprintNodeBuilder.cxx.

301 {
303 auto materialNode = std::dynamic_pointer_cast<Acts::MaterialDesignatorBlueprintNode>(chamberVolumeNode);
304 return materialNode;
305 }
306 auto staticNode = std::dynamic_pointer_cast<Acts::StaticBlueprintNode>(chamberVolumeNode);
307 return staticNode;
308}
Gaudi::Property< bool > m_assignActiveMaterial
Flag to assign active material on the chambers.

◆ buildChamberNode() [2/2]

template<typename T>
std::variant< MuonBlueprintNodeBuilder::staticNodePtr, MuonBlueprintNodeBuilder::materialNodePtr > ActsTrk::MuonBlueprintNodeBuilder::buildChamberNode ( const T & element,
std::unique_ptr< Acts::TrackingVolume > & vol,
const std::vector< blueprintNodePtr > & innerStructure ) const
private

Build a static or a material node for a chamber that corresponds to a single blueprint node (e.g for a single MDT multilayer).

Parameters
innerStructureThe inner structure of the chamber that corresponds to the children nodes
elementThe element representing the chamber/sector for which the node is built
volThe tracking volume associated to the chamber/sector
Returns
A variant holding either a static node or material node depending on wether the assignment of active material is enabled

Definition at line 312 of file MuonBlueprintNodeBuilder.cxx.

314 {
315 //copy of the volume bounds
316 const Acts::VolumeBounds& bounds = vol->volumeBounds();
317 staticNodePtr staticNode = std::make_shared<Acts::StaticBlueprintNode>(std::move(vol));
318 for (auto& childNode : innerStructure) {
319 auto node = std::dynamic_pointer_cast<Acts::StaticBlueprintNode>(childNode);
320 if (node) {
321 staticNode->addChild(std::move(node));
322 }
323 }
325 return staticNode;
326 }
327 auto materialNode = std::make_shared<Acts::MaterialDesignatorBlueprintNode>(element->identString() + "_MaterialNode");
328 configureMaterialFaces(*materialNode, bounds, getActiveMaterial(*element));
329 materialNode->addChild(staticNode);
330 return materialNode;
331}
std::shared_ptr< Acts::StaticBlueprintNode > staticNodePtr
Abrivation of the blue print node pointer.
std::shared_ptr< const Acts::ISurfaceMaterial > getActiveMaterial(const T &element) const
Get the active material for a given element representing the chamber/sector.

◆ buildMuonNode()

std::shared_ptr< Acts::StaticBlueprintNode > ActsTrk::MuonBlueprintNodeBuilder::buildMuonNode ( const Acts::GeometryContext & gctx,
const EnvelopeSet_t & elements,
const std::string & name,
const Acts::GeometryIdentifier & id,
Acts::VolumeBoundFactory & boundsFactory,
const std::vector< ChIdx > & passiveStationIds = {} ) const
private

Build subnodes for the muon system node.

Parameters
gctxThe geometry context
elementsThe name of the stations to include
sideThe side (A, C or Both)
idThe geometry identifier of this node
boundsFactoryThe factory for volume bounds
passiveStationIdsThe ids with the chamber indices we want to put passive material surfaces on

Definition at line 179 of file MuonBlueprintNodeBuilder.cxx.

184 {
185
186 const ActsTrk::GeometryContext* context = gctx.get<const ActsTrk::GeometryContext* >();
187 std::vector<std::string> stationNames;
188
189 //build the material nodes that will have as children the static nodes bult from the tracking volumes of the chambers
190 std::vector<std::variant<staticNodePtr, materialNodePtr>> nodes;
191
192 double innerRadius{0.0};
193 double outerRadius{std::numeric_limits<double>::lowest()};
194 double maxZ{std::numeric_limits<double>::lowest()};
195 double minZ{std::numeric_limits<double>::max()};
196 int chamberId = 1;
197 std::vector<std::shared_ptr<Acts::Surface>> passiveSurfaces;
198
199 std::visit([&](const auto& elems){
200
201 using SetType = std::decay_t<decltype(elems)>;
202 std::unordered_map<unsigned int, SetType> elementsPerStation;
203
204 for(const auto& element : elems){
205 std::unique_ptr<Acts::TrackingVolume> vol{};
206 if (m_alignableVolumes) {
207 vol = std::make_unique<Acts::TrackingVolume>(*element->boundingVolume(),
208 element->identString());
209 } else {
210 vol = std::make_unique<Acts::TrackingVolume>(element->localToGlobalTransform(*context),
211 element->bounds(),
212 element->identString());
213 }
214 // //the chamber geometry id
215 Acts::GeometryIdentifier chId = id.withLayer(chamberId++);
216 vol->assignGeometryId(chId);
217 //build the inner structure of the chamber this will return inner sensitive surfaces
218 //or volumes that have already constructed as blueptint nodes and will nbe assigned as children to the element node
219 std::pair<std::vector<blueprintNodePtr>,std::vector<surfacePtr>> innerStructure = getSensitiveElements(*context, *element, chId, boundsFactory);
220 for(auto& surface: innerStructure.second){
221 vol->addSurface(surface);
222 }
223
224 //calculate the bounds of the cylinder container
225 for(const auto& surface: vol->volumeBounds().orientedSurfaces(vol->localToGlobalTransform(gctx))) {
226 const auto& surfaceRepr = (*surface.surface);
227 const Acts::Polyhedron& polyhedron = surfaceRepr.polyhedronRepresentation(gctx);
228 const Amg::Vector3D& center = surfaceRepr.center(gctx);
229
230 maxZ = std::max(maxZ, center.z());
231 minZ = std::min(minZ, center.z());
232
233 // Outer radius needs to be treated differently due to curvature of cylindrical surface
234 for(const Amg::Vector3D& vertex: polyhedron.vertices){
235 outerRadius = std::max(outerRadius, vertex.perp());
236 }
237 }
238
239 std::variant<staticNodePtr, materialNodePtr> chamberNode;
240 const bool isSingleMdt =
241 (element->readoutEles().size() == 1 &&
242 element->readoutEles().front()->detectorType() == DetectorType::Mdt);
243 //for the single MDT elements we build the material node during the volume construction
244 //and the node returned is the material node already
245 if (isSingleMdt) {
246 // Take ownership of the single existing node where we have already included the static node as child
247 // if we allow active material assignment the node is the material node, otherwise it is the static node
248 chamberNode = buildChamberNode(innerStructure.first.front());
249 } else {
250 //for the non single MDT elements we build the material node that has as child the static node representing the chamber volume if we build with material
251 // or it is a static node with the other static nodes as children if not active material is assigned
252 chamberNode = buildChamberNode(element, vol, innerStructure.first);
253 innerStructure.first.clear();
254 }
255 if (isNullVariant(chamberNode)) {
256 THROW_EXCEPTION("No blueprint node constructed");
257 }
258 nodes.push_back(std::move(chamberNode));
259
260 //keep the elements of the stations we want to assign passive material surfaces
261 if(!Acts::rangeContainsValue(passiveStationIds, element->chamberIndex())){
262 continue;
263 }
264
265 DetIdx detIdx = toDetectorRegionIndex(element->chamberIndex(), element->side());
266 elementsPerStation[regionChamberHash(detIdx, element->chamberIndex())].push_back(element);
267 }
268 //construct the surfaces we want to map passive material on using the elements' geometrical parameters
269 passiveSurfaces = getPassiveMaterialSurfaces(gctx, std::move(elementsPerStation));
270
271 }, elements);
272
273 double halfLengthZ = 0.5 * std::abs(maxZ - minZ);
274 ATH_MSG_DEBUG("Inner radius: " << innerRadius<<", outer radius: " << outerRadius
275 <<", max Z: " << maxZ<<", min Z: " << minZ<<", half length Z: " << halfLengthZ);
276
277 Amg::Isometry3D trf = Amg::getTranslateZ3D(halfLengthZ + minZ);
278
279 auto bounds = boundsFactory.makeBounds<Acts::CylinderVolumeBounds>(innerRadius, outerRadius, halfLengthZ);
280 auto volume = std::make_unique<Acts::TrackingVolume>(trf, bounds, name);
281 volume->assignGeometryId(id);
282
283 //put the passive material surfaces into the volume
284 std::ranges::for_each(passiveSurfaces, [&volume](auto& surf){
285 volume->addSurface(surf);
286 });
287
288 auto muonNode = std::make_shared<Acts::StaticBlueprintNode>(std::move(volume));
289 ATH_MSG_DEBUG("There are " << nodes.size() << " nodes");
290 //loop through the nodes-material pairs to add the nodes to the muon node and assign the material to the faces
291 std::ranges::for_each(nodes, [&muonNode](auto& nodeVariant){
292 std::visit([&](auto&& ptr) {
293 muonNode->addChild(ptr);
294 }, nodeVariant);
295 });
296 return muonNode;
297 }
#define ATH_MSG_DEBUG(x,...)
size_t size() const
Number of registered mappings.
BluePrintSurfPairs_t getSensitiveElements(const ActsTrk::GeometryContext &gctx, const T &element, const Acts::GeometryIdentifier &chId, Acts::VolumeBoundFactory &boundsFactory) const
Get the chamber's sensitive elements.
std::vector< surfacePtr > getPassiveMaterialSurfaces(const Acts::GeometryContext &gctx, const std::unordered_map< unsigned int, ElementSet_t > &elementsPerStation) const
Construct and return the surfaces for the passive material description (e.g cylinders for barrel/ dis...
Muon::MuonStationIndex::DetectorRegionIndex DetIdx
Abrivatin for the detector region index.
Gaudi::Property< bool > m_alignableVolumes
Flag to control if the volumes should be alignable or not.
std::variant< staticNodePtr, materialNodePtr > buildChamberNode(const blueprintNodePtr &chamberNode) const
Build a static or a material node for a chamber that corresponds to a single blueprint node (e....
@ Mdt
MuonSpectrometer.
Eigen::Isometry3d Isometry3D
Eigen::Matrix< double, 3, 1 > Vector3D
Amg::Isometry3D getTranslateZ3D(const double Z)
: Returns a shift transformation along the z-axis
DetectorRegionIndex toDetectorRegionIndex(ChIndex index, int8_t etaSign)
convert ChamberIndex + etaSign into DetectorRegionIndex
#define THROW_EXCEPTION(MESSAGE)
Definition throwExcept.h:10

◆ getActiveMaterial()

template<typename T>
requires (std::is_same_v<T, MuonGMR4::Chamber> || std::is_same_v<T, MuonGMR4::SpectrometerSector>)
std::shared_ptr< const Acts::ISurfaceMaterial > ActsTrk::MuonBlueprintNodeBuilder::getActiveMaterial ( const T & element) const
private

Get the active material for a given element representing the chamber/sector.

Parameters
elementThe element for which to get the active material
Returns
The active surface material

Definition at line 631 of file MuonBlueprintNodeBuilder.cxx.

633 {
634
635 const float thickness = element.halfZ();
636 PVConstLink parentVolume = element.readoutEles().front()->getMaterialGeom()->getParent();
637 GeoModelTools::GeoMaterialHelper geoMaterialHelper;
638 std::pair<GeoModelTools::GeoMaterialPtr, double> geoMaterials = geoMaterialHelper.collectMaterial(parentVolume);
639
640 const Acts::Material aMat = ActsPlugins::GeoModel::geoMaterialConverter(*geoMaterials.first);
641 Acts::MaterialSlab slab{aMat, thickness};
642 std::shared_ptr<Acts::HomogeneousSurfaceMaterial> material = std::make_shared<Acts::HomogeneousSurfaceMaterial>(slab);
643 material->scale(0.5); // we want to split the active material in two and put it on the two faces of the chamber bounds
644
645 return material;
646
647}

◆ getMaterialBins()

std::pair< std::size_t, std::size_t > ActsTrk::MuonBlueprintNodeBuilder::getMaterialBins ( const Muon::MuonStationIndex::ChIndex chIdx) const
private

Definition at line 699 of file MuonBlueprintNodeBuilder.cxx.

699 {
700 switch(chIdx) {
701 using enum ChIndex;
702 case BIS:
703 case BIL:
704 return std::make_pair(1ul * m_nZBinsBI, 1ul * m_nPhiBinsBI);
705 case BML:
706 case BMS:
707 return std::make_pair(1ul * m_nZBinsBM, 1ul * m_nPhiBinsBM);
708 case BOL:
709 case BOS:
710 return std::make_pair(1ul * m_nZBinsBO, 1ul * m_nPhiBinsBO);
711 case EIS:
712 return std::make_pair(1ul* m_nRBinsEI1, 1ul* m_nPhiBinsEI1);
713 case EIL:
714 return std::make_pair(1ul* m_nRBinsEI2, 1ul* m_nPhiBinsEI2);
715 case EMS:
716 return std::make_pair(1ul* m_nRBinsEM1, 1ul* m_nPhiBinsEM1);
717 case EML:
718 return std::make_pair(1ul* m_nRBinsEM2, 1ul* m_nPhiBinsEM2);
719 default:
720 THROW_EXCEPTION("getMaterialBins() - "<<chName(chIdx)<<" is not yet implemented");
721 }
722 return std::make_pair(0ul, 0ul);
723}
@ BIL
Definition RegSelEnums.h:10
@ BOL
Definition RegSelEnums.h:14
@ BIS
Definition RegSelEnums.h:11
@ BOS
Definition RegSelEnums.h:15
@ BML
Definition RegSelEnums.h:12
@ BMS
Definition RegSelEnums.h:13
Gaudi::Property< std::size_t > m_nPhiBinsEM1
Number of bins in phi direction on the disc before the middle big wheel.
Gaudi::Property< std::size_t > m_nZBinsBI
Number of bins in Z direction on the BI cylinder surface.
Gaudi::Property< std::size_t > m_nZBinsBM
Number of bins in Z direction on the BM cylinder surface.
Gaudi::Property< std::size_t > m_nPhiBinsBI
Number of bins in phi direction on the BI cylinder surface.
Gaudi::Property< std::size_t > m_nPhiBinsEI1
Number of bins in phi direction on the disc before the NSW.
Gaudi::Property< std::size_t > m_nPhiBinsEM2
Number of bins in phi direction on the disc after the NSW.
Gaudi::Property< std::size_t > m_nPhiBinsEI2
Number of bins in phi direction on the disc after the NSW.
Gaudi::Property< std::size_t > m_nRBinsEI1
Number of bins in R direction on the disc before the NSW.
Gaudi::Property< std::size_t > m_nRBinsEM1
Number of bins in R direction on the disc before the middle big wheel.
Gaudi::Property< std::size_t > m_nRBinsEM2
Number of bins in R direction on the disc after the middle big wheel.
Gaudi::Property< std::size_t > m_nPhiBinsBM
Number of bins in phi direction on the BM cylinder surface.
Gaudi::Property< std::size_t > m_nZBinsBO
Number of bins in Z direction on the BM cylinder surface.
Gaudi::Property< std::size_t > m_nPhiBinsBO
Number of bins in phi direction on the BM cylinder surface.
Gaudi::Property< std::size_t > m_nRBinsEI2
Number of bins in R direction on the disc after the NSW.
const std::string & chName(ChIndex index)
convert ChIndex into a string
ChIndex
enum to classify the different chamber layers in the muon spectrometer

◆ getPassiveMaterialSurfaces() [1/2]

template<typename ElementSet_t>
std::vector< std::shared_ptr< Acts::Surface > > ActsTrk::MuonBlueprintNodeBuilder::getPassiveMaterialSurfaces ( const Acts::GeometryContext & gctx,
const std::unordered_map< unsigned int, ElementSet_t > & elementsPerStation ) const

Definition at line 476 of file MuonBlueprintNodeBuilder.cxx.

478 {
479
481 return {};
482 }
483 //this is a margin to put the surfaces along Z
484 //(a margin distance from the corresponding chamber's boundary surface)
485 constexpr double margin{4._mm};
486
487 std::vector<std::shared_ptr<Acts::Surface>> surfaces;
488 surfaces.reserve(elementsPerStation.size());
489 LayIdx layIdx = LayIdx::LayerIndexMax;
490 DetIdx detIdx = DetIdx::DetectorRegionIndexMax;
491
492 const ActsTrk::GeometryContext* context = gctx.get<const ActsTrk::GeometryContext* >();
493
494 //lamda function to reject BIS78 chambers from the extension of the passive surface
495 //otherwise they create overlap with the NSW sectors - stop a little bit before the cylinder of the passive surface
496 const auto rejectBIS78 = [&](const MuonGMR4::MuonReadoutElement* readoutEle) {
497 bool reject{false};
498 if(readoutEle->chamberIndex() != ChIdx::BIS){
499 return reject;
500 }
501 int stEta = readoutEle->stationEta();
502 if(m_isRun4){
503 stEta = std::abs(readoutEle->stationEta());
504 }
505 switch (readoutEle->detectorType()) {
506 case DetectorType::Mdt: {
507 const auto* techEle =
508 static_cast<const MuonGMR4::MdtReadoutElement*>(readoutEle);
509 if (techEle->multilayer() == 2 && stEta >= 7) {
510 reject = true;
511 }
512 break;
513 }
514 case DetectorType::Rpc: {
515 const auto* techEle =
516 static_cast<const MuonGMR4::RpcReadoutElement*>(readoutEle);
517 if (techEle->doubletZ() == 2 && stEta >= 7) {
518 reject = true;
519 }
520 break;
521 }
522 default:
523 break;
524 }
525 return reject;
526 };
527
528 for(const auto& [hash, elements] : elementsPerStation){
529
530 //decompose the layer hash to the detector region idx and layer index
531 const auto& [detIdxVal, chIdx] = decomposeRegionChamberHash(hash);
532 layIdx = toLayerIndex(chIdx);
533 detIdx = detIdxVal;
534
535 double maxZ{std::numeric_limits<double>::lowest()};
536 double minZ{std::numeric_limits<double>::max()};
537 double rMin{std::numeric_limits<double>::max()};
538 double rMax{std::numeric_limits<double>::lowest()};
539 //loop through the elements of every station to construct the cylinder/disc surfaces
540 for(const auto& el : elements){
541
542 if(rejectBIS78(el->readoutEles().front())){
543 continue;
544 }
545 const auto& locToGlobal = el->localToGlobalTransform(*context);
546 const auto& bounds = el->bounds();
547 for(const auto& surface : bounds->orientedSurfaces(locToGlobal)){
548 const auto& surfaceRepr = (*surface.surface);
549 const Amg::Vector3D& center = surfaceRepr.center(gctx);
550 rMin = std::min(rMin, center.perp());
551 minZ = std::min(minZ, center.z());
552 maxZ = std::max(maxZ, center.z());
553 rMax = std::max(rMax, center.perp());
554 }
555
556 }
557 double halfZ = 0.5*std::abs(maxZ-minZ);
558 Amg::Isometry3D trf = Amg::Isometry3D::Identity();
559 double zShift{0.};
560 // the chambers are groupd per chamber index and detector region(side) -
561 // we can use the first one for the distinction
562 const auto& testCh = elements.front();
563 int8_t side = testCh->side();
564 switch (testCh->chamberIndex()) {
565 //small NSW sectors (disc passive surface in front of NSW and one in front of EMS)
566 case ChIdx::EIS :
567 case ChIdx::EMS :{
568 side > 0 ? zShift = minZ - margin : zShift = maxZ + margin;
569 trf = Amg::getTranslateZ3D(zShift);
570 auto surface = Acts::Surface::makeShared<Acts::DiscSurface>(trf, std::make_shared<Acts::RadialBounds>(rMin, rMax));
571 const auto [nBins1, nBins2] = getMaterialBins(testCh->chamberIndex());
572 surface->assignSurfaceMaterial(preparePassiveMaterial(surface->bounds(), nBins1, nBins2));
573 surfaces.push_back(surface);
574 break;
575 //large sectors (disc passive surface after NSW/EIL and after EML)
576 } case ChIdx::EIL :
577 case ChIdx::EML : {
578 // HARDCODED!! (maybe think a better solution in the future)
579 // But for the EIL that we put after the EIS/EIL chambers we extend the radius of the disc surface
580 // in order to have a better coverage for the projections from EE
581 if(testCh->chamberIndex() == ChIdx::EIL){
582 rMax += 60*margin;
583 }
584 side > 0 ? zShift = maxZ + margin : zShift = minZ - margin;
585 trf = Amg::getTranslateZ3D(zShift);
586 auto surface = Acts::Surface::makeShared<Acts::DiscSurface>(trf,
587 std::make_shared<Acts::RadialBounds>(rMin, rMax));
588 const auto [nBins1, nBins2] = getMaterialBins(testCh->chamberIndex());
589 surface->assignSurfaceMaterial(preparePassiveMaterial(surface->bounds(), nBins1, nBins2));
590 surfaces.push_back(surface);
591 break;
592 } case ChIdx::BIS :
593 case ChIdx::BML :
594 case ChIdx::BOL : {
595 //hack for run3 because of overlaps with eta = -7 BIS chambers
596
597 if(!m_isRun4 && testCh->chamberIndex() == ChIdx::BIS){
598 halfZ -= 130.;
599
600 }
601 auto surface = Acts::Surface::makeShared<Acts::CylinderSurface>(trf,
602 std::make_shared<Acts::CylinderBounds>(rMin - margin, halfZ));
603
605 const auto [nBins1, nBins2] = getMaterialBins(testCh->chamberIndex());
606 surface->assignSurfaceMaterial(preparePassiveMaterial(surface->bounds(), nBins1, nBins2));
607 }
608 surfaces.push_back(surface);
609 break;
610 } default :
611 THROW_EXCEPTION("No implementation of passive material surface for this station!!!! - sorry :) ");
612 }
613 ATH_MSG_VERBOSE("Putting passive material surface for station " << layerName(layIdx) << "/ "<< regionName(detIdx) << ": minZ = " << minZ << ", maxZ = " << maxZ<< "and radius "<< rMax);
614 }
615
616 if(msgLvl(MSG::VERBOSE)){
617 std::stringstream stream{};
618 for(const auto& surf : surfaces){
619 stream<< " at position : "<< Amg::toString(surf->center(gctx))
620 << "with bounds "<< surf->bounds()<<std::endl;
621 }
622 ATH_MSG_VERBOSE("Constructed "<< surfaces.size()
623 << " surfaces for passive material description : "<<std::endl<<stream.str());
624 }
625
626 return surfaces;
627}
#define ATH_MSG_VERBOSE(x,...)
Gaudi::Property< bool > m_assignEmptyMaterial
Assign empty material slabs for the passive surfaces.
std::shared_ptr< Acts::ISurfaceMaterial > preparePassiveMaterial(const Acts::SurfaceBounds &bounds, const std::size_t nBins1, const std::size_t nBins2) const
Prepare a binned material which is associated to the surface.
Gaudi::Property< bool > m_buildPassiveVolumes
Flag to construct the passive material surfaces.
Gaudi::Property< bool > m_isRun4
Flag to control if we use run4 geometry or not.
std::pair< std::size_t, std::size_t > getMaterialBins(const Muon::MuonStationIndex::ChIndex chIdx) const
Muon::MuonStationIndex::LayerIndex LayIdx
Abrivation for the layer index.
@ Rpc
Monitored Drift Tubes.
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
double halfZ(const Acts::VolumeBounds &bounds)
Returns the half-Z length for the parsed volume bounds (Trapezoid/ Cuboid).
const std::string & layerName(LayerIndex index)
convert LayerIndex into a string
std::pair< DetectorRegionIndex, ChIndex > decomposeRegionChamberHash(unsigned int hash)
decompose the hash into Region and Chamber
const std::string & regionName(DetectorRegionIndex index)
convert DetectorRegionIndex into a string
LayerIndex toLayerIndex(ChIndex index)
convert ChIndex into LayerIndex

◆ getPassiveMaterialSurfaces() [2/2]

template<typename ElementSet_t>
std::vector< surfacePtr > ActsTrk::MuonBlueprintNodeBuilder::getPassiveMaterialSurfaces ( const Acts::GeometryContext & gctx,
const std::unordered_map< unsigned int, ElementSet_t > & elementsPerStation ) const
private

Construct and return the surfaces for the passive material description (e.g cylinders for barrel/ discs for endcaps).

Parameters
gctxThe geometry context
elementsPerStationThe elements (chambers or sectors) grouped per station to which we want to assign passive material This function uses the elements of the station to construct the surfaces and define their bounds

◆ getSensitiveElements()

template<typename T>
requires (std::is_same_v<T, MuonGMR4::Chamber> || std::is_same_v<T, MuonGMR4::SpectrometerSector>)
MuonBlueprintNodeBuilder::BluePrintSurfPairs_t ActsTrk::MuonBlueprintNodeBuilder::getSensitiveElements ( const ActsTrk::GeometryContext & gctx,
const T & element,
const Acts::GeometryIdentifier & chId,
Acts::VolumeBoundFactory & boundsFactory ) const
private

Get the chamber's sensitive elements.

Parameters
gctxGeometry context
elementThe element for which to get the sensitive elements (chamber or sector)
chIdThe geometry identifier of the chamber
boundsFactoryThe factory for volume bounds This function constructs and returns the sensitive elements (volumes and surfaces) of the sector.

Definition at line 336 of file MuonBlueprintNodeBuilder.cxx.

340 {
341
342 std::vector<blueprintNodePtr> readoutVolumes;
343 std::vector<surfacePtr> readoutSurfaces;
344 Acts::GeometryIdentifier::Value mdtId{1};
345
346 for (const MuonGMR4::MuonReadoutElement* readoutEle : element.readoutEles()) {
347
348 std::vector<surfacePtr> detSurfaces = readoutEle->getSurfaces();
349 switch(readoutEle->detectorType()){
350 case DetectorType::Mdt: {
351 const auto* mdtReadoutEle = static_cast<const MuonGMR4::MdtReadoutElement*>(readoutEle);
352 const MuonGMR4::MdtReadoutElement::parameterBook& parameters{mdtReadoutEle->getParameters()};
353
354 std::unique_ptr<ActsTrk::VolumePlacement> placement{};
355
356 // create the MDT multilayer volume with the dedicated builder
357 Acts::MultiWireVolumeBuilder::Config mwCfg;
358 mwCfg.name = m_detMgr->idHelperSvc()->toStringDetEl(mdtReadoutEle->identify());
359 mwCfg.mlSurfaces = detSurfaces;
360 mwCfg.transform = readoutEle->localToGlobalTransform(gctx);
361
362 //initialize a nullptr material node which will be filled in the case of single MDT readout elements
363 //and used to assign the material to the volume and add the static node as child of the material node
364 std::shared_ptr<Acts::MaterialDesignatorBlueprintNode> mdtMaterialNode;
365
366 //special treatment of BIS78 MDT multilayer
367 //use different shape because of clashes with EIL chambers
368 if(isBIS78(readoutEle) && mdtReadoutEle->multilayer() == 2){
369
370
371 //find the minimum and the maximum tube length (x dimension of the diamond bounds)
372 std::vector<double> tubeLengths;
373 tubeLengths.reserve(mdtReadoutEle->numTubesInLay());
374 for(std::size_t tube = 1; tube < mdtReadoutEle->numTubesInLay(); ++tube){
375 const IdentifierHash tubeHash = MuonGMR4::MdtReadoutElement::measurementHash(1,tube);
376 const auto& surface = mdtReadoutEle->surface(tubeHash);
377 const auto& lBounds = static_cast<const Acts::LineBounds&>(surface.bounds());
378 using BoundEnum = Acts::LineBounds::BoundValues;
379 const double tubeLength = 2.*lBounds.get(BoundEnum::eHalfLengthZ);
380 tubeLengths.push_back(tubeLength);
381 }
382 auto [minX,maxX] = std::ranges::minmax_element(tubeLengths);
383 int nSmallTubes = std::count_if(tubeLengths.begin(), tubeLengths.end(), [minX](double length){
384 return std::abs(*minX-length) < Acts::s_epsilon;
385 });
386
387 //create the diamond bounds for the volume
388 constexpr double extraMargin = 1._cm;
389 double y2 = (nSmallTubes+1.)*parameters.tubePitch;
390 double y1 = 2.*parameters.halfY + extraMargin - y2;
391 if (m_alignableVolumes) {
392 placement = std::make_unique<ActsTrk::VolumePlacement>(*readoutEle,
393 Amg::getTranslateY3D(parameters.halfY + extraMargin -y2));
394 }
395 mwCfg.transform = mwCfg.transform * Amg::getTranslateY3D(parameters.halfY + extraMargin - y2);
396 mwCfg.bounds = boundsFactory.makeBounds<Acts::DiamondVolumeBounds>(0.5*(*maxX), 0.5*(*maxX), 0.5*(*minX),
397 y1, y2, parameters.halfHeight);
398
399 } else {
401 placement = std::make_unique<ActsTrk::VolumePlacement>(*readoutEle);
402 }
403 //check for rectangular or trapezoidal shape bounds
404 if(std::abs(parameters.shortHalfX - parameters.longHalfX) < Acts::s_epsilon){
405 mwCfg.bounds = boundsFactory.makeBounds<Acts::CuboidVolumeBounds>(parameters.shortHalfX,
406 parameters.halfY,
407 parameters.halfHeight);
408 } else {
409 mwCfg.bounds = boundsFactory.makeBounds<Acts::TrapezoidVolumeBounds>(parameters.shortHalfX,
410 parameters.longHalfX,
411 parameters.halfY,
412 parameters.halfHeight);
413 }
414 }
415 mwCfg.alignablePlacement = placement.get();
417 element.addPlacement(std::move(placement));
418 }
419 mwCfg.binning = {{Acts::AxisDirection::AxisY, 2u},
420 {Acts::AxisDirection::AxisZ, 1u}};
421 mwCfg.shiftDirection = Acts::AxisDirection::AxisY;
422 Acts::MultiWireVolumeBuilder mdtBuilder{mwCfg};
423 std::unique_ptr<Acts::TrackingVolume> mdtVolume = mdtBuilder.buildVolume();
424
425 mdtVolume->assignGeometryId(chId.withExtra(mdtId++));
426 //create the blueprint node for the mdt multilayers
427 // check if this is a single mdt (single multilayer) chamber so we assign the material directly to the multilayer
428 if(element.readoutEles().size() == 1 && m_assignActiveMaterial){
429
430 mdtMaterialNode = std::make_shared<Acts::MaterialDesignatorBlueprintNode>(element.identString() + "_MaterialNode");
431 configureMaterialFaces(*mdtMaterialNode, mdtVolume->volumeBounds(), getActiveMaterial(element));
432 auto staticNode = std::make_shared<Acts::StaticBlueprintNode>(std::move(mdtVolume));
433 mdtMaterialNode->addChild(std::move(staticNode));
434 readoutVolumes.push_back(std::move(mdtMaterialNode));
435 break;
436 }
437 auto mdtNode = std::make_shared<Acts::StaticBlueprintNode>(std::move(mdtVolume));
438 mdtNode->setNavigationPolicyFactory(mdtBuilder.createNavigationPolicyFactory(gctx.context()));
439 readoutVolumes.push_back(std::move(mdtNode));
440
441 break;
442
443 } case DetectorType::Rpc:
446 case DetectorType::Mm: {
447
448 readoutSurfaces.insert(readoutSurfaces.end(), std::make_move_iterator(detSurfaces.begin()),
449 std::make_move_iterator(detSurfaces.end()));
450
451 break;
452
453 } default:
454 THROW_EXCEPTION("Unknown detector type for readout element: " << readoutEle->detectorType());
455 break;
456
457 }
458 }
459
460 return std::make_pair(std::move(readoutVolumes), std::move(readoutSurfaces));
461}
double length(const pvec &v)
double tubeLength
Acts::GeometryContext context() const
bool isBIS78(const MuonGMR4::MuonReadoutElement *element) const
Helper function determining whether a readout element is BIS78.
static IdentifierHash measurementHash(unsigned layerNumber, unsigned tubeNumber)
Constructs a Measurement hash from layer && tube number.
@ Mm
Maybe not needed in the migration.
@ Tgc
Resitive Plate Chambers.
@ sTgc
Micromegas (NSW).
Amg::Isometry3D getTranslateY3D(const double Y)
: Returns a shift transformation along the y-axis

◆ initialize()

StatusCode ActsTrk::MuonBlueprintNodeBuilder::initialize ( )
override

Definition at line 94 of file MuonBlueprintNodeBuilder.cxx.

94 {
95 ATH_CHECK(detStore()->retrieve(m_detMgr));
96 return StatusCode::SUCCESS;
97 }
#define ATH_CHECK
Evaluate an expression and check for errors.

◆ isBIS78()

bool ActsTrk::MuonBlueprintNodeBuilder::isBIS78 ( const MuonGMR4::MuonReadoutElement * element) const
private

Helper function determining whether a readout element is BIS78.

Definition at line 464 of file MuonBlueprintNodeBuilder.cxx.

464 {
465 int stEta = element->stationEta();
466 if(m_isRun4){
467 stEta = std::abs(element->stationEta());
468 }
469 return element->detectorType() == ActsTrk::DetectorType::Mdt &&
470 element->chamberIndex() == ChIndex::BIS &&
471 stEta >= 7;
472 }
virtual DetectorType detectorType() const =0
Returns the detector element type.
int stationEta() const
Returns the stationEta (positive A site, negative C site).
Muon::MuonStationIndex::ChIndex chamberIndex() const
Returns the chamber index of the Identifier (MMS & STS) have the same chamber Index (EIS).

◆ isElementInTheStation()

template<typename T>
requires (std::is_same_v<T, MuonGMR4::Chamber> || std::is_same_v<T, MuonGMR4::SpectrometerSector>)
bool ActsTrk::MuonBlueprintNodeBuilder::isElementInTheStation ( const T & element,
const std::vector< StIdx > & stationNames,
const EndcapSide side ) const
private

Check if the chamber is in this node.

Parameters
elementThe element to check (chamber or sector)
stationNamesThe names of the stations to check against
sideThe side of the endcap (A, C or Both) This function checks if the chamber is part of the configured chambers in this node. It is used to filter out chambers that are not part of this muon node.

Definition at line 650 of file MuonBlueprintNodeBuilder.cxx.

654 {
655 bool etaSignCorrect = (side == EndcapSide::Both) ||
656 (side == EndcapSide::A && element.side() > 0) ||
657 (side == EndcapSide::C && element.side() < 0);
658 return etaSignCorrect &&
659 Acts::rangeContainsValue(stationIndex, toStationIndex(element.chamberIndex()));
660}
StIndex toStationIndex(ChIndex index)
convert ChIndex into StIndex

◆ preparePassiveMaterial()

std::shared_ptr< Acts::ISurfaceMaterial > ActsTrk::MuonBlueprintNodeBuilder::preparePassiveMaterial ( const Acts::SurfaceBounds & bounds,
const std::size_t nBins1,
const std::size_t nBins2 ) const
private

Prepare a binned material which is associated to the surface.

Parameters
typeThe surface type on which the material is mapped (Plane, Disc, Cylinder)
nBins1Number of bins in the local0 direction
nBins2Number of bins in the complementary direction

Definition at line 664 of file MuonBlueprintNodeBuilder.cxx.

666 {
667 if (nBins1 == 0 || nBins2 == 0) {
668 ATH_MSG_ERROR("Cannot create material for "<<bounds
669 <<" as one of the bin dimensions is zero. nBins1: "<<nBins1<<", nBins2: "<<nBins2);
670 return nullptr;
671 }
672 if (nBins1 == 1 && nBins1 == nBins2) {
673 return std::make_shared<Acts::HomogeneousSurfaceMaterial>();
674 }
675
676 // the ranges and boundary types are left to the surface the material ends
677 // up on, they are resolved from its bounds during material mapping
678 auto protoMaterial = [](Acts::AxisDirection dir1, std::size_t bins1,
679 Acts::AxisDirection dir2, std::size_t bins2) {
680 return std::make_shared<Acts::ProtoGridSurfaceMaterial>(
681 Acts::MultiAxisSpec2D({Acts::AxisSpec::DeferredEquidistant(bins1, dir1),
682 Acts::AxisSpec::DeferredEquidistant(bins2, dir2)}));
683 };
684
685 switch (bounds.type()) {
686 using enum Acts::SurfaceBounds::BoundsType;
687 case eCylinder: {
688 return protoMaterial(Acts::AxisDirection::AxisZ, nBins1,
689 Acts::AxisDirection::AxisRPhi, nBins2);
690 } case eDisc: {
691 return protoMaterial(Acts::AxisDirection::AxisR, nBins1,
692 Acts::AxisDirection::AxisPhi, nBins2);
693 } default:
694 ATH_MSG_ERROR("Unsupoorted type "<<bounds<<".");
695 return nullptr;
696 }
697}
#define ATH_MSG_ERROR(x,...)

Member Data Documentation

◆ m_alignableVolumes

Gaudi::Property<bool> ActsTrk::MuonBlueprintNodeBuilder::m_alignableVolumes {this, "AlignableVolumes", true}
private

Flag to control if the volumes should be alignable or not.

Definition at line 91 of file MuonBlueprintNodeBuilder.h.

91{this, "AlignableVolumes", true};

◆ m_assignActiveMaterial

Gaudi::Property<bool> ActsTrk::MuonBlueprintNodeBuilder::m_assignActiveMaterial {this, "AssignActiveMaterial", true}
private

Flag to assign active material on the chambers.

Definition at line 95 of file MuonBlueprintNodeBuilder.h.

95{this, "AssignActiveMaterial", true};

◆ m_assignEmptyMaterial

Gaudi::Property<bool> ActsTrk::MuonBlueprintNodeBuilder::m_assignEmptyMaterial {this, "AssignEmptyPassiveMaterial", false}
private

Assign empty material slabs for the passive surfaces.

Definition at line 99 of file MuonBlueprintNodeBuilder.h.

99{this, "AssignEmptyPassiveMaterial", false};

◆ m_buildPassiveVolumes

Gaudi::Property<bool> ActsTrk::MuonBlueprintNodeBuilder::m_buildPassiveVolumes {this, "BuildPassiveVolumes", false}
private

Flag to construct the passive material surfaces.

Definition at line 97 of file MuonBlueprintNodeBuilder.h.

97{this, "BuildPassiveVolumes", false};

◆ m_detMgr

const MuonGMR4::MuonDetectorManager* ActsTrk::MuonBlueprintNodeBuilder::m_detMgr {nullptr}
private

the Detector manager

Definition at line 87 of file MuonBlueprintNodeBuilder.h.

87{nullptr};

◆ m_isRun4

Gaudi::Property<bool> ActsTrk::MuonBlueprintNodeBuilder::m_isRun4 {this, "run4Layout", false}
private

Flag to control if we use run4 geometry or not.

Definition at line 93 of file MuonBlueprintNodeBuilder.h.

93{this, "run4Layout", false};

◆ m_nPhiBinsBI

Gaudi::Property<std::size_t> ActsTrk::MuonBlueprintNodeBuilder::m_nPhiBinsBI {this, "nPhiBinsBI", 16}
private

Number of bins in phi direction on the BI cylinder surface.

Definition at line 101 of file MuonBlueprintNodeBuilder.h.

101{this, "nPhiBinsBI", 16};

◆ m_nPhiBinsBM

Gaudi::Property<std::size_t> ActsTrk::MuonBlueprintNodeBuilder::m_nPhiBinsBM {this, "nPhiBinsBM", 16}
private

Number of bins in phi direction on the BM cylinder surface.

Definition at line 105 of file MuonBlueprintNodeBuilder.h.

105{this, "nPhiBinsBM", 16};

◆ m_nPhiBinsBO

Gaudi::Property<std::size_t> ActsTrk::MuonBlueprintNodeBuilder::m_nPhiBinsBO {this, "nPhiBinsBO", 16}
private

Number of bins in phi direction on the BM cylinder surface.

Definition at line 109 of file MuonBlueprintNodeBuilder.h.

109{this, "nPhiBinsBO", 16};

◆ m_nPhiBinsEI1

Gaudi::Property<std::size_t> ActsTrk::MuonBlueprintNodeBuilder::m_nPhiBinsEI1 {this, "nPhiBinsEIbNSW", 16}
private

Number of bins in phi direction on the disc before the NSW.

Definition at line 115 of file MuonBlueprintNodeBuilder.h.

115{this, "nPhiBinsEIbNSW", 16};

◆ m_nPhiBinsEI2

Gaudi::Property<std::size_t> ActsTrk::MuonBlueprintNodeBuilder::m_nPhiBinsEI2 {this, "nPhiBinsEIaNSW", 16}
private

Number of bins in phi direction on the disc after the NSW.

Definition at line 119 of file MuonBlueprintNodeBuilder.h.

119{this, "nPhiBinsEIaNSW", 16};

◆ m_nPhiBinsEM1

Gaudi::Property<std::size_t> ActsTrk::MuonBlueprintNodeBuilder::m_nPhiBinsEM1 {this, "nPhiBinsEMbBW", 16}
private

Number of bins in phi direction on the disc before the middle big wheel.

Definition at line 124 of file MuonBlueprintNodeBuilder.h.

124{this, "nPhiBinsEMbBW", 16};

◆ m_nPhiBinsEM2

Gaudi::Property<std::size_t> ActsTrk::MuonBlueprintNodeBuilder::m_nPhiBinsEM2 {this, "nPhiBinsEMaBW", 16}
private

Number of bins in phi direction on the disc after the NSW.

Definition at line 128 of file MuonBlueprintNodeBuilder.h.

128{this, "nPhiBinsEMaBW", 16};

◆ m_nRBinsEI1

Gaudi::Property<std::size_t> ActsTrk::MuonBlueprintNodeBuilder::m_nRBinsEI1 {this, "nRBinsEIbNSW", 4}
private

Number of bins in R direction on the disc before the NSW.

Definition at line 113 of file MuonBlueprintNodeBuilder.h.

113{this, "nRBinsEIbNSW", 4};

◆ m_nRBinsEI2

Gaudi::Property<std::size_t> ActsTrk::MuonBlueprintNodeBuilder::m_nRBinsEI2 {this, "nRBinsEIaNSW", 4}
private

Number of bins in R direction on the disc after the NSW.

Definition at line 117 of file MuonBlueprintNodeBuilder.h.

117{this, "nRBinsEIaNSW", 4};

◆ m_nRBinsEM1

Gaudi::Property<std::size_t> ActsTrk::MuonBlueprintNodeBuilder::m_nRBinsEM1 {this, "nRBinsEMbBW", 16}
private

Number of bins in R direction on the disc before the middle big wheel.

Definition at line 122 of file MuonBlueprintNodeBuilder.h.

122{this, "nRBinsEMbBW", 16};

◆ m_nRBinsEM2

Gaudi::Property<std::size_t> ActsTrk::MuonBlueprintNodeBuilder::m_nRBinsEM2 {this, "nRBinsEMaBW", 5}
private

Number of bins in R direction on the disc after the middle big wheel.

Definition at line 126 of file MuonBlueprintNodeBuilder.h.

126{this, "nRBinsEMaBW", 5};

◆ m_nZBinsBI

Gaudi::Property<std::size_t> ActsTrk::MuonBlueprintNodeBuilder::m_nZBinsBI {this, "nZBinsBI", 12}
private

Number of bins in Z direction on the BI cylinder surface.

Definition at line 103 of file MuonBlueprintNodeBuilder.h.

103{this, "nZBinsBI", 12};

◆ m_nZBinsBM

Gaudi::Property<std::size_t> ActsTrk::MuonBlueprintNodeBuilder::m_nZBinsBM {this, "nZBinsBM", 12}
private

Number of bins in Z direction on the BM cylinder surface.

Definition at line 107 of file MuonBlueprintNodeBuilder.h.

107{this, "nZBinsBM", 12};

◆ m_nZBinsBO

Gaudi::Property<std::size_t> ActsTrk::MuonBlueprintNodeBuilder::m_nZBinsBO {this, "nZBinsBO", 12}
private

Number of bins in Z direction on the BM cylinder surface.

Definition at line 111 of file MuonBlueprintNodeBuilder.h.

111{this, "nZBinsBO", 12};

◆ m_useFrustumNav

Gaudi::Property<bool> ActsTrk::MuonBlueprintNodeBuilder::m_useFrustumNav {this, "UseFrustumNav", false}
private

Flag to use frustum navigation.

Definition at line 130 of file MuonBlueprintNodeBuilder.h.

130{this, "UseFrustumNav", false};

◆ m_useSectors

Gaudi::Property<bool> ActsTrk::MuonBlueprintNodeBuilder::m_useSectors {this, "UseSectors", false}
private

Flag to control if we want to build the muon node from sectors or chambers.

Definition at line 89 of file MuonBlueprintNodeBuilder.h.

89{this, "UseSectors", false};

The documentation for this class was generated from the following files: