10#include "CLHEP/Geometry/Vector3D.h"
11#include "CLHEP/Units/SystemOfUnits.h"
12#include "CLHEP/Vector/ThreeVector.h"
22 const GeoVFullPhysVol* geophysvol,
42 const HepGeom::Transform3D&
46 return m_cache.ptr()->m_transformCLHEP;
49 const HepGeom::Transform3D
53 const GeoTrf::Transform3D* ptrXf =
m_geoAlignStore->getDefAbsPosition(getMaterialGeom());
66 const HepGeom::Vector3D<double>&
70 return m_cache.ptr()->m_phiAxisCLHEP;
77 return m_cache.ptr()->m_phiAxis;
80 const HepGeom::Vector3D<double>&
84 return m_cache.ptr()->m_etaAxisCLHEP;
91 return m_cache.ptr()->m_etaAxis;
100 if (!dir.m_etaDirection) xEta = -xEta;
101 if (!dir.m_phiDirection) xPhi = -xPhi;
108 double r = std::hypot(
x,
y);
109 double phi = std::atan2(
y,
x);
116 HepGeom::Point3D<double>
124 double xPhi = hitPosition[
m_hitPhi];
125 double xEta = hitPosition[
m_hitEta];
126 if (!dir.m_depthDirection) xDepth = -xDepth;
127 if (!dir.m_phiDirection) xPhi = -xPhi;
128 if (!dir.m_etaDirection) xEta = -xEta;
129 return {xPhi, xEta, xDepth};
143 HepGeom::Point3D<double> corners[4];
148 double phiOffset = 0.;
150 for (
auto & corner : corners) {
151 double etaMinPoint = 0.;
152 double etaMaxPoint = 0.;
153 double phiPoint = 0.;
156 getEtaPhiPoint(corner, deltaZ, etaMinPoint, etaMaxPoint, phiPoint);
163 if (phiPoint < -0.5 *
M_PI) {
164 phiOffset = -0.5 *
M_PI;
165 }
else if (phiPoint > 0.5 *
M_PI) {
166 phiOffset = 0.5 *
M_PI;
169 etaMin = etaMinPoint;
170 etaMax = etaMaxPoint;
172 phiPoint -= phiOffset;
174 if (phiPoint < -
M_PI) phiPoint += 2. *
M_PI;
175 if (phiPoint >
M_PI) phiPoint -= 2. *
M_PI;
178 etaMin = std::min(etaMin, etaMinPoint);
179 etaMax = std::max(etaMax, etaMaxPoint);
205 double phiTol,
double etaTol)
const
232 return m_design->localPositionOfCell(cellId);
239 return m_design->localPositionOfCell(cellId);
246 return m_design->numberOfConnectedCells(readoutId);
260 if (!
m_id.is_valid())
throw std::runtime_error(
"SolidStateDetectorElementBase: Invalid identifier");
263 m_surface = std::make_unique<Trk::PlaneSurface>(*
this);
278 const GeoTrf::Transform3D* ptrXf;
279 GeoTrf::Transform3D geotrf;
288 geotrf = (*ptrXf) *
m_design->moduleShift();
291 geotrf.setIdentity();
299 geotrf = getMaterialGeom()->getAbsoluteTransform() *
m_design->moduleShift();
302 const GeoTrf::Transform3D& geoTransform = geotrf;
310 cache.
m_origin = geoTransform * centerGeoModel;
334 bool setAxisDir =
false;
344 Amg::Vector3D globalDepthAxis(geoTransform.linear() * geoModelDepthAxis);
345 Amg::Vector3D globalPhiAxis(geoTransform.linear() * geoModelPhiAxis);
346 Amg::Vector3D globalEtaAxis(geoTransform.linear() * geoModelEtaAxis);
363 dir.m_barrelLike =
true;
365 if (std::abs(globalEtaAxis.dot(nominalEta)) < 0.5) {
366 dir.m_barrelLike =
false;
369 if (dir.m_barrelLike) {
371 nominalNormal = unitR;
373 nominalNormal(2) = -1.0;
382 dir.m_depthAngle = globalDepthAxis.dot(nominalNormal);
383 dir.m_depthDirection =
true;
384 if (dir.m_depthAngle < 0) {
386 dir.m_depthDirection =
false;
392 ATH_MSG_VERBOSE(
"Orientation of local depth axis does not follow Run 1/2/3 convention.");
405 dir.m_phiAngle = globalPhiAxis.dot(nominalPhi);
406 dir.m_phiDirection =
true;
407 if (dir.m_phiAngle < 0) {
409 dir.m_phiDirection =
false;
414 if (not isHGTD and std::abs(dir.m_phiAngle) < 0.5) {
415 ATH_MSG_VERBOSE(
"Orientation of local xPhi axis does not follow Run 1/2/3 convention.");
421 dir.m_etaAngle = globalEtaAxis.dot(nominalEta);
422 dir.m_etaDirection =
true;
423 if (dir.m_etaAngle < 0) {
425 dir.m_etaDirection =
false;
430 if (not isHGTD and std::abs(dir.m_etaAngle) < 0.5) {
431 ATH_MSG_VERBOSE(
"Orientation of local xEta axis does not follow Run 1/2/3 convention.");
449 double det = t(0,0) * (t(1,1)*t(2,2) - t(1,2)*t(2,1)) -
450 t(0,1) * (t(1,0)*t(2,2) - t(1,2)*t(2,0)) +
451 t(0,2) * (t(1,0)*t(2,1) - t(1,1)*t(2,0));
453 ATH_MSG_DEBUG(
"Local frame is left-handed. (hitEtaDirection, hitPhiDirection, hitDepthDirection) = ("
454 << dir.m_etaDirection <<
", "
455 << dir.m_phiDirection <<
", "
456 << dir.m_depthDirection <<
")");
473 m_cache.set (std::move (cache));
483 double radialShift = sensorCenter[0];
485 HepGeom::Point3D<double> corners[4];
490 double phiOffset = 0.;
493 const HepGeom::Transform3D rShift = HepGeom::TranslateY3D(radialShift);
495 for (
auto & corner : corners) {
497 corner.transform(rShift);
503 double rPoint = globalPoint.perp();
504 double zPoint = globalPoint.z();
505 double phiPoint = globalPoint.phi();
513 if (phiPoint < -0.5 *
M_PI) {
514 phiOffset = -0.5 *
M_PI;
515 }
else if (phiPoint > 0.5 *
M_PI) {
516 phiOffset = 0.5 *
M_PI;
523 phiPoint -= phiOffset;
525 if (phiPoint < -
M_PI) phiPoint += 2. *
M_PI;
526 if (phiPoint >
M_PI) phiPoint -= 2. *
M_PI;
558 double tmpLength =
length();
561 corners[0][
distPhi] = -0.5 * tmpMinWidth;
562 corners[0][
distEta] = -0.5 * tmpLength;
566 corners[1][
distPhi] = 0.5 * tmpMinWidth;
567 corners[1][
distEta] = -0.5 * tmpLength;
571 corners[2][
distPhi] = 0.5 * tmpMaxWidth;
572 corners[2][
distEta] = 0.5 * tmpLength;
576 corners[3][
distPhi] = -0.5 * tmpMaxWidth;
577 corners[3][
distEta] = 0.5 * tmpLength;
587 double& etaMin,
double& etaMax,
double&
phi)
const
592 double r = globalPoint.perp();
593 double z = globalPoint.z();
595 double thetaMin = std::atan2(
r,(
z + deltaZ));
596 etaMax = -std::log(tan(0.5 * thetaMin));
597 double thetaMax = std::atan2(
r,(
z - deltaZ));
598 etaMin = -std::log(tan(0.5 * thetaMax));
600 phi = globalPoint.phi();
603 const HepGeom::Transform3D
620 static const HepGeom::Vector3D<double> localAxes[3] = {
621 HepGeom::Vector3D<double>(1., 0., 0.),
622 HepGeom::Vector3D<double>(0., 1., 0.),
623 HepGeom::Vector3D<double>(0., 0., 1.)
627 int signPhi = dir.m_phiDirection? +1:-1;
628 int signEta = dir.m_etaDirection? +1:-1;
630 const HepGeom::Transform3D recoToHit(HepGeom::Point3D<double>(0., 0., 0.),
633 HepGeom::Point3D<double>(0., 0., 0.),
Scalar phi() const
phi method
#define ATH_MSG_VERBOSE(x)
bool is_hgtd(Identifier id) const
Ensure that the extensions for the Vector3D are properly loaded.
Base class for the detector design classes for ITk and HGTD.
Identifier for the strip or pixel cell.
Helper class to concentrate common items, such as the pointer to the IdHelper, the lorentzAngle tool ...
class to run intersection tests
Identifier for the strip or pixel readout cell.
void getExtent(CachedVals &cache) const
Calculate extent in r,z and phi.
const Amg::Transform3D defTransform() const
double length() const
Length in eta direction (z - barrel, r - endcap)
virtual const DetectorDesign & design() const
access to the local description (inline):
HepGeom::Point3D< double > hitLocalToLocal3D(const HepGeom::Point3D< double > &hitPosition) const
Same as previuos method but 3D.
std::unique_ptr< Trk::Surface > m_surface
SiCellId connectedCell(const SiCellId cellId, int number) const
Get the cell ids sharing the readout for this cell.
SiCellId cellIdOfPosition(const Amg::Vector2D &localPos) const
As in previous method but returns SiCellId.
void getEtaPhiRegion(double deltaZ, double &etaMin, double &etaMax, double &phiMin, double &phiMax, double &rz) const
Method for building up region of interest table.
const Amg::Vector3D & etaAxis() const
Amg::Vector2D localPosition(const HepGeom::Point3D< double > &globalPosition) const
transform a global position into a 2D local position (reconstruction frame) (inline)
const GeoAlignmentStore * m_geoAlignStore
DetectorDesign::Axis m_hitEta
Axes.
const HepGeom::Transform3D recoToHitTransform() const
Transform to go from local reconstruction frame to local hit frame.
void getCorners(HepGeom::Point3D< double > *corners) const
Return the four corners of an element in local coordinates.
const DetectorDesign * m_design
local description of this detector element
virtual SiCellId cellIdFromIdentifier(const Identifier &identifier) const =0
SiCellId from Identifier.
const SiCommonItems * m_commonItems
SolidStateDetectorElementBase()=delete
Don't allow no-argument constructor.
virtual const Trk::SurfaceBounds & bounds() const override final
Return the boundaries of the element.
CxxUtils::CachedValue< CachedVals > m_cache
int numberOfConnectedCells(const SiCellId cellId) const
Test if readout cell has more than one diode associated with it.
virtual double get_rz() const =0
virtual ~SolidStateDetectorElementBase()
Destructor.
double maxWidth() const
Max width.
HepGeom::Point3D< double > globalPosition(const HepGeom::Point3D< double > &localPos) const
transform a reconstruction local position into a global position (inline):
SiIntersect inDetector(const Amg::Vector2D &localPosition, double phiTol, double etaTol) const
Test that it is in the active region.
const Amg::Vector3D & phiAxis() const
void getEtaPhiPoint(const HepGeom::Point3D< double > &point, double deltaZ, double &etaMin, double &etaMax, double &phi) const
Get eta and phi coresponding to a point in local coordinates.
Identifier identifierOfPosition(const Amg::Vector2D &localPos) const
Full identifier of the cell for a given position: assumes a raw local position (no Lorentz shift)
const HepGeom::Vector3D< double > & phiAxisCLHEP() const
To determine if readout direction between online and offline needs swapping, see methods swapPhiReado...
virtual void updateCache() const
Recalculate cached values.
double minWidth() const
Min width.
DetectorDesign::Axis m_hitPhi
const HepGeom::Transform3D & transformCLHEP() const
Local (reconstruction frame) to global transform.
const HepGeom::Vector3D< double > & etaAxisCLHEP() const
Get reconstruction local eta axes in global frame.
CxxUtils::CachedValue< AxisDir > m_axisDir
const HepGeom::Transform3D defTransformCLHEP() const
Default Local (reconstruction frame) to global transform ie with no misalignment.
virtual Identifier identifierFromCellId(const SiCellId &cellId) const =0
Identifier <-> SiCellId (ie strip number or pixel eta_index,phi_index) Identifier from SiCellId (ie s...
DetectorDesign::Axis m_hitDepth
void commonConstructor()
Common code for constructors.
const AtlasDetectorID * getIdHelper() const
Returns the id helper (inline)
Amg::Vector2D rawLocalPositionOfCell(const SiCellId &cellId) const
Returns position (center) of cell.
Amg::Vector2D hitLocalToLocal(double xEta, double xPhi) const
Simulation/Hit local frame to reconstruction local frame.
Identifier m_id
identifier of this detector element
Abstract base class for surface bounds to be specified.
TrkDetElementBase(const GeoVFullPhysVol *fullPhysVol)
Constructor from GeoVFullPhysVolume.
HepGeom::Transform3D EigenTransformToCLHEP(const Amg::Transform3D &eigenTransf)
Converts an Eigen-based Amg::Transform3D into a CLHEP-based HepGeom::Transform3D.
Amg::Transform3D CLHEPTransformToEigen(const HepGeom::Transform3D &CLHEPtransf)
Converts a CLHEP-based HepGeom::Transform3D into an Eigen Amg::Transform3D.
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
@ distEta
readout for silicon
@ distEta
readout for silicon
HepGeom::Transform3D m_transformCLHEP
Amg::Transform3D m_transformHit
HepGeom::Vector3D< double > m_centerCLHEP
HepGeom::Vector3D< double > m_etaAxisCLHEP
HepGeom::Vector3D< double > m_phiAxisCLHEP
Amg::Transform3D m_transform
std::string number(const double &d, const std::string &s)