13#include <GaudiKernel/IMessageSvc.h>
14#include <GeoModelKernel/GeoLogVol.h>
15#include <GeoModelKernel/GeoShape.h>
16#include <GeoModelKernel/GeoVFullPhysVol.h>
17#include <GeoModelKernel/GeoDefinitions.h>
24#include "GaudiKernel/SystemOfUnits.h"
25#include "GeoModelHelpers/getChildNodesWithTrf.h"
26#include "GeoModelHelpers/StringUtils.h"
27#include "GeoModelHelpers/GeoShapeUtils.h"
28#include "GeoModelHelpers/TransformToStringConverter.h"
30#include "GeoModelKernel/GeoFullPhysVol.h"
31#include "GeoModelKernel/GeoShapeSubtraction.h"
32#include "GeoModelKernel/GeoTrd.h"
41#include "GaudiKernel/ISvcLocator.h"
49#define THROW_EXCEPTION_MM(MSG) \
51 std::stringstream sstr{}; \
52 sstr<<"MMReadoutElement - "<<idHelperSvc()->toStringDetEl(identify())<<" "<<__LINE__<<": "; \
54 throw std::runtime_error(sstr.str()); \
58 template <
class ObjType,
size_t N>
void assign(
const std::vector<ObjType>& in,
59 std::array<ObjType, N>& out) {
60 for (
size_t k =0 ; k < std::min(in.size(), N) ; ++k){
66using namespace GeoStrUtils;
74 std::string fixName = (stName[2] ==
'L') ?
"MML" :
"MMS";
77 Identifier id = mgr->mmIdHelper()->channelID(fixName, zi, fi, mL, 1, 1);
81 if (mgr->MinimalGeoFlag()) {
84 bool foundShape =
false;
85 const PVConstLink pvc {getMaterialGeom()};
86 const GeoTrd* trd=
dynamic_cast<const GeoTrd *
> (pvc->getLogVol()->getShape());
94 ATH_MSG_DEBUG(
"Expected a GeoTrd but got "<<printGeoShape(pvc->getLogVol()->getShape()));
97 std::vector<GeoChildNodeWithTrf> children{getAllSubVolumes(pvc)};
98 for (
const GeoChildNodeWithTrf& child : children) {
99 ATH_MSG_VERBOSE(
"Child node "<<child.nodeName<<
" "<<child.volume->getLogVol()->getName());
100 if (child.volume->getLogVol()->getName().find(
"Sensitive") == std::string::npos &&
102 child.volume->getLogVol()->getName() !=
"actMicroMegaGas") {
114 const GeoShape* childShape = child.volume->getLogVol()->getShape();
115 while (childShape->typeID() != GeoTrd::getClassTypeID()){
116 auto [opA, opB] = getOps(childShape);
117 ATH_MSG_VERBOSE(
"Operands are "<<printGeoShape(opA)<<
", "<<printGeoShape(opB));
120 const GeoTrd* trd =
dynamic_cast<const GeoTrd*
>(childShape);
121 m_halfX = trd->getZHalfLength();
140 SmartIF<IGeoDbTagSvc> geoDbTag{Gaudi::svcLocator()->service(
"GeoDbTagSvc")};
144 SmartIF<IRDBAccessSvc> accessSvc{Gaudi::svcLocator()->service(geoDbTag->getParamSvcName())};
150 for (
unsigned int ind = 0; ind < wmmRec->
size(); ind++) {
151 std::string WMM_TYPE = (*wmmRec)[ind]->getString(
"WMM_TYPE");
152 if (sector_l != WMM_TYPE[4]){
158 if (
m_ml != (
int) (WMM_TYPE[12]-
'0')){
161 const double Tck = (*wmmRec)[ind]->getDouble(
"Tck");
162 const double activeBottomLength = (*wmmRec)[ind]->getDouble(
"activeBottomLength");
163 const double activeH = (*wmmRec)[ind]->getDouble(
"activeH");
164 const double activeTopLength = (*wmmRec)[ind]->getDouble(
"activeTopLength");
165 const double gasTck = (*wmmRec)[ind]->getDouble(
"gasTck");
166 const int nMissedBottomEta = (*wmmRec)[ind]->getInt(
"nMissedBottomEta");
167 const int nMissedBottomStereo = (*wmmRec)[ind]->getInt(
"nMissedBottomStereo");
168 const int nMissedTopEta = (*wmmRec)[ind]->getInt(
"nMissedTopEta");
169 const int nMissedTopStereo = (*wmmRec)[ind]->getInt(
"nMissedTopStereo");
171 assign(tokenizeInt((*wmmRec)[ind]->getString(
"readoutSide"),
";"),
m_readoutSide);
172 const std::vector<double>
stereoAngle{tokenizeDouble((*wmmRec)[ind]->getString(
"stereoAngle"),
";")};
173 const double stripPitch = (*wmmRec)[ind]->getDouble(
"stripPitch");
174 const int totalStrips = (*wmmRec)[ind]->getInt (
"totalStrips");
175 const double ylFrame = (*wmmRec)[ind]->getDouble(
"ylFrame");
176 const double ysFrame = (*wmmRec)[ind]->getDouble(
"ysFrame");
182 m_offset = -0.5*(ylFrame - ysFrame);
215 <<
", strip pitch " << design.
inputPitch <<
", nstrips " << design.
nch
216 <<
" stereo " << design.
stereoAngle() / Gaudi::Units::degree
230 SmartIF<IGeoDbTagSvc> geoDbTag{Gaudi::svcLocator()->service(
"GeoDbTagSvc")};
234 if (geoDbTag->getSqliteReader()) {
246 double ylFrame = mm->ylFrame();
247 double ysFrame = mm->ysFrame();
260 m_offset = -0.5*(ylFrame - ysFrame);
296 <<
", strip pitch " << design.
inputPitch <<
", nstrips " << design.
nch
297 <<
" stereo " << design.
stereoAngle() / Gaudi::Units::degree
314 for (
int layer = 0; layer <
m_nlayers; ++layer) {
317 const double sAngle =
m_etaDesign[layer].stereoAngle();
318 m_surfaceData->m_layerSurfaces.emplace_back(std::make_unique<Trk::PlaneSurface>(*
this,
id));
333 ATH_MSG_DEBUG(
"MMReadoutElement layer " << layer <<
" sAngle " << sAngle <<
" phi direction MM eta strip "
334 << (
m_surfaceData->m_layerTransforms.back().linear() * Amg::Vector3D::UnitY()).phi() );
347 if (gasgap < 1 || gasgap >
m_nlayers)
return false;
374 const Amg::Transform3D permute{GeoTrf::GeoRotation{90.*Gaudi::Units::deg,90.*Gaudi::Units::deg, 0.}};
391 m_delta = Amg::Transform3D::Identity();
407 double t0 = locPosML.x();
408 double s0 = locPosML.y();
409 double z0 = locPosML.z();
418 double bp =
m_BLinePar->getParameter(Parameter::bp);
419 double bn =
m_BLinePar->getParameter(Parameter::bn);
421 double sn =
m_BLinePar->getParameter(Parameter::sn);
422 double tw =
m_BLinePar->getParameter(Parameter::tw);
423 double eg =
m_BLinePar->getParameter(Parameter::eg)*1.e-3;
424 double ep =
m_BLinePar->getParameter(Parameter::ep)*1.e-3;
425 double en =
m_BLinePar->getParameter(Parameter::en)*1.e-3;
427 double ds{0.}, dz{0.}, dt{0.};
429 if (bp != 0 || bn != 0)
430 dt += 0.5*(s_rel*s_rel - 1)*((bp + bn) + (bp - bn)*z_rel);
432 if (
sp != 0 || sn != 0)
433 dt += 0.5*(z_rel*z_rel - 1)*((
sp + sn) + (
sp - sn)*s_rel);
436 dt -= tw*s_rel*z_rel;
446 if (ep != 0 || en != 0) {
450 double delta = s_rel*s_rel * ((ep + en)*s_rel/6 + (ep - en)/4);
451 double phi = s_rel * ((ep + en)*s_rel + (ep - en)) / 2;
470 ATH_MSG_WARNING(
"Unable to get MuonChannelDesign, therefore cannot provide position corrections. Returning." );
474 bool conditionsApplied{
false};
477#ifndef SIMULATIONBASE
488 ATH_MSG_WARNING(
"As-built corrections are provided only within the active area. Returning." );
505 pos[0] += strip_id.
ilayer%2 ? -2.75 : 2.75;
510 conditionsApplied =
true;
522 if (!conditionsApplied) {
527 conditionsApplied =
true;
533 if (conditionsApplied) pos = trfToML.inverse()*pos;
Scalar phi() const
phi method
#define ATH_MSG_VERBOSE(x)
#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_MM(MSG)
Amg::Transform3D delta() const
Returns the final transformations of the A lines.
virtual unsigned int size() const =0
MMDetectorDescription * Get_MMDetector(char type, int ieta, int iphi, int layer=1, char side='A')
void posOnDefChamber(Amg::Vector3D &locPosML) const
transform a position (in chamber-frame coordinates) to the deformed-chamber geometry
double stereoAngle(const Identifier &id) const
Wrapper to MuonChannelDesign::stereoAngle()
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
~MMReadoutElement()
destructor
std::array< Amg::Transform3D, 4 > m_Xlg
void initDesign()
initialize the design classes for this readout element
MMReadoutElement(GeoVFullPhysVol *pv, const std::string &stName, int zi, int fi, int mL, MuonDetectorManager *mgr)
constructor
void setDelta(const ALinePar &aline)
Amg::Vector3D localToGlobalCoords(const Amg::Vector3D &locPos, const Identifier &id) const
simHit local (SD) To Global position - to be used by MuonGeoAdaprors only
virtual void fillCache() override final
function to fill tracking cache
void setBLinePar(const BLinePar &bLine)
read B-line (chamber-deformation) parameters
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...
const BLinePar * m_BLinePar
std::array< int, 4 > m_readoutSide
void setChamberLayer(int ml)
set methods only to be used by MuonGeoModel
const MuonChannelDesign * getDesign(const Identifier &id) const
returns the MuonChannelDesign class for the given identifier
const MmIdHelper & m_idHelper
std::array< MuonChannelDesign, 4 > m_etaDesign
const ALinePar * m_ALinePar
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 NswAsBuilt::StripCalculator * getMMAsBuiltCalculator() 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.
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
Ensure that the Athena extensions are properly loaded.
Ensure that the ATLAS eigen extensions are properly loaded.
double activeBottomLength
std::vector< double > stereoAngle
std::vector< int > readoutSide
double stereoAngle() const
returns the stereo angle
double hasStereoAngle() const
returns whether the stereo angle is non-zero
double firstPos() const
Returns the position of the first strip along the x-axis.
void defineTrapezoid(double HalfShortY, double HalfLongY, double HalfHeight)
set the trapezoid dimensions
int positionRelativeToStrip(const Amg::Vector2D &lpos, Amg::Vector2D &rel_pos) const
STRIPS ONLY.
void setFirstPos(const double pos)
Set the position of the first strip along the x-axis.
Athena indices of a MM strip.
quadrupletIdentifier_t quadruplet