15 #include <GeoModelKernel/GeoLogVol.h>
16 #include <GeoModelKernel/GeoDefinitions.h>
17 #include <GeoModelHelpers/StringUtils.h>
18 #include <GeoModelHelpers/TransformToStringConverter.h>
19 #include <GeoModelHelpers/getChildNodesWithTrf.h>
22 #include <ext/alloc_traits.h>
28 #include "GeoModelKernel/GeoFullPhysVol.h"
29 #include "GaudiKernel/SystemOfUnits.h"
42 #include "GaudiKernel/ISvcLocator.h"
49 #define THROW_EXCEPTION_RE(MSG) \
51 std::stringstream sstr{}; \
52 sstr<<"sTgcReadoutElement - "<<idHelperSvc()->toStringDetEl(identify())<<" "<<__LINE__<<": "; \
54 throw std::runtime_error(sstr.str()); \
57 using namespace GeoStrUtils;
61 sTgcReadoutElement::sTgcReadoutElement(GeoVFullPhysVol*
pv,
const std::string& stName,
int zi,
int fi,
int mL,
MuonDetectorManager*
mgr)
65 std::string fixName = (stName[1] ==
'L') ?
"STL" :
"STS";
66 Identifier id =
mgr->stgcIdHelper()->channelID(fixName, zi, fi, mL, 1,
67 sTgcIdHelper::sTgcChannelTypes::Strip, 1);
81 PVConstLink pvc {getMaterialGeom()};
82 auto sensitiveVol = getAllSubVolumes(pvc,[](
const GeoChildNodeWithTrf&
node){
83 return node.nodeName.find(
"Gas") != std::string::npos;
86 for (
unsigned int llay = 0; llay< sensitiveVol.size(); ++llay) {
87 m_Xlg[llay] = sensitiveVol[llay].transform;
90 SmartIF<IGeoDbTagSvc> geoDbTag{Gaudi::svcLocator()->service(
"GeoDbTagSvc")};
91 SmartIF<IRDBAccessSvc> accessSvc{Gaudi::svcLocator()->service(geoDbTag->getParamSvcName())};
97 PVConstLink
parent = getMaterialGeom()->getParent();
98 unsigned int index=
parent->indexOf(getMaterialGeom()).value();
99 std::string pVName=
parent->getNameOfChildVol(
index);
100 float yCutoutCathode(0);
101 if (nswPars->size()==0) {
104 yCutoutCathode=(*nswPars)[0]->getFloat(
"NSW_sTGC_yCutoutCathode");
107 for (
size_t w=0;
w<nswdimRec->size();
w++) {
109 const std::string
type = nswdim->
getString(
"NSW_TYPE").substr(5,4);
110 std::string logVolSubName=getMaterialGeom()->getLogVol()->getName().substr(7,4);
111 if (
type==logVolSubName) {
119 for (
unsigned int ind = 0; ind < wstgcRec->size(); ind++) {
120 std::string WSTGC_TYPE = (*wstgcRec)[ind]->getString(
"WSTGC_TYPE");
123 if (std::abs(
getStationEta())!=(
int) (WSTGC_TYPE[7]-
'0'))
continue;
127 const double gasTck = (*wstgcRec)[ind]->getDouble(
"gasTck");
128 const double Tck = (*wstgcRec)[ind]->getDouble(
"Tck");
129 const double xFrame = (*wstgcRec)[ind]->getDouble(
"xFrame");
130 const double ylFrame = (*wstgcRec)[ind]->getDouble(
"ylFrame");
131 const double ysFrame = (*wstgcRec)[ind]->getDouble(
"ysFrame");
132 const double wirePitch = (*wstgcRec)[ind]->getDouble(
"wirePitch");
133 const double stripPitch = (*wstgcRec)[ind]->getDouble(
"stripPitch");
134 const double stripWidth = (*wstgcRec)[ind]->getDouble(
"stripWidth");
135 const double sPadWidth = (*wstgcRec)[ind]->getDouble(
"sPadWidth");
136 const double lPadWidth = (*wstgcRec)[ind]->getDouble(
"lPadWidth");
137 const double anglePadPhi = (*wstgcRec)[ind]->getDouble(
"anglePadPhi");
138 const double sStripWidth = (*wstgcRec)[ind]->getDouble(
"sStripWidth");
139 const double lStripWidth = (*wstgcRec)[ind]->getDouble(
"lStripWidth");
140 const int wireGroupWidth = (*wstgcRec)[ind]->getInt(
"wireGroupWidth");
141 const int nStrips = (*wstgcRec)[ind]->getInt(
"nStrips");
142 const std::vector<double> padH =
tokenizeDouble((*wstgcRec)[ind]->getString(
"padH"),
";");
143 const std::vector<int> nPadPhi =
tokenizeInt((*wstgcRec)[ind]->getString(
"nPadPhi"),
";");
144 const std::vector<double> firstPadPhiDivision_A =
tokenizeDouble((*wstgcRec)[ind]->getString(
"firstPadPhiDivision_A"),
";");
145 const std::vector<double> PadPhiShift_A =
tokenizeDouble((*wstgcRec)[ind]->getString(
"PadPhiShift_A"),
";");
146 const std::vector<int> nPadH =
tokenizeInt((*wstgcRec)[ind]->getString(
"nPadH"),
";");
147 const std::vector<double> firstPadH =
tokenizeDouble((*wstgcRec)[ind]->getString(
"firstPadH"),
";");
148 const std::vector<double> firstPadRow =
tokenizeDouble((*wstgcRec)[ind]->getString(
"firstPadRow"),
";");
149 const std::vector<double> wireCutout =
tokenizeDouble((*wstgcRec)[ind]->getString(
"wireCutout"),
";");
150 const std::vector<int> nWires =
tokenizeInt((*wstgcRec)[ind]->getString(
"nWires"),
";");
151 const std::vector<int> firstWire =
tokenizeInt((*wstgcRec)[ind]->getString(
"firstWire"),
";");
152 const std::vector<double> firstStripWidth =
tokenizeDouble((*wstgcRec)[ind]->getString(
"firstStripWidth"),
";");
153 const std::vector<int> nWireGroups =
tokenizeInt((*wstgcRec)[ind]->getString(
"nWireGroups"),
";");
154 const std::vector<double> firstWireGroup =
tokenizeDouble((*wstgcRec)[ind]->getString(
"firstWireGroup"),
";");
159 std::string
side = (Etasign > 0) ?
"A" :
"C";
183 0.5 * (
getRsize() - ysFrame - ylFrame));
187 0.5 * (
getRsize() - ysFrame - ylFrame), yCutout);
207 0.5 * (
getRsize() - ysFrame - ylFrame) );
211 0.5 * (
getRsize() - ysFrame - ylFrame), yCutout);
259 if (sector_l ==
'L') {
282 if (
manager()->MinimalGeoFlag() == 0) {
283 PVConstLink pvc {getMaterialGeom()};
284 unsigned int nchildvol = pvc->getNChildVols();
286 std::string::size_type npos;
287 for (
unsigned ich = 0; ich < nchildvol; ++ich) {
288 PVConstLink
pc = pvc->getChildVol(ich);
289 std::string childname = (
pc->getLogVol())->
getName();
292 if ((npos = childname.find(
"Sensitive")) == std::string::npos) {
297 ATH_MSG_DEBUG(
"number of sTGC layers > 4: increase transform array size");
300 m_Xlg[llay - 1] = pvc->getXToChildVol(ich);
307 std::string
side = (Etasign > 0) ?
"A" :
"C";
326 double ysFrame = stgc->
ysFrame();
327 double ylFrame = stgc->
ylFrame();
328 double xFrame = stgc->
xFrame();
348 0.5 * (
getRsize() - ysFrame - ylFrame));
352 0.5 * (
getRsize() - ysFrame - ylFrame), yCutout);
377 0.5 * (
getRsize() - ysFrame - ylFrame) );
381 0.5 * (
getRsize() - ysFrame - ylFrame), yCutout);
430 if (sector_l ==
'L') {
441 <<
" layer " <<
il<<
", pad phi angular width "
458 SmartIF<IGeoDbTagSvc> geoDbTag{Gaudi::svcLocator()->service(
"GeoDbTagSvc")};
517 m_surfaceData->m_layerSurfaces.push_back(std::make_unique<Trk::PlaneSurface>(*
this,
id));
533 const double shift{
layer%2 == 0 ? 0.01 : -0.01};
538 m_surfaceData->m_layerSurfaces.push_back(std::make_unique<Trk::PlaneSurface>(*
this,
id));
553 m_surfaceData->m_layerSurfaces.push_back(std::make_unique<Trk::PlaneSurface>(*
this,
id));
574 if (gasgap < 1 || gasgap >
m_nlayers)
return false;
577 if (strip < 1)
return false;
581 const auto [etaId, phiId] =
m_padDesign[gasgap -1].etaPhiId(strip);
582 if (etaId < 0 || phiId < 0)
return false;
600 if (!design)
return -1;
619 if (pad.first > 0 && pad.second > 0) {
621 bool is_valid {
true};
623 const Identifier padID = id_helper.padID(
id, id_helper.multilayer(
id),
630 int channel = id_helper.channel(padID);
631 int padEta = id_helper.padEta(padID);
632 int padPhi = id_helper.padPhi(padID);
637 padEta != pad.first || padPhi != pad.second) {
639 ATH_MSG_WARNING(
" bad pad indices: input " << pad.first <<
" " << pad.second <<
" from ID " << padEta <<
" "
646 ATH_MSG_WARNING(__LINE__<<
" bad channelNumber" <<pad.first<<
" "<<pad.second );
656 ATH_MSG_WARNING(
"no wire design when trying to get the wire number" );
675 double pos_wire = -9999.9;
679 ATH_MSG_WARNING(
"no wire design when trying to get the 1st wire position" );
684 ATH_MSG_WARNING(
"attempt to retrieve the 1st wire position with a wrong identifier" );
696 ATH_MSG_WARNING(
"no wire design when trying to get the total number of wires" );
699 nWires = design->
nch;
701 ATH_MSG_WARNING(
"attempt to retrieve the number of wires with a wrong identifier" );
717 if (channelType != 2) shift = ((gg % 2) ^ (channelType==0)) ? 0.01 : -0.01;
748 m_delta = Amg::Transform3D::Identity();
765 double t0 = locPosML.x();
766 double s0 = locPosML.y();
767 double z0 = locPosML.z();
770 double s_rel = s0/(
width/2.);
785 double ds{0.}, dz{0.},
dt{0.};
787 if (bp != 0 ||
bn != 0)
788 dt += 0.5*(s_rel*s_rel - 1)*((bp +
bn) + (bp -
bn)*z_rel);
790 if (sp != 0 || sn != 0)
791 dt += 0.5*(z_rel*z_rel - 1)*((sp + sn) + (sp - sn)*s_rel);
794 dt -= tw*s_rel*z_rel;
804 if (ep != 0 ||
en != 0) {
808 double delta = s_rel*s_rel * ((ep +
en)*s_rel/6 + (ep -
en)/4);
809 double phi = s_rel * ((ep +
en)*s_rel + (ep -
en)) / 2;
828 ATH_MSG_WARNING(
"Unable to get MuonChannelDesign, therefore cannot provide position corrections. Returning." );
832 #ifndef SIMULATIONBASE
840 # pragma GCC diagnostic push
841 # pragma GCC diagnostic ignored "-Warray-bounds"
845 # pragma GCC diagnostic pop
868 pos = trfToML.inverse()*
pos;