ATLAS Offline Software
SpectrometerSector.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include "Identifier/Identifier.h"
6 #include <GeoModelKernel/throwExcept.h>
7 #include <cstddef>
8 #ifndef SIMULATIONBASE
10 #include <Acts/Surfaces/PlaneSurface.hpp>
11 #include <Acts/Geometry/TrapezoidVolumeBounds.hpp>
12 #include <Acts/Geometry/Volume.hpp>
14 
21 
22 #include <format>
23 
24 namespace {
25  std::vector<unsigned int> range (unsigned min, unsigned max) {
26  assert(max > min);
27  std::vector<unsigned int> v(max - min);
28  std::iota(v.begin(), v.end(), min);
29  return v;
30  };
31 }
32 
33 namespace MuonGMR4 {
34 
36 using BoundEnums = Acts::TrapezoidVolumeBounds::BoundValues;
37 
39  AthMessaging("MuonSpectrometerSector"), m_args{std::move(args)} {
40  for (auto & chamber : m_args.chambers) {
41  chamber->setParent(this);
42  }
43  }
44 
46  if (side() != other.side()) {
47  return side() < other.side();
48  }
49  if (sector() != other.sector()) {
50  return sector() < other.sector();
51  }
52  if (other.chamberIndex() != chamberIndex()) {
53  return chamberIndex() < other.chamberIndex();
54  }
55  return (*m_args.chambers.front()) < (*other.m_args.chambers.front());
56 }
57 int8_t SpectrometerSector::side() const {
58  return m_args.chambers.front()->stationEta() > 0 ? 1 : -1;
59 }
61 const Muon::IMuonIdHelperSvc* SpectrometerSector::idHelperSvc() const { return m_args.chambers.front()->idHelperSvc();}
63 int SpectrometerSector::stationPhi() const { return m_args.chambers.front()->stationPhi(); }
64 int SpectrometerSector::sector() const {return m_args.chambers.front()->sector(); }
65 bool SpectrometerSector::barrel() const { return m_args.chambers.front()->barrel(); }
66 std::string SpectrometerSector::identString() const {
67  return std::format("{:} {:}-side sector: {:2}",
69  side() == 1 ? 'A' : 'C' , sector());
70 }
72 const Acts::PlaneSurface& SpectrometerSector::surface() const {
73  return *m_args.surface;
74 }
76  return surface().transform(gctx.context());
77 }
79  return localToGlobalTrans(gctx).inverse();
80 }
81 double SpectrometerSector::halfXLong() const { return m_args.bounds->get(BoundEnums::eHalfLengthXposY); }
82 double SpectrometerSector::halfXShort() const { return m_args.bounds->get(BoundEnums::eHalfLengthXnegY); }
83 double SpectrometerSector::halfY() const { return m_args.bounds->get(BoundEnums::eHalfLengthY); }
84 double SpectrometerSector::halfZ() const { return m_args.bounds->get(BoundEnums::eHalfLengthZ); }
85 
86 
87 std::shared_ptr<Acts::Volume> SpectrometerSector::boundingVolume(const ActsGeometryContext& gctx) const {
88  return std::make_shared<Acts::Volume>(localToGlobalTrans(gctx), bounds());
89 }
90 std::shared_ptr<Acts::TrapezoidVolumeBounds> SpectrometerSector::bounds() const {
91  return m_args.bounds;
92 }
94  Chamber::ReadoutSet toReturn{};
95  for (const ChamberPtr& ch : chambers()) {
96  toReturn.insert(toReturn.end(), ch->readoutEles().begin(), ch->readoutEles().end());
97  }
98  return toReturn;
99 }
100 const std::vector<SpectrometerSector::chamberLocation> & SpectrometerSector::chamberLocations() const{
101  return m_args.detectorLocs;
102 
103 }
104 std::ostream& operator<<(std::ostream& ostr,
106  ostr<<std::endl
107  <<"halfX (S/L): "<<args.bounds->get(BoundEnums::eHalfLengthXnegY)
108  <<"/"<<args.bounds->get(BoundEnums::eHalfLengthXposY)<<" [mm], ";
109  ostr<<"halfY: "<<args.bounds->get(BoundEnums::eHalfLengthY)<<" [mm], ";
110  ostr<<"halfZ: "<<args.bounds->get(BoundEnums::eHalfLengthZ)<<" [mm], ";
111  ostr<<"************************************************************************"<<std::endl;
112  for (const SpectrometerSector::ChamberPtr& ch : args.chambers) {
113  ostr<<" --- "<<(*ch)<<std::endl;
114  }
115  return ostr;
116 }
117 std::ostream& operator<<(std::ostream& ostr, const SpectrometerSector& chamber) {
118  ostr<<"MS sector "<<chamber.identString()<<" "<<chamber.parameters();
119  return ostr;
120 }
121 
122 const std::vector<unsigned int>& SpectrometerSector::logicalLayerIdx(const MuonReadoutElement* reEle) const{
123  return m_detLayIdCache.at(reEle);
124 };
125 
126 std::unordered_map<const MuonReadoutElement*, std::vector<unsigned int>>
128 
129  std::unordered_map<const MuonReadoutElement*, std::vector<unsigned int>> cache{};
130  const ActsGeometryContext gctx{};
131  const Amg::Transform3D sectorTrans = globalToLocalTrans(gctx);
132 
133  // sort the Readout elements by z in the sector fram
134  Chamber::ReadoutSet reEleSorted {readoutEles()};
135  std::ranges::sort(reEleSorted, [&sectorTrans, &gctx](const MuonReadoutElement* reEle1, const MuonReadoutElement* reEle2)-> bool {
136  return (sectorTrans * reEle1->center(gctx, reEle1->identify())).z() < (sectorTrans * reEle2->center(gctx, reEle2->identify())).z();
137  });
138 
139  // this is a function to find the next logical layer, returning the corresponding reEle and Id
140  auto nextLayer = [this, &cache, &reEleSorted](const Identifier& lastId) ->
141  std::pair<const MuonReadoutElement*, const Identifier> {
142 
143  const MuonReadoutElement* nextReEle {nullptr};
144  Identifier nextId {};
145 
146  for (const MuonReadoutElement* reEle : reEleSorted){
147 
148  // Check if this reEle has already been filled up
149  if (cache.count(reEle)) continue;
150 
151  // compute the logical layer Id of the first layer of the reEle (first layer/gasgap, first channel, projecting to
152  // stationEta=1, doubletZ=1, doubletPhi=1, according to the technology)
153  const Identifier logicalId {computeDetLayerId(reEle)};
154 
155  //if we find another measurement layer with the same detLayerId as the last we added (e.g. the same gasgap of two RPC z doublets)
156  if (logicalId == lastId){
157  return std::make_pair(reEle, logicalId);
158  }
159 
160  // Save the next (subsequent) logic layer in z
161  if (!nextReEle) {
162  nextReEle = reEle;
163  nextId = logicalId;
164  }
165 
166  }
167  return std::make_pair(nextReEle, nextId);
168  };
169 
170  unsigned int layCounter {0}, nIter {0};
171  Identifier lastId {};
172  while(++nIter <= reEleSorted.size()){
173 
174  auto [nextReEle, nextId] = nextLayer(lastId);
175  if (!nextReEle){
176  THROW_EXCEPTION("Failed to retrieve next reEle in fillDetLayIdCache()");
177  }
178 
179  unsigned int nLayers = nLayerPerReadout(nextReEle);
180 
181  if (nextId != lastId) {
182  cache[nextReEle] = range(layCounter, layCounter + nLayers);
183  lastId = nextId;
184  layCounter += nLayers;
185  }
186  else{
187  cache[nextReEle] = range(layCounter - nLayers, layCounter);
188  }
189 
190  ATH_MSG_DEBUG( identString() << " ReEle: " << idHelperSvc()->toStringDetEl(nextReEle->identify()) <<
191  " Add logicLay: " << idHelperSvc()->toStringGasGap(nextId) << " nInserted, layCounter " << cache.at(nextReEle).size() << " ," << layCounter);
192  }
193  return cache;
194 };
195 
197 
198  switch (rele->detectorType()) {
200  auto mdtRele = dynamic_cast<const MdtReadoutElement*>(rele);
201  return idHelperSvc()->mdtIdHelper().channelID(mdtRele->stationName(), 1,
202  mdtRele->stationPhi(),
203  mdtRele->multilayer(),
204  1,1);
205  }
207  auto rpcRele = dynamic_cast<const RpcReadoutElement*>(rele);
208  return idHelperSvc()->rpcIdHelper().channelID(rpcRele->stationName(), 1,
209  rpcRele->stationPhi(),
210  rpcRele->doubletR(), 1, 1,
211  1, 0, 1);
212  }
214  auto tgcRele = dynamic_cast<const TgcReadoutElement*>(rele);
215  return idHelperSvc()->tgcIdHelper().channelID(tgcRele->stationName(), 1,
216  tgcRele->stationPhi(),
217  1, 0, 1);
218  }
220  auto stgcRele = dynamic_cast<const sTgcReadoutElement*>(rele);
221  return idHelperSvc()->stgcIdHelper().channelID(stgcRele->stationName(), 1,
222  stgcRele->stationPhi(),
223  stgcRele->multilayer(),
224  1, 0, 1);
225  }
227  auto mmRele = dynamic_cast<const MmReadoutElement*>(rele);
228  return idHelperSvc()->mmIdHelper().channelID(mmRele->stationName(), 1,
229  mmRele->stationPhi(),
230  mmRele->multilayer(),
231  1, 1);
232  }
233  default:
234  THROW_EXCEPTION("Unexpected Readout Element Type in computeDetLayerId()");
235  }
236 }
237 
239 
240  switch (rele->detectorType()) {
242  auto mdtRele = dynamic_cast<const MdtReadoutElement*>(rele);
243  return mdtRele->numLayers();
244  }
246  auto rpcRele = dynamic_cast<const RpcReadoutElement*>(rele);
247  return rpcRele->nGasGaps();
248  }
250  auto tgcRele = dynamic_cast<const TgcReadoutElement*>(rele);
251  return tgcRele->nGasGaps();
252  }
254  auto stgcRele = dynamic_cast<const sTgcReadoutElement*>(rele);
255  return stgcRele->numLayers();
256  }
258  auto mmRele = dynamic_cast<const MmReadoutElement*>(rele);
259  return mmRele->nGasGaps();
260  }
261  default:
262  THROW_EXCEPTION("Unexpected Readout Element Type in nLayerPerReadout()");
263  }
264 }
265 
266 }
267 
268 #endif
GeoModel::TransientConstSharedPtr
The TransientConstSharedPtr allows non-const access if the pointer itself is non-const but in the con...
Definition: TransientConstSharedPtr.h:13
MuonGMR4::MmReadoutElement
Definition: MmReadoutElement.h:18
MuonGMR4::SpectrometerSector::boundingVolume
std::shared_ptr< Acts::Volume > boundingVolume(const ActsGeometryContext &gctx) const
Returns the Acts::Volume representation of the sector.
Definition: SpectrometerSector.cxx:87
Muon::IMuonIdHelperSvc::stgcIdHelper
virtual const sTgcIdHelper & stgcIdHelper() const =0
access to TgcIdHelper
sendEI_SPB.ch
ch
Definition: sendEI_SPB.py:35
MuonGMR4::SpectrometerSector::sector
int sector() const
Returns the sector of the MS-sector.
Definition: SpectrometerSector.cxx:64
MuonGMR4::SpectrometerSector::side
int8_t side() const
Returns the side of the MS-sector 1 -> A side ; -1 -> C side.
Definition: SpectrometerSector.cxx:57
MuonGMR4::MmReadoutElement::nGasGaps
unsigned int nGasGaps() const
Returns the number of gas gaps.
MuonGMR4::RpcReadoutElement::nGasGaps
unsigned nGasGaps() const
Returns the number of gasgaps described by this ReadOutElement (usally 2 or 3)
MuonGMR4::SpectrometerSector
A spectrometer sector forms the envelope of all chambers that are placed in the same MS sector & laye...
Definition: SpectrometerSector.h:40
vtune_athena.format
format
Definition: vtune_athena.py:14
MuonGMR4::SpectrometerSector::stationPhi
int stationPhi() const
: Returns the station phi of the sector
Definition: SpectrometerSector.cxx:63
python.CaloAddPedShiftConfig.args
args
Definition: CaloAddPedShiftConfig.py:47
MuonGMR4::SpectrometerSector::computeDetLayerId
Identifier computeDetLayerId(const MuonReadoutElement *rele) const
Helper function calculating the logic layer Id and the physical layer id.
Definition: SpectrometerSector.cxx:196
calibdata.chamber
chamber
Definition: calibdata.py:31
sTgcIdHelper::channelID
Identifier channelID(int stationName, int stationEta, int stationPhi, int multilayer, int gasGap, int channelType, int channel) const
Definition: sTgcIdHelper.cxx:886
max
constexpr double max()
Definition: ap_fixedTest.cxx:33
MuonGMR4::SpectrometerSector::chambers
const ChamberSet & chambers() const
Returns the associated chambers with this sector.
Definition: SpectrometerSector.cxx:71
MuonGMR4::SpectrometerSector::m_args
defineArgs m_args
Definition: SpectrometerSector.h:173
MuonGMR4::SpectrometerSector::fillDetLayIdCache
std::unordered_map< const MuonReadoutElement *, std::vector< unsigned int > > fillDetLayIdCache() const
Function filling the map mapping the readout elements to layer numbers.
Definition: SpectrometerSector.cxx:127
min
constexpr double min()
Definition: ap_fixedTest.cxx:26
MuonGMR4::SpectrometerSector::readoutEles
Chamber::ReadoutSet readoutEles() const
Returns the list of all associated readout elements.
Definition: SpectrometerSector.cxx:93
MuonGMR4::SpectrometerSector::defineArgs
Definition: SpectrometerSector.h:106
ActsTrk::DetectorType::Tgc
@ Tgc
Resitive Plate Chambers.
MuonGMR4::MuonReadoutElement
The MuonReadoutElement is an abstract class representing the geometry representing the muon detector.
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/MuonReadoutElement.h:38
MuonGMR4::SpectrometerSector::halfXShort
double halfXShort() const
Short extend of the chamber in the x-direction at negative Y.
Definition: SpectrometerSector.cxx:82
ActsTrk::IDetectorElementBase::detectorType
virtual DetectorType detectorType() const =0
Returns the detector element type.
MuonGMR4::SpectrometerSector::halfZ
double halfZ() const
Thickness of the chamber in the z-direction.
Definition: SpectrometerSector.cxx:84
RpcIdHelper::channelID
Identifier channelID(int stationName, int stationEta, int stationPhi, int doubletR, int doubletZ, int doubletPhi, int gasGap, int measuresPhi, int strip) const
Definition: RpcIdHelper.cxx:931
ActsTrk::DetectorType::sTgc
@ sTgc
Micromegas (NSW)
SpectrometerSector.h
Muon::IMuonIdHelperSvc::mmIdHelper
virtual const MmIdHelper & mmIdHelper() const =0
access to CscIdHelper
MuonGMR4::SpectrometerSector::identString
std::string identString() const
Returns a string encoding the chamber index & the sector of the MS sector.
Definition: SpectrometerSector.cxx:66
MuonGMR4::RpcReadoutElement
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/RpcReadoutElement.h:17
MuonGMR4::TgcReadoutElement::nGasGaps
unsigned nGasGaps() const
Returns the number of gasgaps described by this ReadOutElement (usally 2 or 3)
MuonGMR4::BoundEnums
Acts::TrapezoidVolumeBounds::BoundValues BoundEnums
Definition: Chamber.cxx:13
MuonGMR4::ChamberSet
SpectrometerSector::ChamberSet ChamberSet
Definition: SpectrometerSector.cxx:35
MuonGMR4::SpectrometerSector::halfY
double halfY() const
Extend of the chamber in the y-direction.
Definition: SpectrometerSector.cxx:83
MuonGMR4::SpectrometerSector::m_detLayIdCache
const std::unordered_map< const MuonReadoutElement *, std::vector< unsigned int > > m_detLayIdCache
Map mapping each Readout Element to the layer numbering in the sector frame.
Definition: SpectrometerSector.h:178
ActsGeometryContext::context
Acts::GeometryContext context() const
Definition: ActsGeometryContext.h:45
sTgcReadoutElement.h
MuonGMR4::SpectrometerSector::chamberIndex
Muon::MuonStationIndex::ChIndex chamberIndex() const
Returns the chamber index scheme.
Definition: SpectrometerSector.cxx:62
MuonGMR4::SpectrometerSector::halfXLong
double halfXLong() const
Long-extend of the chamber in the x-direction at positive Y.
Definition: SpectrometerSector.cxx:81
MuonGMR4
The ReadoutGeomCnvAlg converts the Run4 Readout geometry build from the GeoModelXML into the legacy M...
Definition: MdtCalibInput.h:19
MuonGMR4::SpectrometerSector::logicalLayerIdx
const std::vector< unsigned int > & logicalLayerIdx(const MuonReadoutElement *reEle) const
Returns the logic layer numbering of a given Readout Element.
Definition: SpectrometerSector.cxx:122
ActsTrk::DetectorType::Mm
@ Mm
Maybe not needed in the migration.
MuonGMR4::SpectrometerSector::chamberLocations
const std::vector< chamberLocation > & chamberLocations() const
returns the list of all MDT chambers in the sector for fast navigation
Definition: SpectrometerSector.cxx:100
Muon::MuonStationIndex::chName
const std::string & chName(ChIndex index)
convert ChIndex into a string
Definition: MuonStationIndex.cxx:119
MuonGMR4::SpectrometerSector::barrel
bool barrel() const
Returns whether the sector is placed in the barrel.
Definition: SpectrometerSector.cxx:65
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
MuonGMR4::SpectrometerSector::globalToLocalTrans
Amg::Transform3D globalToLocalTrans(const ActsGeometryContext &gctx) const
Returns the global -> local transformation from the ATLAS global.
Definition: SpectrometerSector.cxx:78
MuonGMR4::SpectrometerSector::nLayerPerReadout
unsigned int nLayerPerReadout(const MuonReadoutElement *rele) const
Helper function giving the number of measurement layers in a given readout ele.
Definition: SpectrometerSector.cxx:238
MuonGMR4::MdtReadoutElement::numLayers
unsigned int numLayers() const
Returns the number of tube layer.
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
MuonGMR4::Chamber::ReadoutSet
std::vector< const MuonReadoutElement * > ReadoutSet
Define the list of read out elements of the chamber.
Definition: Chamber.h:26
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:194
MuonGMR4::MuonReadoutElement::center
Amg::Vector3D center(const ActsGeometryContext &ctx) const
Returns the detector center (Which is the same as the detector center of the first measurement layer)
AthMessaging
Class to provide easy MsgStream access and capabilities.
Definition: AthMessaging.h:55
NoDeletePtr.h
MuonGMR4::SpectrometerSector::surface
const Acts::PlaneSurface & surface() const
Returns the associated surface.
Definition: SpectrometerSector.cxx:72
ActsGeometryContext
Include the GeoPrimitives which need to be put first.
Definition: ActsGeometryContext.h:27
MuonGMR4::SpectrometerSector::SpectrometerSector
SpectrometerSector(defineArgs &&args)
Standard constructor taking the defining parameters.
Definition: SpectrometerSector.cxx:38
ActsTrk::DetectorType::Mdt
@ Mdt
MuonSpectrometer.
MuonGMR4::MdtReadoutElement
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/MdtReadoutElement.h:18
MuonGMR4::SpectrometerSector::idHelperSvc
const Muon::IMuonIdHelperSvc * idHelperSvc() const
Returns the IdHelpeSvc.
Definition: SpectrometerSector.cxx:61
MdtIdHelper::channelID
Identifier channelID(int stationName, int stationEta, int stationPhi, int multilayer, int tubeLayer, int tube) const
Definition: MdtIdHelper.cxx:659
MuonGMR4::SpectrometerSector::defineArgs::surface
std::shared_ptr< const Acts::PlaneSurface > surface
Surface in the centre of the chamber plane.
Definition: SpectrometerSector.h:112
Muon::IMuonIdHelperSvc::mdtIdHelper
virtual const MdtIdHelper & mdtIdHelper() const =0
access to MdtIdHelper
MuonGMR4::SpectrometerSector::defineArgs::bounds
std::shared_ptr< Acts::TrapezoidVolumeBounds > bounds
Surrouding box chamber bounds.
Definition: SpectrometerSector.h:110
MuonGMR4::MuonReadoutElement::identify
Identifier identify() const override final
Return the athena identifier.
MuonGMR4::SpectrometerSector::defineArgs::chambers
ChamberSet chambers
List of readout elements in the chamber.
Definition: SpectrometerSector.h:108
MuonGMR4::SpectrometerSector::bounds
std::shared_ptr< Acts::TrapezoidVolumeBounds > bounds() const
Returns the volume bounds.
Definition: SpectrometerSector.cxx:90
THROW_EXCEPTION
#define THROW_EXCEPTION(MESSAGE)
Definition: throwExcept.h:10
MuonGMR4::sTgcReadoutElement::numLayers
unsigned int numLayers() const
Returns the number of gas gap layers.
MuonGMR4::sTgcReadoutElement
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/sTgcReadoutElement.h:20
Muon::IMuonIdHelperSvc::tgcIdHelper
virtual const TgcIdHelper & tgcIdHelper() const =0
access to TgcIdHelper
RpcReadoutElement.h
python.PyAthena.v
v
Definition: PyAthena.py:154
MuonGMR4::SpectrometerSector::parameters
const defineArgs & parameters() const
Returns the reference to the defining parameters of the sector.
Definition: SpectrometerSector.cxx:60
MuonGMR4::SpectrometerSector::ChamberSet
std::vector< ChamberPtr > ChamberSet
Definition: SpectrometerSector.h:43
InDetDD::other
@ other
Definition: InDetDD_Defs.h:16
MdtReadoutElement.h
MuonGMR4::SpectrometerSector::localToGlobalTrans
const Amg::Transform3D & localToGlobalTrans(const ActsGeometryContext &gctx) const
Returns the local -> global tarnsformation from the sector.
Definition: SpectrometerSector.cxx:75
ActsTrk::DetectorType::Rpc
@ Rpc
Monitored Drift Tubes.
Muon::IMuonIdHelperSvc
Interface for Helper service that creates muon Identifiers and can be used to print Identifiers.
Definition: IMuonIdHelperSvc.h:27
TgcIdHelper::channelID
Identifier channelID(int stationName, int stationEta, int stationPhi, int gasGap, int isStrip, int channel) const
Definition: TgcIdHelper.cxx:583
MuonGMR4::SpectrometerSector::defineArgs::detectorLocs
std::vector< chamberLocation > detectorLocs
Definition: SpectrometerSector.h:114
Muon::MuonStationIndex::ChIndex
ChIndex
enum to classify the different chamber layers in the muon spectrometer
Definition: MuonStationIndex.h:15
MmIdHelper::channelID
Identifier channelID(int stationName, int stationEta, int stationPhi, int multilayer, int gasGap, int channel) const
Definition: MmIdHelper.cxx:736
MuonReadoutElement.h
TgcReadoutElement.h
MuonGMR4::operator<<
std::ostream & operator<<(std::ostream &ostr, const Chamber::defineArgs &args)
Definition: Chamber.cxx:15
MuonGMR4::TgcReadoutElement
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/TgcReadoutElement.h:19
MmReadoutElement.h
Muon::IMuonIdHelperSvc::rpcIdHelper
virtual const RpcIdHelper & rpcIdHelper() const =0
access to RpcIdHelper
MuonGMR4::SpectrometerSector::operator<
bool operator<(const SpectrometerSector &other) const
Definition: SpectrometerSector.cxx:45
Identifier
Definition: IdentifierFieldParser.cxx:14