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 #ifndef SIMULATIONBASE
23 # include "Acts/Surfaces/TrapezoidBounds.hpp"
24 # include "Acts/Surfaces/LineBounds.hpp"
25 #endif
26 
27 using namespace CxxUtils;
28 using namespace ActsTrk;
29 
30 namespace MuonGMR4 {
32 
33 
34 StatusCode MdtReadoutGeomTool::loadDimensions(FactoryCache& facCache,
35  MdtReadoutElement::defineArgs& define) const {
36 
37  ATH_MSG_VERBOSE("Load dimensions of "<<m_idHelperSvc->toString(define.detElId)
38  <<std::endl<<std::endl<<m_geoUtilTool->dumpVolume(define.physVol));
39  const GeoShape* shape = m_geoUtilTool->extractShape(define.physVol);
40  if (!shape) {
41  ATH_MSG_FATAL("Failed to deduce a valid shape for "<<m_idHelperSvc->toString(define.detElId));
42  return StatusCode::FAILURE;
43  }
46  if (shape->typeID() == GeoTrd::getClassTypeID()) {
47  ATH_MSG_VERBOSE("Extracted shape "<<m_geoUtilTool->dumpShape(shape));
48  const GeoTrd* trd = static_cast<const GeoTrd*>(shape);
49  define.longHalfX = std::max(trd->getYHalfLength1(), trd->getYHalfLength2()) * Gaudi::Units::mm;
50  define.shortHalfX = std::min(trd->getYHalfLength1(), trd->getYHalfLength2())* Gaudi::Units::mm;
51  define.halfY = trd->getZHalfLength()* Gaudi::Units::mm;
52  define.halfHeight = std::max(trd->getXHalfLength1(), trd->getXHalfLength2()) * Gaudi::Units::mm;
53  } else {
54  ATH_MSG_FATAL("Unknown shape type "<<shape->type());
55  return StatusCode::FAILURE;
56  }
60  const MdtIdHelper& idHelper{m_idHelperSvc->mdtIdHelper()};
61  for (unsigned int ch = 1; ch < define.physVol->getNChildNodes(); ++ch) {
62  const GeoGraphNode* childNode = (*define.physVol->getChildNode(ch));
63  const GeoVPhysVol* childVol = dynamic_cast<const GeoVPhysVol*>(childNode);
64  if (!childVol || childVol->getLogVol()->getName() != "TubeLayerLog") {
65  continue;
66  }
67  const GeoTransform* trfNode = dynamic_cast<const GeoTransform*>(*define.physVol->getChildNode(ch-1));
68  if (!trfNode) {
69  ATH_MSG_FATAL("Expect a GeoTransform node right before the tubelayer node");
70  return StatusCode::FAILURE;
71  }
72  ATH_MSG_VERBOSE("Add new tube layer "<<m_idHelperSvc->toStringDetEl(define.detElId)<<
73  std::endl<<std::endl<<m_geoUtilTool->dumpVolume(childVol));
74  const Identifier tubeLayId = idHelper.channelID(define.detElId,
75  idHelper.multilayer(define.detElId),
76  define.tubeLayers.size() +1, 1);
77  MdtTubeLayerPtr newLay = std::make_unique<MdtTubeLayer>(childVol, trfNode, facCache.cutTubes[tubeLayId]);
78  define.tubeLayers.emplace_back(*facCache.tubeLayers.insert(newLay).first);
79 
80  const MdtTubeLayer& lay{*define.tubeLayers.back()};
83  bool chEndPlug{false};
84  for (unsigned int tube = 0 ; tube < lay.nTubes(); ++tube) {
85  constexpr std::string_view airTubeName{"airTube"};
86  PVConstLink tubeVol{lay.getTubeNode(tube)};
87  if (tubeVol->getLogVol()->getName() == airTubeName) {
88  define.removedTubes.insert(MdtReadoutElement::measurementHash(define.tubeLayers.size(), tube+1));
89  } else if (!chEndPlug) {
91  chEndPlug = true;
92  std::vector<physVolWithTrans> endPlugs = m_geoUtilTool->findAllLeafNodesByName(tubeVol, "Endplug");
93  if (endPlugs.empty()) {
95  continue;
96  }
97  const GeoShape* plugShape = m_geoUtilTool->extractShape(endPlugs[0].volume);
98  if (plugShape->typeID() != GeoTube::getClassTypeID()){
99  ATH_MSG_FATAL("The shape "<<m_geoUtilTool->dumpShape(plugShape)<<" is not a tube");
100  return StatusCode::FAILURE;
101  }
102  const GeoTube* plugTube = static_cast<const GeoTube*>(plugShape);
103  define.endPlugLength = plugTube->getZHalfLength();
104  }
105  }
106  }
107  define.readoutSide = facCache.readoutOnLeftSide.count(m_idHelperSvc->chamberId(define.detElId)) ? -1. : 1.;
108  return StatusCode::SUCCESS;
109 }
110 StatusCode MdtReadoutGeomTool::buildReadOutElements(MuonDetectorManager& mgr) {
111  ATH_CHECK(m_geoDbTagSvc.retrieve());
112  ATH_CHECK(m_idHelperSvc.retrieve());
113  ATH_CHECK(m_geoUtilTool.retrieve());
114  GeoModelIO::ReadGeoModel* sqliteReader = m_geoDbTagSvc->getSqliteReader();
115  if (!sqliteReader) {
116  ATH_MSG_FATAL("Error, the tool works exclusively from sqlite geometry inputs");
117  return StatusCode::FAILURE;
118  }
119  FactoryCache facCache{};
120  ATH_CHECK(readParameterBook(facCache));
121  const MdtIdHelper& idHelper{m_idHelperSvc->mdtIdHelper()};
122  // Get the list of full phys volumes from SQLite, and create detector elements
123  physNodeMap mapFPV = sqliteReader->getPublishedNodes<std::string, GeoFullPhysVol*>("Muon");
124 #ifndef SIMULATIONBASE
125  auto boundFactory = std::make_shared<Acts::SurfaceBoundFactory>();
126 #endif
127  for (auto& [key, pv] : mapFPV) {
134  std::vector<std::string> key_tokens = tokenize(key, "_");
135  if (key_tokens.size() != 5 ||
136  key_tokens[1].find("MDT") == std::string::npos)
137  continue;
138 
140  bool isValid{false};
141  define.detElId = idHelper.channelID(key_tokens[0].substr(0, 3),
142  atoi(key_tokens[2]),
143  atoi(key_tokens[3]),
144  atoi(key_tokens[4]), 1, 1, isValid);
145  if (!isValid) {
146  ATH_MSG_FATAL("Failed to build a good identifier out of " << key);
147  return StatusCode::FAILURE;
148  }
149  ATH_MSG_DEBUG("Key "<<key<<" brought us "<<m_idHelperSvc->toStringDetEl(define.detElId));
151  define.physVol = pv;
152  define.chambDesign = key_tokens[1];
153  define.alignTransform = m_geoUtilTool->findAlignableTransform(define.physVol);
154 
156  ParamBookTable::const_iterator book_itr = facCache.parBook.find(define.chambDesign);
157  if (book_itr == facCache.parBook.end()) {
158  ATH_MSG_FATAL("There is no chamber called "<<define.chambDesign);
159  return StatusCode::FAILURE;
160  }
161  static_cast<parameterBook&>(define) = book_itr->second;
162 #ifndef SIMULATIONBASE
163  define.boundFactory = boundFactory;
164  #endif
166  ATH_CHECK(loadDimensions(facCache, define));
167  std::unique_ptr<MdtReadoutElement> mdtDetectorElement = std::make_unique<MdtReadoutElement>(std::move(define));
168  ATH_CHECK(mgr.addMdtReadoutElement(std::move(mdtDetectorElement)));
169  }
170  return StatusCode::SUCCESS;
171 }
172 StatusCode MdtReadoutGeomTool::readParameterBook(FactoryCache& cache) const {
173  ServiceHandle<IRDBAccessSvc> accessSvc(m_geoDbTagSvc->getParamSvcName(),
174  name());
175  ATH_CHECK(accessSvc.retrieve());
176  IRDBRecordset_ptr paramTable = accessSvc->getRecordsetPtr("WMDT", "");
177  if (paramTable->size() == 0) {
178  ATH_MSG_FATAL("Empty parameter book table found");
179  return StatusCode::FAILURE;
180  }
181  ATH_MSG_VERBOSE("Found the " << paramTable->nodeName() << " ["
182  << paramTable->tagName() << "] table with "
183  << paramTable->size() << " records");
184  for (const IRDBRecord_ptr& record : *paramTable) {
186  pars.tubeWall = record->getDouble("TUBWAL") * Gaudi::Units::cm;
187  pars.tubePitch = record->getDouble("TUBPIT") * Gaudi::Units::cm;
188  pars.tubeInnerRad = record->getDouble("TUBRAD") * Gaudi::Units::cm;
189  pars.endPlugLength = record->getDouble("TUBDEA") * Gaudi::Units::cm;
190  pars.radLengthX0 = record->getDouble("X0");
191  unsigned int nLay = record->getInt("LAYMDT");
192  const std::string key {record->getString("WMDT_TYPE")};
193  ATH_MSG_DEBUG("Extracted parameters " <<pars<<" number of layers: "<<nLay<<" will be safed under key "<<key);
194  cache.parBook[key] = std::move(pars);
195  }
197  const MdtIdHelper& idHelper{m_idHelperSvc->mdtIdHelper()};
198  paramTable = accessSvc->getRecordsetPtr("MdtTubeROSides" ,"");
199  if (paramTable->size() == 0) {
200  ATH_MSG_FATAL("Empty parameter book table found");
201  return StatusCode::FAILURE;
202  }
203  ATH_MSG_VERBOSE("Found the " << paramTable->nodeName() << " ["
204  << paramTable->tagName() << "] table with "
205  << paramTable->size() << " records");
206  for (const IRDBRecord_ptr& record : *paramTable) {
207  const std::string stName = record->getString("stationName");
208  const int stEta = record->getInt("stationEta");
209  const int stPhi = record->getInt("stationPhi");
210  const int side = record->getInt("side");
211  if (side == -1) {
212  bool isValid{false};
213  cache.readoutOnLeftSide.insert(idHelper.elementID(stName,stEta,stPhi, isValid));
214  if (!isValid) {
215  ATH_MSG_FATAL("station "<<stName<<" eta: "<<stEta<<" phi: "<<stPhi<<" is unknown.");
216  return StatusCode::FAILURE;
217  }
218  }
219  }
221  paramTable = accessSvc->getRecordsetPtr("MdtCutTubes" ,"");
222  if (paramTable->size() == 0) {
223  ATH_MSG_INFO("No information about cut mdt tubes has been found. Skipping.");
224  return StatusCode::SUCCESS;
225  }
226  for (const IRDBRecord_ptr& record : *paramTable) {
227  const std::string stName = record->getString("stationName");
228  const int stEta = record->getInt("stationEta");
229  const int stPhi = record->getInt("stationPhi");
230  const int multiLay = record->getInt("multiLayer");
231  const int tubeLay = record->getInt("tubeLayer");
232  bool isValid{false};
233  const Identifier tubeId = idHelper.channelID(stName, stEta, stPhi, multiLay, tubeLay, 1 , isValid);
234  if (!isValid) {
235  ATH_MSG_FATAL("Failed to deduce valid Idnetifier "<<stName<<", "<<stEta<<", "<<stPhi<<","<<multiLay<<", "<<tubeLay);
236  return StatusCode::FAILURE;
237  }
238  FactoryCache::CutTubes cutTubes{};
239 
240  cutTubes.firstTube = record->getInt("firstTube");
241  cutTubes.lastTube = record->getInt("lastTube");
242  cutTubes.unCutHalfLength = record->getDouble("uncutHalfLength");
243  ATH_MSG_VERBOSE("Found new uncut tube set in "<<m_idHelperSvc->toString(tubeId)<<" tubes: ["
244  <<cutTubes.firstTube<<"-"<<cutTubes.lastTube<<"], length: "<< 2.*cutTubes.unCutHalfLength );
245  cache.cutTubes[tubeId].insert(std::move(cutTubes));
246 
247  }
248  return StatusCode::SUCCESS;
249 }
250 
251 } // namespace MuonGMR4
make_hlt_rep.pars
pars
Definition: make_hlt_rep.py:90
MuonGMR4::MdtReadoutElement::parameterBook::boundFactory
std::shared_ptr< Acts::SurfaceBoundFactory > boundFactory
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:64
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::removedTubes
std::set< IdentifierHash > removedTubes
List of tube places without tubes.
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/MdtReadoutElement.h:30
python.SystemOfUnits.mm
float mm
Definition: SystemOfUnits.py:98
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:27
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:58
min
constexpr double min()
Definition: ap_fixedTest.cxx:26
MuonGMR4::MdtReadoutGeomTool::FactoryCache
Definition: MdtReadoutGeomTool.h:38
Muon::MuonStationIndex::stName
const std::string & stName(StIndex index)
convert StIndex into a string
Definition: MuonStationIndex.cxx:104
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:872
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
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:56
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:19
EventPrimitivesToStringConverter.h
MuonGMR4::MdtReadoutElement::parameterBook
Set of parameters to describe a MDT chamber.
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/MdtReadoutElement.h:22
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
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:240
MuonGMR4::physVolWithTrans
IMuonGeoUtilityTool::physVolWithTrans physVolWithTrans
Definition: MdtReadoutGeomTool.cxx:31
MuonGMR4::MdtReadoutGeomTool::FactoryCache::readoutOnLeftSide
std::unordered_set< Identifier > readoutOnLeftSide
List of chambers that have the readout chip at negative Z.
Definition: MdtReadoutGeomTool.h:42
MuonGMR4::MdtReadoutElement::parameterBook::endPlugLength
double endPlugLength
Depth of the endplug into the active tube volume.
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/MdtReadoutElement.h:41
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:53
IRDBRecord.h
Definition of the abstract IRDBRecord interface.
GeoPrimitivesHelpers.h
IRDBRecord_ptr
std::unique_ptr< IRDBRecord > IRDBRecord_ptr
Definition: IRDBRecordset.h:23
python.changerun.pv
pv
Definition: changerun.py:79
MuonGMR4::MdtReadoutElement::parameterBook::longHalfX
double longHalfX
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/MdtReadoutElement.h:54
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: MSTrackingVolumeBuilder.cxx:25
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:30
ServiceHandle< IRDBAccessSvc >
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37
MuonGMR4::MdtReadoutElement::defineArgs
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/MdtReadoutElement.h:70
Identifier
Definition: IdentifierFieldParser.cxx:14
MuonGMR4::MdtReadoutGeomTool::FactoryCache::parBook
ParamBookTable parBook
Definition: MdtReadoutGeomTool.h:39