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_ERROR(
"Orientation of local depth axis does not follow correct convention.");
393 dir.m_depthDirection =
true;
406 dir.m_phiAngle = globalPhiAxis.dot(nominalPhi);
407 dir.m_phiDirection =
true;
408 if (dir.m_phiAngle < 0) {
410 dir.m_phiDirection =
false;
415 if (not isHGTD and std::abs(dir.m_phiAngle) < 0.5) {
416 ATH_MSG_ERROR(
"Orientation of local xPhi axis does not follow correct convention.");
417 dir.m_phiDirection =
true;
423 dir.m_etaAngle = globalEtaAxis.dot(nominalEta);
424 dir.m_etaDirection =
true;
425 if (dir.m_etaAngle < 0) {
427 dir.m_etaDirection =
false;
432 if (not isHGTD and std::abs(dir.m_etaAngle) < 0.5) {
433 ATH_MSG_ERROR(
"Orientation of local xEta axis does not follow correct convention.");
434 dir.m_etaDirection =
true;
452 double det = t(0,0) * (t(1,1)*t(2,2) - t(1,2)*t(2,1)) -
453 t(0,1) * (t(1,0)*t(2,2) - t(1,2)*t(2,0)) +
454 t(0,2) * (t(1,0)*t(2,1) - t(1,1)*t(2,0));
456 ATH_MSG_DEBUG(
"Local frame is left-handed. (hitEtaDirection, hitPhiDirection, hitDepthDirection) = ("
457 << dir.m_etaDirection <<
", "
458 << dir.m_phiDirection <<
", "
459 << dir.m_depthDirection <<
")");
476 m_cache.set (std::move (cache));
486 double radialShift = sensorCenter[0];
488 HepGeom::Point3D<double> corners[4];
493 double phiOffset = 0.;
496 const HepGeom::Transform3D rShift = HepGeom::TranslateY3D(radialShift);
498 for (
auto & corner : corners) {
500 corner.transform(rShift);
506 double rPoint = globalPoint.perp();
507 double zPoint = globalPoint.z();
508 double phiPoint = globalPoint.phi();
516 if (phiPoint < -0.5 *
M_PI) {
517 phiOffset = -0.5 *
M_PI;
518 }
else if (phiPoint > 0.5 *
M_PI) {
519 phiOffset = 0.5 *
M_PI;
526 phiPoint -= phiOffset;
528 if (phiPoint < -
M_PI) phiPoint += 2. *
M_PI;
529 if (phiPoint >
M_PI) phiPoint -= 2. *
M_PI;
561 double tmpLength =
length();
564 corners[0][
distPhi] = -0.5 * tmpMinWidth;
565 corners[0][
distEta] = -0.5 * tmpLength;
569 corners[1][
distPhi] = 0.5 * tmpMinWidth;
570 corners[1][
distEta] = -0.5 * tmpLength;
574 corners[2][
distPhi] = 0.5 * tmpMaxWidth;
575 corners[2][
distEta] = 0.5 * tmpLength;
579 corners[3][
distPhi] = -0.5 * tmpMaxWidth;
580 corners[3][
distEta] = 0.5 * tmpLength;
590 double& etaMin,
double& etaMax,
double&
phi)
const
595 double r = globalPoint.perp();
596 double z = globalPoint.z();
598 double thetaMin = std::atan2(
r,(
z + deltaZ));
599 etaMax = -std::log(tan(0.5 * thetaMin));
600 double thetaMax = std::atan2(
r,(
z - deltaZ));
601 etaMin = -std::log(tan(0.5 * thetaMax));
603 phi = globalPoint.phi();
606 const HepGeom::Transform3D
623 static const HepGeom::Vector3D<double> localAxes[3] = {
624 HepGeom::Vector3D<double>(1., 0., 0.),
625 HepGeom::Vector3D<double>(0., 1., 0.),
626 HepGeom::Vector3D<double>(0., 0., 1.)
630 int signPhi = dir.m_phiDirection? +1:-1;
631 int signEta = dir.m_etaDirection? +1:-1;
633 const HepGeom::Transform3D recoToHit(HepGeom::Point3D<double>(0., 0., 0.),
636 HepGeom::Point3D<double>(0., 0., 0.),
Scalar phi() const
phi method
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)