ATLAS Offline Software
ActsDetectorElement.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 
7 #include "GeoModelHelpers/throwExcept.h"
8 
9 // ATHENA
17 #include "TrkSurfaces/Surface.h"
20 
21 // PACKAGE
23 // ACTS
24 #include "Acts/Definitions/Units.hpp"
25 #include "Acts/Geometry/GeometryContext.hpp"
26 #include "Acts/Surfaces/AnnulusBounds.hpp"
27 #include "Acts/Surfaces/DiscSurface.hpp"
28 #include "Acts/Surfaces/LineBounds.hpp"
29 #include "Acts/Surfaces/PlaneSurface.hpp"
30 #include "Acts/Surfaces/RectangleBounds.hpp"
31 #include "Acts/Surfaces/StrawSurface.hpp"
32 #include "Acts/Surfaces/TrapezoidBounds.hpp"
33 #include "Acts/Visualization/ObjVisualization3D.hpp"
34 #include "Acts/Visualization/PlyVisualization3D.hpp"
35 
36 
37 // STL
38 #include <mutex>
39 #include <variant>
40 
41 
42 using Acts::Surface;
43 using Acts::Transform3;
44 
45 using namespace Acts::UnitLiterals;
46 using namespace ActsTrk;
47 
48 
49 constexpr double length_unit = 1_mm;
50 
52  GeoVDetectorElement{detElem.getMaterialGeom()},
53  m_type{detElem.isPixel() ? DetectorType::Pixel : DetectorType::Sct},
54  m_detElement{&detElem} {
55 
56 
57  auto boundsType = detElem.bounds().type();
58 
59  m_thickness = detElem.thickness();
60 
61 
62  if (boundsType == Trk::SurfaceBounds::Rectangle) {
63 
64  const InDetDD::SiDetectorDesign &design = detElem.design();
65  double hlX = design.width() / 2. * length_unit;
66  double hlY = design.length() / 2. * length_unit;
67 
68  auto rectangleBounds = std::make_shared<const Acts::RectangleBounds>(hlX, hlY);
69 
70  m_bounds = rectangleBounds;
71  m_surface = Acts::Surface::makeShared<Acts::PlaneSurface>(rectangleBounds, *this);
72 
73  } else if (boundsType == Trk::SurfaceBounds::Trapezoid) {
74 
75  const InDetDD::SiDetectorDesign &design = detElem.design();
76 
77  double minHlX = design.minWidth() / 2. * length_unit;
78  double maxHlX = design.maxWidth() / 2. * length_unit;
79  double hlY = design.length() / 2. * length_unit;
80 
81  auto trapezoidBounds =
82  std::make_shared<const Acts::TrapezoidBounds>(minHlX, maxHlX, hlY);
83 
84  m_bounds = trapezoidBounds;
85 
86  m_surface = Acts::Surface::makeShared<Acts::PlaneSurface>(trapezoidBounds, *this);
87 
88 
89  } else if (boundsType == Trk::SurfaceBounds::Annulus) {
90 
91  const InDetDD::SiDetectorDesign &design = detElem.design();
92  const auto *annulus = dynamic_cast<const InDetDD::StripStereoAnnulusDesign *>(&design);
93  if (annulus == nullptr) {
94  throw std::domain_error("ActsDetectorElement got inconsistent surface");
95  }
96 
97  double phi = annulus->phiWidth();
98  double phiS = annulus->stereo();
99  double R = annulus->waferCentreR();
100  double maxR = annulus->maxR();
101  double minR = annulus->minR();
102 
103  // phiAvg is the bounds-internal local rotation. We don't want one
104  double phiAvg = 0;
105  // phi is the total opening angle, set up symmetric phi bounds
106  double phiMax = phi / 2.;
107  double phiMin = -phiMax;
108 
109 
110  Amg::Vector2D originStripXYRotated(R * (1 - std::cos(phiS)),
111  R * std::sin(-phiS));
112 
113  auto annulusBounds = std::make_shared<Acts::AnnulusBounds>(
114  minR, maxR, phiMin, phiMax, originStripXYRotated, phiAvg);
115  m_bounds = annulusBounds;
116 
117  m_surface = Acts::Surface::makeShared<Acts::DiscSurface>(annulusBounds, *this);
118 
119  } else {
120  std::cout << boundsType << std::endl;
121  throw std::domain_error("ActsDetectorElement does not support this surface type");
122  }
123 }
124 
126  const InDetDD::TRT_BaseElement &detElem,
127  const Identifier &id) :
128  GeoVDetectorElement{detElem.getMaterialGeom()},
129  m_type{DetectorType::Trt},
130  m_detElement{&detElem},
131  m_trtTrf{std::make_unique<Amg::Transform3D>(trf)},
132  m_explicitIdentifier(id) {
133 
134  // we know this is a straw
135  double length = detElem.strawLength() * 0.5 * length_unit;
136 
137  // we need to find the radius
138  auto ecElem = dynamic_cast<const InDetDD::TRT_EndcapElement *>(&detElem);
139  auto brlElem = dynamic_cast<const InDetDD::TRT_BarrelElement *>(&detElem);
140  double innerTubeRadius{0.};
141  if (ecElem) {
142  innerTubeRadius = ecElem->getDescriptor()->innerTubeRadius() * length_unit;
143  } else {
144  if (brlElem) {
145  innerTubeRadius =
146  brlElem->getDescriptor()->innerTubeRadius() * length_unit;
147  } else {
148  THROW_EXCEPTION("Cannot get tube radius for element in ActsDetectorElement c'tor");
149  }
150  }
151 
152  auto lineBounds =
153  std::make_shared<const Acts::LineBounds>(innerTubeRadius, length);
154  m_bounds = lineBounds;
155 
156  m_surface = Acts::Surface::makeShared<Acts::StrawSurface>(lineBounds, *this);
157 }
158 
160  GeoVDetectorElement{detElem.getMaterialGeom()},
161  m_type{DetectorType::Hgtd},
162  m_detElement{&detElem},
163  m_thickness{detElem.thickness()},
164  m_explicitIdentifier{id} {
165 
166  auto boundsType = detElem.bounds().type();
167 
168  if (boundsType == Trk::SurfaceBounds::Rectangle) {
169 
170  const InDetDD::HGTD_ModuleDesign &design = detElem.design();
171  double hlX = design.width() / 2. * length_unit;
172  double hlY = design.length() / 2. * length_unit;
173 
174  auto rectangleBounds =
175  std::make_shared<const Acts::RectangleBounds>(hlX, hlY);
176 
177  m_bounds = rectangleBounds;
178 
179  m_surface = Acts::Surface::makeShared<Acts::PlaneSurface>(rectangleBounds, *this);
180 
181  } else {
182  throw std::domain_error(
183  "ActsDetectorElement: the surface type of HGTD is not does not Rectangle, it is wrong");
184  }
185 }
186 
188 
189  GeoAlignmentStore* geoModelStore = store ? store->geoModelAlignment.get() : nullptr;
190  Amg::Transform3D l2g{Amg::Transform3D::Identity()};
191  switch (m_type) {
192  case DetectorType::Hgtd:{
193  l2g= m_detElement->getMaterialGeom()->getAbsoluteTransform(geoModelStore);
194  break;
195  } case DetectorType::Trt: {
196  l2g = (*m_trtTrf);
197  break;
198  }
200  default: {
201  const auto& detElem = static_cast<const InDetDD::SiDetectorElement&>(*m_detElement);
202  const InDetDD::SiDetectorDesign&design = detElem.design();
203  const Trk::SurfaceBounds::BoundsType boundsType = detElem.bounds().type();
204 
205  // extra shift for split row modules
206  Amg::Transform3D extraTransform{Amg::CLHEPTransformToEigen(detElem.recoToHitTransform())};
207  if (boundsType == Trk::SurfaceBounds::Rectangle &&
208  typeid(design) == typeid(InDetDD::StripBoxDesign) ) {
209  extraTransform = design.moduleShift() * extraTransform;
210  } else if (boundsType == Trk::SurfaceBounds::Annulus) {
211  // need to rotate pi/2 to reproduce ABXY orientation, phiS so that phi=0
212  // is center and symmetric
213  const double phiShift = M_PI_2 - static_cast<const InDetDD::StripStereoAnnulusDesign&>(design).stereo();
214 
215  const Amg::Vector2D origin2D = static_cast<const Acts::AnnulusBounds&>(m_surface->bounds()).moduleOrigin();
216  const Amg::Translation3D transl{origin2D.x(), origin2D.y(), 0};
217  const Amg::Transform3D originTrf{transl * Amg::getRotateZ3D(-phiShift)};
218  extraTransform = extraTransform * originTrf.inverse();
219  }
220  l2g = m_detElement->getMaterialGeom()->getAbsoluteTransform(geoModelStore) * extraTransform;
221  }
222  };
223  // need to make sure translation has correct units
224  l2g.translation() *= 1.0 / CLHEP::mm * length_unit;
225 
226  return l2g;
227 
228 }
230  if (detectorType() == DetectorType::Pixel || detectorType() == DetectorType::Sct) {
231  return IdentityHelper(static_cast<const InDetDD::SiDetectorElement *>(m_detElement));
232  } else {
233  throw std::domain_error("Cannot get IdentityHelper for TRT element");
234  }
235 }
236 
237 const Acts::Transform3 &ActsDetectorElement::transform(const Acts::GeometryContext &anygctx) const {
238  return m_trfCache.transform(anygctx);
239 }
240 
242  if (store.detType != detectorType()) return 0;
244  return 1;
245 }
246 
247 const Acts::Transform3 & ActsDetectorElement::getDefaultTransform() const {
248  return m_trfCache.getTransform(nullptr);
249 }
250 
251 const Acts::Surface &ActsDetectorElement::surface() const {
252  return (*m_surface);
253 }
254 
256  return (*m_surface);
257 }
258 
260  if (const auto *detElem =
261  dynamic_cast<const InDetDD::SiDetectorElement *>(m_detElement);
262  detElem != nullptr) {
263  return detElem->surface();
264  } else {
265  throw std::domain_error("Cannot get surface for TRT element");
266  }
267 }
268 
269 double ActsDetectorElement::thickness() const { return m_thickness; }
270 
271 Identifier ActsDetectorElement::identify() const {
272  if (const auto *detElem =
273  dynamic_cast<const InDetDD::SiDetectorElement *>(m_detElement);
274  detElem != nullptr) {
275  return detElem->identify();
276  } else if (dynamic_cast<const InDetDD::TRT_BaseElement *>(m_detElement) !=
277  nullptr) {
278  return m_explicitIdentifier;
279  } else if (dynamic_cast<const InDetDD::HGTD_DetectorElement *>(m_detElement) !=
280  nullptr) {
281  return m_explicitIdentifier;
282  } else {
283  THROW_EXCEPTION("Unknown detector element type");
284  }
285 }
286 
287 const GeoVDetectorElement *
289  return m_detElement;
290 }
TrapezoidBounds.h
GeoAlignmentStore
Ensure that the extensions for the Vector3D are properly loaded.
Definition: GeoAlignmentStore.h:24
store
StoreGateSvc * store
Definition: fbtTestBasics.cxx:69
Trk::SurfaceBounds::BoundsType
BoundsType
Definition: SurfaceBounds.h:59
ActsDetectorElement::m_type
DetectorType m_type
Definition: ActsDetectorElement.h:103
InDetDD::TRT_BarrelElement
Definition: TRT_BarrelElement.h:44
StripBoxDesign.h
InDetDD::DetectorDesign::width
virtual double width() const =0
Method to calculate average width of a module.
phi
Scalar phi() const
phi method
Definition: AmgMatrixBasePlugin.h:64
IDTPM::R
float R(const U &p)
Definition: TrackParametersHelper.h:101
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:107
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:241
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:288
InDetDD::TRT_EndcapElement
Definition: TRT_EndcapElement.h:44
Trk::SurfaceBounds::Annulus
@ Annulus
Definition: SurfaceBounds.h:70
ActsDetectorElement::detectorType
DetectorType detectorType() const override final
Detector type.
Definition: ActsDetectorElement.cxx:291
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
THROW_EXCEPTION
#define THROW_EXCEPTION(MSG)
Definition: MMReadoutElement.cxx:48
length_unit
constexpr double length_unit
Definition: ActsDetectorElement.cxx:49
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:251
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:237
ActsDetectorElement::atlasSurface
const Trk::Surface & atlasSurface() const
Return a shared pointer on the ATLAS surface associated with this identifier,.
Definition: ActsDetectorElement.cxx:259
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:247
ActsDetectorElement::m_surface
std::shared_ptr< Acts::Surface > m_surface
Corresponding Surface.
Definition: ActsDetectorElement.h:113
ActsDetectorElement::thickness
virtual double thickness() const final override
Returns the thickness of the module.
Definition: ActsDetectorElement.cxx:269
InDetDD::DetectorDesign::maxWidth
virtual double maxWidth() const =0
Method to calculate maximum width of a module.
ActsDetectorElement::identityHelper
IdentityHelper identityHelper() const
Definition: ActsDetectorElement.cxx:229
ActsDetectorElement.h
TRT_BarrelElement.h
ActsDetectorElement::identify
Identifier identify() const override final
Identifier.
Definition: ActsDetectorElement.cxx:271
ActsDetectorElement::m_thickness
double m_thickness
Thickness of this detector element.
Definition: ActsDetectorElement.h:111
ActsTrk::TransformCache::getTransform
const Amg::Transform3D & getTransform(const DetectorAlignStore *store) const
Returns the matching transformation from the alignment store.
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
python.SystemOfUnits.mm
int mm
Definition: SystemOfUnits.py:83
StripStereoAnnulusDesign.h
ActsDetectorElement::m_trfCache
ActsTrk::TransformCacheDetEle< ActsDetectorElement > m_trfCache
Definition: ActsDetectorElement.h:105
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:118
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: MuonDetectorBuilderTool.cxx:34
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:75
length
double length(const pvec &v)
Definition: FPGATrackSimLLPDoubletHoughTransformTool.cxx:26
ActsTrk::TransformCache::transform
const Amg::Transform3D & transform(const Acts::GeometryContext &gctx) const
returns the cached transform from the Acts Geometry context
ActsDetectorElement::ActsDetectorElement
ActsDetectorElement(const InDetDD::SiDetectorElement &detElem)
Definition: ActsDetectorElement.cxx:51
InDetDD::TRT_BaseElement
Definition: TRT_BaseElement.h:57