ATLAS Offline Software
MuonPhaseII/MuonDetDescr/MuonGeoModelTestR4/src/GeoModelRpcTest.cxx
Go to the documentation of this file.
1 
2 /*
3  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
4 */
5 #include "GeoModelRpcTest.h"
9 #include <fstream>
10 
11 namespace {
12 // Splitting this out into a separate function avoids a false positive
13 // out-of-bounds array access warning from gcc14 in the archflag build.
14 // (It should also be addressed in versions of Eigen after 3.4.)
15 std::string stripPosToString (const MuonGMR4::RpcReadoutElement* reElement,
16  const ActsGeometryContext& gctx,
17  const IdentifierHash measHash)
18 {
19  Amg::Vector3D v = reElement->stripPosition(gctx, measHash);
20  return Amg::toString(v);
21 }
22 }
23 
24 using namespace ActsTrk;
25 namespace MuonGMR4{
26 
27 
29  ATH_CHECK(m_idHelperSvc.retrieve());
30  ATH_CHECK(m_geoCtxKey.initialize());
32  ATH_CHECK(m_tree.init(this));
33 
34  const RpcIdHelper& idHelper{m_idHelperSvc->rpcIdHelper()};
35  auto translateTokenList = [this, &idHelper](const std::vector<std::string>& chNames){
36 
37  std::set<Identifier> transcriptedIds{};
38  for (const std::string& token : chNames) {
39  if (token.size() != 6) {
40  ATH_MSG_WARNING("Wrong format given for "<<token<<". Expecting 6 characters");
41  continue;
42  }
44  const std::string statName = token.substr(0, 3);
45  const unsigned statEta = std::atoi(token.substr(3, 1).c_str()) * (token[4] == 'A' ? 1 : -1);
46  const unsigned statPhi = std::atoi(token.substr(5, 1).c_str());
47  bool isValid{false};
48  const Identifier eleId = idHelper.elementID(statName, statEta, statPhi, 1, isValid);
49  if (!isValid) {
50  ATH_MSG_WARNING("Failed to deduce a station name for " << token);
51  continue;
52  }
53  transcriptedIds.insert(eleId);
54  std::copy_if(idHelper.detectorElement_begin(), idHelper.detectorElement_end(),
55  std::inserter(transcriptedIds, transcriptedIds.end()),
56  [&eleId, &idHelper](const Identifier& copyMe){
57  return idHelper.stationName(copyMe) == idHelper.stationName(eleId) &&
58  idHelper.stationEta(copyMe) == idHelper.stationEta(eleId) &&
59  idHelper.stationPhi(copyMe) == idHelper.stationPhi(eleId);
60  });
61  }
62  return transcriptedIds;
63  };
64 
65  std::vector <std::string>& selectedSt = m_selectStat.value();
66  const std::vector <std::string>& excludedSt = m_excludeStat.value();
67  selectedSt.erase(std::remove_if(selectedSt.begin(), selectedSt.end(),
68  [&excludedSt](const std::string& token){
69  return std::ranges::find(excludedSt, token) != excludedSt.end();
70  }), selectedSt.end());
71 
72  if (selectedSt.size()) {
73  m_testStations = translateTokenList(selectedSt);
74  std::stringstream sstr{};
75  for (const Identifier& id : m_testStations) {
76  sstr<<" *** "<<m_idHelperSvc->toString(id)<<std::endl;
77  }
78  ATH_MSG_INFO("Test only the following stations "<<std::endl<<sstr.str());
79  } else {
80  const std::set<Identifier> excluded = translateTokenList(excludedSt);
82  for(auto itr = idHelper.detectorElement_begin();
83  itr!= idHelper.detectorElement_end();++itr){
84  if (!excluded.count(*itr)) {
85  m_testStations.insert(*itr);
86  }
87  }
89  if (!excluded.empty()) {
90  std::stringstream excluded_report{};
91  for (const Identifier& id : excluded){
92  excluded_report << " *** " << m_idHelperSvc->toStringDetEl(id) << std::endl;
93  }
94  ATH_MSG_INFO("Test all station except the following excluded ones " << std::endl << excluded_report.str());
95  }
96  }
97  ATH_CHECK(detStore()->retrieve(m_detMgr));
98  return StatusCode::SUCCESS;
99 }
101  ATH_CHECK(m_tree.write());
102  return StatusCode::SUCCESS;
103 }
105  const EventContext& ctx{Gaudi::Hive::currentContext()};
106 
107  const ActsGeometryContext* geoContextHandle{nullptr};
108  ATH_CHECK(SG::get(geoContextHandle, m_geoCtxKey, ctx));
109  const ActsGeometryContext& gctx{*geoContextHandle};
110 
111  for (const Identifier& test_me : m_testStations) {
112  ATH_MSG_DEBUG("Test retrieval of Rpc detector element "<<m_idHelperSvc->toStringDetEl(test_me));
113  const RpcReadoutElement* reElement = m_detMgr->getRpcReadoutElement(test_me);
114  if (!reElement) {
115  continue;
116  }
118  if (reElement->identify() != test_me) {
119  ATH_MSG_FATAL("Expected to retrieve "<<m_idHelperSvc->toStringDetEl(test_me)
120  <<". But got instead "<<m_idHelperSvc->toStringDetEl(reElement->identify()));
121  return StatusCode::FAILURE;
122  }
123  ATH_CHECK(dumpToTree(ctx,gctx,reElement));
124  const Amg::Transform3D globToLocal{reElement->globalToLocalTrans(gctx)};
125  const Amg::Transform3D& localToGlob{reElement->localToGlobalTrans(gctx)};
127  const Amg::Transform3D transClosure = globToLocal * localToGlob;
128  if (!Amg::doesNotDeform(transClosure)) {
129  ATH_MSG_FATAL("Closure test failed for "<<m_idHelperSvc->toStringDetEl(test_me)
130  <<". Ended up with "<< Amg::toString(transClosure) );
131  return StatusCode::FAILURE;
132  }
133  const RpcIdHelper& id_helper{m_idHelperSvc->rpcIdHelper()};
134  for (unsigned int gasGap = 1; gasGap <= reElement->nGasGaps(); ++gasGap) {
135  for (int doubPhi = reElement->doubletPhi(); doubPhi <= reElement->doubletPhiMax(); ++doubPhi) {
136  for (bool measPhi: {false, true}) {
137  unsigned int numStrip = (measPhi ? reElement->nPhiStrips() :
138  reElement->nEtaStrips());
139  for (unsigned int strip = 1; strip < numStrip ; ++strip) {
140  bool isValid{false};
141  const Identifier chId = id_helper.channelID(reElement->identify(),
142  reElement->doubletZ(),
143  doubPhi, gasGap, measPhi, strip, isValid);
144  if (!isValid) {
145  continue;
146  }
148  const IdentifierHash measHash = reElement->measurementHash(chId);
149  const IdentifierHash layHash = reElement->layerHash(chId);
150  ATH_MSG_VERBOSE("gasGap: "<<gasGap<<", doubletPhi: "<<doubPhi<<", measPhi: "<<measPhi
151  <<" --> layerHash: "<<static_cast<unsigned>(layHash));
152  const Identifier backCnv = reElement->measurementId(measHash);
153  if (backCnv != chId) {
154  ATH_MSG_FATAL("The back and forth conversion of "<<m_idHelperSvc->toString(chId)
155  <<" failed. Got "<<m_idHelperSvc->toString(backCnv));
156  return StatusCode::FAILURE;
157  }
158  if (layHash != reElement->layerHash(measHash)) {
159  ATH_MSG_FATAL("Constructing the layer hash from the identifier "<<
160  m_idHelperSvc->toString(chId)<<" leadds to different layer hashes "<<
161  layHash<<" vs. "<< reElement->layerHash(measHash));
162  return StatusCode::FAILURE;
163  }
164  ATH_MSG_VERBOSE("Channel "<<m_idHelperSvc->toString(chId)<<" strip position "
165  <<stripPosToString(reElement, gctx, measHash));
166  }
167  }
168  }
169  }
170  }
171  return StatusCode::SUCCESS;
172 }
173 StatusCode GeoModelRpcTest::dumpToTree(const EventContext& ctx,
174  const ActsGeometryContext& gctx,
175  const RpcReadoutElement* reElement){
176 
177  m_stIndex = reElement->stationName();
178  m_stEta = reElement->stationEta();
179  m_stPhi = reElement->stationPhi();
180  m_doubletR = reElement->doubletR();
181  m_doubletZ = reElement->doubletZ();
182  m_doubletPhi = reElement->doubletPhi();
183  m_chamberDesign = reElement->chamberDesign();
184 
185  m_numRpcLayers = reElement->nGasGaps();
186 
187  m_numGasGapsPhi = reElement->nPhiPanels();
188  m_numPhiPanels = reElement->nPhiPanels();
189 
191  m_numStripsEta = reElement->nEtaStrips();
192  m_numStripsPhi = reElement->nPhiStrips();
193 
194  m_stripEtaPitch = reElement->stripEtaPitch();
195  m_stripPhiPitch = reElement->stripPhiPitch();
196  m_stripEtaWidth = reElement->stripEtaWidth();
197  m_stripPhiWidth = reElement->stripPhiWidth();
198  m_stripEtaLength = reElement->stripEtaLength();
199  m_stripPhiLength = reElement->stripPhiLength();
200 
202  const Amg::Transform3D& transform{reElement->localToGlobalTrans(gctx)};
203  m_readoutTransform = transform;
204  m_alignableNode = reElement->alignableTransform()->getDefTransform();
205 
206  const RpcIdHelper& id_helper{m_idHelperSvc->rpcIdHelper()};
207 
208  for (unsigned int gasGap = 1; gasGap <= reElement->nGasGaps(); ++gasGap) {
209  for (int doubPhi = reElement->doubletPhi(); doubPhi <= reElement->doubletPhiMax(); ++doubPhi) {
210  for (bool measPhi: {false, true}) {
211  unsigned int numStrip = (measPhi ? reElement->nPhiStrips() :
212  reElement->nEtaStrips());
213  for (unsigned int strip = 1; strip <= numStrip ; ++strip) {
214 
215  bool isValid{false};
216  const Identifier stripID = id_helper.channelID(reElement->identify(),
217  reElement->doubletZ(),
218  doubPhi, gasGap, measPhi, strip, isValid);
219  if (!isValid) {
220  ATH_MSG_WARNING("Invalid Identifier detected for readout element "
221  <<m_idHelperSvc->toStringDetEl(reElement->identify())
222  <<" gap: "<<gasGap<<" strip: "<<strip<<" meas phi: "<<measPhi);
223  continue;
224  }
225  const IdentifierHash measHash = reElement->measurementHash(stripID);
226  const IdentifierHash layHash = reElement->layerHash(measHash);
227  const Amg::Vector3D stripPos = reElement->stripPosition(gctx, measHash);
228  m_stripPos.push_back(stripPos);
229  m_locStripPos.push_back((reElement->globalToLocalTrans(gctx, layHash) * stripPos).block<2,1>(0,0));
230  m_stripPosGasGap.push_back(gasGap);
231  m_stripPosMeasPhi.push_back(measPhi);
232  m_stripPosNum.push_back(strip);
233  m_stripDblPhi.push_back(doubPhi);
234 
235  if (strip != 1) continue;
236  const Amg::Transform3D locToGlob = reElement->localToGlobalTrans(gctx, layHash);
237  m_stripRot.push_back(locToGlob);
238  m_stripRotGasGap.push_back(gasGap);
239  m_stripRotMeasPhi.push_back(measPhi);
240  m_stripRotDblPhi.push_back(doubPhi);
241  }
242  }
243  }
244  }
245  return m_tree.fill(ctx) ? StatusCode::SUCCESS : StatusCode::FAILURE;
246 }
247 
248 }
249 
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
MuonGMR4::RpcReadoutElement::stripPhiLength
double stripPhiLength() const
Returns the length of a phi strip.
dumpTgcDigiDeadChambers.gasGap
list gasGap
Definition: dumpTgcDigiDeadChambers.py:33
python.tests.PyTestsLib.finalize
def finalize(self)
_info( "content of StoreGate..." ) self.sg.dump()
Definition: PyTestsLib.py:50
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
MuonGMR4::RpcReadoutElement::nGasGaps
unsigned nGasGaps() const
Returns the number of gasgaps described by this ReadOutElement (usally 2 or 3)
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
MuonGMR4::RpcReadoutElement::doubletR
int doubletR() const
Returns the doublet R field of the MuonReadoutElement identifier.
ActsGeometryContext.h
MuonGMR4::RpcReadoutElement::stripEtaPitch
double stripEtaPitch() const
Strip pitch in eta.
initialize
void initialize()
Definition: run_EoverP.cxx:894
MuonGMR4::MuonReadoutElement::chamberDesign
const std::string & chamberDesign() const
The chamber design refers to the construction parameters of a readout element.
MuonGMR4::RpcReadoutElement::measurementId
Identifier measurementId(const IdentifierHash &measHash) const override final
Converts the measurement hash back to the full Identifier.
MuonGMR4::RpcReadoutElement::stripPhiPitch
double stripPhiPitch() const
Strip pitch in phi.
MuonGMR4::MuonReadoutElement::globalToLocalTrans
Amg::Transform3D globalToLocalTrans(const ActsGeometryContext &ctx) const
Transformations to translate between local <-> global coordinates.
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/src/MuonReadoutElement.cxx:78
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
isValid
bool isValid(const T &p)
Av: we implement here an ATLAS-sepcific convention: all particles which are 99xxxxx are fine.
Definition: AtlasPID.h:867
MuonGMR4::RpcReadoutElement::nPhiPanels
int nPhiPanels() const
Returns the number of phi panels (1 or 2)
MuonGMR4::RpcReadoutElement
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/RpcReadoutElement.h:17
RpcIdHelper
Definition: RpcIdHelper.h:51
LArG4FSStartPointFilterLegacy.execute
execute
Definition: LArG4FSStartPointFilterLegacy.py:20
Amg::toString
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Definition: GeoPrimitivesToStringConverter.h:40
MuonGMR4
The ReadoutGeomCnvAlg converts the Run4 Readout geometry build from the GeoModelXML into the legacy M...
Definition: MdtCalibInput.h:19
EventPrimitivesToStringConverter.h
SG::get
const T * get(const ReadCondHandleKey< T > &key, const EventContext &ctx)
Convenience function to retrieve an object given a ReadCondHandleKey.
Definition: ReadCondHandle.h:287
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
MuonGMR4::RpcReadoutElement::doubletPhi
int doubletPhi() const
Returns the doublet Phi field of the MuonReadoutElement identifier.
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
Amg::doesNotDeform
bool doesNotDeform(const Amg::Transform3D &trans)
Checks whether the linear part of the transformation rotates or stetches any of the basis vectors.
Definition: GeoPrimitivesHelpers.h:383
MuonGMR4::RpcReadoutElement::stripPosition
Amg::Vector3D stripPosition(const ActsGeometryContext &ctx, const Identifier &measId) const
Returns the position of the strip center.
Amg::transform
Amg::Vector3D transform(Amg::Vector3D &v, Amg::Transform3D &tr)
Transform a point from a Trasformation3D.
Definition: GeoPrimitivesHelpers.h:156
MuonGMR4::RpcReadoutElement::nEtaStrips
unsigned nEtaStrips() const
Number of strips measuring the eta coordinate.
GeoModelRpcTest.h
AnalysisUtils::copy_if
Out copy_if(In first, const In &last, Out res, const Pred &p)
Definition: IFilterUtils.h:30
MuonGMR4::RpcReadoutElement::doubletZ
int doubletZ() const
Returns the doublet Z field of the MuonReadoutElement identifier.
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
MuonGMR4::RpcReadoutElement::measurementHash
IdentifierHash measurementHash(const Identifier &measId) const override final
Constructs the identifier hash from the full measurement Identifier.
ActsGeometryContext
Include the GeoPrimitives which need to be put first.
Definition: ActsGeometryContext.h:27
python.PyKernel.detStore
detStore
Definition: PyKernel.py:41
MuonGMR4::MuonReadoutElement::alignableTransform
const GeoAlignableTransform * alignableTransform() const
Returnsthe alignable transform of the readout element.
MuonGMR4::RpcReadoutElement::layerHash
IdentifierHash layerHash(const Identifier &measId) const override final
MuonGMR4::MuonReadoutElement::identify
Identifier identify() const override final
Return the athena identifier.
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
RpcReadoutElement.h
python.PyAthena.v
v
Definition: PyAthena.py:154
MuonGMR4::MuonReadoutElement::stationName
int stationName() const
Returns the stationName (BIS, BOS, etc) encoded into the integer.
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
MuonGMR4::MuonReadoutElement::localToGlobalTrans
const Amg::Transform3D & localToGlobalTrans(const ActsGeometryContext &ctx) const
Returns the local to global transformation into the ATLAS coordinate system.
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/src/MuonReadoutElement.cxx:81
CxxUtils::atoi
int atoi(std::string_view str)
Helper functions to unpack numbers decoded in string into integers and doubles The strings are requir...
Definition: Control/CxxUtils/Root/StringUtils.cxx:85
ActsTrk
The AlignStoreProviderAlg loads the rigid alignment corrections and pipes them through the readout ge...
Definition: MSTrackingVolumeBuilder.cxx:24
MuonGMR4::RpcReadoutElement::stripPhiWidth
double stripPhiWidth() const
Strip width in phi.
MuonGMR4::MuonReadoutElement::stationEta
int stationEta() const
Returns the stationEta (positive A site, negative O site)
MuonGMR4::RpcReadoutElement::stripEtaWidth
double stripEtaWidth() const
Strip width in eta.
MuonGMR4::MuonReadoutElement::stationPhi
int stationPhi() const
Returns the stationPhi (1-8) -> sector (2*phi - (isSmall))
MuonGMR4::RpcReadoutElement::stripEtaLength
double stripEtaLength() const
Returns the length of an eta strip.
MuonGMR4::RpcReadoutElement::nPhiStrips
unsigned nPhiStrips() const
Number of strips measuring the phi coordinate.
Identifier
Definition: IdentifierFieldParser.cxx:14