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< surfacePtrgetPassiveMaterialSurfaces (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, materialNodePtrbuildChamberNode (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, materialNodePtrbuildChamberNode (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::MuonDetectorManagerm_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
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(*context),
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::Transform3D 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.
Amg::Transform3D getTranslateZ3D(const double Z)
: Returns a shift transformation along the z-axis
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 3, 1 > Vector3D
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 Amg::Transform3D& 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::Transform3D trf = Amg::Transform3D::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 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::Experimental::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::AxisSpec::Equidistant(
411 static_cast<std::size_t>(std::lround(2 * parameters.halfY / parameters.tubePitch)),
412 -parameters.halfY,
413 parameters.halfY,
414 Acts::AxisBoundaryType::Bound,
415 Acts::AxisDirection::AxisY), 2u},
416 {Acts::AxisSpec::Equidistant(
417 static_cast<std::size_t>(std::lround(2 * parameters.halfHeight / parameters.tubePitch)),
418 -parameters.halfHeight,
419 parameters.halfHeight,
420 Acts::AxisBoundaryType::Bound,
421 Acts::AxisDirection::AxisZ), 1u}};
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());
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
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::Transform3D 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 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_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: