ATLAS Offline Software
MuonPhaseII/MuonDetDescr/MuonGeoModelTestR4/src/GeoModelMmTest.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 "GeoModelMmTest.h"
9 #include <fstream>
10 
11 using namespace ActsTrk;
12 
13 namespace MuonGMR4{
14 
16  ATH_CHECK(m_idHelperSvc.retrieve());
17  ATH_CHECK(m_geoCtxKey.initialize());
19  ATH_CHECK(m_tree.init(this));
20 
21  const MmIdHelper& idHelper{m_idHelperSvc->mmIdHelper()};
22 
23  auto translateTokenList = [this, &idHelper](const std::vector<std::string>& chNames){
24 
25  std::set<Identifier> transcriptedIds{};
26  for (const std::string& token : chNames) {
27  if (token.size() != 6) {
28  ATH_MSG_WARNING("Wrong format given for "<<token<<". Expecting 6 characters");
29  continue;
30  }
32  const std::string statName = token.substr(0, 3);
33  const unsigned statEta = std::atoi(token.substr(3, 1).c_str()) * (token[4] == 'A' ? 1 : -1);
34  const unsigned statPhi = std::atoi(token.substr(5, 1).c_str());
35  bool isValid{false};
36  const Identifier eleId = idHelper.elementID(statName, statEta, statPhi, isValid);
37  if (!isValid) {
38  ATH_MSG_WARNING("Failed to deduce a station name for " << token);
39  continue;
40  }
41  transcriptedIds.insert(eleId);
42  const Identifier secMlId = idHelper.multilayerID(eleId, 2, isValid);
43  if (isValid){
44  transcriptedIds.insert(secMlId);
45  }
46  }
47  return transcriptedIds;
48  };
49 
50  std::vector <std::string>& selectedSt = m_selectStat.value();
51  const std::vector <std::string>& excludedSt = m_excludeStat.value();
52  selectedSt.erase(std::remove_if(selectedSt.begin(), selectedSt.end(),
53  [&excludedSt](const std::string& token){
54  return std::ranges::find(excludedSt, token) != excludedSt.end();
55  }), selectedSt.end());
56 
57  if (selectedSt.size()) {
58  m_testStations = translateTokenList(selectedSt);
59  std::stringstream sstr{};
60  for (const Identifier& id : m_testStations) {
61  sstr<<" *** "<<m_idHelperSvc->toString(id)<<std::endl;
62  }
63  ATH_MSG_INFO("Test only the following stations "<<std::endl<<sstr.str());
64  } else {
65  const std::set<Identifier> excluded = translateTokenList(excludedSt);
67  for(auto itr = idHelper.detectorElement_begin();
68  itr!= idHelper.detectorElement_end();++itr){
69  if (!excluded.count(*itr)) {
70  m_testStations.insert(*itr);
71  }
72  }
74  if (!excluded.empty()) {
75  std::stringstream excluded_report{};
76  for (const Identifier& id : excluded){
77  excluded_report << " *** " << m_idHelperSvc->toStringDetEl(id) << std::endl;
78  }
79  ATH_MSG_INFO("Test all station except the following excluded ones " << std::endl << excluded_report.str());
80  }
81  }
82  ATH_CHECK(detStore()->retrieve(m_detMgr));
83  return StatusCode::SUCCESS;
84 }
86  ATH_CHECK(m_tree.write());
87  return StatusCode::SUCCESS;
88 }
90  const EventContext& ctx{Gaudi::Hive::currentContext()};
91  const ActsGeometryContext* geoContextHandle{nullptr};
92  ATH_CHECK(SG::get(geoContextHandle, m_geoCtxKey, ctx));
93  const ActsGeometryContext& gctx{*geoContextHandle};
94 
95  for (const Identifier& test_me : m_testStations) {
96  ATH_MSG_DEBUG("Test retrieval of Mm detector element "<<m_idHelperSvc->toStringDetEl(test_me));
97  const MmReadoutElement* reElement = m_detMgr->getMmReadoutElement(test_me);
98  if (!reElement) {
99  continue;
100  }
102  if (reElement->identify() != test_me) {
103  ATH_MSG_FATAL("Expected to retrieve "<<m_idHelperSvc->toStringDetEl(test_me)
104  <<". But got instead "<<m_idHelperSvc->toStringDetEl(reElement->identify()));
105  return StatusCode::FAILURE;
106  }
107  const Amg::Transform3D globToLocal{reElement->globalToLocalTrans(gctx)};
108  const Amg::Transform3D& localToGlob{reElement->localToGlobalTrans(gctx)};
110  if (!Amg::doesNotDeform(globToLocal * localToGlob)) {
111  ATH_MSG_FATAL("Closure test failed for "<<m_idHelperSvc->toStringDetEl(test_me)
112  <<" "<<Amg::toString(globToLocal * localToGlob));
113  return StatusCode::FAILURE;
114  }
115  const MmIdHelper& id_helper{m_idHelperSvc->mmIdHelper()};
116  for (unsigned int layer = 1; layer <= reElement->nGasGaps(); ++layer) {
117  const IdentifierHash layerHash{MuonGMR4::MmReadoutElement::createHash(layer, 0)};
118  const int numStrips = reElement->numStrips(layerHash);
119  const int fStrip = reElement->firstStrip(layerHash);
120  const int lStrip = fStrip+numStrips-1;
121 
122  for (int strip = fStrip; strip < lStrip; ++strip) {
123  bool isValid{false};
124 
125  const Identifier chId = id_helper.channelID(reElement->identify(),
126  reElement->multilayer(),
127  layer, strip, isValid);
128  if (!isValid) {
129  continue;
130  }
131 
133  const IdentifierHash channelHash = reElement->measurementHash(chId);
134  const IdentifierHash layHash = reElement->layerHash(chId);
135  const Identifier backCnv = reElement->measurementId(channelHash);
136  if (backCnv != chId) {
137  ATH_MSG_FATAL("The back and forth conversion of "<<m_idHelperSvc->toString(chId)
138  <<" failed. Got "<<m_idHelperSvc->toString(backCnv));
139  return StatusCode::FAILURE;
140  }
141  if (layHash != reElement->layerHash(channelHash)) {
142  ATH_MSG_FATAL("Constructing the layer hash from the identifier "<<
143  m_idHelperSvc->toString(chId)<<" leads to different layer hashes "<<
144  layHash<<" vs. "<< reElement->layerHash(channelHash));
145  return StatusCode::FAILURE;
146  }
147  const MuonGMR4::StripDesign& design{reElement->stripLayer(layHash).design()};
148  const Amg::Vector3D stripPos = reElement->stripPosition(gctx, channelHash);
149  const Amg::Vector3D locStripPos = reElement->globalToLocalTrans(gctx, layHash) * stripPos;
150  const Amg::Vector2D stripPos2D{locStripPos.block<2,1>(0,0)};
151  const double stripLen{design.stripLength(strip)};
152  if (stripLen && (design.stripNumber(stripPos2D) != strip ||
153  design.stripNumber(stripPos2D - 0.49 * stripLen * Amg::Vector2D::UnitY()) != strip ||
154  design.stripNumber(stripPos2D + 0.49 * stripLen * Amg::Vector2D::UnitY()) != strip)) {
155  ATH_MSG_FATAL("Conversion channel -> strip -> channel failed for "
156  <<m_idHelperSvc->toString(chId)<<" "<<Amg::toString(stripPos)<<", local: "
157  <<Amg::toString(locStripPos)<<" got "<<design.stripNumber(stripPos2D)
158  <<", first strip: "<<fStrip<<std::endl<<design);
159  return StatusCode::FAILURE;
160  }
161  ATH_MSG_VERBOSE("first strip "<<fStrip<<", numStrips "<< numStrips << ", channel "
162  << m_idHelperSvc->toString(chId) <<", strip position " << Amg::toString(stripPos));
163  }
164  }
165  ATH_CHECK(dumpToTree(ctx,gctx,reElement));
166  }
167 
168  return StatusCode::SUCCESS;
169 }
170 StatusCode GeoModelMmTest::dumpToTree(const EventContext& ctx,
171  const ActsGeometryContext& gctx,
172  const MmReadoutElement* reElement) {
173 
174 
175 
176  m_stIndex = reElement->stationName();
177  m_stEta = reElement->stationEta();
178  m_stPhi = reElement->stationPhi();
179  m_stML = reElement->multilayer();
180  m_chamberDesign = reElement->chamberDesign();
181  m_stStripPitch = reElement->stripLayer(MuonGMR4::MmReadoutElement::createHash(1,1)).design().stripPitch();
184  const Amg::Transform3D& transform{reElement->localToGlobalTrans(gctx)};
185  m_readoutTransform = transform;
186  m_alignableNode = reElement->alignableTransform()->getDefTransform();
187 
189  m_moduleHeight = reElement->moduleHeight();
190  m_moduleWidthS = reElement->moduleWidthS();
191  m_moduleWidthL = reElement->moduleWidthL();
192 
193  const MmIdHelper& id_helper{m_idHelperSvc->mmIdHelper()};
194  for (unsigned int layer = 1; layer <= reElement->nGasGaps(); ++layer) {
195 
196  const IdentifierHash layHash{MuonGMR4::MmReadoutElement::createHash(layer, 0)};
197  unsigned int numStrips = reElement->numStrips(layHash);
198  unsigned int fStrip = reElement->firstStrip(layHash);
199  unsigned int lStrip = fStrip+numStrips-1;
200 
201  for (unsigned int strip = fStrip; strip <= lStrip ; ++strip) {
202  bool isValid{false};
203  const Identifier chId = id_helper.channelID(reElement->identify(),
204  reElement->multilayer(),
205  layer, strip, isValid);
206  if (!isValid) {
207  ATH_MSG_WARNING("Invalid Identifier detected for readout element "
208  <<m_idHelperSvc->toStringDetEl(reElement->identify())
209  <<" layer: "<<layer<<" strip: "<<strip);
210  continue;
211  }
212  const IdentifierHash measHash{reElement->measurementHash(chId)};
213 
214  const MuonGMR4::StripDesign& design{reElement->stripLayer(measHash).design()};
215  if (strip == fStrip) {
216  const Amg::Transform3D stripLocalToGlob = reElement->localToGlobalTrans(gctx, chId);
217  ATH_MSG_VERBOSE(m_idHelperSvc->toStringGasGap(chId)<<" "<< "transform: "
218  << Amg::toString(stripLocalToGlob)<<", perp: "<<stripLocalToGlob.translation().perp());
219  m_stripRot.push_back(stripLocalToGlob);
220  m_stripRotGasGap.push_back(layer);
221  m_firstStripPos.push_back(design.firstStripPos());
222  m_readoutSide.push_back(reElement->readoutSide(measHash));
223 
224  m_ActiveWidthS = reElement->gapLengthS(measHash);
225  m_ActiveWidthL = reElement->gapLengthL(measHash);
226  m_ActiveHeightR = reElement->gapHeight(measHash);
227  m_firstStrip.push_back(design.firstStripNumber());
228  m_nStrips.push_back(design.numStrips());
229  }
230  CheckVector2D center = design.center(strip);
231  if (!center) {
232  ATH_MSG_WARNING("Strip "<<m_idHelperSvc->toString(chId)<<" is outside bounds "<<design);
233  continue;
234  }
235  m_stripLength.push_back(reElement->stripLength(measHash));
236  m_locStripCenter.push_back(center.value());
237  m_isStereo.push_back(design.hasStereoAngle());
238  m_stripCenter.push_back(reElement->stripPosition(gctx, measHash));
239  m_stripLeftEdge.push_back(reElement->leftStripEdge(gctx,measHash));
240  m_stripRightEdge.push_back(reElement->rightStripEdge(gctx,measHash));
241  m_gasGap.push_back(layer);
242  m_channel.push_back(strip);
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::MmReadoutElement::moduleWidthS
double moduleWidthS() const
Returns the width at the short edge.
MuonGMR4::MmReadoutElement
Definition: MmReadoutElement.h:18
MuonGMR4::MmReadoutElement::stripLength
double stripLength(const IdentifierHash &measHash) const
Returns the strip length.
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::StripDesign
Definition: StripDesign.h:30
GeoModelMmTest.h
MuonGMR4::MmReadoutElement::createHash
static IdentifierHash createHash(const int gasGap, const int strip)
MuonGMR4::MmReadoutElement::nGasGaps
unsigned int nGasGaps() const
Returns the number of gas gaps.
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
ActsGeometryContext.h
Amg::Vector2D
Eigen::Matrix< double, 2, 1 > Vector2D
Definition: GeoPrimitives.h:48
MuonGMR4::MmReadoutElement::gapLengthS
double gapLengthS(const IdentifierHash &layerHash) const
Length of gas Gap on short side.
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::MuonReadoutElement::globalToLocalTrans
Amg::Transform3D globalToLocalTrans(const ActsGeometryContext &ctx) const
Transformations to translate between local <-> global coordinates.
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/src/MuonReadoutElement.cxx:78
MuonGMR4::MmReadoutElement::gapLengthL
double gapLengthL(const IdentifierHash &layerHash) const
Length of gas Gap on long side.
MuonGMR4::MmReadoutElement::numStrips
unsigned int numStrips(const IdentifierHash &layerHash) const
Returns the number of total active strips.
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
LArG4FSStartPointFilterLegacy.execute
execute
Definition: LArG4FSStartPointFilterLegacy.py:20
Amg::toString
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Definition: GeoPrimitivesToStringConverter.h:40
MuonGMR4::MmReadoutElement::multilayer
int multilayer() const
Returns the multi layer of the element [1-2].
MuonGMR4
The ReadoutGeomCnvAlg converts the Run4 Readout geometry build from the GeoModelXML into the legacy M...
Definition: MdtCalibInput.h:19
EventPrimitivesToStringConverter.h
MuonGMR4::MmReadoutElement::stripPosition
Amg::Vector3D stripPosition(const ActsGeometryContext &ctx, const Identifier &measId) const
Returns the position of the strip center.
MuonGMR4::MmReadoutElement::moduleWidthL
double moduleWidthL() const
Returns the width at the top edge.
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
TRT::Hit::layer
@ layer
Definition: HitInfo.h:79
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
Amg::transform
Amg::Vector3D transform(Amg::Vector3D &v, Amg::Transform3D &tr)
Transform a point from a Trasformation3D.
Definition: GeoPrimitivesHelpers.h:156
MuonGMR4::MmReadoutElement::measurementId
Identifier measurementId(const IdentifierHash &measHash) const override final
Converts the measurement hash back to the full Identifier.
MuonGMR4::MmReadoutElement::readoutSide
int readoutSide(const IdentifierHash &measHash) const
Returns the readout side.
MuonGMR4::MmReadoutElement::firstStrip
unsigned int firstStrip(const IdentifierHash &layerHash) const
Returns the first active strip.
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
ActsGeometryContext
Include the GeoPrimitives which need to be put first.
Definition: ActsGeometryContext.h:27
MuonGMR4::StripLayer::design
const StripDesign & design(bool phiView=false) const
Returns the underlying strip design.
MuonGMR4::MmReadoutElement::leftStripEdge
Amg::Vector3D leftStripEdge(const ActsGeometryContext &ctx, const Identifier &measId) const
Returns the global position of the strip edge.
MuonGMR4::MmReadoutElement::stripLayer
const StripLayer & stripLayer(const Identifier &measId) const
python.PyKernel.detStore
detStore
Definition: PyKernel.py:41
MuonGMR4::MuonReadoutElement::alignableTransform
const GeoAlignableTransform * alignableTransform() const
Returnsthe alignable transform of the readout element.
MuonGMR4::MuonReadoutElement::identify
Identifier identify() const override final
Return the athena identifier.
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
MuonGMR4::MmReadoutElement::gapHeight
double gapHeight(const IdentifierHash &layerHash) const
Height of gas Gap.
MuonGMR4::MuonReadoutElement::stationName
int stationName() const
Returns the stationName (BIS, BOS, etc) encoded into the integer.
MmIdHelper
Definition: MmIdHelper.h:54
MuonGMR4::MmReadoutElement::measurementHash
IdentifierHash measurementHash(const Identifier &measId) const override final
Constructs the identifier hash from the full measurement Identifier.
MuonGMR4::MmReadoutElement::layerHash
IdentifierHash layerHash(const Identifier &measId) const override final
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
MuonGMR4::MmReadoutElement::moduleHeight
double moduleHeight() const
Returns the height along the z-axis.
MuonGMR4::MmReadoutElement::rightStripEdge
Amg::Vector3D rightStripEdge(const ActsGeometryContext &ctx, const Identifier &measId) const
Returns the global position of the strip edge.
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::MuonReadoutElement::stationEta
int stationEta() const
Returns the stationEta (positive A site, negative O site)
MuonGMR4::StripDesign::stripPitch
double stripPitch() const
Distance between two adjacent strips.
MuonGMR4::MuonReadoutElement::stationPhi
int stationPhi() const
Returns the stationPhi (1-8) -> sector (2*phi - (isSmall))
MmReadoutElement.h
Identifier
Definition: IdentifierFieldParser.cxx:14