7 #include <GaudiKernel/SystemOfUnits.h>
14 #include <GeoModelKernel/GeoFullPhysVol.h>
15 #include <GeoModelKernel/GeoPhysVol.h>
16 #include <GeoModelKernel/GeoBox.h>
18 #include <GeoModelRead/ReadGeoModel.h>
22 #ifndef SIMULATIONBASE
23 # include "Acts/Utilities/BoundFactory.hpp"
40 GeoChildNodeWithTrf{std::move(physVol)},
49 std::unique_ptr<StripDesign> RpcReadoutGeomTool::constructDesign(
const GeoBox* planeBox,
51 bool phiPlane)
const {
54 ATH_MSG_VERBOSE(
"Parameter book does not for see a readout in "<<(phiPlane?
"phi" :
"eta")<<
" direction");
58 const double halfX = phiPlane ? planeBox->getYHalfLength() : planeBox->getZHalfLength();
59 const double halfY = phiPlane ? planeBox->getZHalfLength() : planeBox->getYHalfLength();
64 auto newDesign = std::make_unique<StripDesign>();
65 newDesign->defineTrapezoid(halfY, halfY, halfX);
66 newDesign->defineStripLayout(firstPos * Amg::Vector2D::UnitX(), pitch,
width,
nStrips);
74 <<std::endl<<std::endl<<m_geoUtilTool->dumpVolume(define.
physVol));
76 const GeoShape* shape = m_geoUtilTool->extractShape(define.
physVol);
79 return StatusCode::FAILURE;
81 ATH_MSG_DEBUG(
"Extracted shape "<<m_geoUtilTool->dumpShape(shape));
83 if (shape->typeID() != GeoBox::getClassTypeID()) {
84 ATH_MSG_FATAL(__FILE__<<
":"<<__LINE__<<
" expect shape to be a box but it's "<<m_geoUtilTool->dumpShape(shape));
85 return StatusCode::FAILURE;
88 const GeoBox* box =
static_cast<const GeoBox*
>(shape);
102 std::vector<GeoChildNodeWithTrf> rpcLayers = getChildrenWithRef(define.
physVol,
false);
104 rpcLayers.erase(std::remove_if(rpcLayers.begin(), rpcLayers.end(),
105 [](
const GeoChildNodeWithTrf& subVol){ return !subVol.volumeId; }), rpcLayers.end());
107 std::ranges::sort(rpcLayers, [](
const GeoChildNodeWithTrf&
a,
const GeoChildNodeWithTrf&
b){
108 return a.volumeId.value_or(0) <
b.volumeId.value_or(0);});
110 if (rpcLayers.empty()) {
111 ATH_MSG_FATAL(
"The volume "<<m_idHelperSvc->toStringDetEl(define.
detElId)<<
" does not have any childern with Identifiers "
112 <<std::endl<<m_geoUtilTool->dumpVolume(define.
physVol));
113 return StatusCode::FAILURE;
117 const unsigned modulePhi = m_idHelperSvc->rpcIdHelper().doubletPhi(define.
detElId);
119 std::vector<gapVolume> allGapsWithIdx{};
120 for (
const GeoChildNodeWithTrf& rpcSinglet : rpcLayers) {
121 auto fetchNodes = [
this, &rpcSinglet] (
const std::string& leafName) {
122 std::vector<GeoChildNodeWithTrf> nodes = m_geoUtilTool->findAllLeafNodesByName(rpcSinglet.volume, leafName);
123 std::ranges::for_each(nodes,[&rpcSinglet](GeoChildNodeWithTrf&
node){
node.transform = rpcSinglet.transform *
node.transform; });
126 std::vector<GeoChildNodeWithTrf> gasGaps = fetchNodes(
"RpcGasGap");
127 if (gasGaps.empty()) {
128 ATH_MSG_FATAL(
"The child "<<m_geoUtilTool->dumpVolume(rpcSinglet.volume)<<
" has "<<gasGaps.size()<<
" gasGaps. ");
129 return StatusCode::FAILURE;
131 std::vector<GeoChildNodeWithTrf> stripLayers = fetchNodes(
"bottomStripLayer");
132 if (stripLayers.empty()) {
133 ATH_MSG_FATAL(
"The child "<<m_geoUtilTool->dumpVolume(rpcSinglet.volume)<<
" does not have a strip layer ");
134 return StatusCode::FAILURE;
137 for (GeoChildNodeWithTrf& stripPanel : stripLayers) {
139 stripPanel.transform.translation().x() = gasGaps.front().transform.translation().x();
140 const int doubPhi =
std::max(modulePhi, 1
u*stripPanel.volumeId.value_or(999));
141 allGapsWithIdx.emplace_back(std::move(stripPanel),
gasGap, doubPhi);
145 const bool isAside{m_idHelperSvc->stationEta(define.
detElId) > 0};
154 return StatusCode::FAILURE;
156 const wRPCTable& paramBook{parBookItr->second};
158 auto insertStripLayer = [
this, &define, &factoryCache](std::unique_ptr<StripLayer> stripLay) {
159 const unsigned layIdx =
static_cast<unsigned>(stripLay->hash());
160 if (layIdx >= define.
layers.size()) {
161 define.
layers.resize(layIdx + 1);
166 for (
gapVolume& gapVol : allGapsWithIdx) {
167 const GeoShape* gapShape = m_geoUtilTool->extractShape(gapVol.volume);
168 if (gapShape->typeID() != GeoBox::getClassTypeID()) {
170 return StatusCode::FAILURE;
172 const GeoBox* gapBox =
static_cast<const GeoBox*
>(gapShape);
173 ATH_MSG_DEBUG(
"Gas gap dimensions "<<m_geoUtilTool->dumpShape(gapBox));
174 StripDesignPtr etaDesign = constructDesign(gapBox, paramBook,
false);
175 StripDesignPtr phiDesign = constructDesign(gapBox, paramBook,
true);
177 etaDesign = (*factoryCache.
stripDesigns.emplace(etaDesign).first);
180 phiDesign = (*factoryCache.
stripDesigns.emplace(phiDesign).first);
191 insertStripLayer(std::make_unique<StripLayer>(factoryCache.
trfNodeMaker.makeTransform(gapVol.transform),
193 RpcReadoutElement::createHash(0, gapVol.gasGap, gapVol.doubPhi,
false)));
196 insertStripLayer(std::make_unique<StripLayer>(factoryCache.
trfNodeMaker.makeTransform(gapVol.transform*
199 RpcReadoutElement::createHash(0, gapVol.gasGap, gapVol.doubPhi,
true)));
202 return StatusCode::SUCCESS;
205 GeoModelIO::ReadGeoModel* sqliteReader = m_geoDbTagSvc->getSqliteReader();
207 ATH_MSG_FATAL(
"Error, the tool works exclusively from sqlite geometry inputs");
208 return StatusCode::FAILURE;
214 const RpcIdHelper& idHelper{m_idHelperSvc->rpcIdHelper()};
218 physNodeMap mapFPV = sqliteReader->getPublishedNodes<std::string, GeoFullPhysVol*>(
"Muon");
219 #ifndef SIMULATIONBASE
220 auto layerBounds = std::make_shared<Acts::SurfaceBoundFactory>();
222 for (
auto& [
key,
pv] : mapFPV) {
229 std::vector<std::string> key_tokens =
tokenize(
key,
"_");
230 if (key_tokens.size() < 7 ||
231 key_tokens[1].find(
"RPC") == std::string::npos) {
236 const Identifier elementID = idHelper.padID(idHelper.stationNameIndex(key_tokens[0].substr(0, 3)),
245 return StatusCode::FAILURE;
249 define.chambDesign = key_tokens[1];
250 define.alignTransform = m_geoUtilTool->findAlignableTransform(define.physVol);
251 define.detElId = elementID;
252 ATH_MSG_VERBOSE(
"Key "<<
key<<
" lead to Identifier "<<m_idHelperSvc->toStringDetEl(elementID));
253 ATH_CHECK(loadDimensions(define, facCache));
254 #ifndef SIMULATIONBASE
255 define.layerBounds = layerBounds;
257 std::unique_ptr<RpcReadoutElement> readoutEle = std::make_unique<RpcReadoutElement>(std::move(define));
258 ATH_CHECK(
mgr.addRpcReadoutElement(std::move(readoutEle)));
260 return StatusCode::SUCCESS;
266 if (paramTable->size() == 0) {
268 return StatusCode::FAILURE;
271 << paramTable->tagName() <<
"] table with "
272 << paramTable->size() <<
" records");
275 const std::string chambType = record->getString(
"WRPC_TYPE");
279 const double stripDeadWidth = record->getDouble(
"stripDeadWidth") *
Gaudi::Units::cm;
295 <<
", etaStripOffSet: "<<(record->getDouble(
"etaStripOffSet") *
Gaudi::Units::cm)
296 <<
", phiStripOffSet: "<<(record->getDouble(
"phiStripOffSet") *
Gaudi::Units::cm)
299 return StatusCode::SUCCESS;