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::Experimental::BlueprintNode>
 Abrivation of the blueprint node ptr base class.
using staticNodePtr = std::shared_ptr<Acts::Experimental::StaticBlueprintNode>
 Abrivation of the blue print node pointer.
using materialNodePtr = std::shared_ptr<Acts::Experimental::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::Experimental::BlueprintNode > buildBlueprintNode (const Acts::GeometryContext &gctx, std::shared_ptr< Acts::Experimental::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_assignActiveMaterial {this, "AssignActiveMaterial", false}
 Flag to assign active material on the chambers.
Gaudi::Property< bool > m_buildPassiveVolumes {this, "BuildPassiveVolumes", true}
 Flag to construct the passive material 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 42 of file MuonBlueprintNodeBuilder.h.

Member Typedef Documentation

◆ blueprintNodePtr

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

Abrivation of the blueprint node ptr base class.

Definition at line 45 of file MuonBlueprintNodeBuilder.h.

◆ BluePrintSurfPairs_t

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

Definition at line 53 of file MuonBlueprintNodeBuilder.h.

◆ ChIdx

Abrivation for the chamber index.

Definition at line 65 of file MuonBlueprintNodeBuilder.h.

◆ DetIdx

Abrivatin for the detector region index.

Definition at line 61 of file MuonBlueprintNodeBuilder.h.

◆ DetLayIdx_t

Abrivation for the stations indices.

Definition at line 67 of file MuonBlueprintNodeBuilder.h.

◆ EnvelopeSet_t

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

Definition at line 70 of file MuonBlueprintNodeBuilder.h.

◆ EnvelopesPerStIdx_t

◆ LayIdx

Abrivation for the layer index.

Definition at line 63 of file MuonBlueprintNodeBuilder.h.

◆ materialNodePtr

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

Abrivation of the material node pointer.

Definition at line 49 of file MuonBlueprintNodeBuilder.h.

◆ MuonChamberSet

Abrivation of the container holding all chambers.

Definition at line 55 of file MuonBlueprintNodeBuilder.h.

◆ MuonSectorSet

Abrivation of the container holding all ms sectors.

Definition at line 57 of file MuonBlueprintNodeBuilder.h.

◆ staticNodePtr

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

Abrivation of the blue print node pointer.

Definition at line 47 of file MuonBlueprintNodeBuilder.h.

◆ StIdx

Abrivation of the station index.

Definition at line 59 of file MuonBlueprintNodeBuilder.h.

◆ surfacePtr

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

Abrivation of the surface pointer.

Definition at line 51 of file MuonBlueprintNodeBuilder.h.

Member Enumeration Documentation

◆ EndcapSide

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

Definition at line 74 of file MuonBlueprintNodeBuilder.h.

74 : std::uint8_t {
75 A,
76 C,
77 Both
78 };
struct color C

Member Function Documentation

◆ buildBlueprintNode()

std::shared_ptr< Acts::Experimental::BlueprintNode > ActsTrk::MuonBlueprintNodeBuilder::buildBlueprintNode ( const Acts::GeometryContext & gctx,
std::shared_ptr< Acts::Experimental::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 103 of file MuonBlueprintNodeBuilder.cxx.

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

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

296 {
298 auto materialNode = std::dynamic_pointer_cast<Acts::Experimental::MaterialDesignatorBlueprintNode>(chamberVolumeNode);
299 return materialNode;
300 }
301 auto staticNode = std::dynamic_pointer_cast<Acts::Experimental::StaticBlueprintNode>(chamberVolumeNode);
302 return staticNode;
303}
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 307 of file MuonBlueprintNodeBuilder.cxx.

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

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

614 {
615
616 const float thickness = element.halfZ();
617 PVConstLink parentVolume = element.readoutEles().front()->getMaterialGeom()->getParent();
618 GeoModelTools::GeoMaterialHelper geoMaterialHelper;
619 std::pair<GeoModelTools::GeoMaterialPtr, double> geoMaterials = geoMaterialHelper.collectMaterial(parentVolume);
620
621 const Acts::Material aMat = ActsPlugins::GeoModel::geoMaterialConverter(*geoMaterials.first);
622 Acts::MaterialSlab slab{aMat, thickness};
623 std::shared_ptr<Acts::HomogeneousSurfaceMaterial> material = std::make_shared<Acts::HomogeneousSurfaceMaterial>(slab);
624 material->scale(0.5); // we want to split the active material in two and put it on the two faces of the chamber bounds
625
626 return material;
627
628}

◆ getMaterialBins()

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

Definition at line 677 of file MuonBlueprintNodeBuilder.cxx.

677 {
678 switch(chIdx) {
679 using enum ChIndex;
680 case BIS:
681 case BIL:
682 return std::make_pair(1ul * m_nZBinsBI, 1ul * m_nPhiBinsBI);
683 case BML:
684 case BMS:
685 return std::make_pair(1ul * m_nZBinsBM, 1ul * m_nPhiBinsBM);
686 case BOL:
687 case BOS:
688 return std::make_pair(1ul * m_nZBinsBO, 1ul * m_nPhiBinsBO);
689 case EIS:
690 return std::make_pair(1ul* m_nRBinsEI1, 1ul* m_nPhiBinsEI1);
691 case EIL:
692 return std::make_pair(1ul* m_nRBinsEI2, 1ul* m_nPhiBinsEI2);
693 case EMS:
694 return std::make_pair(1ul* m_nRBinsEM1, 1ul* m_nPhiBinsEM1);
695 case EML:
696 return std::make_pair(1ul* m_nRBinsEM2, 1ul* m_nPhiBinsEM2);
697 default:
698 THROW_EXCEPTION("getMaterialBins() - "<<chName(chIdx)<<" is not yet implemented");
699 }
700 return std::make_pair(0ul, 0ul);
701}
@ 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 472 of file MuonBlueprintNodeBuilder.cxx.

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

335 {
336
337 std::vector<blueprintNodePtr> readoutVolumes;
338 std::vector<surfacePtr> readoutSurfaces;
339 Acts::GeometryIdentifier::Value mdtId{1};
340
341 for (const MuonGMR4::MuonReadoutElement* readoutEle : element.readoutEles()) {
342
343 std::vector<surfacePtr> detSurfaces = readoutEle->getSurfaces();
344 switch(readoutEle->detectorType()){
345 case DetectorType::Mdt: {
346 const auto* mdtReadoutEle = static_cast<const MuonGMR4::MdtReadoutElement*>(readoutEle);
347 const MuonGMR4::MdtReadoutElement::parameterBook& parameters{mdtReadoutEle->getParameters()};
348
349 std::unique_ptr<ActsTrk::VolumePlacement> placement{};
350
351 // create the MDT multilayer volume with the dedicated builder
352 Acts::Experimental::MultiWireVolumeBuilder::Config mwCfg;
353 mwCfg.name = m_detMgr->idHelperSvc()->toStringDetEl(mdtReadoutEle->identify());
354 mwCfg.mlSurfaces = detSurfaces;
355 mwCfg.transform = readoutEle->localToGlobalTransform(gctx);
356
357 //initialize a nullptr material node which will be filled in the case of single MDT readout elements
358 //and used to assign the material to the volume and add the static node as child of the material node
359 std::shared_ptr<Acts::Experimental::MaterialDesignatorBlueprintNode> mdtMaterialNode;
360
361 //special treatment of BIS78 MDT multilayer
362 //use different shape because of clashes with EIL chambers
363 if(isBIS78(readoutEle) && mdtReadoutEle->multilayer() == 2){
364
365
366 //find the minimum and the maximum tube length (x dimension of the diamond bounds)
367 std::vector<double> tubeLengths;
368 tubeLengths.reserve(mdtReadoutEle->numTubesInLay());
369 for(std::size_t tube = 1; tube < mdtReadoutEle->numTubesInLay(); ++tube){
370 const IdentifierHash tubeHash = MuonGMR4::MdtReadoutElement::measurementHash(1,tube);
371 const auto& surface = mdtReadoutEle->surface(tubeHash);
372 const auto& lBounds = static_cast<const Acts::LineBounds&>(surface.bounds());
373 using BoundEnum = Acts::LineBounds::BoundValues;
374 const double tubeLength = 2.*lBounds.get(BoundEnum::eHalfLengthZ);
375 tubeLengths.push_back(tubeLength);
376 }
377 auto [minX,maxX] = std::ranges::minmax_element(tubeLengths);
378 int nSmallTubes = std::count_if(tubeLengths.begin(), tubeLengths.end(), [minX](double length){
379 return std::abs(*minX-length) < Acts::s_epsilon;
380 });
381
382 //create the diamond bounds for the volume
383 constexpr double extraMargin = 1._cm;
384 double y2 = (nSmallTubes+1.)*parameters.tubePitch;
385 double y1 = 2.*parameters.halfY + extraMargin - y2;
386 if (m_alignableVolumes) {
387 placement = std::make_unique<ActsTrk::VolumePlacement>(*readoutEle,
388 Amg::getTranslateY3D(parameters.halfY + extraMargin -y2));
389 }
390 mwCfg.transform = mwCfg.transform * Amg::getTranslateY3D(parameters.halfY + extraMargin - y2);
391 mwCfg.bounds = boundsFactory.makeBounds<Acts::DiamondVolumeBounds>(0.5*(*maxX), 0.5*(*maxX), 0.5*(*minX),
392 y1, y2, parameters.halfHeight);
393
394 } else {
396 placement = std::make_unique<ActsTrk::VolumePlacement>(*readoutEle);
397 }
398 //check for rectangular or trapezoidal shape bounds
399 if(std::abs(parameters.shortHalfX - parameters.longHalfX) < Acts::s_epsilon){
400 mwCfg.bounds = boundsFactory.makeBounds<Acts::CuboidVolumeBounds>(parameters.shortHalfX,
401 parameters.halfY,
402 parameters.halfHeight);
403 } else {
404 mwCfg.bounds = boundsFactory.makeBounds<Acts::TrapezoidVolumeBounds>(parameters.shortHalfX,
405 parameters.longHalfX,
406 parameters.halfY,
407 parameters.halfHeight);
408 }
409 }
410 mwCfg.alignablePlacement = placement.get();
412 element.addPlacement(std::move(placement));
413 }
414 mwCfg.binning = {{{Acts::AxisDirection::AxisY, Acts::AxisBoundaryType::Bound,
415 -parameters.halfY,
416 parameters.halfY,
417 static_cast<std::size_t>(std::lround(2 * parameters.halfY / parameters.tubePitch))}, 2u},
418 {{Acts::AxisDirection::AxisZ, Acts::AxisBoundaryType::Bound,
419 -parameters.halfHeight,
420 parameters.halfHeight,
421 static_cast<std::size_t>(std::lround(2 * parameters.halfHeight / parameters.tubePitch))}, 1u}};
422 Acts::Experimental::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::Experimental::MaterialDesignatorBlueprintNode>(element.identString() + "_MaterialNode");
431 configureMaterialFaces(*mdtMaterialNode, mdtVolume->volumeBounds(), getActiveMaterial(element));
432 auto staticNode = std::make_shared<Acts::Experimental::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::Experimental::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: " << ActsTrk::to_string(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
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).
std::string to_string(const DetectorType &type)
Amg::Transform3D getTranslateY3D(const double Y)
: Returns a shift transformation along the y-axis

◆ initialize()

StatusCode ActsTrk::MuonBlueprintNodeBuilder::initialize ( )
override

Definition at line 97 of file MuonBlueprintNodeBuilder.cxx.

97 {
98 ATH_CHECK(detStore()->retrieve(m_detMgr));
99 return StatusCode::SUCCESS;
100 }
#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 return element->detectorType() == ActsTrk::DetectorType::Mdt &&
466 element->chamberIndex() == ChIndex::BIS &&
467 element->stationEta()>=7;
468 }
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 631 of file MuonBlueprintNodeBuilder.cxx.

635 {
636 bool etaSignCorrect = (side == EndcapSide::Both) ||
637 (side == EndcapSide::A && element.side() > 0) ||
638 (side == EndcapSide::C && element.side() < 0);
639 return etaSignCorrect &&
640 Acts::rangeContainsValue(stationIndex, toStationIndex(element.chamberIndex()));
641}
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 645 of file MuonBlueprintNodeBuilder.cxx.

647 {
648 if (nBins1 == 0 || nBins2 == 0) {
649 ATH_MSG_ERROR("Cannot create material for "<<bounds
650 <<" as one of the bin dimensions is zero. nBins1: "<<nBins1<<", nBins2: "<<nBins2);
651 return nullptr;
652 }
653 if (nBins1 == 1 && nBins1 == nBins2) {
654 return std::make_shared<Acts::HomogeneousSurfaceMaterial>();
655 }
656
657 std::vector<Acts::DirectedProtoAxis> pmBinning = {};
658
659 switch (bounds.type()) {
660 using enum Acts::SurfaceBounds::BoundsType;
661 case eCylinder: {
662 pmBinning = {{Acts::AxisDirection::AxisZ, Acts::AxisBoundaryType::Bound, nBins1},
663 {Acts::AxisDirection::AxisPhi, Acts::AxisBoundaryType::Bound, nBins2}};
664 break;
665 } case eDisc: {
666 pmBinning = {{Acts::AxisDirection::AxisR, Acts::AxisBoundaryType::Bound, nBins1},
667 {Acts::AxisDirection::AxisPhi, Acts::AxisBoundaryType::Bound, nBins2}};
668
669 break;
670 } default:
671 ATH_MSG_ERROR("Unsupoorted type "<<bounds<<".");
672 return nullptr;
673 }
674 return std::make_shared<Acts::ProtoGridSurfaceMaterial>(pmBinning);
675}
#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 94 of file MuonBlueprintNodeBuilder.h.

94{this, "AlignableVolumes", true};

◆ m_assignActiveMaterial

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

Flag to assign active material on the chambers.

Definition at line 96 of file MuonBlueprintNodeBuilder.h.

96{this, "AssignActiveMaterial", false};

◆ m_buildPassiveVolumes

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

Flag to construct the passive material surfaces.

Definition at line 98 of file MuonBlueprintNodeBuilder.h.

98{this, "BuildPassiveVolumes", true};

◆ m_detMgr

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

the Detector manager

Definition at line 90 of file MuonBlueprintNodeBuilder.h.

90{nullptr};

◆ 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 100 of file MuonBlueprintNodeBuilder.h.

100{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 104 of file MuonBlueprintNodeBuilder.h.

104{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 108 of file MuonBlueprintNodeBuilder.h.

108{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 114 of file MuonBlueprintNodeBuilder.h.

114{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 118 of file MuonBlueprintNodeBuilder.h.

118{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 123 of file MuonBlueprintNodeBuilder.h.

123{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 127 of file MuonBlueprintNodeBuilder.h.

127{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 112 of file MuonBlueprintNodeBuilder.h.

112{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 116 of file MuonBlueprintNodeBuilder.h.

116{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 121 of file MuonBlueprintNodeBuilder.h.

121{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 125 of file MuonBlueprintNodeBuilder.h.

125{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 102 of file MuonBlueprintNodeBuilder.h.

102{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 106 of file MuonBlueprintNodeBuilder.h.

106{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 110 of file MuonBlueprintNodeBuilder.h.

110{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 92 of file MuonBlueprintNodeBuilder.h.

92{this, "UseSectors", false};

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