7#include <GaudiKernel/IMessageSvc.h>
8#include <GeoModelKernel/GeoDefinitions.h>
9#include <GeoModelKernel/GeoLogVol.h>
10#include <GeoModelKernel/GeoVFullPhysVol.h>
11#include <GeoModelKernel/GeoVPhysVol.h>
23#include "GaudiKernel/MsgStream.h"
24#include "GeoModelKernel/GeoFullPhysVol.h"
46 for (
unsigned int i = 0; i < 4; i++)
m_wireplanez[i] = 0.;
48 if (mgr->MinimalGeoFlag() == 0) {
49 if (GeoFullPhysVol* pvc =
dynamic_cast<GeoFullPhysVol*
>(pv)) {
50 unsigned int nchildvol = pvc->getNChildVols();
52 std::string::size_type npos;
53 for (
unsigned ich = 0; ich < nchildvol; ich++) {
54 PVConstLink pc = pvc->getChildVol(ich);
55 std::string childname = (pc->getLogVol())->getName();
56 int nch1 = pc->getNChildVols();
58 for (
int ngv = 0; ngv < nch1; ngv++) {
59 PVConstLink pcgv = pc->getChildVol(ngv);
60 std::string childname1 = (pcgv->getLogVol())->getName();
62 if ((npos = childname1.find(
"CscArCO2")) != std::string::npos) {
63 const GeoTrf::Vector3D trans = (pvc->getXToChildVol(ich) * pc->getXToChildVol(ngv)).translation();
70 std::stringstream error_str{};
71 error_str<<__FILE__<<
":"<<__LINE__<<
" - Cannot performa dynamic cast!";
72 throw std::runtime_error(error_str.str());
81 for (
unsigned int i = 0; i < 4; ++i) {
82 for (
unsigned int j = 0; j < 3; ++j) {
86 for (
unsigned int i = 0; i < 4; ++i) {
87 for (
unsigned int j = 0; j < 3; ++j) {
142 if (log.level() <= MSG::VERBOSE) log <<
"CscReadoutElement::wireLayerPos got localWireLayerPos " << localP <<
endmsg;
144 return cscTrans * localP;
193 return (realLength * sWidth / (lWidth - sWidth));
198 double gslWidth = shortLongWidth - 2 *
roxacellWidth() * (1 - std::cos(alpha)) / std::sin(alpha);
199 lWidth = 2 * (bigLength + 0.5 * sWidth / std::tan(beta) + 0.5 * gslWidth * std::tan(alpha)) /
200 (std::tan(alpha) + 1.0 / std::tan(beta));
201 double shortLength = bigLength - (lWidth - gslWidth) * std::tan(alpha) / 2.;
202 return (shortLength * sWidth / (lWidth - sWidth));
213 int channel = idh->
strip(
id);
223 int channel = idh->
strip(
id);
233 int channel = idh->
strip(
id);
234 return stripPos(
eta, chamberLayer, wireLayer, measPhi, channel);
242 int channel = idh->
strip(
id);
251 return cscTrans * localP;
257 return cscTrans * localP;
286 int channel = idh->
strip(
id);
288 return stripLength(chamberLayer, measPhi, channel, epsilon);
301 double gslWidth{0.}, sLength{0.};
306 gslWidth = shortLongWidth - 2 *
roxacellWidth() * (1 - std::cos(alpha)) / std::sin(alpha);
307 bigWidth = 2 * (chamberLength + 0.5 * smallWidth / std::tan(beta) + 0.5 * gslWidth * std::tan(alpha)) /
308 (std::tan(alpha) + 1.0 / std::tan(beta));
317 sLength = 2.0 * (effectiveLength / 2.0 + pos) * std::tan(beta) + smallWidth;
320 sLength = chamberLength;
324 double shortLength = chamberLength - (bigWidth - gslWidth) * std::tan(alpha) / 2.;
325 sLength = chamberLength - 2.0 *
diff * shortLength / (bigWidth - smallWidth);
327 sLength = chamberLength * (1.0 - 2.0 *
diff / (bigWidth - smallWidth));
330 return (sLength - epsilon);
336 double epsilon = 0.0;
342 double gslWidth = shortLongWidth - 2 *
roxacellWidth() * (1 - std::cos(alpha)) / std::sin(alpha);
344 double bigWidth = 2 * (bigLength + 0.5 * smallWidth / std::tan(beta) + 0.5 * gslWidth * std::tan(alpha)) /
345 (std::tan(alpha) + 1.0 / std::tan(beta));
346 double shortLength = bigLength - (bigWidth - gslWidth) * std::tan(alpha) / 2.;
349 if (std::abs(
stripPos) > (gslWidth / 2.)) epsilon = (std::abs(
stripPos) - gslWidth / 2.) * std::tan(alpha);
351 double z0 = shortLength - bigLength / 2;
354 double corr1 =
diff / std::tan(alpha);
355 double corr2 =
diff * std::tan(beta);
356 epsilon = 2.0 * (corr1 + corr2);
359 if (epsilon < 0.0) epsilon = 0.0;
372 return transfPtr_internalgeo * nominalLP;
380 double x = stripPlane.x();
381 double y = stripPlane.y();
382 double z = stripPlane.z();
389 double epsilon = 0.0;
415 double x = wireLayerPosition.x();
416 double y = wireLayerPosition.y();
417 double z = wireLayerPosition.z();
436 transfPtr_internalgeo *=
442 return transfPtr_internalgeo * nominalLCP;
449 return cscTrans.inverse() * globalP;
456 return cscTrans * localP;
471 double pos = stripWidth * (
strip - 0.5 -
nStrips / 2.0);
472 if (
eta > 0 && measPhi) pos *= -1;
478 if (measPhi != 0 && measPhi != 1)
throw std::runtime_error (
"CscReadoutElement::localStripLayerPos bad measPhi");
481 double x = wireLayerPosition.x();
482 double y = wireLayerPosition.y();
483 double z = wireLayerPosition.z();
485 if (wireLayer == 1 || wireLayer == 3) {
487 x = wireLayerPosition.x() + anodeCathodeDis;
489 x = wireLayerPosition.x() - anodeCathodeDis;
492 x = wireLayerPosition.x() - anodeCathodeDis;
494 x = wireLayerPosition.x() + anodeCathodeDis;
506 if (measPhi == 0)
return 1.0;
517 double sinstero = (posStrip.y() * etaAxis.x() - posStrip.x() * etaAxis.y()) / (posStrip.perp() * etaAxis.perp());
524 if (log.level() <= MSG::VERBOSE) {
525 constexpr std::array<int, 2>
eta{1, -1};
526 constexpr std::array<int, 2> maxStrips{192, 48};
527 int chamberLayer = 1;
529 for (
int measPhi = 0; measPhi < 2; ++measPhi) {
530 for (
int ieta = 0; ieta < 2; ++ieta) {
531 for (
int ilayer = 1; ilayer <= wireLayer; ++ilayer) {
532 int strips[3] = {1, maxStrips[measPhi] / 2, maxStrips[measPhi]};
533 for (
int i = 0; i < 3; i++) {
534 int istrip = strips[i];
537 log << MSG::VERBOSE <<
"the nominal positions = " << npos.x() <<
" " << npos.y() <<
" " << npos.z() <<
endmsg;
538 log << MSG::VERBOSE <<
"the positions = " << pos.x() <<
" " << pos.y() <<
" " << pos.z() <<
endmsg;
560 if (!idh->
get_id(hash,
id, &context))
569 return cscTrans * localP;
575 const int wlayer = idh.
wireLayer(
x.identify());
576 const bool notAllowedLayer = (wlayer > 4 || wlayer <1);
581 <<
"Inconsistent CSC int. Aline assignment - Internal alignment will not be applied ");
589 m_cscIntRot[wlayer - 1][0] =
x.getParameter(Parameter::rotS);
590 m_cscIntRot[wlayer - 1][1] =
x.getParameter(Parameter::rotZ);
591 m_cscIntRot[wlayer - 1][2] =
x.getParameter(Parameter::rotT);
593 for (
unsigned int j = 0; j < 3; ++j) {
594 ATH_MSG_DEBUG(
"<CscReadoutElement::setCscInternalAlignmentPar()>: m_cscIntTransl[" << (wlayer - 1) <<
"][" << j
596 ATH_MSG_DEBUG(
"<CscReadoutElement::setCscInternalAlignmentPar()>: m_cscIntRot[" << (wlayer - 1) <<
"][" << j
621 surfaceTRotation.col(0) = muonTRotation.col(1);
622 surfaceTRotation.col(1) = muonTRotation.col(2);
623 surfaceTRotation.col(2) = muonTRotation.col(0);
624 if (measPhi == 0) surfaceTRotation = surfaceTRotation *
Amg::AngleAxis3D(
M_PI / 2., Amg::Vector3D::UnitZ());
630 if (log.level() <= MSG::DEBUG) {
631 log << MSG::DEBUG <<
"nominalTransform+++++++++++Original Tranformation ++++++++++++++++++++++" <<
endmsg;
632 log << MSG::DEBUG << (transfPtr_orig)(0, 0) <<
" " << (transfPtr_orig)(0, 1) <<
" " << (transfPtr_orig)(0, 2) <<
" "
633 << (transfPtr_orig)(0, 3) <<
endmsg;
634 log << MSG::DEBUG << (transfPtr_orig)(1, 0) <<
" " << (transfPtr_orig)(1, 1) <<
" " << (transfPtr_orig)(1, 2) <<
" "
635 << (transfPtr_orig)(1, 3) <<
endmsg;
636 log << MSG::DEBUG << (transfPtr_orig)(2, 0) <<
" " << (transfPtr_orig)(2, 1) <<
" " << (transfPtr_orig)(2, 2) <<
" "
637 << (transfPtr_orig)(2, 3) <<
endmsg;
638 log << MSG::DEBUG <<
"+++++ transf ends " <<
endmsg;
641 return transfPtr_orig;
664 if (log.level() <= MSG::WARNING) log << MSG::WARNING <<
"calling fillCache on an already filled cache" <<
endmsg;
673 for (
int mp = 1; mp >= 0; --mp) {
681 surfaceTRotation.col(0) = muonTRotation.col(1);
682 surfaceTRotation.col(1) = muonTRotation.col(2);
683 surfaceTRotation.col(2) = muonTRotation.col(0);
684 if (mp == 0) surfaceTRotation = surfaceTRotation *
Amg::AngleAxis3D(
M_PI / 2., Amg::Vector3D::UnitZ());
687 transfPtr_orig.pretranslate(trans3D.translation());
690 transfPtr_internalgeo *=
696 transfPtr_internalgeo *=
704 m_surfaceData->m_layerSurfaces.emplace_back(std::make_unique<Trk::PlaneSurface>(*
this,
id));
725 if (wireLayer < 1 || wireLayer >
Ngasgaps())
return false;
728 int channel = idh->
strip(
id);
730 if (channel < 1 || channel >
NetaStrips(wireLayer))
return false;
731 }
else if (measPhi == 1) {
732 if (channel < 1 || channel >
NphiStrips(wireLayer))
return false;
741 if (log.level() <= MSG::WARNING) log << MSG::WARNING <<
" distanceToReadout::dummy routine " <<
endmsg;
747 if (log.level() <= MSG::WARNING) log << MSG::WARNING <<
" stripNumber::dummy routine " <<
endmsg;
754 if (!
surface(
id).globalToLocal(gpos, gpos, pos)) {
756 if (log.level() <= MSG::WARNING)
757 log << MSG::WARNING <<
" stripPosition:: globalToLocal failed " <<
surface(
id).
transform().inverse() * gpos <<
endmsg;
Scalar eta() const
pseudorapidity method
#define ATH_MSG_WARNING(x)
void diff(const Jet &rJet1, const Jet &rJet2, std::map< std::string, double > varDiff)
Difference between jets - Non-Class function required by trigger.
Parameter
amdb frame (s, z, t) = chamber frame (y, z, x)
Identifier parentID(const Identifier &id) const
get parent id from channel id
Identifier channelID(int stationName, int stationEta, int stationPhi, int chamberLayer, int wireLayer, int measuresPhi, int strip) const
Identifier elementID(int stationName, int stationEta, int stationPhi) const
int wireLayer(const Identifier &id) const
int chamberLayer(const Identifier &id) const
int strip(const Identifier &id) const
bool measuresPhi(const Identifier &id) const override
This class saves the "context" of an expanded identifier (ExpandedIdentifier) for compact or hash ver...
This is a "hash" representation of an Identifier.
double lengthUpToMaxWidth() const
Amg::Vector3D localClusterPos(int eta, int wireLayer, int measPhi, double x0) const
takes into account internal alignment parameters, hence gives generally answer (local here is the sta...
virtual bool stripPosition(const Identifier &id, Amg::Vector2D &pos) const override final
strip position If the strip number is outside the range of valid strips, the function will return fal...
Amg::Vector3D localStripPos(const Identifier &id) const
takes into account internal alignment parameters, hence gives generally accurate answer (local here i...
double stripLength(int chamberLayer, int measuresPhi, int stripNumber, double &epsilon) const
std::array< double, maxwlay > m_wireplanez
Amg::Vector3D nominalLocalStripPos(const Identifier &id) const
ignores internal alignment parameters, hence gives generally incorrect answer (local here is the stat...
double getGasGapIntAlign_t(int gasGap) const
double shortWidth() const
double StripPitch(int chlayer, int measphi) const
double StripWidth(int chlayer, int measphi) const
double cathodeReadoutPitch(int chLayer, int measuresPhi) const
virtual bool measuresPhi(const Identifier &id) const override final
returns whether the given identifier measures phi or not
Amg::Vector3D nominalLocalClusterPos(int eta, int wireLayer, int measPhi, double x0) const
ignores internal alignment parameters, hence gives generally incorrect answer (local here is the stat...
virtual int stripNumber(const Amg::Vector2D &pos, const Identifier &id) const override final
strip number corresponding to local position.
Amg::Vector3D wireLayerPos(const Identifier &id) const
double getGasGapIntAlign_rots(int gasGap) const
double getGasGapIntAlign_rotz(int gasGap) const
double getGasGapIntAlign_z(int gasGap) const
virtual bool spacePointPosition(const Identifier &phiId, const Identifier &etaId, Amg::Vector2D &pos) const override
space point position for a given pair of phi and eta identifiers The LocalPosition is expressed in th...
Amg::Vector3D globalToLocalCoords(const Amg::Vector3D &x, const Identifier &id) const
double activeWidth(int measuresPhi) const
double sinStereo(const Identifier &stripId) const
Amg::Vector3D globalPos(const Amg::Vector3D &localP) const
station-level method: does not depend on the strip view/layer, hence it cannot account for internal a...
double lengthCorrection(int measuresPhi, double stripPos) const
virtual int numberOfStrips(const Identifier &layerId) const override final
number of strips per layer
virtual ~CscReadoutElement()
Amg::Vector3D localPos(const Amg::Vector3D &globalP) const
station-level method: does not depend on the strip view/layer, hence it cannot account for internal a...
int NphiStrips(int gasgaplayer) const
Amg::Vector3D localToGlobalCoords(const Amg::Vector3D &x, const Identifier &id) const
localToGlobalCoords and Transf connect the Gas Gap Frame (defined as a Sensitive Detector) to the Glo...
Amg::Transform3D nominalTransform(const Identifier &id) const
like tracking Transform but nominal - returns a transform not a reference to it
double getGasGapIntAlign_rott(int gasGap) const
double m_cscIntTransl[4][3]
Amg::Vector3D stripPosOnTrackingSurface(const Identifier &id) const
nominal strip pos in the tracking local frame of the measurement surface
Amg::Vector3D stripPos(const Identifier &id) const
takes into account internal alignment parameters, hence gives accurate answer
double xCoordinateInTrackingFrame(const Identifier &id) const
virtual double distanceToReadout(const Amg::Vector2D &pos, const Identifier &id) const override final
distance to readout.
Amg::Transform3D globalToLocalTransf(const Identifier &id) const
Amg::Vector3D nominalCenter(int gasGap) const
like tracking center but nominal - returns a Amg::Vector3D not a reference to it
CscReadoutElement(GeoVFullPhysVol *pv, const std::string &stName, MuonDetectorManager *mgr)
Amg::Vector3D nominalGlobalPos(const Amg::Vector3D &localP) const
ignores internal alignment parameters, hence gives generally incorrect answer
double roxacellWidth() const
Amg::Transform3D localToGlobalTransf(const Identifier &id) const
virtual void fillCache() override
int NetaStrips(int gasgaplayer) const
Amg::Vector3D originForInternalALines(int gasGap) const
like tracking center but nominal - returns a Amg::Vector3D not a reference to it
Amg::Vector3D localWireLayerPos(const Identifier &id) const
virtual bool containsId(const Identifier &id) const override
Amg::Vector3D nominalStripPos(const Identifier &id) const
ignores internal alignment parameters, hence gives generally incorrect answer
Amg::Vector3D localStripLayerPos(const Identifier &id) const
int maxNumberOfStrips(int measuresPhi) const
double anodeCathodeDistance() const
void setCscInternalAlignmentPar(const ALinePar &)
double getGasGapIntAlign_s(int gasGap) const
Amg::Vector3D stripLayerPos(const Identifier &id) const
virtual const Trk::PlaneSurface & surface() const override
access to chamber surface (phi orientation), uses the first gas gap
virtual void clearCache() override final
clear the cache of the readout elememt
std::unique_ptr< SurfaceData > m_surfaceData
MuonClusterReadoutElement(GeoVFullPhysVol *pv, MuonDetectorManager *mgr, Trk::DetectorElemType detType)
The MuonDetectorManager stores the transient representation of the Muon Spectrometer geometry and pro...
const CscIdHelper * cscIdHelper() const
const Muon::IMuonIdHelperSvc * idHelperSvc() const
const Amg::Transform3D & absTransform() const
void setStationName(const std::string &)
const MuonDetectorManager * manager() const
Identifier identify() const override final
Returns the ATLAS Identifier of the MuonReadOutElement.
int stationEta(const Identifier &id) const
virtual int get_id(const IdentifierHash &hash_id, Identifier &id, const IdContext *context=0) const override
Create compact id from hash id (return == 0 for OK)
IdContext channel_context() const
id for channel
virtual const CscIdHelper & cscIdHelper() const =0
access to CscIdHelper
Abstract base class for surface bounds to be specified.
const Amg::Transform3D & transform() const
Returns HepGeom::Transform3D by reference.
singleton-like access to IMessageSvc via open function and helper
Eigen::AngleAxisd AngleAxis3D
Eigen::Matrix< double, 3, 3 > RotationMatrix3D
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
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.