15 #include <GeoModelKernel/GeoLogVol.h>
16 #include <GeoModelKernel/GeoVFullPhysVol.h>
17 #include <GeoModelKernel/GeoVPhysVol.h>
18 #include <GeoModelHelpers/StringUtils.h>
21 #include <ext/alloc_traits.h>
27 #include "GeoModelKernel/GeoFullPhysVol.h"
40 #include "GaudiKernel/ISvcLocator.h"
46 #define THROW_EXCEPTION(MSG) \
48 std::stringstream sstr{}; \
49 sstr<<"sTgcReadoutElement - "<<idHelperSvc()->toStringDetEl(identify())<<" "<<__LINE__<<": "; \
51 throw std::runtime_error(sstr.str()); \
54 using namespace GeoStrUtils;
62 std::string fixName = (stName[1] ==
'L') ?
"STL" :
"STS";
63 Identifier
id =
mgr->stgcIdHelper()->channelID(fixName, zi,
fi, mL, 1,
64 sTgcIdHelper::sTgcChannelTypes::Strip, 1);
78 ISvcLocator* svcLocator = Gaudi::svcLocator();
80 svcLocator->service(
"GeoDbTagSvc",geoDbTag).ignore();
83 svcLocator->service(geoDbTag->getParamSvcName(),accessSvc).ignore();
88 PVConstLink
parent = getMaterialGeom()->getParent();
89 unsigned int index=
parent->indexOf(getMaterialGeom());
90 std::string pVName=
parent->getNameOfChildVol(
index);
91 float yCutoutCathode(0);
92 if (nswPars->size()==0) {
95 yCutoutCathode=(*nswPars)[0]->getFloat(
"NSW_sTGC_yCutoutCathode");
98 for (
unsigned int ind = 0;
ind < wstgcRec->size();
ind++) {
99 std::string WSTGC_TYPE = (*wstgcRec)[
ind]->getString(
"WSTGC_TYPE");
102 if (std::abs(
getStationEta())!=(
int) (WSTGC_TYPE[7]-
'0'))
continue;
103 if (
m_ml != (
int) (pVName[7]-
'0'))
continue;
105 std::string logVolSubName=getMaterialGeom()->getLogVol()->getName().substr(7,4);
108 for (
w=0;
w<nswdimRec->size();
w++) {
109 nswdim = (*nswdimRec)[
w];
110 const std::string
type = nswdim->getString(
"NSW_TYPE").substr(5,4);
111 if (
type==logVolSubName) {
120 const double gasTck = (*wstgcRec)[
ind]->getDouble(
"gasTck");
121 const double Tck = (*wstgcRec)[
ind]->getDouble(
"Tck");
122 const double xFrame = (*wstgcRec)[
ind]->getDouble(
"xFrame");
123 const double ylFrame = (*wstgcRec)[
ind]->getDouble(
"ylFrame");
124 const double ysFrame = (*wstgcRec)[
ind]->getDouble(
"ysFrame");
125 const double wirePitch = (*wstgcRec)[
ind]->getDouble(
"wirePitch");
126 const double stripPitch = (*wstgcRec)[
ind]->getDouble(
"stripPitch");
127 const double stripWidth = (*wstgcRec)[
ind]->getDouble(
"stripWidth");
128 const double sPadWidth = (*wstgcRec)[
ind]->getDouble(
"sPadWidth");
129 const double lPadWidth = (*wstgcRec)[
ind]->getDouble(
"lPadWidth");
130 const double anglePadPhi = (*wstgcRec)[
ind]->getDouble(
"anglePadPhi");
131 const double sStripWidth = (*wstgcRec)[
ind]->getDouble(
"sStripWidth");
132 const double lStripWidth = (*wstgcRec)[
ind]->getDouble(
"lStripWidth");
133 const int wireGroupWidth = (*wstgcRec)[
ind]->getInt(
"wireGroupWidth");
134 const int nStrips = (*wstgcRec)[
ind]->getInt(
"nStrips");
135 const std::vector<double> padH =
tokenizeDouble((*wstgcRec)[
ind]->getString(
"padH"),
";");
136 const std::vector<double> rankPadPhi =
tokenizeDouble((*wstgcRec)[
ind]->getString(
"rankPadPhi"),
";");
137 const std::vector<int> nPadPhi =
tokenizeInt((*wstgcRec)[
ind]->getString(
"nPadPhi"),
";");
138 const std::vector<double> firstPadPhiDivision_C =
tokenizeDouble((*wstgcRec)[
ind]->getString(
"firstPadPhiDivision_C"),
";");
139 const std::vector<double> PadPhiShift_C =
tokenizeDouble((*wstgcRec)[
ind]->getString(
"PadPhiShift_C"),
";");
140 const std::vector<double> firstPadPhiDivision_A =
tokenizeDouble((*wstgcRec)[
ind]->getString(
"firstPadPhiDivision_A"),
";");
141 const std::vector<double> PadPhiShift_A =
tokenizeDouble((*wstgcRec)[
ind]->getString(
"PadPhiShift_A"),
";");
142 const std::vector<double> rankPadH =
tokenizeDouble((*wstgcRec)[
ind]->getString(
"rankPadH"),
";");
143 const std::vector<int> nPadH =
tokenizeInt((*wstgcRec)[
ind]->getString(
"nPadH"),
";");
144 const std::vector<double> firstPadH =
tokenizeDouble((*wstgcRec)[
ind]->getString(
"firstPadH"),
";");
145 const std::vector<double> firstPadRow =
tokenizeDouble((*wstgcRec)[
ind]->getString(
"firstPadRow"),
";");
146 const std::vector<double> wireCutout =
tokenizeDouble((*wstgcRec)[
ind]->getString(
"wireCutout"),
";");
147 const std::vector<int> nWires =
tokenizeInt((*wstgcRec)[
ind]->getString(
"nWires"),
";");
148 const std::vector<int> firstWire =
tokenizeInt((*wstgcRec)[
ind]->getString(
"firstWire"),
";");
149 const std::vector<double> firstTriggerBand =
tokenizeDouble((*wstgcRec)[
ind]->getString(
"firstTriggerBand"),
";");
150 const std::vector<int> nTriggerBands =
tokenizeInt((*wstgcRec)[
ind]->getString(
"nTriggerBands"),
";");
151 const std::vector<double> firstStripInTrigger =
tokenizeDouble((*wstgcRec)[
ind]->getString(
"firstStripInTrigger"),
";");
152 const std::vector<double> firstStripWidth =
tokenizeDouble((*wstgcRec)[
ind]->getString(
"firstStripWidth"),
";");
153 const std::vector<double> StripsInBandsLayer1 =
tokenizeDouble((*wstgcRec)[
ind]->getString(
"StripsInBandsLayer1"),
";");
154 const std::vector<double> StripsInBandsLayer2 =
tokenizeDouble((*wstgcRec)[
ind]->getString(
"StripsInBandsLayer2"),
";");
155 const std::vector<double> StripsInBandsLayer3 =
tokenizeDouble((*wstgcRec)[
ind]->getString(
"StripsInBandsLayer3"),
";");
156 const std::vector<double> StripsInBandsLayer4 =
tokenizeDouble((*wstgcRec)[
ind]->getString(
"StripsInBandsLayer4"),
";");
157 const std::vector<int> nWireGroups =
tokenizeInt((*wstgcRec)[
ind]->getString(
"nWireGroups"),
";");
158 const std::vector<double> firstWireGroup =
tokenizeDouble((*wstgcRec)[
ind]->getString(
"firstWireGroup"),
";");
163 std::string
side = (Etasign > 0) ?
"A" :
"C";
263 if (sector_l ==
'L') {
279 std::string
side = (Etasign > 0) ?
"A" :
"C";
298 double ysFrame = stgc->
ysFrame();
299 double ylFrame = stgc->
ylFrame();
300 double xFrame = stgc->
xFrame();
402 if (sector_l ==
'L') {
427 if (
manager()->MinimalGeoFlag() == 0) {
428 PVConstLink pvc {getMaterialGeom()};
429 unsigned int nchildvol = pvc->getNChildVols();
431 std::string::size_type npos;
432 for (
unsigned ich = 0; ich < nchildvol; ++ich) {
433 PVConstLink
pc = pvc->getChildVol(ich);
434 std::string childname = (
pc->getLogVol())->getName();
437 if ((npos = childname.find(
"Sensitive")) != std::string::npos) {
440 ATH_MSG_DEBUG(
"number of sTGC layers > 4: increase transform array size");
443 m_Xlg[llay - 1] = pvc->getXToChildVol(ich);
449 ISvcLocator* svcLocator = Gaudi::svcLocator();
451 StatusCode sc = svcLocator->service(
"GeoDbTagSvc",geoDbTag);
510 m_surfaceData->m_layerSurfaces.push_back(std::make_unique<Trk::PlaneSurface>(*
this,
id));
526 const double shift{
layer%2 == 0 ? 0.01 : -0.01};
531 m_surfaceData->m_layerSurfaces.push_back(std::make_unique<Trk::PlaneSurface>(*
this,
id));
546 m_surfaceData->m_layerSurfaces.push_back(std::make_unique<Trk::PlaneSurface>(*
this,
id));
567 if (gasgap < 1 || gasgap >
m_nlayers)
return false;
570 if (strip < 1)
return false;
574 const auto [etaId, phiId] =
m_padDesign[gasgap -1].etaPhiId(strip);
575 if (etaId < 0 || phiId < 0)
return false;
593 if (!design)
return -1;
612 if (pad.first > 0 && pad.second > 0) {
614 bool is_valid {
true};
616 const Identifier padID = id_helper.
padID(
id, id_helper.multilayer(
id),
623 int channel = id_helper.channel(padID);
624 int padEta = id_helper.padEta(padID);
625 int padPhi = id_helper.padPhi(padID);
630 padEta != pad.first || padPhi != pad.second) {
632 ATH_MSG_WARNING(
" bad pad indices: input " << pad.first <<
" " << pad.second <<
" from ID " << padEta <<
" "
639 ATH_MSG_WARNING(__LINE__<<
" bad channelNumber" <<pad.first<<
" "<<pad.second );
649 ATH_MSG_WARNING(
"no wire design when trying to get the wire number" );
668 double pos_wire = -9999.9;
672 ATH_MSG_WARNING(
"no wire design when trying to get the 1st wire position" );
677 ATH_MSG_WARNING(
"attempt to retrieve the 1st wire position with a wrong identifier" );
689 ATH_MSG_WARNING(
"no wire design when trying to get the total number of wires" );
692 nWires = design->
nch;
694 ATH_MSG_WARNING(
"attempt to retrieve the number of wires with a wrong identifier" );
710 if (channelType != 2) shift = ((gg % 2) ^ (channelType==0)) ? 0.01 : -0.01;
739 m_delta = Amg::Transform3D::Identity();
756 double t0 = locPosML.x();
757 double s0 = locPosML.y();
758 double z0 = locPosML.z();
761 double s_rel = s0/(
width/2.);
776 double ds{0.}, dz{0.},
dt{0.};
778 if (bp != 0 ||
bn != 0)
779 dt += 0.5*(s_rel*s_rel - 1)*((bp +
bn) + (bp -
bn)*z_rel);
781 if (sp != 0 || sn != 0)
782 dt += 0.5*(z_rel*z_rel - 1)*((sp + sn) + (sp - sn)*s_rel);
785 dt -= tw*s_rel*z_rel;
795 if (ep != 0 ||
en != 0) {
799 double delta = s_rel*s_rel * ((ep +
en)*s_rel/6 + (ep -
en)/4);
800 double phi = s_rel * ((ep +
en)*s_rel + (ep -
en)) / 2;
819 ATH_MSG_WARNING(
"Unable to get MuonChannelDesign, therefore cannot provide position corrections. Returning." );
823 bool conditionsApplied{
false};
826 #ifndef SIMULATIONBASE
838 ATH_MSG_WARNING(
"As-built corrections are provided only for eta strips within the active area. Returning." );
854 pos[0] += (strip_id.
ilayer%2) ? 0.01 : -0.01;
859 conditionsApplied =
true;
871 if (!conditionsApplied) {
875 conditionsApplied =
true;
881 if (conditionsApplied)
pos = trfToML.inverse()*
pos;