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()); \
57using namespace GeoStrUtils;
65 std::string fixName = (stName[1] ==
'L') ?
"STL" :
"STS";
66 Identifier id = mgr->stgcIdHelper()->channelID(fixName, zi, fi, mL, 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);
250 m_padDesign[il].firstPhiPos= firstPadPhiDivision_A[il];
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();
291 ATH_MSG_DEBUG(
"Volume Type: " << pc->getLogVol()->getShape()->type());
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")};
475 for (
int layer{0}; layer <
m_nlayers; ++layer) {
487 m_surfaceData->m_surfBounds.push_back(std::make_unique<Trk::RotatedDiamondBounds>(
m_etaDesign[layer].minYSize() / 2.,
499 m_surfaceData->m_surfBounds.push_back(std::make_unique<Trk::RotatedTrapezoidBounds>(
m_etaDesign[layer].xSize() / 2.,
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;
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};
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;
730 static const Amg::Transform3D permute{GeoTrf::GeoRotation{90.*Gaudi::Units::deg,90.*Gaudi::Units::deg, 0.}};
748 m_delta = Amg::Transform3D::Identity();
765 double t0 = locPosML.x();
766 double s0 = locPosML.y();
767 double z0 = locPosML.z();
776 const double bp =
m_BLinePar->getParameter(Parameter::bp);
777 const double bn =
m_BLinePar->getParameter(Parameter::bn);
778 const double sp =
m_BLinePar->getParameter(Parameter::sp);
779 const double sn =
m_BLinePar->getParameter(Parameter::sn);
780 const double tw =
m_BLinePar->getParameter(Parameter::tw);
781 const double eg =
m_BLinePar->getParameter(Parameter::eg)*1.e-3;
782 const double ep =
m_BLinePar->getParameter(Parameter::ep)*1.e-3;
783 const double en =
m_BLinePar->getParameter(Parameter::en)*1.e-3;
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
851 if (log.level() <= MSG::DEBUG) {
868 pos = trfToML.inverse()*pos;
Scalar phi() const
phi method
#define ATH_MSG_WARNING(x)
Definition of the abstract IRDBAccessSvc interface.
std::shared_ptr< IRDBRecordset > IRDBRecordset_ptr
Definition of the abstract IRDBRecord interface.
Definition of the abstract IRDBRecordset interface.
#define THROW_EXCEPTION_RE(MSG)
const std::string & GetName() const
Amg::Transform3D delta() const
Returns the final transformations of the A lines.
IRDBRecord is one record in the IRDBRecordset object.
virtual const std::string & getString(const std::string &fieldName) const =0
Get string field value.
virtual double getDouble(const std::string &fieldName) const =0
Get double field value.
virtual unsigned int size() const =0
std::unique_ptr< SurfaceData > m_surfaceData
MuonClusterReadoutElement(GeoVFullPhysVol *pv, MuonDetectorManager *mgr, Trk::DetectorElemType detType)
virtual const Amg::Transform3D & transform() const override
Return local to global transform.
The MuonDetectorManager stores the transient representation of the Muon Spectrometer geometry and pro...
const sTGCAsBuiltData * getsTGCAsBuilt() const
const sTgcIdHelper * stgcIdHelper() const
void setIdentifier(const Identifier &id)
Sets the Identifier, hashes & station names.
void setLongSsize(double)
const Muon::IMuonIdHelperSvc * idHelperSvc() const
const Amg::Transform3D & absTransform() const
void setStationName(const std::string &)
int getStationPhi() const
const MuonDetectorManager * manager() const
int getStationEta() const
double getLongSsize() const
const std::string & getStationName() const
Identifier identify() const override final
Returns the ATLAS Identifier of the MuonReadOutElement.
double wirePitch(int gas_gap=1) const
single wire pitch.
const MuonPadDesign * getPadDesign(const Identifier &id) const
returns the MuonChannelDesign class for the given identifier
virtual void fillCache() override final
function to fill tracking cache
std::array< MuonChannelDesign, 4 > m_phiDesign
const MuonChannelDesign * getDesign(const Identifier &id) const
returns the MuonChannelDesign class for the given identifier
std::array< Amg::Transform3D, 4 > m_Xlg
int numberOfWires(const Identifier &id) const
Get the total number of wires (single wires) of a chamber.
const sTgcIdHelper & m_idHelper
~sTgcReadoutElement()
destructor
double channelPitch(const Identifier &id) const
Channel pitch.
std::array< MuonPadDesign, 4 > m_padDesign
static constexpr int m_nlayers
sTgcReadoutElement(GeoVFullPhysVol *pv, const std::string &stName, int zi, int fi, int mL, MuonDetectorManager *mgr)
constructor
const BLinePar * m_BLinePar
Amg::Vector3D localToGlobalCoords(const Amg::Vector3D &locPos, Identifier id) const
simHit local (SD) To Global position - to be used by MuonGeoAdaprors only
void setBLinePar(const BLinePar &bLine)
read B-line (chamber-deformation) parameters
void initDesignFromAGDD(double thickness)
std::array< MuonChannelDesign, 4 > m_etaDesign
void initDesignFromSQLite(double thickness)
void initDesign(double thickness)
initialize the design classes for this readout element
virtual bool spacePointPosition(const Identifier &phiId, const Identifier &etaId, Amg::Vector2D &pos) const override final
space point position for a given pair of phi and eta identifiers The LocalPosition is expressed in th...
double positionFirstWire(const Identifier &id) const
Get the local position of the first wire of the chamber corresponding to the identifier.
virtual bool containsId(const Identifier &id) const override final
function to be used to check whether a given Identifier is contained in the readout element
void posOnDefChamber(Amg::Vector3D &locPosML) const
transform a position (in chamber-frame coordinates) to the deformed-chamber geometry
int wireNumber(const Amg::Vector2D &pos, const Identifier &id) const
wire number corresponding to local position
const ALinePar * m_ALinePar
void setChamberLayer(int ml)
set methods only to be used by MuonGeoModel
void setDelta(const ALinePar &aline)
int padNumber(const Amg::Vector2D &pos, const Identifier &id) const
pad number corresponding to local position
Amg::Vector2D correctPosition(const Identifier &channelId, const Amg::Vector2D &pos) const
sTGCReadoutParameters & GetReadoutParameters()
void yCutoutCathode(double y)
void stripWidth(double y)
MuonGM::sTGC_Technology * GetTechnology()
void stripPitch(double y)
sTGCDetectorDescription * Get_sTGCDetector(char type, int ieta, int iphi, int layer=1, char side='A')
int padPhi(const Identifier &id) const
int multilayer(const Identifier &id) const
int padEta(const Identifier &id) const
int channel(const Identifier &id) const override
Identifier padID(int stationName, int stationEta, int stationPhi, int multilayer, int gasGap, int channelType, int padEta, int padPhi) const
int gasGap(const Identifier &id) const override
get the hashes
Amg::Transform3D getTranslate3D(const double X, const double Y, const double Z)
: Returns a shift transformation along an arbitrary axis
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Amg::Transform3D getTranslateZ3D(const double Z)
: Returns a shift transformation along the z-axis
Amg::Transform3D getRotateZ3D(double angle)
get a rotation transformation around Z-axis
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
Amg::Transform3D getRotateY3D(double angle)
get a rotation transformation around Y-axis
Eigen::Translation< double, 3 > Translation3D
IMessageSvc * getMessageSvc(bool quiet=false)
Ensure that the Athena extensions are properly loaded.
int nStrips(const MuonGM::TgcReadoutElement &readoutEle, int layer)
Ensure that the ATLAS eigen extensions are properly loaded.
int wireNumber(const Amg::Vector2D &pos) const
calculate the sTGC wire number. The method can return a value outside the range [1,...
double firstPos() const
Returns the position of the first strip along the x-axis.
Parameters defining the design of the readout sTGC pads.
std::pair< int, int > channelNumber(const Amg::Vector2D &pos) const
calculate local channel number, range 1=nstrips like identifiers.
double channelWidth(const Amg::Vector2D &pos, bool measPhi, bool preciseMeas=false) const
calculate local channel width
std::vector< int > firstWireGroup
std::vector< int > nWireGroups
std::vector< double > firstPadPhiDivision_A
std::vector< double > firstStripWidth
std::vector< int > nPadPhi
std::vector< double > firstPadH
std::vector< double > firstWire
std::vector< int > nWires
std::vector< double > padH
std::vector< double > wireCutout
std::vector< int > firstPadRow
std::vector< double > PadPhiShift_A
std::vector< double > nPadH