Loading [MathJax]/extensions/tex2jax.js
ATLAS Offline Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
Classes | Public Member Functions | Private Member Functions | Private Attributes | List of all members
MuonGMR4::RpcReadoutGeomTool Class Reference

#include <RpcReadoutGeomTool.h>

Inheritance diagram for MuonGMR4::RpcReadoutGeomTool:
Collaboration diagram for MuonGMR4::RpcReadoutGeomTool:

Classes

struct  FactoryCache
 
struct  wRPCTable
 Struct to cache the relevant parameters of from the WRPC tables. More...
 

Public Member Functions

StatusCode buildReadOutElements (MuonDetectorManager &mgr) override final
 

Private Member Functions

StatusCode readParameterBook (FactoryCache &cache)
 Retrieves the auxillary tables from the database. More...
 
StatusCode loadDimensions (RpcReadoutElement::defineArgs &args, FactoryCache &factory)
 Loads the chamber dimensions from GeoModel. More...
 

Private Attributes

ServiceHandle< Muon::IMuonIdHelperSvcm_idHelperSvc
 
ServiceHandle< IGeoDbTagSvcm_geoDbTagSvc {this, "GeoDbTagSvc", "GeoDbTagSvc"}
 
PublicToolHandle< IMuonGeoUtilityToolm_geoUtilTool {this,"GeoUtilTool", "" }
 

Detailed Description

Definition at line 19 of file RpcReadoutGeomTool.h.

Member Function Documentation

◆ buildReadOutElements()

StatusCode MuonGMR4::RpcReadoutGeomTool::buildReadOutElements ( MuonDetectorManager mgr)
finaloverride

Retrieve the list of full physical volumes & alignable nodes and connect them together afterwards

The keys should be formatted like <STATION_NAME>_<MUON_CHAMBERTYPE>_etc. The <MUON_CHAMBERTYPE> also indicates whether we're dealing with a MDT / TGC / CSC / RPC chamber If we are dealing with a MDT chamber, then there are 3 additional properties encoded into the chamber <STATIONETA>_<STATIONPHI>_<DOUBLETR>_<DOUBLETPHI>_<DOUBLETZ>

Retrieve first the station Identifier

stationEta

stationPhi

DoubletR

DoubletZ

DoubletPhi

Definition at line 198 of file RpcReadoutGeomTool.cxx.

198  {
199  GeoModelIO::ReadGeoModel* sqliteReader = m_geoDbTagSvc->getSqliteReader();
200  if (!sqliteReader) {
201  ATH_MSG_FATAL("Error, the tool works exclusively from sqlite geometry inputs");
202  return StatusCode::FAILURE;
203  }
204 
205  FactoryCache facCache{};
206  ATH_CHECK(readParameterBook(facCache));
207 
208  const RpcIdHelper& idHelper{m_idHelperSvc->rpcIdHelper()};
209  // Get the list of full phys volumes from SQLite, and create detector elements
210 
212  physNodeMap mapFPV = sqliteReader->getPublishedNodes<std::string, GeoFullPhysVol*>("Muon");
213 #ifndef SIMULATIONBASE
214  SurfaceBoundSetPtr<Acts::RectangleBounds> layerBounds = std::make_shared<SurfaceBoundSet<Acts::RectangleBounds>>();
215 #endif
216  for (auto& [key, pv] : mapFPV) {
223  std::vector<std::string> key_tokens = tokenize(key, "_");
224  if (key_tokens.size() < 7 ||
225  key_tokens[1].find("RPC") == std::string::npos) {
226  continue;
227  }
228  bool isValid{false};
230  const Identifier elementID = idHelper.padID(idHelper.stationNameIndex(key_tokens[0].substr(0, 3)),
231  atoi(key_tokens[2]),
232  atoi(key_tokens[3]),
233  atoi(key_tokens[4]),
234  atoi(key_tokens[6]),
235  atoi(key_tokens[5]),
236  isValid);
237  if (!isValid) {
238  ATH_MSG_FATAL("Failed to construct the station Identifier from "<<key);
239  return StatusCode::FAILURE;
240  }
241  defineArgs define{};
242  define.physVol = pv;
243  define.chambDesign = key_tokens[1];
244  define.alignTransform = m_geoUtilTool->findAlignableTransform(define.physVol);
245  define.detElId = elementID;
246  ATH_MSG_VERBOSE("Key "<<key<<" lead to Identifier "<<m_idHelperSvc->toStringDetEl(elementID));
247  ATH_CHECK(loadDimensions(define, facCache));
248 #ifndef SIMULATIONBASE
249  define.layerBounds = layerBounds;
250 #endif
251  std::unique_ptr<RpcReadoutElement> readoutEle = std::make_unique<RpcReadoutElement>(std::move(define));
252  ATH_CHECK(mgr.addRpcReadoutElement(std::move(readoutEle)));
253  }
254  return StatusCode::SUCCESS;
255 }

◆ loadDimensions()

StatusCode MuonGMR4::RpcReadoutGeomTool::loadDimensions ( RpcReadoutElement::defineArgs args,
FactoryCache factory 
)
private

Loads the chamber dimensions from GeoModel.

The half sizes of the

Rpc are made up out of 2 or 3 gasGap singlet. A singlet module is a RPC gas gap sandwiched by two strip layers. In large sectors, the gas gap may be split into two gasGaps.

    | Strip layer  |  Strip layer |    |  Strip layer  |  Strip layer |
    |           gas gap           |    |    Gas gap    |    Gas gap   | 
    | Strip layer  |  Strip layer |    |  Strip layer  |  Strip layer |

Fetch all volumes with Identifiers from the tree

Next sort them by Identifier

Fetch for each rpc layer the gasGaps

Adjust the height of the strip panel to be in the centre of the gasGap

We know now whether we had 2 or 3 gasgaps and also whether there 2 or 1 panels in phi

Special case for the BML4 DBZ = 3 chambers. The doubletPhi is incorporated into the detector element but there's only one strip panel

Define the strip layout

Define the box layout

Next build the phi layer

Definition at line 51 of file RpcReadoutGeomTool.cxx.

52  {
53 
54  ATH_MSG_VERBOSE("Load dimensions of "<<m_idHelperSvc->toString(define.detElId)
55  <<std::endl<<std::endl<<m_geoUtilTool->dumpVolume(define.physVol));
56 
57  const GeoShape* shape = m_geoUtilTool->extractShape(define.physVol);
58  if (!shape) {
59  ATH_MSG_FATAL("Failed to deduce a valid shape for "<<m_idHelperSvc->toString(define.detElId));
60  return StatusCode::FAILURE;
61  }
62  ATH_MSG_DEBUG("Extracted shape "<<m_geoUtilTool->dumpShape(shape));
64  if (shape->typeID() != GeoBox::getClassTypeID()) {
65  ATH_MSG_FATAL(__FILE__<<":"<<__LINE__<<" expect shape to be a box but it's "<<m_geoUtilTool->dumpShape(shape));
66  return StatusCode::FAILURE;
67  }
68 
69  const GeoBox* box = static_cast<const GeoBox*>(shape);
70  define.halfThickness = box->getXHalfLength() * Gaudi::Units::mm;
71  define.halfLength = box->getZHalfLength() * Gaudi::Units::mm;
72  define.halfWidth = box->getYHalfLength() * Gaudi::Units::mm;
73 
83  std::vector<GeoChildNodeWithTrf> rpcLayers = getChildrenWithRef(define.physVol, false);
85  rpcLayers.erase(std::remove_if(rpcLayers.begin(), rpcLayers.end(),
86  [](const GeoChildNodeWithTrf& subVol){ return !subVol.volumeId; }), rpcLayers.end());
88  std::ranges::sort(rpcLayers, [](const GeoChildNodeWithTrf& a, const GeoChildNodeWithTrf& b){
89  return a.volumeId.value_or(0) < b.volumeId.value_or(0);});
90 
91  if (rpcLayers.empty()) {
92  ATH_MSG_FATAL("The volume "<<m_idHelperSvc->toStringDetEl(define.detElId)<<" does not have any childern with Identifiers "
93  <<std::endl<<m_geoUtilTool->dumpVolume(define.physVol));
94  return StatusCode::FAILURE;
95  }
97  unsigned int gasGap{0};
98  const unsigned int modulePhi = m_idHelperSvc->rpcIdHelper().doubletPhi(define.detElId);
99 
100  std::vector<gapVolume> allGapsWithIdx{};
101  for (const GeoChildNodeWithTrf& rpcSinglet : rpcLayers) {
102  auto fetchNodes = [this, &rpcSinglet] (const std::string& leafName) {
103  std::vector<GeoChildNodeWithTrf> nodes = m_geoUtilTool->findAllLeafNodesByName(rpcSinglet.volume, leafName);
104  std::ranges::for_each(nodes,[&rpcSinglet](GeoChildNodeWithTrf& node){ node.transform = rpcSinglet.transform * node.transform; });
105  return nodes;
106  };
107  std::vector<GeoChildNodeWithTrf> gasGaps = fetchNodes("RpcGasGap");
108  if (gasGaps.empty()) {
109  ATH_MSG_FATAL("The child "<<m_geoUtilTool->dumpVolume(rpcSinglet.volume)<<" has "<<gasGaps.size()<<" gasGaps. ");
110  return StatusCode::FAILURE;
111  }
112  std::vector<GeoChildNodeWithTrf> stripLayers = fetchNodes("bottomStripLayer");
113  if (stripLayers.empty()) {
114  ATH_MSG_FATAL("The child "<<m_geoUtilTool->dumpVolume(rpcSinglet.volume)<<" does not have a strip layer ");
115  return StatusCode::FAILURE;
116  }
117  ++gasGap;
118  for (GeoChildNodeWithTrf& stripPanel : stripLayers) {
120  stripPanel.transform.translation().x() = gasGaps.front().transform.translation().x();
121  const int doubPhi = std::max(modulePhi, 1u*stripPanel.volumeId.value_or(999));
122  allGapsWithIdx.emplace_back(std::move(stripPanel), gasGap, doubPhi);
123  }
124  }
125 
126  const bool isAside{m_idHelperSvc->stationEta(define.detElId) > 0};
128  define.nGasGaps = gasGap;
131  define.nPanelsInPhi = modulePhi == 2 ? 1 : allGapsWithIdx.size () / gasGap;
132  FactoryCache::ParamBookTable::const_iterator parBookItr = factoryCache.parameterBook.find(define.chambDesign);
133  if (parBookItr == factoryCache.parameterBook.end()) {
134  ATH_MSG_FATAL("The chamber "<<define.chambDesign<<" is not part of the WRPC table");
135  return StatusCode::FAILURE;
136  }
137  const wRPCTable& paramBook{parBookItr->second};
138 
139  for (gapVolume& gapVol : allGapsWithIdx) {
140  const GeoShape* gapShape = m_geoUtilTool->extractShape(gapVol.volume);
141  if (gapShape->typeID() != GeoBox::getClassTypeID()) {
142  ATH_MSG_FATAL("Failed to extract a geo shape");
143  return StatusCode::FAILURE;
144  }
145  const GeoBox* gapBox = static_cast<const GeoBox*>(gapShape);
146  ATH_MSG_DEBUG("Gas gap dimensions "<<m_geoUtilTool->dumpShape(gapBox));
147  StripDesignPtr etaDesign = std::make_unique<StripDesign>();
149  const double firstStripPosEta = -gapBox->getZHalfLength() + paramBook.firstOffSetEta;
150  etaDesign->defineStripLayout(firstStripPosEta * Amg::Vector2D::UnitX(),
151  paramBook.stripPitchEta,
152  paramBook.stripWidthEta,
153  paramBook.numEtaStrips);
155  etaDesign->defineTrapezoid(gapBox->getYHalfLength(), gapBox->getYHalfLength(), gapBox->getZHalfLength());
156  gapVol.transform = gapVol.transform * Amg::getRotateY3D( (isAside ? -90. : 90.)* Gaudi::Units::degree);
157 
158  etaDesign = (*factoryCache.stripDesigns.emplace(etaDesign).first);
159  const IdentifierHash etaHash {RpcReadoutElement::createHash(0, gapVol.gasGap, gapVol.doubPhi, false)};
160  const unsigned int etaIdx = static_cast<unsigned int>(etaHash);
161  if (etaIdx >= define.layers.size()) {
162  define.layers.resize(etaIdx + 1);
163  }
164 
165  auto etaLayer = std::make_unique<StripLayer>(gapVol.transform, etaDesign, etaHash);
166  define.layers[etaIdx] = (*factoryCache.stripLayers.emplace(std::move(etaLayer)).first);
167 
168  ATH_MSG_VERBOSE("Added new eta gap at "<<(*define.layers[etaIdx]));
169  if (!define.etaDesign) define.etaDesign = etaDesign;
170 
171  if (!paramBook.numPhiStrips) {
172  ATH_MSG_VERBOSE("Rpc readout element without phi strips");
173  continue;
174  }
175  StripDesignPtr phiDesign = std::make_unique<StripDesign>();
176  const double firstStripPosPhi = -gapBox->getYHalfLength() + paramBook.firstOffSetPhi;
177  phiDesign->defineStripLayout(firstStripPosPhi * Amg::Vector2D::UnitX(),
178  paramBook.stripPitchPhi,
179  paramBook.stripWidthPhi,
180  paramBook.numPhiStrips);
181  phiDesign->defineTrapezoid(gapBox->getZHalfLength(), gapBox->getZHalfLength(), gapBox->getYHalfLength());
183  phiDesign = (*factoryCache.stripDesigns.emplace(phiDesign).first);
184 
185  const IdentifierHash phiHash {RpcReadoutElement::createHash(0, gapVol.gasGap, gapVol.doubPhi, true)};
186  const unsigned int phiIdx = static_cast<unsigned int>(phiHash);
187  if (phiIdx >= define.layers.size()) {
188  define.layers.resize(phiIdx + 1);
189  }
190  auto phiLayer = std::make_unique<StripLayer>(gapVol.transform * Amg::getRotateZ3D(90. * Gaudi::Units::deg),
191  phiDesign, phiHash);
192  define.layers[phiIdx] = (*factoryCache.stripLayers.emplace(std::move(phiLayer)).first);
193  ATH_MSG_VERBOSE("Added new phi gap at "<<(*define.layers[phiIdx]));
194  if (!define.phiDesign) define.phiDesign = phiDesign;
195  }
196  return StatusCode::SUCCESS;
197 }

◆ readParameterBook()

StatusCode MuonGMR4::RpcReadoutGeomTool::readParameterBook ( FactoryCache cache)
private

Retrieves the auxillary tables from the database.

Definition at line 256 of file RpcReadoutGeomTool.cxx.

256  {
257  ServiceHandle<IRDBAccessSvc> accessSvc(m_geoDbTagSvc->getParamSvcName(), name());
258  ATH_CHECK(accessSvc.retrieve());
259  IRDBRecordset_ptr paramTable = accessSvc->getRecordsetPtr("WRPC", "");
260  if (paramTable->size() == 0) {
261  ATH_MSG_FATAL("Empty parameter book table found");
262  return StatusCode::FAILURE;
263  }
264  ATH_MSG_VERBOSE("Found the " << paramTable->nodeName() << " ["
265  << paramTable->tagName() << "] table with "
266  << paramTable->size() << " records");
267 
268  for (const IRDBRecord_ptr& record : *paramTable) {
269  const std::string chambType = record->getString("WRPC_TYPE");
270  wRPCTable& parBook = cache.parameterBook[record->getString("WRPC_TYPE")];
271  parBook.stripPitchEta = record->getDouble("etaStripPitch") * Gaudi::Units::cm;
272  parBook.stripPitchPhi = record->getDouble("phiStripPitch") * Gaudi::Units::cm;
273  const double stripDeadWidth = record->getDouble("stripDeadWidth") * Gaudi::Units::cm;
274  parBook.stripWidthEta = parBook.stripPitchEta - stripDeadWidth;
275  parBook.stripWidthPhi = parBook.stripPitchPhi - stripDeadWidth;
276  parBook.numEtaStrips = record->getInt("nEtaStrips");
277  parBook.numPhiStrips = record->getInt("nPhiStrips");
278  parBook.firstOffSetPhi = record->getDouble("phiStripOffSet") * Gaudi::Units::cm +
279  0.5 * parBook.stripPitchPhi;
280  parBook.firstOffSetEta = record->getDouble("etaStripOffSet") * Gaudi::Units::cm +
281  record->getDouble("TCKSSU") * Gaudi::Units::cm +
282  0.5 * parBook.stripPitchEta;
283 
284  ATH_MSG_VERBOSE("Extracted parameters for chamber "<<chambType
285  <<", num strips (eta/phi): "<<parBook.numEtaStrips<<"/"<<parBook.numPhiStrips
286  <<", strip pitch (eta/phi) "<<parBook.stripPitchEta<<"/"<<parBook.stripPitchPhi
287  <<", strip width (eta/phi): "<<parBook.stripWidthEta<<"/"<<parBook.stripWidthPhi
288  <<", strip offset (eta/phi): "<<parBook.firstOffSetEta<<"/"<<parBook.firstOffSetPhi
289  <<", etaStripOffSet: "<<(record->getDouble("etaStripOffSet") * Gaudi::Units::cm)
290  <<", phiStripOffSet: "<<(record->getDouble("phiStripOffSet") * Gaudi::Units::cm)
291  <<", TCKSSU: "<<(record->getDouble("TCKSSU")* Gaudi::Units::cm));
292  }
293  return StatusCode::SUCCESS;
294 }

Member Data Documentation

◆ m_geoDbTagSvc

ServiceHandle<IGeoDbTagSvc> MuonGMR4::RpcReadoutGeomTool::m_geoDbTagSvc {this, "GeoDbTagSvc", "GeoDbTagSvc"}
private

Definition at line 30 of file RpcReadoutGeomTool.h.

◆ m_geoUtilTool

PublicToolHandle<IMuonGeoUtilityTool> MuonGMR4::RpcReadoutGeomTool::m_geoUtilTool {this,"GeoUtilTool", "" }
private

Definition at line 32 of file RpcReadoutGeomTool.h.

◆ m_idHelperSvc

ServiceHandle<Muon::IMuonIdHelperSvc> MuonGMR4::RpcReadoutGeomTool::m_idHelperSvc
private
Initial value:
{this, "IdHelperSvc",
"Muon::MuonIdHelperSvc/MuonIdHelperSvc"}

Definition at line 27 of file RpcReadoutGeomTool.h.


The documentation for this class was generated from the following files:
MuonGMR4::RpcReadoutGeomTool::loadDimensions
StatusCode loadDimensions(RpcReadoutElement::defineArgs &args, FactoryCache &factory)
Loads the chamber dimensions from GeoModel.
Definition: RpcReadoutGeomTool.cxx:51
dumpTgcDigiDeadChambers.gasGap
list gasGap
Definition: dumpTgcDigiDeadChambers.py:33
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
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::RpcReadoutGeomTool::readParameterBook
StatusCode readParameterBook(FactoryCache &cache)
Retrieves the auxillary tables from the database.
Definition: RpcReadoutGeomTool.cxx:256
deg
#define deg
Definition: SbPolyhedron.cxx:17
MuonGMR4::RpcReadoutGeomTool::m_idHelperSvc
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
Definition: RpcReadoutGeomTool.h:27
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:812
RpcIdHelper
Definition: RpcIdHelper.h:51
Trk::u
@ u
Enums for curvilinear frames.
Definition: ParamDefs.h:77
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
cm
const double cm
Definition: Simulation/ISF/ISF_FastCaloSim/ISF_FastCaloSimParametrization/tools/FCAL_ChannelMap.cxx:25
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
IRDBRecordset_ptr
std::shared_ptr< IRDBRecordset > IRDBRecordset_ptr
Definition: IRDBAccessSvc.h:25
MuonGMR4::StripDesignPtr
GeoModel::TransientConstSharedPtr< StripDesign > StripDesignPtr
Definition: StripDesign.h:29
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
Amg::getRotateY3D
Amg::Transform3D getRotateY3D(double angle)
get a rotation transformation around Y-axis
Definition: GeoPrimitivesHelpers.h:261
MuonGMR4::RpcReadoutGeomTool::m_geoDbTagSvc
ServiceHandle< IGeoDbTagSvc > m_geoDbTagSvc
Definition: RpcReadoutGeomTool.h:30
python.SystemOfUnits.mm
int mm
Definition: SystemOfUnits.py:83
a
TList * a
Definition: liststreamerinfos.cxx:10
IRDBRecord_ptr
std::unique_ptr< IRDBRecord > IRDBRecord_ptr
Definition: IRDBRecordset.h:23
python.changerun.pv
pv
Definition: changerun.py:81
MuonGMR4::RpcReadoutGeomTool::m_geoUtilTool
PublicToolHandle< IMuonGeoUtilityTool > m_geoUtilTool
Definition: RpcReadoutGeomTool.h:32
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::SurfaceBoundSetPtr
std::shared_ptr< SurfaceBoundSet< BoundType > > SurfaceBoundSetPtr
Aberivation to create a new SurfaceBoundSetPtr.
Definition: Tracking/Acts/ActsGeoUtils/ActsGeoUtils/Defs.h:19
MuonGMR4::MuonReadoutElement::defineArgs::physVol
GeoIntrusivePtr< GeoVFullPhysVol > physVol
Pointer to the underlying physical volume in GeoModel.
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/MuonReadoutElement.h:45
python.SystemOfUnits.degree
tuple degree
Definition: SystemOfUnits.py:106
node
Definition: node.h:21
MuonGMR4::defineArgs
RpcReadoutElement::defineArgs defineArgs
Definition: RpcReadoutGeomTool.cxx:33
ServiceHandle< IRDBAccessSvc >
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37
MuonGMR4::RpcReadoutElement::createHash
static IdentifierHash createHash(const unsigned int strip, const unsigned int gasGap, const unsigned int doubPhi, const bool measPhi)
Constructs an Identifier hash from the Identifier fields controlled by this readout element
Identifier
Definition: IdentifierFieldParser.cxx:14