ATLAS Offline Software
MuonPhaseII/MuonDetDescr/MuonGeoModelTestR4/src/GeoModelMdtTest.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 "GeoModelMdtTest.h"
10 
11 #include <fstream>
12 
13 using namespace ActsTrk;
14 
15 namespace MuonGMR4{
16 
17 
19  ATH_CHECK(m_idHelperSvc.retrieve());
20  ATH_CHECK(m_geoCtxKey.initialize());
21  ATH_CHECK(m_cablingKey.initialize(!m_cablingKey.empty()));
23  ATH_CHECK(m_tree.init(this));
24 
25  const MdtIdHelper& idHelper{m_idHelperSvc->mdtIdHelper()};
26  auto translateTokenList = [this, &idHelper](const std::vector<std::string>& chNames){
27 
28  std::set<Identifier> transcriptedIds{};
29  for (const std::string& token : chNames) {
30  if (token.size() != 6) {
31  ATH_MSG_WARNING("Wrong format given for "<<token<<". Expecting 6 characters");
32  continue;
33  }
35  const std::string statName = token.substr(0, 3);
36  const unsigned statEta = std::atoi(token.substr(3, 1).c_str()) * (token[4] == 'A' ? 1 : -1);
37  const unsigned statPhi = std::atoi(token.substr(5, 1).c_str());
38  bool isValid{false};
39  const Identifier eleId = idHelper.elementID(statName, statEta, statPhi, isValid);
40  if (!isValid) {
41  ATH_MSG_WARNING("Failed to deduce a station name for " << token);
42  continue;
43  }
44  transcriptedIds.insert(eleId);
45  const Identifier secMlId = idHelper.multilayerID(eleId, 2, isValid);
46  if (isValid){
47  transcriptedIds.insert(secMlId);
48  }
49  }
50  return transcriptedIds;
51  };
52 
53  std::vector <std::string>& selectedSt = m_selectStat.value();
54  const std::vector <std::string>& excludedSt = m_excludeStat.value();
55  selectedSt.erase(std::remove_if(selectedSt.begin(), selectedSt.end(),
56  [&excludedSt](const std::string& token){
57  return std::ranges::find(excludedSt, token) != excludedSt.end();
58  }), selectedSt.end());
59 
60  if (selectedSt.size()) {
61  m_testStations = translateTokenList(selectedSt);
62  std::stringstream sstr{};
63  for (const Identifier& id : m_testStations) {
64  sstr<<" *** "<<m_idHelperSvc->toString(id)<<std::endl;
65  }
66  ATH_MSG_INFO("Test only the following stations "<<std::endl<<sstr.str());
67  } else {
68  const std::set<Identifier> excluded = translateTokenList(excludedSt);
70  for(auto itr = idHelper.detectorElement_begin();
71  itr!= idHelper.detectorElement_end();++itr){
72  if (!excluded.count(*itr)) {
73  m_testStations.insert(*itr);
74  }
75  }
77  if (!excluded.empty()) {
78  std::stringstream excluded_report{};
79  for (const Identifier& id : excluded){
80  excluded_report << " *** " << m_idHelperSvc->toStringDetEl(id) << std::endl;
81  }
82  ATH_MSG_INFO("Test all station except the following excluded ones " << std::endl << excluded_report.str());
83  }
84  }
85  ATH_CHECK(detStore()->retrieve(m_detMgr));
86  return StatusCode::SUCCESS;
87 }
89  ATH_CHECK(m_tree.write());
90  return StatusCode::SUCCESS;
91 }
93  const EventContext& ctx{Gaudi::Hive::currentContext()};
94 
95  const ActsTrk::GeometryContext* geoContextHandle{nullptr};
96  ATH_CHECK(SG::get(geoContextHandle, m_geoCtxKey, ctx));
97 
98  const ActsTrk::GeometryContext& gctx{*geoContextHandle};
99 
100  const MdtIdHelper& id_helper{m_idHelperSvc->mdtIdHelper()};
101  for (const Identifier& test_me : m_testStations) {
102  const int ml = id_helper.multilayer(test_me);
103  const std::string detStr = m_idHelperSvc->toStringDetEl(test_me);
104  ATH_MSG_DEBUG("Test retrieval of Mdt detector element "<<detStr);
105  const MdtReadoutElement* reElement = m_detMgr->getMdtReadoutElement(test_me);
106  if (!reElement) {
107  continue;
108  }
110  if (reElement->identify() != test_me) {
111  ATH_MSG_FATAL("Expected to retrieve "<<detStr<<". But got instead "<<m_idHelperSvc->toStringDetEl(reElement->identify()));
112  return StatusCode::FAILURE;
113  }
114  ATH_CHECK(dumpToTree(ctx,gctx,reElement));
115  const Amg::Transform3D globToLocal{reElement->globalToLocalTrans(gctx)};
116  const Amg::Transform3D& localToGlob{reElement->localToGlobalTrans(gctx)};
118  const Amg::Transform3D transClosure = globToLocal * localToGlob;
119  if (!Amg::doesNotDeform(transClosure)) {
120  ATH_MSG_FATAL("Closure test failed for "<<detStr<<". Ended up with "<< Amg::toString(transClosure) );
121  return StatusCode::FAILURE;
122  }
123  for (unsigned int lay = 1 ; lay <= reElement->numLayers() ; ++lay ) {
124  for (unsigned int tube = 1; tube <=reElement->numTubesInLay(); ++tube ){
125  const Identifier tube_id = id_helper.channelID(test_me,ml,lay,tube);
127  const IdentifierHash measHash = reElement->measurementHash(tube_id);
128  const Identifier cnv_tube_id = reElement->measurementId(measHash);
129  if (tube_id != cnv_tube_id) {
130  ATH_MSG_FATAL("Failed to convert "<<m_idHelperSvc->toString(tube_id)<<" back and forth "<<m_idHelperSvc->toString(cnv_tube_id));
131  return StatusCode::FAILURE;
132  }
133  }
134  }
135  }
136  dumpReadoutSideXML();
137  return StatusCode::SUCCESS;
138 }
139 void GeoModelMdtTest::dumpReadoutSideXML() const {
140  if (m_swapRead.empty()) return;
141  std::ofstream swapReadXML{m_swapRead};
142  if (!swapReadXML.good()) {
143  ATH_MSG_ERROR("Failed to create "<<m_swapRead);
144  return;
145  }
146  std::set<Identifier> chamberIDs{};
147  const MdtIdHelper& idHelper{m_idHelperSvc->mdtIdHelper()};
148  swapReadXML<<"<Table name=\"MdtTubeROSides\">"<<std::endl;
149  unsigned int counter{1};
150  for (MdtIdHelper::const_id_iterator itr = idHelper.detectorElement_begin();
151  itr != idHelper.detectorElement_end();
152  ++itr){
153  const Identifier swap{*itr};
154  const MdtReadoutElement* readoutEle = m_detMgr->getMdtReadoutElement(swap);
155  if(!readoutEle) continue;
156  if (!chamberIDs.insert(idHelper.elementID(swap)).second) continue;
157  const int side = readoutEle->getParameters().readoutSide;
158  swapReadXML<<" <Row ";
159  swapReadXML<<"MDTTUBEROSIDES_DATA_ID=\""<<counter<<"\" ";
160  swapReadXML<<"stationName=\""<<m_idHelperSvc->stationNameString(swap)<<"\" ";
161  swapReadXML<<"stationEta=\""<<m_idHelperSvc->stationEta(swap)<<"\" ";
162  swapReadXML<<"stationPhi=\""<<m_idHelperSvc->stationPhi(swap)<<"\" ";
163  swapReadXML<<"side=\""<<side<<"\" ";
164  swapReadXML<<"/>"<<std::endl;
165  ++counter;
166  }
167  swapReadXML<<"</Table>"<<std::endl;
168 
169 }
170 StatusCode GeoModelMdtTest::dumpToTree(const EventContext& ctx,
171  const ActsTrk::GeometryContext& gctx,
172  const MdtReadoutElement* readoutEle) {
173 
174 
175  m_stIndex = readoutEle->stationName();
176  m_stEta = readoutEle->stationEta();
177  m_stPhi = readoutEle->stationPhi();
178  m_stML = readoutEle->multilayer();
179  m_chamberDesign = readoutEle->chamberDesign();
180 
181  m_numLayers = readoutEle->numLayers();
182  m_numTubes = readoutEle->numTubesInLay();
183 
184  m_tubeRad = readoutEle->innerTubeRadius();
185  m_tubePitch = readoutEle->tubePitch();
186 
188  const Amg::Transform3D& transform {readoutEle->localToGlobalTrans(gctx)};
189  m_readoutTransform = transform;
190  m_alignableNode = readoutEle->alignableTransform()->getDefTransform();
191 
192  const MuonMDT_CablingMap* cabling{nullptr};
193  ATH_CHECK(SG::get(cabling, m_cablingKey, ctx));
195  for (unsigned int lay = 1; lay <= readoutEle->numLayers(); ++lay) {
196  for (unsigned int tube = 1; tube <= readoutEle->numTubesInLay(); ++tube) {
197  const IdentifierHash measHash{readoutEle->measurementHash(lay,tube)};
198  if (!readoutEle->isValid(measHash)) continue;
199  const Amg::Transform3D& tubeTransform{readoutEle->localToGlobalTrans(gctx,measHash)};
200  m_tubeLay.push_back(lay);
201  m_tubeNum.push_back(tube);
202  m_tubeTransform.push_back(tubeTransform);
203  m_tubePosInCh.push_back(readoutEle->msSector()->globalToLocalTrans(gctx) *
204  readoutEle->center(gctx, measHash));
205  m_roPos.push_back(readoutEle->readOutPos(gctx, measHash));
206  m_tubeLength.push_back(readoutEle->tubeLength(measHash));
207  m_activeTubeLength.push_back(readoutEle->activeTubeLength(measHash));
208  m_wireLength.push_back(readoutEle->wireLength(measHash));
209  if (cabling) {
210  MdtCablingData translation{};
211  if (!cabling->convert(readoutEle->measurementId(measHash), translation) ||
212  !cabling->getOnlineId(translation, msgStream())){
213  ATH_MSG_FATAL("Cabling translation failed");
214  return StatusCode::FAILURE;
215  }
216  m_cablingCSM.push_back(translation.csm);
217  m_cablingMROD.push_back(translation.mrod);
218  m_cablingTdcId.push_back(translation.tdcId);
219  m_cablingTdcCh.push_back(translation.channelId);
220  }
221  }
222  }
223 
224  return m_tree.fill(ctx) ? StatusCode::SUCCESS : StatusCode::FAILURE;
225 }
226 
227 }
228 
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
MdtIdHelper::multilayer
int multilayer(const Identifier &id) const
Access to components of the ID.
Definition: MdtIdHelper.cxx:727
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::MuonReadoutElement::msSector
const SpectrometerSector * msSector() const
Returns the pointer to the envelope volume enclosing all chambers in the sector.
MuonGMR4::MdtReadoutElement::numTubesInLay
unsigned int numTubesInLay() const
Returns the number of tubes per layer.
MuonGMR4::MdtReadoutElement::readOutPos
Amg::Vector3D readOutPos(const ActsTrk::GeometryContext &ctx, const Identifier &measId) const
Returns the global position of the readout card.
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
MuonGMR4::MdtReadoutElement::tubeLength
double tubeLength(const IdentifierHash &hash) const
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/src/MdtReadoutElement.cxx:185
initialize
void initialize()
Definition: run_EoverP.cxx:894
MuonGMR4::MdtReadoutElement::measurementHash
static IdentifierHash measurementHash(unsigned int layerNumber, unsigned int tubeNumber)
Transform the layer and tube number to the measurementHash.
MuonGMR4::MuonReadoutElement::chamberDesign
const std::string & chamberDesign() const
The chamber design refers to the construction parameters of a readout element.
ReadCellNoiseFromCool.cabling
cabling
Definition: ReadCellNoiseFromCool.py:154
MuonGMR4::MdtReadoutElement::activeTubeLength
double activeTubeLength(const IdentifierHash &hash) const
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/src/MdtReadoutElement.cxx:173
isValid
bool isValid(const T &p)
Av: we implement here an ATLAS-sepcific convention: all particles which are 99xxxxx are fine.
Definition: AtlasPID.h:872
SpectrometerSector.h
MuonGMR4::MdtReadoutElement::parameterBook::readoutSide
double readoutSide
Is the readout chip at positive or negative Z?
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/MdtReadoutElement.h:60
TRT::Hit::side
@ side
Definition: HitInfo.h:83
LArG4FSStartPointFilterLegacy.execute
execute
Definition: LArG4FSStartPointFilterLegacy.py:20
MuonGMR4::MdtReadoutElement::measurementId
Identifier measurementId(const IdentifierHash &measHash) const override final
Converts the measurement hash back to the full Identifier.
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/src/MdtReadoutElement.cxx:46
MuonGMR4::MdtReadoutElement::multilayer
unsigned int multilayer() const
Returns the multi layer of the MdtReadoutElement.
MuonGMR4::MdtReadoutElement::wireLength
double wireLength(const IdentifierHash &hash) const
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/src/MdtReadoutElement.cxx:188
GeometryContext.h
GeoModelMdtTest.h
MuonMDT_CablingMap
Definition: MuonMDT_CablingMap.h:28
calibdata.tube_id
tube_id
Definition: calibdata.py:29
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
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
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::MdtReadoutElement::numLayers
unsigned int numLayers() const
Returns the number of tube layer.
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
MdtIdHelper
Definition: MdtIdHelper.h:61
MuonGMR4::MuonReadoutElement::localToGlobalTrans
const Amg::Transform3D & localToGlobalTrans(const ActsTrk::GeometryContext &ctx) const
Returns the local to global transformation into the ATLAS coordinate system.
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/src/MuonReadoutElement.cxx:81
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
MdtCablingData
Definition: MdtCablingData.h:84
ActsTrk::GeometryContext
Definition: GeometryContext.h:28
WriteCalibToCool.swap
swap
Definition: WriteCalibToCool.py:94
MuonGMR4::MdtReadoutElement::innerTubeRadius
double innerTubeRadius() const
Returns the inner tube radius.
MuonGMR4::SpectrometerSector::globalToLocalTrans
Amg::Transform3D globalToLocalTrans(const ActsTrk::GeometryContext &gctx) const
Returns the global -> local transformation from the ATLAS global.
Definition: SpectrometerSector.cxx:78
python.PyKernel.detStore
detStore
Definition: PyKernel.py:41
MuonGMR4::MdtReadoutElement
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/MdtReadoutElement.h:18
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.
MuonGMR4::MdtReadoutElement::tubePitch
double tubePitch() const
Returns the pitch between 2 tubes in a layer.
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::center
Amg::Vector3D center(const ActsTrk::GeometryContext &ctx) const
Returns the detector center (Which is the same as the detector center of the first measurement layer)
MdtReadoutElement.h
GeoPrimitivesToStringConverter.h
MuonIdHelper::const_id_iterator
std::vector< Identifier >::const_iterator const_id_iterator
Definition: MuonIdHelper.h:140
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: MdtCalibInput.h:31
MuonGMR4::MuonReadoutElement::stationEta
int stationEta() const
Returns the stationEta (positive A site, negative O site)
MuonGMR4::MdtReadoutElement::getParameters
const parameterBook & getParameters() const
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/src/MdtReadoutElement.cxx:45
test_pyathena.counter
counter
Definition: test_pyathena.py:15
MuonGMR4::MuonReadoutElement::globalToLocalTrans
Amg::Transform3D globalToLocalTrans(const ActsTrk::GeometryContext &ctx) const
Transformations to translate between local <-> global coordinates.
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/src/MuonReadoutElement.cxx:78
MuonGMR4::MdtReadoutElement::isValid
bool isValid(const IdentifierHash &measHash) const
MuonGMR4::MuonReadoutElement::stationPhi
int stationPhi() const
Returns the stationPhi (1-8) -> sector (2*phi - (isSmall))
calibdata.tube
tube
Definition: calibdata.py:30
Identifier
Definition: IdentifierFieldParser.cxx:14