ATLAS Offline Software
MdtReadoutGeomTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include "MdtReadoutGeomTool.h"
6 
7 #include <GaudiKernel/SystemOfUnits.h>
10 
13 #include <GeoModelKernel/GeoFullPhysVol.h>
14 #include <GeoModelKernel/GeoPhysVol.h>
15 #include <GeoModelKernel/GeoTrd.h>
16 #include <GeoModelKernel/GeoTube.h>
17 
18 #include <GeoModelRead/ReadGeoModel.h>
21 
22 
24 #ifndef SIMULATIONBASE
25 # include "Acts/Surfaces/TrapezoidBounds.hpp"
26 # include "Acts/Surfaces/LineBounds.hpp"
27 #endif
28 
29 using namespace CxxUtils;
30 using namespace ActsTrk;
31 
32 namespace MuonGMR4 {
34 
35 
36 MdtReadoutGeomTool::MdtReadoutGeomTool(const std::string& type,
37  const std::string& name,
38  const IInterface* parent)
39  : base_class{type, name, parent} {}
40 
42  MdtReadoutElement::defineArgs& define) const {
43 
44  ATH_MSG_VERBOSE("Load dimensions of "<<m_idHelperSvc->toString(define.detElId)
45  <<std::endl<<std::endl<<m_geoUtilTool->dumpVolume(define.physVol));
46  const GeoShape* shape = m_geoUtilTool->extractShape(define.physVol);
47  if (!shape) {
48  ATH_MSG_FATAL("Failed to deduce a valid shape for "<<m_idHelperSvc->toString(define.detElId));
49  return StatusCode::FAILURE;
50  }
53  if (shape->typeID() == GeoTrd::getClassTypeID()) {
54  ATH_MSG_VERBOSE("Extracted shape "<<m_geoUtilTool->dumpShape(shape));
55  const GeoTrd* trd = static_cast<const GeoTrd*>(shape);
56  define.longHalfX = std::max(trd->getYHalfLength1(), trd->getYHalfLength2()) * Gaudi::Units::mm;
57  define.shortHalfX = std::min(trd->getYHalfLength1(), trd->getYHalfLength2())* Gaudi::Units::mm;
58  define.halfY = trd->getZHalfLength()* Gaudi::Units::mm;
59  define.halfHeight = std::max(trd->getXHalfLength1(), trd->getXHalfLength2()) * Gaudi::Units::mm;
60  } else {
61  ATH_MSG_FATAL("Unknown shape type "<<shape->type());
62  return StatusCode::FAILURE;
63  }
67  const MdtIdHelper& idHelper{m_idHelperSvc->mdtIdHelper()};
68  for (unsigned int ch = 1; ch < define.physVol->getNChildNodes(); ++ch) {
69  const GeoGraphNode* childNode = (*define.physVol->getChildNode(ch));
70  const GeoVPhysVol* childVol = dynamic_cast<const GeoVPhysVol*>(childNode);
71  if (!childVol || childVol->getLogVol()->getName() != "TubeLayerLog") {
72  continue;
73  }
74  const GeoTransform* trfNode = dynamic_cast<const GeoTransform*>(*define.physVol->getChildNode(ch-1));
75  if (!trfNode) {
76  ATH_MSG_FATAL("Expect a GeoTransform node right before the tubelayer node");
77  return StatusCode::FAILURE;
78  }
79  ATH_MSG_VERBOSE("Add new tube layer "<<m_idHelperSvc->toStringDetEl(define.detElId)<<
80  std::endl<<std::endl<<m_geoUtilTool->dumpVolume(childVol));
81  const Identifier tubeLayId = idHelper.channelID(define.detElId,
82  idHelper.multilayer(define.detElId),
83  define.tubeLayers.size() +1, 1);
84  MdtTubeLayerPtr newLay = std::make_unique<MdtTubeLayer>(childVol, trfNode, facCache.cutTubes[tubeLayId]);
85  define.tubeLayers.emplace_back(*facCache.tubeLayers.insert(newLay).first);
86 
87  const MdtTubeLayer& lay{*define.tubeLayers.back()};
90  bool chEndPlug{false};
91  for (unsigned int tube = 0 ; tube < lay.nTubes(); ++tube) {
92  constexpr std::string_view airTubeName{"airTube"};
93  PVConstLink tubeVol{lay.getTubeNode(tube)};
94  if (tubeVol->getLogVol()->getName() == airTubeName) {
95  define.removedTubes.insert(MdtReadoutElement::measurementHash(define.tubeLayers.size(), tube+1));
96  } else if (!chEndPlug) {
98  chEndPlug = true;
99  std::vector<physVolWithTrans> endPlugs = m_geoUtilTool->findAllLeafNodesByName(tubeVol, "Endplug");
100  if (endPlugs.empty()) {
102  continue;
103  }
104  const GeoShape* plugShape = m_geoUtilTool->extractShape(endPlugs[0].volume);
105  if (plugShape->typeID() != GeoTube::getClassTypeID()){
106  ATH_MSG_FATAL("The shape "<<m_geoUtilTool->dumpShape(plugShape)<<" is not a tube");
107  return StatusCode::FAILURE;
108  }
109  const GeoTube* plugTube = static_cast<const GeoTube*>(plugShape);
110  define.endPlugLength = plugTube->getZHalfLength();
111  }
112  }
113  }
114  define.readoutSide = facCache.readoutOnLeftSide.count(m_idHelperSvc->chamberId(define.detElId)) ? -1. : 1.;
115  return StatusCode::SUCCESS;
116 }
118  ATH_CHECK(m_geoDbTagSvc.retrieve());
119  ATH_CHECK(m_idHelperSvc.retrieve());
120  ATH_CHECK(m_geoUtilTool.retrieve());
121  GeoModelIO::ReadGeoModel* sqliteReader = m_geoDbTagSvc->getSqliteReader();
122  if (!sqliteReader) {
123  ATH_MSG_FATAL("Error, the tool works exclusively from sqlite geometry inputs");
124  return StatusCode::FAILURE;
125  }
126  FactoryCache facCache{};
127  ATH_CHECK(readParameterBook(facCache));
128  const MdtIdHelper& idHelper{m_idHelperSvc->mdtIdHelper()};
129  // Get the list of full phys volumes from SQLite, and create detector elements
130  physNodeMap mapFPV = sqliteReader->getPublishedNodes<std::string, GeoFullPhysVol*>("Muon");
131 #ifndef SIMULATIONBASE
132  SurfaceBoundSetPtr<Acts::LineBounds> tubeBounds = std::make_shared<SurfaceBoundSet<Acts::LineBounds>>();
133  SurfaceBoundSetPtr<Acts::TrapezoidBounds> layerBounds = std::make_shared<SurfaceBoundSet<Acts::TrapezoidBounds>>();
134 #endif
135  for (auto& [key, pv] : mapFPV) {
142  std::vector<std::string> key_tokens = tokenize(key, "_");
143  if (key_tokens.size() != 5 ||
144  key_tokens[1].find("MDT") == std::string::npos)
145  continue;
146 
148  bool isValid{false};
149  define.detElId = idHelper.channelID(key_tokens[0].substr(0, 3),
150  atoi(key_tokens[2]),
151  atoi(key_tokens[3]),
152  atoi(key_tokens[4]), 1, 1, isValid);
153  if (!isValid) {
154  ATH_MSG_FATAL("Failed to build a good identifier out of " << key);
155  return StatusCode::FAILURE;
156  }
157  ATH_MSG_DEBUG("Key "<<key<<" brought us "<<m_idHelperSvc->toStringDetEl(define.detElId));
159  define.physVol = pv;
160  define.chambDesign = key_tokens[1];
161  define.alignTransform = m_geoUtilTool->findAlignableTransform(define.physVol);
162 
164  ParamBookTable::const_iterator book_itr = facCache.parBook.find(define.chambDesign);
165  if (book_itr == facCache.parBook.end()) {
166  ATH_MSG_FATAL("There is no chamber called "<<define.chambDesign);
167  return StatusCode::FAILURE;
168  }
169  static_cast<parameterBook&>(define) = book_itr->second;
170 #ifndef SIMULATIONBASE
171  define.tubeBounds = tubeBounds;
172  define.layerBounds = layerBounds;
173  #endif
175  ATH_CHECK(loadDimensions(facCache, define));
176  std::unique_ptr<MdtReadoutElement> mdtDetectorElement = std::make_unique<MdtReadoutElement>(std::move(define));
177  ATH_CHECK(mgr.addMdtReadoutElement(std::move(mdtDetectorElement)));
178  }
179  return StatusCode::SUCCESS;
180 }
182  ServiceHandle<IRDBAccessSvc> accessSvc(m_geoDbTagSvc->getParamSvcName(),
183  name());
184  ATH_CHECK(accessSvc.retrieve());
185  IRDBRecordset_ptr paramTable = accessSvc->getRecordsetPtr("WMDT", "");
186  if (paramTable->size() == 0) {
187  ATH_MSG_FATAL("Empty parameter book table found");
188  return StatusCode::FAILURE;
189  }
190  ATH_MSG_VERBOSE("Found the " << paramTable->nodeName() << " ["
191  << paramTable->tagName() << "] table with "
192  << paramTable->size() << " records");
193  for (const IRDBRecord_ptr& record : *paramTable) {
195  pars.tubeWall = record->getDouble("TUBWAL") * Gaudi::Units::cm;
196  pars.tubePitch = record->getDouble("TUBPIT") * Gaudi::Units::cm;
197  pars.tubeInnerRad = record->getDouble("TUBRAD") * Gaudi::Units::cm;
198  pars.endPlugLength = record->getDouble("TUBDEA") * Gaudi::Units::cm;
199  pars.radLengthX0 = record->getDouble("X0");
200  unsigned int nLay = record->getInt("LAYMDT");
201  const std::string key {record->getString("WMDT_TYPE")};
202  ATH_MSG_DEBUG("Extracted parameters " <<pars<<" number of layers: "<<nLay<<" will be safed under key "<<key);
203  cache.parBook[key] = std::move(pars);
204  }
206  const MdtIdHelper& idHelper{m_idHelperSvc->mdtIdHelper()};
207  paramTable = accessSvc->getRecordsetPtr("MdtTubeROSides" ,"");
208  if (paramTable->size() == 0) {
209  ATH_MSG_FATAL("Empty parameter book table found");
210  return StatusCode::FAILURE;
211  }
212  ATH_MSG_VERBOSE("Found the " << paramTable->nodeName() << " ["
213  << paramTable->tagName() << "] table with "
214  << paramTable->size() << " records");
215  for (const IRDBRecord_ptr& record : *paramTable) {
216  const std::string stName = record->getString("stationName");
217  const int stEta = record->getInt("stationEta");
218  const int stPhi = record->getInt("stationPhi");
219  const int side = record->getInt("side");
220  if (side == -1) {
221  bool isValid{false};
222  cache.readoutOnLeftSide.insert(idHelper.elementID(stName,stEta,stPhi, isValid));
223  if (!isValid) {
224  ATH_MSG_FATAL("station "<<stName<<" eta: "<<stEta<<" phi: "<<stPhi<<" is unknown.");
225  return StatusCode::FAILURE;
226  }
227  }
228  }
230  paramTable = accessSvc->getRecordsetPtr("MdtCutTubes" ,"");
231  if (paramTable->size() == 0) {
232  ATH_MSG_INFO("No information about cut mdt tubes has been found. Skipping.");
233  return StatusCode::SUCCESS;
234  }
235  for (const IRDBRecord_ptr& record : *paramTable) {
236  const std::string stName = record->getString("stationName");
237  const int stEta = record->getInt("stationEta");
238  const int stPhi = record->getInt("stationPhi");
239  const int multiLay = record->getInt("multiLayer");
240  const int tubeLay = record->getInt("tubeLayer");
241  bool isValid{false};
242  const Identifier tubeId = idHelper.channelID(stName, stEta, stPhi, multiLay, tubeLay, 1 , isValid);
243  if (!isValid) {
244  ATH_MSG_FATAL("Failed to deduce valid Idnetifier "<<stName<<", "<<stEta<<", "<<stPhi<<","<<multiLay<<", "<<tubeLay);
245  return StatusCode::FAILURE;
246  }
247  FactoryCache::CutTubes cutTubes{};
248 
249  cutTubes.firstTube = record->getInt("firstTube");
250  cutTubes.lastTube = record->getInt("lastTube");
251  cutTubes.unCutHalfLength = record->getDouble("uncutHalfLength");
252  ATH_MSG_VERBOSE("Found new uncut tube set in "<<m_idHelperSvc->toString(tubeId)<<" tubes: ["
253  <<cutTubes.firstTube<<"-"<<cutTubes.lastTube<<"], length: "<< 2.*cutTubes.unCutHalfLength );
254  cache.cutTubes[tubeId].insert(std::move(cutTubes));
255 
256  }
257  return StatusCode::SUCCESS;
258 }
259 
260 } // namespace MuonGMR4
make_hlt_rep.pars
pars
Definition: make_hlt_rep.py:90
GeoModel::TransientConstSharedPtr
The TransientConstSharedPtr allows non-const access if the pointer itself is non-const but in the con...
Definition: TransientConstSharedPtr.h:13
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
sendEI_SPB.ch
ch
Definition: sendEI_SPB.py:35
MuonGMR4::MdtReadoutGeomTool::FactoryCache::tubeLayers
MdtTubeLayerSet tubeLayers
Definition: MdtReadoutGeomTool.h:46
MuonGMR4::MdtReadoutElement::parameterBook::tubeBounds
ActsTrk::SurfaceBoundSetPtr< Acts::LineBounds > tubeBounds
Sets of surface bounds which is shared amongst all readout elements used to assign the same bound obj...
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/MdtReadoutElement.h:69
MuonGMR4::MdtReadoutElement::parameterBook::removedTubes
std::set< IdentifierHash > removedTubes
List of tube places without tubes.
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/MdtReadoutElement.h:35
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
MuonGMR4::MuonDetectorManager
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/MuonDetectorManager.h:62
MdtReadoutGeomTool.h
MuonGMR4::MdtReadoutElement::parameterBook::tubeLayers
std::vector< MdtTubeLayerPtr > tubeLayers
Vector defining the position of all tubes in each tube layer.
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/MdtReadoutElement.h:32
max
constexpr double max()
Definition: ap_fixedTest.cxx:33
CxxUtils::tokenize
std::vector< std::string > tokenize(const std::string &the_str, std::string_view delimiters)
Splits the string into smaller substrings.
Definition: Control/CxxUtils/Root/StringUtils.cxx:15
MuonGMR4::MdtReadoutElement::parameterBook::halfHeight
double halfHeight
Height of the chamber ~ number of layers.
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/MdtReadoutElement.h:63
min
constexpr double min()
Definition: ap_fixedTest.cxx:26
MuonGMR4::MdtReadoutElement::measurementHash
static IdentifierHash measurementHash(unsigned int layerNumber, unsigned int tubeNumber)
Transform the layer and tube number to the measurementHash.
MuonGMR4::MdtReadoutGeomTool::FactoryCache
Definition: MdtReadoutGeomTool.h:38
SurfaceBoundSet.h
MuonGMR4::MdtTubeLayer
Helper struct to retrieve the tube lengths and the tube centers directly from the GeoModel tree.
Definition: MdtTubeLayer.h:28
MuonGMR4::MdtReadoutGeomTool::FactoryCache::cutTubes
std::unordered_map< Identifier, CutTubeSet > cutTubes
Definition: MdtReadoutGeomTool.h:45
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:620
MuonGMR4::MdtReadoutGeomTool::m_geoDbTagSvc
ServiceHandle< IGeoDbTagSvc > m_geoDbTagSvc
Definition: MdtReadoutGeomTool.h:31
MuonGMR4::MdtReadoutGeomTool::readParameterBook
StatusCode readParameterBook(FactoryCache &facCache) const
Retrieves the auxillary tables from the database.
Definition: MdtReadoutGeomTool.cxx:181
MuonGMR4::MdtReadoutGeomTool::m_geoUtilTool
PublicToolHandle< IMuonGeoUtilityTool > m_geoUtilTool
Definition: MdtReadoutGeomTool.h:34
MuonGMR4::MdtReadoutElement::parameterBook::readoutSide
double readoutSide
Is the readout chip at positive or negative Z?
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/MdtReadoutElement.h:65
TRT::Hit::side
@ side
Definition: HitInfo.h:83
BchCleanup.mgr
mgr
Definition: BchCleanup.py:294
cm
const double cm
Definition: Simulation/ISF/ISF_FastCaloSim/ISF_FastCaloSimParametrization/tools/FCAL_ChannelMap.cxx:25
MuonGMR4::MdtReadoutElement::parameterBook::halfY
double halfY
Length ~ number of tubes.
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/MdtReadoutElement.h:61
IRDBAccessSvc.h
Definition of the abstract IRDBAccessSvc interface.
MuonGMR4
The ReadoutGeomCnvAlg converts the Run4 Readout geometry build from the GeoModelXML into the legacy M...
Definition: MdtCalibInput.h:20
EventPrimitivesToStringConverter.h
MuonGMR4::MdtReadoutElement::parameterBook
Set of parameters to describe a MDT chamber.
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/MdtReadoutElement.h:27
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
CxxUtils
Definition: aligned_vector.h:29
MuonGMR4::MdtTubeLayer::CutTubes
Constructor taking the GeoModel parent node of the tube nodes.
Definition: MdtTubeLayer.h:36
MuonDetectorManager.h
MuonGMR4::MdtTubeLayer::CutTubes::firstTube
unsigned int firstTube
First tube of the cut.
Definition: MdtTubeLayer.h:38
MdtIdHelper
Definition: MdtIdHelper.h:61
test_pyathena.parent
parent
Definition: test_pyathena.py:15
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
IRDBRecordset_ptr
std::shared_ptr< IRDBRecordset > IRDBRecordset_ptr
Definition: IRDBAccessSvc.h:25
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
MuonGMR4::MdtReadoutGeomTool::buildReadOutElements
StatusCode buildReadOutElements(MuonDetectorManager &mgr) override final
Definition: MdtReadoutGeomTool.cxx:117
MuonGMR4::MdtReadoutGeomTool::loadDimensions
StatusCode loadDimensions(FactoryCache &facCache, MdtReadoutElement::defineArgs &args) const
Loads the chamber dimensions from GeoModel.
Definition: MdtReadoutGeomTool.cxx:41
MuonGMR4::physVolWithTrans
IMuonGeoUtilityTool::physVolWithTrans physVolWithTrans
Definition: MdtReadoutGeomTool.cxx:33
MuonGMR4::MdtReadoutGeomTool::FactoryCache::readoutOnLeftSide
std::unordered_set< Identifier > readoutOnLeftSide
List of chambers that have the readout chip at negative Z.
Definition: MdtReadoutGeomTool.h:42
python.SystemOfUnits.mm
int mm
Definition: SystemOfUnits.py:83
MuonGMR4::MdtReadoutElement::parameterBook::endPlugLength
double endPlugLength
Depth of the endplug into the active tube volume.
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/MdtReadoutElement.h:46
MuonGMR4::MdtReadoutElement::parameterBook::shortHalfX
double shortHalfX
The chambers have either a rectangular or a trapezoidal shape to first approximation.
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/MdtReadoutElement.h:58
IRDBRecord.h
Definition of the abstract IRDBRecord interface.
GeoPrimitivesHelpers.h
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
IRDBRecord_ptr
std::unique_ptr< IRDBRecord > IRDBRecord_ptr
Definition: IRDBRecordset.h:23
python.changerun.pv
pv
Definition: changerun.py:81
MuonGMR4::MdtReadoutElement::parameterBook::longHalfX
double longHalfX
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/MdtReadoutElement.h:59
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
MuonGMR4::MuonReadoutElement::defineArgs::detElId
Identifier detElId
ATLAS identifier.
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/MuonReadoutElement.h:51
ActsTrk
The AlignStoreProviderAlg loads the rigid alignment corrections and pipes them through the readout ge...
Definition: MuonDetectorBuilderTool.cxx:54
ActsTrk::SurfaceBoundSetPtr
std::shared_ptr< SurfaceBoundSet< BoundType > > SurfaceBoundSetPtr
Aberivation to create a new SurfaceBoundSetPtr.
Definition: Tracking/Acts/ActsGeoUtils/ActsGeoUtils/Defs.h:19
IRDBRecordset.h
Definition of the abstract IRDBRecordset interface.
MuonGMR4::MuonReadoutElement::defineArgs::physVol
GeoIntrusivePtr< GeoVFullPhysVol > physVol
Pointer to the underlying physical volume in GeoModel.
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/MuonReadoutElement.h:45
calibdata.tube
tube
Definition: calibdata.py:31
MuonGMR4::MdtReadoutGeomTool::m_idHelperSvc
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
Definition: MdtReadoutGeomTool.h:28
ServiceHandle< IRDBAccessSvc >
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37
MuonGMR4::MdtReadoutElement::defineArgs
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/MdtReadoutElement.h:76
Identifier
Definition: IdentifierFieldParser.cxx:14
MuonGMR4::MdtReadoutGeomTool::FactoryCache::parBook
ParamBookTable parBook
Definition: MdtReadoutGeomTool.h:39