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.

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 98 of file MuonBlueprintNodeBuilder.cxx.

98 {
99
100EnvelopeSet_t elements;
101EnvelopeSet_t barrelStations, endcapOuterAStations, endcapOuterCStations,
102 endcapMiddleAStations, endcapMiddleCStations;
103
104if (m_useSectors) {
105 elements = m_detMgr->getAllSectors();
106} else {
107 elements = m_detMgr->getAllChambers();
108}
109
110std::visit([&](auto& elems) {
111 using SetType = std::decay_t<decltype(elems)>;
112
113 // Initialize station containers of the same type
114 SetType barrel, endcapA, endcapC, endcapMiddleA, endcapMiddleC;
115
116 for (const auto& element : elems) {
117 if (isElementInTheStation(*element,
118 {StIdx::BI, StIdx::BM, StIdx::BO, StIdx::BE, StIdx::EE, StIdx::EI},
120 barrel.push_back(element);
121 } else if (isElementInTheStation(*element, {StIdx::EO}, EndcapSide::A)) {
122 endcapA.push_back(element);
123 } else if (isElementInTheStation(*element, {StIdx::EO}, EndcapSide::C)) {
124 endcapC.push_back(element);
125 } else if (isElementInTheStation(*element, {StIdx::EM}, EndcapSide::A)) {
126 endcapMiddleA.push_back(element);
127 } else if (isElementInTheStation(*element, {StIdx::EM}, EndcapSide::C)) {
128 endcapMiddleC.push_back(element);
129 } else {
130 ATH_MSG_WARNING("Element " << element->identString()
131 << " not assigned to any station!");
132 }
133 }
134
135 // Assign back into the outer variants
136 barrelStations = std::move(barrel);
137 endcapOuterAStations = std::move(endcapA);
138 endcapOuterCStations = std::move(endcapC);
139 endcapMiddleAStations = std::move(endcapMiddleA);
140 endcapMiddleCStations = std::move(endcapMiddleC);
141}, elements);
142
143 // Top level node for the Muon system
144auto muonNode = std::make_shared<Acts::CylinderContainerBlueprintNode>("MuonNode", Acts::AxisDirection::AxisZ);
145
146Acts::VolumeBoundFactory boundsFactory{};
147using namespace ActsTrk::detail::GeoVolIds;
148auto barrelNode = buildMuonNode(gctx, barrelStations, "BI_BM_BO_EE_EI", Acts::GeometryIdentifier().withVolume(s_muonBarrelId), boundsFactory, {ChIdx::BIS, ChIdx::BML, ChIdx::BOL,
149 ChIdx::EIS, ChIdx::EIL});
150auto endcapANode = buildMuonNode(gctx, endcapOuterAStations, "EO_A", Acts::GeometryIdentifier().withVolume(s_muonEndcapAId), boundsFactory);
151auto endcapCNode = buildMuonNode(gctx, endcapOuterCStations, "EO_C", Acts::GeometryIdentifier().withVolume(s_muonEndcapCId), boundsFactory);
152auto endcapMiddleANode = buildMuonNode(gctx, endcapMiddleAStations, "EM_A", Acts::GeometryIdentifier().withVolume(s_muonEndcapMiddleAId), boundsFactory, {ChIdx::EML, ChIdx::EMS});
153auto endcapMiddleCNode = buildMuonNode(gctx, endcapMiddleCStations, "EM_C", Acts::GeometryIdentifier().withVolume(s_muonEndcapMiddleCId), boundsFactory, {ChIdx::EML, ChIdx::EMS});
154
155//Add to the muon barrel child node (e.g calo or Itk) - if existed
156if(childNode){
157 barrelNode->addChild(std::move(childNode));
158}
159muonNode->addChild(std::move(barrelNode));
160muonNode->addChild(std::move(endcapANode));
161muonNode->addChild(std::move(endcapCNode));
162muonNode->addChild(std::move(endcapMiddleANode));
163muonNode->addChild(std::move(endcapMiddleCNode));
164
165return muonNode;
166
167}
#define ATH_MSG_WARNING(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
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 292 of file MuonBlueprintNodeBuilder.cxx.

292 {
294 auto materialNode = std::dynamic_pointer_cast<Acts::MaterialDesignatorBlueprintNode>(chamberVolumeNode);
295 return materialNode;
296 }
297 auto staticNode = std::dynamic_pointer_cast<Acts::StaticBlueprintNode>(chamberVolumeNode);
298 return staticNode;
299}
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 303 of file MuonBlueprintNodeBuilder.cxx.

305 {
306 //copy of the volume bounds
307 const Acts::VolumeBounds& bounds = vol->volumeBounds();
308 staticNodePtr staticNode = std::make_shared<Acts::StaticBlueprintNode>(std::move(vol));
309 for (auto& childNode : innerStructure) {
310 auto node = std::dynamic_pointer_cast<Acts::StaticBlueprintNode>(childNode);
311 if (node) {
312 staticNode->addChild(std::move(node));
313 }
314 }
316 return staticNode;
317 }
318 auto materialNode = std::make_shared<Acts::MaterialDesignatorBlueprintNode>(element->identString() + "_MaterialNode");
319 configureMaterialFaces(*materialNode, bounds, getActiveMaterial(*element));
320 materialNode->addChild(staticNode);
321 return materialNode;
322}
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 170 of file MuonBlueprintNodeBuilder.cxx.

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

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

◆ getMaterialBins()

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

Definition at line 690 of file MuonBlueprintNodeBuilder.cxx.

690 {
691 switch(chIdx) {
692 using enum ChIndex;
693 case BIS:
694 case BIL:
695 return std::make_pair(1ul * m_nZBinsBI, 1ul * m_nPhiBinsBI);
696 case BML:
697 case BMS:
698 return std::make_pair(1ul * m_nZBinsBM, 1ul * m_nPhiBinsBM);
699 case BOL:
700 case BOS:
701 return std::make_pair(1ul * m_nZBinsBO, 1ul * m_nPhiBinsBO);
702 case EIS:
703 return std::make_pair(1ul* m_nRBinsEI1, 1ul* m_nPhiBinsEI1);
704 case EIL:
705 return std::make_pair(1ul* m_nRBinsEI2, 1ul* m_nPhiBinsEI2);
706 case EMS:
707 return std::make_pair(1ul* m_nRBinsEM1, 1ul* m_nPhiBinsEM1);
708 case EML:
709 return std::make_pair(1ul* m_nRBinsEM2, 1ul* m_nPhiBinsEM2);
710 default:
711 THROW_EXCEPTION("getMaterialBins() - "<<chName(chIdx)<<" is not yet implemented");
712 }
713 return std::make_pair(0ul, 0ul);
714}
@ 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 467 of file MuonBlueprintNodeBuilder.cxx.

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

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

92 {
93 ATH_CHECK(detStore()->retrieve(m_detMgr));
94 return StatusCode::SUCCESS;
95 }
#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 455 of file MuonBlueprintNodeBuilder.cxx.

455 {
456 int stEta = element->stationEta();
457 if(m_isRun4){
458 stEta = std::abs(element->stationEta());
459 }
460 return element->detectorType() == ActsTrk::DetectorType::Mdt &&
461 element->chamberIndex() == ChIndex::BIS &&
462 stEta >= 7;
463 }
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 641 of file MuonBlueprintNodeBuilder.cxx.

645 {
646 bool etaSignCorrect = (side == EndcapSide::Both) ||
647 (side == EndcapSide::A && element.side() > 0) ||
648 (side == EndcapSide::C && element.side() < 0);
649 return etaSignCorrect &&
650 Acts::rangeContainsValue(stationIndex, toStationIndex(element.chamberIndex()));
651}
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 655 of file MuonBlueprintNodeBuilder.cxx.

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