ATLAS Offline Software
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 
44 using Acts::Surface;
45 using Acts::Transform3;
46 
47 using namespace Acts::UnitLiterals;
48 using namespace ActsTrk;
49 
50 
51 constexpr 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},
58  m_explicitIdentifier(detElem.identify())
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 
131  const InDetDD::TRT_BaseElement &detElem,
132  const Identifier &id) :
133  GeoVDetectorElement{detElem.getMaterialGeom()},
134  m_idHash(detElem.identifyHash()),
135  m_type{DetectorType::Trt},
136  m_detElement{&detElem},
137  m_trtTrf{std::make_unique<Amg::Transform3D>(trf)},
138  m_explicitIdentifier(id)
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()),
170  m_type{DetectorType::Hgtd},
171  m_detElement{&detElem},
172  m_thickness{detElem.thickness()},
173  m_explicitIdentifier{id}
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 }
240  if (detectorType() == DetectorType::Pixel || detectorType() == DetectorType::Sct) {
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 
247 const 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 
257 const Acts::Transform3 & ActsDetectorElement::getDefaultTransform() const {
258  return m_trfCache.getTransform(nullptr);
259 }
260 
261 const 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 
279 double ActsDetectorElement::thickness() const { return m_thickness; }
280 
282  return m_explicitIdentifier;
283 }
284 
285 const GeoVDetectorElement *
287  return m_detElement;
288 }
TrapezoidBounds.h
GeoAlignmentStore
Ensure that the extensions for the Vector3D are properly loaded.
Definition: GeoAlignmentStore.h:24
SGTest::store
TestStore store
Definition: TestStore.cxx:23
Trk::SurfaceBounds::BoundsType
BoundsType
Definition: SurfaceBounds.h:59
ActsDetectorElement::m_type
DetectorType m_type
Definition: ActsDetectorElement.h:109
InDetDD::TRT_BarrelElement
Definition: TRT_BarrelElement.h:43
StripBoxDesign.h
InDetDD::DetectorDesign::width
virtual double width() const =0
Method to calculate average width of a module.
python.SystemOfUnits.mm
float mm
Definition: SystemOfUnits.py:98
phi
Scalar phi() const
phi method
Definition: AmgMatrixBasePlugin.h:67
RectangleBounds.h
Surface.h
InDetDD::DetectorDesign::moduleShift
virtual const Amg::Transform3D moduleShift() const
Definition: DetectorDesign.cxx:130
ActsTrk::DetectorType
DetectorType
Simple enum to Identify the Type of the ACTS sub detector.
Definition: GeometryDefs.h:17
ActsGeometryContext.h
ActsDetectorElement::m_detElement
const GeoVDetectorElement * m_detElement
Detector element as variant.
Definition: ActsDetectorElement.h:112
Amg::Vector2D
Eigen::Matrix< double, 2, 1 > Vector2D
Definition: GeoPrimitives.h:48
ActsDetectorElement::storeAlignedTransforms
virtual unsigned int storeAlignedTransforms(const ActsTrk::DetectorAlignStore &alignStore) const override
Caches the aligned transformation in the provided store. Returns the number of cached elements.
Definition: ActsDetectorElement.cxx:251
ActsTrk::DetectorAlignStore
Definition: DetectorAlignStore.h:20
Trk::SurfaceBounds::Rectangle
@ Rectangle
Definition: SurfaceBounds.h:65
IdentityHelper.h
InDetDD::StripBoxDesign
Definition: StripBoxDesign.h:31
InDetDD::HGTD_DetectorElement
Definition: HGTD_DetectorElement.h:40
InDetDD::DetectorDesign::length
virtual double length() const =0
Method to calculate length of a module.
ActsDetectorElement::upstreamDetectorElement
const GeoVDetectorElement * upstreamDetectorElement() const
Returns the underllying GeoModel detectorelement that this one is based on.
Definition: ActsDetectorElement.cxx:286
InDetDD::TRT_EndcapElement
Definition: TRT_EndcapElement.h:43
Trk::SurfaceBounds::Annulus
@ Annulus
Definition: SurfaceBounds.h:70
ActsDetectorElement::detectorType
DetectorType detectorType() const override final
Detector type.
Definition: ActsDetectorElement.cxx:289
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
length_unit
constexpr double length_unit
Definition: ActsDetectorElement.cxx:51
InDetDD::TRT_BarrelDescriptor::innerTubeRadius
double innerTubeRadius() const
Get inner tube radius of the straw.
InDetDD::HGTD_ModuleDesign::length
virtual double length() const
Method to calculate length of a module.
Definition: HGTD_ModuleDesign.cxx:65
ActsDetectorElement::surface
virtual const Acts::Surface & surface() const final override
Return surface associated with this identifier, which should come from the.
Definition: ActsDetectorElement.cxx:261
Amg::getRotateZ3D
Amg::Transform3D getRotateZ3D(double angle)
get a rotation transformation around Z-axis
Definition: GeoPrimitivesHelpers.h:270
m_type
TokenType m_type
the type
Definition: TProperty.cxx:44
SurfaceBounds.h
TRT_EndcapElement.h
Trk::SurfaceBounds::type
virtual BoundsType type() const =0
Return the bounds type - for persistency optimization.
ActsTrk::DetectorType::Pixel
@ Pixel
Inner detector legacy.
DetType::Pixel
@ Pixel
Definition: DetType.h:13
AnnulusBounds.h
InDetDD::TRT_BarrelElement::getDescriptor
const TRT_BarrelDescriptor * getDescriptor() const
Returns a pointer to a descriptor, giving common information on module construction:
Definition: TRT_BarrelElement.cxx:72
ActsDetectorElement::transform
virtual const Acts::Transform3 & transform(const Acts::GeometryContext &gctx) const final override
Definition: ActsDetectorElement.cxx:247
ActsDetectorElement::atlasSurface
const Trk::Surface & atlasSurface() const
Return a shared pointer on the ATLAS surface associated with this identifier,.
Definition: ActsDetectorElement.cxx:269
HGTD_DetectorElement.h
InDetDD::StripStereoAnnulusDesign
Definition: StripStereoAnnulusDesign.h:50
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
ActsDetectorElement::getDefaultTransform
const Acts::Transform3 & getDefaultTransform() const
Returns default transform.
Definition: ActsDetectorElement.cxx:257
ActsDetectorElement::m_surface
std::shared_ptr< Acts::Surface > m_surface
Corresponding Surface.
Definition: ActsDetectorElement.h:118
AnalysisUtils::Delta::R
double R(const INavigable4Momentum *p1, const double v_eta, const double v_phi)
Definition: AnalysisMisc.h:49
ActsDetectorElement::thickness
virtual double thickness() const final override
Returns the thickness of the module.
Definition: ActsDetectorElement.cxx:279
InDetDD::DetectorDesign::maxWidth
virtual double maxWidth() const =0
Method to calculate maximum width of a module.
ActsDetectorElement::identityHelper
IdentityHelper identityHelper() const
Definition: ActsDetectorElement.cxx:239
ActsDetectorElement.h
TRT_BarrelElement.h
ActsDetectorElement::identify
Identifier identify() const override final
Identifier.
Definition: ActsDetectorElement.cxx:281
ActsDetectorElement::m_thickness
double m_thickness
Thickness of this detector element.
Definition: ActsDetectorElement.h:116
InDetDD::SiDetectorElement
Definition: SiDetectorElement.h:109
InDetDD::HGTD_ModuleDesign::bounds
virtual const Trk::SurfaceBounds & bounds() const
Element boundary.
Definition: HGTD_ModuleDesign.cxx:135
Trk::SurfaceBounds::Trapezoid
@ Trapezoid
Definition: SurfaceBounds.h:67
THROW_EXCEPTION
#define THROW_EXCEPTION(MESSAGE)
Definition: throwExcept.h:10
SiDetectorElement.h
StripStereoAnnulusDesign.h
ActsDetectorElement::m_trfCache
ActsTrk::TransformCacheDetEle< ActsDetectorElement > m_trfCache
Definition: ActsDetectorElement.h:110
InDetDD::DetectorDesign::minWidth
virtual double minWidth() const =0
Method to calculate minimum width of a module.
Amg::CLHEPTransformToEigen
Amg::Transform3D CLHEPTransformToEigen(const HepGeom::Transform3D &CLHEPtransf)
Converts a CLHEP-based HepGeom::Transform3D into an Eigen Amg::Transform3D.
Definition: CLHEPtoEigenConverter.h:38
ActsDetectorElement::m_explicitIdentifier
Identifier m_explicitIdentifier
Definition: ActsDetectorElement.h:122
Amg::Translation3D
Eigen::Translation< double, 3 > Translation3D
Definition: GeoPrimitives.h:44
InDetDD::HGTD_ModuleDesign
Definition: HGTD_ModuleDesign.h:43
ActsTrk
The AlignStoreProviderAlg loads the rigid alignment corrections and pipes them through the readout ge...
Definition: MSTrackingVolumeBuilder.cxx:25
InDetDD::HGTD_ModuleDesign::width
virtual double width() const
Method to calculate average width of a module.
Definition: HGTD_ModuleDesign.cxx:71
drawFromPickle.sin
sin
Definition: drawFromPickle.py:36
CaloLCW_tf.trf
trf
Definition: CaloLCW_tf.py:20
InDetDD::SiDetectorDesign
Definition: SiDetectorDesign.h:50
IdentityHelper
Definition: IdentityHelper.h:14
Trk::Surface
Definition: Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/Surface.h:79
length
double length(const pvec &v)
Definition: FPGATrackSimLLPDoubletHoughTransformTool.cxx:26
ActsDetectorElement::ActsDetectorElement
ActsDetectorElement(const InDetDD::SiDetectorElement &detElem)
Definition: ActsDetectorElement.cxx:53
InDetDD::TRT_BaseElement
Definition: TRT_BaseElement.h:52
Identifier
Definition: IdentifierFieldParser.cxx:14