ATLAS Offline Software
Loading...
Searching...
No Matches
ActsDetectorElement.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7#include "GeoModelKernel/throwExcept.h"
8
9// ATHENA
19#include "TrkSurfaces/Surface.h"
22
23// PACKAGE
25// ACTS
26#include "Acts/Definitions/Units.hpp"
27#include "Acts/Geometry/GeometryContext.hpp"
28#include "Acts/Surfaces/AnnulusBounds.hpp"
29#include "Acts/Surfaces/DiscSurface.hpp"
30#include "Acts/Surfaces/LineBounds.hpp"
31#include "Acts/Surfaces/PlaneSurface.hpp"
32#include "Acts/Surfaces/RectangleBounds.hpp"
33#include "Acts/Surfaces/StrawSurface.hpp"
34#include "Acts/Surfaces/TrapezoidBounds.hpp"
35#include "Acts/Visualization/ObjVisualization3D.hpp"
36#include "Acts/Visualization/PlyVisualization3D.hpp"
37
38
39// STL
40#include <mutex>
41#include <variant>
42
43
44using Acts::Surface;
45using Acts::Transform3;
46
47using namespace Acts::UnitLiterals;
48using namespace ActsTrk;
49
50
51constexpr double length_unit = 1_mm;
52
54 GeoVDetectorElement{detElem.getMaterialGeom()},
55 m_idHash(detElem.identifyHash()),
56 m_type{detElem.isPixel() ? DetectorType::Pixel : DetectorType::Sct},
57 m_detElement{&detElem},
59{
60
61
62 auto boundsType = detElem.bounds().type();
63
64 m_thickness = detElem.thickness();
65
66
67 if (boundsType == Trk::SurfaceBounds::Rectangle) {
68
69 const InDetDD::SiDetectorDesign &design = detElem.design();
70 double hlX = design.width() / 2. * length_unit;
71 double hlY = design.length() / 2. * length_unit;
72
73 auto rectangleBounds = std::make_shared<const Acts::RectangleBounds>(hlX, hlY);
74
75 m_bounds = rectangleBounds;
76 m_surface = Acts::Surface::makeShared<Acts::PlaneSurface>(rectangleBounds, *this);
77
78 } else if (boundsType == Trk::SurfaceBounds::Trapezoid) {
79
80 const InDetDD::SiDetectorDesign &design = detElem.design();
81
82 double minHlX = design.minWidth() / 2. * length_unit;
83 double maxHlX = design.maxWidth() / 2. * length_unit;
84 double hlY = design.length() / 2. * length_unit;
85
86 auto trapezoidBounds =
87 std::make_shared<const Acts::TrapezoidBounds>(minHlX, maxHlX, hlY);
88
89 m_bounds = trapezoidBounds;
90
91 m_surface = Acts::Surface::makeShared<Acts::PlaneSurface>(trapezoidBounds, *this);
92
93
94 } else if (boundsType == Trk::SurfaceBounds::Annulus) {
95
96 const InDetDD::SiDetectorDesign &design = detElem.design();
97 const auto *annulus = dynamic_cast<const InDetDD::StripStereoAnnulusDesign *>(&design);
98 if (annulus == nullptr) {
99 throw std::domain_error("ActsDetectorElement got inconsistent surface");
100 }
101
102 double phi = annulus->phiWidth();
103 double phiS = annulus->stereo();
104 double R = annulus->waferCentreR();
105 double maxR = annulus->maxR();
106 double minR = annulus->minR();
107
108 // phiAvg is the bounds-internal local rotation. We don't want one
109 double phiAvg = 0;
110 // phi is the total opening angle, set up symmetric phi bounds
111 double phiMax = phi / 2.;
112 double phiMin = -phiMax;
113
114
115 Amg::Vector2D originStripXYRotated(R * (1 - std::cos(phiS)),
116 R * std::sin(-phiS));
117
118 auto annulusBounds = std::make_shared<Acts::AnnulusBounds>(
119 minR, maxR, phiMin, phiMax, originStripXYRotated, phiAvg);
120 m_bounds = annulusBounds;
121
122 m_surface = Acts::Surface::makeShared<Acts::DiscSurface>(annulusBounds, *this);
123
124 } else {
125 std::cout << boundsType << std::endl;
126 throw std::domain_error("ActsDetectorElement does not support this surface type");
127 }
128}
129
130ActsDetectorElement::ActsDetectorElement(const Acts::Transform3 &trf,
131 const InDetDD::TRT_BaseElement &detElem,
132 const Identifier &id) :
133 GeoVDetectorElement{detElem.getMaterialGeom()},
134 m_idHash(detElem.identifyHash()),
136 m_detElement{&detElem},
137 m_trtTrf{std::make_unique<Amg::Transform3D>(trf)},
139{
140
141
142 // we know this is a straw
143 double length = detElem.strawLength() * 0.5 * length_unit;
144
145 // we need to find the radius
146 auto ecElem = dynamic_cast<const InDetDD::TRT_EndcapElement *>(&detElem);
147 auto brlElem = dynamic_cast<const InDetDD::TRT_BarrelElement *>(&detElem);
148 double innerTubeRadius{0.};
149 if (ecElem) {
150 innerTubeRadius = ecElem->getDescriptor()->innerTubeRadius() * length_unit;
151 } else {
152 if (brlElem) {
153 innerTubeRadius =
154 brlElem->getDescriptor()->innerTubeRadius() * length_unit;
155 } else {
156 THROW_EXCEPTION("Cannot get tube radius for element in ActsDetectorElement c'tor");
157 }
158 }
159
160 auto lineBounds =
161 std::make_shared<const Acts::LineBounds>(innerTubeRadius, length);
162 m_bounds = lineBounds;
163
164 m_surface = Acts::Surface::makeShared<Acts::StrawSurface>(lineBounds, *this);
165}
166
168 GeoVDetectorElement{detElem.getMaterialGeom()},
169 m_idHash(detElem.identifyHash()),
171 m_detElement{&detElem},
172 m_thickness{detElem.thickness()},
174{
175
176 auto boundsType = detElem.bounds().type();
177
178 if (boundsType == Trk::SurfaceBounds::Rectangle) {
179
180 const InDetDD::HGTD_ModuleDesign &design = detElem.design();
181 double hlX = design.width() / 2. * length_unit;
182 double hlY = design.length() / 2. * length_unit;
183
184 auto rectangleBounds =
185 std::make_shared<const Acts::RectangleBounds>(hlX, hlY);
186
187 m_bounds = rectangleBounds;
188
189 m_surface = Acts::Surface::makeShared<Acts::PlaneSurface>(rectangleBounds, *this);
190
191 } else {
192 throw std::domain_error(
193 "ActsDetectorElement: the surface type of HGTD is not does not Rectangle, it is wrong");
194 }
195}
196
198
199 GeoAlignmentStore* geoModelStore = store ? store->geoModelAlignment.get() : nullptr;
200 Amg::Transform3D l2g{Amg::Transform3D::Identity()};
201 switch (m_type) {
202 case DetectorType::Hgtd:{
203 l2g= m_detElement->getMaterialGeom()->getAbsoluteTransform(geoModelStore);
204 break;
205 } case DetectorType::Trt: {
206 l2g = (*m_trtTrf);
207 break;
208 }
210 default: {
211 const auto& detElem = static_cast<const InDetDD::SiDetectorElement&>(*m_detElement);
212 const InDetDD::SiDetectorDesign&design = detElem.design();
213 const Trk::SurfaceBounds::BoundsType boundsType = detElem.bounds().type();
214
215 // extra shift for split row modules
216 Amg::Transform3D extraTransform{Amg::CLHEPTransformToEigen(detElem.recoToHitTransform())};
217 if (boundsType == Trk::SurfaceBounds::Rectangle &&
218 typeid(design) == typeid(InDetDD::StripBoxDesign) ) {
219 extraTransform = design.moduleShift() * extraTransform;
220 } else if (boundsType == Trk::SurfaceBounds::Annulus) {
221 // need to rotate pi/2 to reproduce ABXY orientation, phiS so that phi=0
222 // is center and symmetric
223 const double phiShift = M_PI_2 - static_cast<const InDetDD::StripStereoAnnulusDesign&>(design).stereo();
224
225 const Amg::Vector2D origin2D = static_cast<const Acts::AnnulusBounds&>(m_surface->bounds()).moduleOrigin();
226 const Amg::Translation3D transl{origin2D.x(), origin2D.y(), 0};
227 const Amg::Transform3D originTrf{transl * Amg::getRotateZ3D(-phiShift)};
228 extraTransform = extraTransform * originTrf.inverse();
229 }
230 l2g = m_detElement->getMaterialGeom()->getAbsoluteTransform(geoModelStore) * extraTransform;
231 }
232 };
233 // need to make sure translation has correct units
234 l2g.translation() *= 1.0 / CLHEP::mm * length_unit;
235
236 return l2g;
237
238}
241 return IdentityHelper(static_cast<const InDetDD::SiDetectorElement *>(m_detElement));
242 } else {
243 throw std::domain_error("Cannot get IdentityHelper for TRT element");
244 }
245}
246
247const Acts::Transform3 &ActsDetectorElement::transform(const Acts::GeometryContext &anygctx) const {
248 return m_trfCache.transform(anygctx);
249}
250
252 if (store.detType != detectorType()) return 0;
253 m_trfCache.getTransform(&store);
254 return 1;
255}
256
257const Acts::Transform3 & ActsDetectorElement::getDefaultTransform() const {
258 return m_trfCache.getTransform(nullptr);
259}
260
261const Acts::Surface &ActsDetectorElement::surface() const {
262 return (*m_surface);
263}
264
266 return (*m_surface);
267}
268
270 if (const auto *detElem =
271 dynamic_cast<const InDetDD::SiDetectorElement *>(m_detElement);
272 detElem != nullptr) {
273 return detElem->surface();
274 } else {
275 throw std::domain_error("Cannot get surface for TRT element");
276 }
277}
278
280
284
285const GeoVDetectorElement *
constexpr double length_unit
Scalar phi() const
phi method
Eigen::Affine3d Transform3D
double length(const pvec &v)
ActsDetectorElement(const InDetDD::SiDetectorElement &detElem)
std::unique_ptr< const Amg::Transform3D > m_trtTrf
virtual double thickness() const final override
Returns the thickness of the module.
const Acts::Transform3 & getDefaultTransform() const
Returns default transform.
virtual const Acts::Transform3 & transform(const Acts::GeometryContext &gctx) const final override
ActsTrk::DetectorType DetectorType
const Trk::Surface & atlasSurface() const
Return a shared pointer on the ATLAS surface associated with this identifier,.
double m_thickness
Thickness of this detector element.
ActsTrk::TransformCacheDetEle< ActsDetectorElement > m_trfCache
DetectorType detectorType() const override final
Detector type.
std::shared_ptr< const Acts::SurfaceBounds > m_bounds
Boundaries of the detector element.
Identifier identify() const override final
Identifier.
IdentifierHash identifyHash() const
Identifier hash.
IdentityHelper identityHelper() const
std::shared_ptr< Acts::Surface > m_surface
Corresponding Surface.
const GeoVDetectorElement * m_detElement
Detector element as variant.
const GeoVDetectorElement * upstreamDetectorElement() const
Returns the underllying GeoModel detectorelement that this one is based on.
virtual const Acts::Surface & surface() const final override
Return surface associated with this identifier, which should come from the.
virtual unsigned int storeAlignedTransforms(const ActsTrk::DetectorAlignStore &alignStore) const override
Caches the aligned transformation in the provided store. Returns the number of cached elements.
Ensure that the extensions for the Vector3D are properly loaded.
virtual const Amg::Transform3D moduleShift() const
virtual double maxWidth() const =0
Method to calculate maximum width of a module.
virtual double minWidth() const =0
Method to calculate minimum width of a module.
virtual double length() const =0
Method to calculate length of a module.
virtual double width() const =0
Method to calculate average width of a module.
Class to hold geometrical description of an HGTD detector element.
const HGTD_ModuleDesign & design() const override final
access to the local description:
Class used to describe the design of a module (diode segmentation and readout scheme)
virtual double width() const
Method to calculate average width of a module.
virtual double length() const
Method to calculate length of a module.
Base class for the detector design classes for Pixel and SCT.
Class to hold geometrical description of a silicon detector element.
virtual const SiDetectorDesign & design() const override final
access to the local description (inline):
virtual const Trk::SurfaceBounds & bounds() const override final
Return the boundaries of the element.
Extended TRT_BaseElement to describe a TRT readout element, this is a planar layer with n ( order of ...
Virtual base class of TRT readout elements.
virtual const double & strawLength() const =0
Active straw length.
Extended class of a TRT_BaseElement to describe a readout elment in the endcap.
BoundsType
This enumerator simplifies the persistency, by saving a dynamic_cast to happen.
Abstract Base Class for tracking surfaces.
The AlignStoreProviderAlg loads the rigid alignment corrections and pipes them through the readout ge...
@ Pixel
Inner detector legacy.
@ Trt
Maybe the Sct / Pixel for Itk become seperate entries?
Definition of ATLAS Math & Geometry primitives (Amg)
Amg::Transform3D CLHEPTransformToEigen(const HepGeom::Transform3D &CLHEPtransf)
Converts a CLHEP-based HepGeom::Transform3D into an Eigen Amg::Transform3D.
Amg::Transform3D getRotateZ3D(double angle)
get a rotation transformation around Z-axis
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Translation< double, 3 > Translation3D
STL namespace.
#define THROW_EXCEPTION(MESSAGE)
Definition throwExcept.h:10