ATLAS Offline Software
MmReadoutGeomTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include "MmReadoutGeomTool.h"
6 
7 #include <GaudiKernel/SystemOfUnits.h>
10 
13 #include <GeoModelKernel/GeoFullPhysVol.h>
14 #include <GeoModelKernel/GeoPhysVol.h>
15 #include <GeoModelKernel/GeoTrd.h>
16 
17 #include <GeoModelRead/ReadGeoModel.h>
20 
21 
22 #ifndef SIMULATIONBASE
23 # include "Acts/Utilities/BoundFactory.hpp"
24 #endif
25 
26 using namespace ActsTrk;
27 using namespace CxxUtils;
28 
29 
30 
31 namespace MuonGMR4 {
32 
33 
35 
36 StatusCode MmReadoutGeomTool::loadDimensions(MmReadoutElement::defineArgs& define,
37  FactoryCache& factoryCache) {
38 
39  ATH_MSG_VERBOSE("Load dimensions of "<<m_idHelperSvc->toString(define.detElId)
40  <<std::endl<<std::endl<<m_geoUtilTool->dumpVolume(define.physVol->getParent()));
41  const GeoShape* shape = m_geoUtilTool->extractShape(define.physVol);
42  if (!shape) {
43  ATH_MSG_FATAL("Failed to deduce a valid shape for "<<m_idHelperSvc->toString(define.detElId));
44  return StatusCode::FAILURE;
45  }
46  ATH_MSG_DEBUG("Extracted shape "<<m_geoUtilTool->dumpShape(shape));
48  if (shape->typeID() != GeoTrd::getClassTypeID()) {
49  ATH_MSG_FATAL(__FILE__<<":"<<__LINE__<<" expect shape to be a trapezoid but it's "<<m_geoUtilTool->dumpShape(shape));
50  return StatusCode::FAILURE;
51  }
52 
53  const GeoTrd* trapezoid = static_cast<const GeoTrd*>(shape);
54  define.halfThickness = trapezoid->getXHalfLength1() * Gaudi::Units::mm;
55  define.halfShortWidth = trapezoid->getYHalfLength1() * Gaudi::Units::mm;
56  define.halfLongWidth = trapezoid->getYHalfLength2() * Gaudi::Units::mm;
57  define.halfHeight = trapezoid->getZHalfLength() * Gaudi::Units::mm;
58 
59  ATH_MSG_DEBUG("Extracted parameters "
60  <<", halfThickness: "<<define.halfThickness<<"/"
61  <<", halfShortWidth : "<<define.halfShortWidth<<"/"
62  <<", halfLongWidth : "<<define.halfLongWidth<<"/"
63  <<", halfHeight : "<<define.halfHeight);
64 
65 
66  std::vector<physVolWithTrans> allGasGaps = m_geoUtilTool->findAllLeafNodesByName(define.physVol, "actMicroMegaGas");
67  if (allGasGaps.empty()) {
68  ATH_MSG_FATAL("The volume "<<m_idHelperSvc->toStringDetEl(define.detElId)<<" does not have any children actMicroMegaGas");
69  return StatusCode::FAILURE;
70  }
71 
73  define.nGasGaps = allGasGaps.size();
74  ATH_MSG_VERBOSE("The number of gasGaps are: " << define.nGasGaps);
75 
76  FactoryCache::ParamBookTable::const_iterator parBookItr = factoryCache.parameterBook.find(define.chambDesign);
77  if (parBookItr == factoryCache.parameterBook.end()) {
78  ATH_MSG_FATAL("The chamber "<<define.chambDesign<<" is not part of the WMM table");
79  return StatusCode::FAILURE;
80  }
81 
82  const wMMTable& paramBook{parBookItr->second};
83 
84  define.readoutSide = paramBook.readoutSide;
85 
86  for (std::size_t gap = 0; gap < allGasGaps.size(); ++gap) {
87 
88  auto& gapVol = allGasGaps[gap];
89  const Amg::Vector3D posGapI = gapVol.transform.translation();
90 
91  //Check sorting of gasGaps. For Q1 --> Eta layers should be first. For Q2--> Stereo Layers should be first.
92  //Add ATH_MSG_INFO("**************************************"); before the gasGap loop.
93  ATH_MSG_DEBUG("quadruplet " << define.chambDesign.substr(6,7) << " stereoAngle : " << paramBook.stereoAngle.at(gap) << " totalStrips " << paramBook.totalActiveStrips.at(gap) << " GasGAP POS X : " << posGapI.x() );
94 
95  const GeoShape* gapShape = m_geoUtilTool->extractShape(gapVol.volume);
96  if (gapShape->typeID() != GeoTrd::getClassTypeID()) {
97  ATH_MSG_FATAL("Failed to extract a geo shape");
98  return StatusCode::FAILURE;
99  }
100 
101  bool isStereo = static_cast<bool>(paramBook.stereoAngle.at(gap));
102 
103  const GeoTrd* gapTrd = static_cast<const GeoTrd*>(gapShape);
104  ATH_MSG_DEBUG("MicroMegas Gas gap dimensions "<<m_geoUtilTool->dumpShape(gapTrd));
105  double gapHalfHeight = gapTrd->getZHalfLength();
106  double gapHalfShortY = std::min(gapTrd->getYHalfLength1(), gapTrd->getYHalfLength2());
107  double gapHalfLongY = std::max(gapTrd->getYHalfLength1(), gapTrd->getYHalfLength2());
108 
109  double firstStripPos{0.};
110  int firstActiveStrip{0};
111  if (isStereo) {
112  firstActiveStrip = paramBook.nMissedBottomStereo + 1;
113  firstStripPos = -gapHalfHeight + (1.*(firstActiveStrip - paramBook.nMissedBottomEta) -0.5)* paramBook.stripPitch;
114  } else {
115  firstActiveStrip = paramBook.nMissedBottomEta + 1;
116  firstStripPos = -gapHalfHeight + 0.5*paramBook.stripPitch;
117  }
118  /*The origin of the chamber/gasGap axes system is located at the center of the chamber.
119  We subtract the HalfLength across the Z axis to transform from the center to the origin of the trapezoid
120  The we add the strip pitch to reach the position of the first strip.*/
121  StripDesignPtr stripDesign = std::make_unique<StripDesign>();
122 
123  stripDesign->defineStripLayout(firstStripPos * Amg::Vector2D::UnitX(),
124  paramBook.stripPitch,
125  paramBook.stripWidth,
126  paramBook.totalActiveStrips.at(gap),
127  firstActiveStrip);
128 
130  stripDesign->defineTrapezoid(gapHalfShortY, gapHalfLongY, gapHalfHeight, paramBook.stereoAngle.at(gap));
131 
132  //Necessary strip layer rotation to match the alignment coordinate system
133  Amg::Transform3D stripLayerRotation{gapVol.transform
135  * Amg::getRotateZ3D(stripDesign->stereoAngle())};
136 
137 
138  stripDesign = (*factoryCache.stripDesigns.emplace(stripDesign).first);
139  auto stripLayer = std::make_unique<StripLayer>(factoryCache.trfNodeMaker.makeTransform(stripLayerRotation),
140  stripDesign,
141  IdentifierHash{static_cast<unsigned int>(gap)});
142  define.layers.push_back(*factoryCache.stripLayers.emplace(std::move(stripLayer)).first);
143  } //end of gas gap loop
144  return StatusCode::SUCCESS;
145 }
146 
147 StatusCode MmReadoutGeomTool::buildReadOutElements(MuonDetectorManager& mgr) {
148  ATH_CHECK(m_geoDbTagSvc.retrieve());
149  ATH_CHECK(m_idHelperSvc.retrieve());
150  ATH_CHECK(m_geoUtilTool.retrieve());
151  GeoModelIO::ReadGeoModel* sqliteReader = m_geoDbTagSvc->getSqliteReader();
152  if (!sqliteReader) {
153  ATH_MSG_FATAL("Error, the tool works exclusively from sqlite geometry inputs");
154  return StatusCode::FAILURE;
155  }
156 
157  FactoryCache facCache{};
158  ATH_CHECK(readParameterBook(facCache));
159 
160 
161  const MmIdHelper& idHelper{m_idHelperSvc->mmIdHelper()};
162  // Get the list of full phys volumes from SQLite, and create detector elements
164  physNodeMap mapFPV = sqliteReader->getPublishedNodes<std::string, GeoFullPhysVol*>("Muon");
165 #ifndef SIMULATIONBASE
166  auto layerBounds= std::make_shared<Acts::SurfaceBoundFactory>();
167 #endif
168 
169  for (auto& [key, pv] : mapFPV) {
172  // e.g. MM_SM1Q2_1_6_1 . It's the "type" Attribute in the new GeoModel XML files.
173  std::vector<std::string> key_tokens = tokenize(key, "_");
174 
175  if (key_tokens[0].find("MM") == std::string::npos){
176  continue;
177  }
178  ATH_MSG_DEBUG("Retrieving MicroMegas Quadruplet : " << key );
179 
181  bool isValid{false};
182  define.detElId = idHelper.channelID(key_tokens[1][0] == 'S' ? "MMS" : "MML", // Replace <MM> string part with <MMS> or <MML> to match the Identifier.
183  atoi(key_tokens[2].c_str()), // Eta index
184  atoi(key_tokens[3].c_str()), // Phi index (from 0 to 7 in GeoModel). needs a +1
185  atoi(key_tokens[4].c_str()), 1, 1, isValid); //Copy Number which reflects the number of the multilayer.
186  // THen the two 1s are reflecting gasGap and channel Number. They can be set to 1s as this is all we need
187  // to get the Identifier for the multilayer.
188 
189 
190  if (!isValid) {
191  ATH_MSG_FATAL("Failed to build a good identifier out of " << key);
192  return StatusCode::FAILURE;
193  }
194 
195  ATH_MSG_DEBUG("Key "<<key<<" brought us "<<m_idHelperSvc->toStringDetEl(define.detElId));
196  define.physVol = pv;
197  define.chambDesign = key_tokens[0]+"_"+key_tokens[1]; // Recover the string denoted in WMM tables. e.g. chambDesign = "MM_SM1Q2"
198  define.alignTransform = m_geoUtilTool->findAlignableTransform(define.physVol);
199  ATH_CHECK(loadDimensions(define, facCache));
200 #ifndef SIMULATIONBASE
201  define.layerBounds = layerBounds;
202 #endif
203  std::unique_ptr<MmReadoutElement> readoutEle = std::make_unique<MmReadoutElement>(std::move(define));
204  ATH_CHECK(mgr.addMmReadoutElement(std::move(readoutEle)));
205  }
206  return StatusCode::SUCCESS;
207 }
208 
209 
210 
211 StatusCode MmReadoutGeomTool::readParameterBook(FactoryCache& cache) {
212 
213  ServiceHandle<IRDBAccessSvc> accessSvc(m_geoDbTagSvc->getParamSvcName(), name());
214  ATH_CHECK(accessSvc.retrieve());
215  IRDBRecordset_ptr paramTable = accessSvc->getRecordsetPtr("WMM", "");
216  if (paramTable->size() == 0) {
217  ATH_MSG_FATAL("Empty parameter book table found");
218  return StatusCode::FAILURE;
219  }
220  ATH_MSG_VERBOSE("Found the " << paramTable->nodeName() << " ["
221  << paramTable->tagName() << "] table with "
222  << paramTable->size() << " records");
223 
224 
225 
226  for (const IRDBRecord_ptr& record : *paramTable) {
227  const std::string chambType = record->getString("WMM_TYPE");
228  wMMTable& parBook = cache.parameterBook[chambType];
229  parBook.stripPitch = record->getDouble("stripPitch") ;
230  parBook.stripWidth = record->getDouble("stripWidth") ;
231  parBook.stereoAngle = tokenizeDouble(record->getString("stereoAngle"), ";");
232  parBook.totalActiveStrips = tokenizeInt(record->getString("totalActiveStrips"), ";");
233  parBook.readoutSide = tokenizeInt(record->getString("readoutSide"),";");
234  parBook.nMissedBottomEta = record->getInt("nMissedBottomEta");
235  parBook.nMissedBottomStereo = record->getInt("nMissedBottomStereo");
236  parBook.nMissedTopEta = record->getInt("nMissedTopEta");
237  parBook.distBotFrameStrip = record->getDouble("dR_botFrame1stStrip");
238 
239  ATH_MSG_VERBOSE("Extracted parameters for chamber "<<chambType
240  <<", stripPitch: "<<parBook.stripPitch
241  <<", stripWidth: "<<parBook.stripWidth
242  <<", steroAngle: "<<parBook.stereoAngle
243  <<", totalActiveStrips: "<<parBook.totalActiveStrips
244  <<", readoutSites: "<<parBook.readoutSide);
245  }
246 
247  return StatusCode::SUCCESS;
248 }
249 
250 
251 
252 
253 
254 } // namespace MuonGMR4
GeoModel::TransientConstSharedPtr< StripDesign >
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
CxxUtils::tokenizeDouble
std::vector< double > tokenizeDouble(const std::string &the_str, std::string_view delimiter)
Definition: Control/CxxUtils/Root/StringUtils.cxx:34
python.SystemOfUnits.mm
float mm
Definition: SystemOfUnits.py:98
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
MuonGMR4::MuonDetectorManager
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/MuonDetectorManager.h:62
MuonGMR4::MmReadoutGeomTool::wMMTable::readoutSide
std::vector< int > readoutSide
Definition: MmReadoutGeomTool.h:43
CxxUtils::tokenizeInt
std::vector< int > tokenizeInt(const std::string &the_str, std::string_view delimiter)
Definition: Control/CxxUtils/Root/StringUtils.cxx:55
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::MmReadoutGeomTool::wMMTable::stripWidth
double stripWidth
Definition: MmReadoutGeomTool.h:39
min
constexpr double min()
Definition: ap_fixedTest.cxx:26
MuonGMR4::MmReadoutGeomTool::wMMTable::stereoAngle
std::vector< double > stereoAngle
Definition: MmReadoutGeomTool.h:41
MuonGMR4::MmReadoutGeomTool::FactoryCache::parameterBook
ParamBookTable parameterBook
Definition: MmReadoutGeomTool.h:59
deg
#define deg
Definition: SbPolyhedron.cxx:17
MuonGMR4::MmReadoutElement::parameterBook::halfThickness
double halfThickness
Trapezoid dimensions of MicroMegas envelope half-thickness along z-axis.
Definition: MmReadoutElement.h:26
MuonGMR4::MmReadoutGeomTool::FactoryCache
Cache object to the wMMTable & store stripDesigns & layers to make the information available througho...
Definition: MmReadoutGeomTool.h:53
MuonGMR4::MmReadoutElement::parameterBook::readoutSide
std::vector< int > readoutSide
Readout sides.
Definition: MmReadoutElement.h:36
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::MmReadoutElement::parameterBook::halfShortWidth
double halfShortWidth
width of the lower edge
Definition: MmReadoutElement.h:28
CaloSwCorrections.gap
def gap(flags, cells_name, *args, **kw)
Definition: CaloSwCorrections.py:212
Amg::getRotateZ3D
Amg::Transform3D getRotateZ3D(double angle)
get a rotation transformation around Z-axis
Definition: GeoPrimitivesHelpers.h:270
BchCleanup.mgr
mgr
Definition: BchCleanup.py:294
MuonGMR4::MmReadoutElement::parameterBook::nGasGaps
unsigned int nGasGaps
number of gasGaps
Definition: MmReadoutElement.h:34
MuonGMR4::MmReadoutGeomTool::wMMTable::totalActiveStrips
std::vector< int > totalActiveStrips
Definition: MmReadoutGeomTool.h:42
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::MmReadoutGeomTool::wMMTable::distBotFrameStrip
double distBotFrameStrip
Definition: MmReadoutGeomTool.h:40
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::MmReadoutElement::parameterBook::halfHeight
double halfHeight
length in the radial direction
Definition: MmReadoutElement.h:32
MuonGMR4::MmReadoutGeomTool::wMMTable::stripPitch
double stripPitch
Definition: MmReadoutGeomTool.h:38
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
CxxUtils
Definition: aligned_vector.h:29
MuonDetectorManager.h
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
MuonGMR4::MmReadoutGeomTool::FactoryCache::trfNodeMaker
GeoDeDuplicator trfNodeMaker
Helper object to turn Amg::Transforms into GeoModel tree transform nodes.
Definition: MmReadoutGeomTool.h:61
MuonGMR4::MmReadoutElement::parameterBook::halfLongWidth
double halfLongWidth
width of the upper edge
Definition: MmReadoutElement.h:30
IRDBRecordset_ptr
std::shared_ptr< IRDBRecordset > IRDBRecordset_ptr
Definition: IRDBAccessSvc.h:25
MuonGMR4::MmReadoutElement::parameterBook::layers
std::vector< StripLayerPtr > layers
Pointers to the strip layers.
Definition: MmReadoutElement.h:38
MuonGMR4::MuonReadoutElement::defineArgs::chambDesign
std::string chambDesign
chamber design name as it's occuring in the parameter book tables E.g. BMS5, RPC10,...
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/MuonReadoutElement.h:49
MuonGMR4::MmReadoutGeomTool::FactoryCache::stripLayers
std::set< StripLayerPtr, StripLayerSorter > stripLayers
Definition: MmReadoutGeomTool.h:57
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
MuonGMR4::physVolWithTrans
IMuonGeoUtilityTool::physVolWithTrans physVolWithTrans
Definition: MdtReadoutGeomTool.cxx:31
Amg::getRotateY3D
Amg::Transform3D getRotateY3D(double angle)
get a rotation transformation around Y-axis
Definition: GeoPrimitivesHelpers.h:261
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
MuonGMR4::MmReadoutGeomTool::wMMTable
Struct to cache the relevant parameters of from the WRPC tables.
Definition: MmReadoutGeomTool.h:37
IRDBRecord.h
Definition of the abstract IRDBRecord interface.
MmIdHelper
Definition: MmIdHelper.h:54
MuonGMR4::MmReadoutGeomTool::wMMTable::nMissedBottomEta
int nMissedBottomEta
Definition: MmReadoutGeomTool.h:44
GeoPrimitivesHelpers.h
IRDBRecord_ptr
std::unique_ptr< IRDBRecord > IRDBRecord_ptr
Definition: IRDBRecordset.h:23
python.changerun.pv
pv
Definition: changerun.py:79
MuonGMR4::MmReadoutGeomTool::wMMTable::nMissedTopEta
int nMissedTopEta
Definition: MmReadoutGeomTool.h:46
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:24
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
MuonGMR4::MmReadoutGeomTool::wMMTable::nMissedBottomStereo
int nMissedBottomStereo
Definition: MmReadoutGeomTool.h:45
MuonGMR4::MmReadoutGeomTool::FactoryCache::stripDesigns
std::set< StripDesignPtr, StripDesignSorter > stripDesigns
Definition: MmReadoutGeomTool.h:56
MmReadoutGeomTool.h
MuonGMR4::MmReadoutElement::defineArgs
Definition: MmReadoutElement.h:48
ServiceHandle< IRDBAccessSvc >
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37