ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DiscSurface.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file DiscSurface.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2016-2020 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
10 
11 #include <algorithm>
12 #include <cmath>
13 #include <iomanip>
14 #include <iostream>
15 #include <numeric>
16 #include <utility>
17 #include <vector>
18 
25 
28 
29 Acts::DiscSurface::DiscSurface(const DiscSurface& other)
30  : GeometryObject(), Surface(other), m_bounds(other.m_bounds) {}
31 
32 Acts::DiscSurface::DiscSurface(const GeometryContext& gctx,
33  const DiscSurface& other,
34  const Transform3D& transf)
35  : GeometryObject(),
36  Surface(gctx, other, transf),
37  m_bounds(other.m_bounds) {}
38 
39 Acts::DiscSurface::DiscSurface(std::shared_ptr<const Transform3D> htrans,
40  double rmin, double rmax, double hphisec)
41  : GeometryObject(),
42  Surface(std::move(htrans)),
43  m_bounds(std::make_shared<const RadialBounds>(rmin, rmax, hphisec)) {}
44 
45 Acts::DiscSurface::DiscSurface(std::shared_ptr<const Transform3D> htrans,
46  double minhalfx, double maxhalfx, double maxR,
47  double minR, double avephi, double stereo)
48  : GeometryObject(),
49  Surface(std::move(htrans)),
50  m_bounds(std::make_shared<const DiscTrapezoidBounds>(
51  minhalfx, maxhalfx, maxR, minR, avephi, stereo)) {}
52 
53 Acts::DiscSurface::DiscSurface(std::shared_ptr<const Transform3D> htrans,
54  std::shared_ptr<const DiscBounds> dbounds)
55  : GeometryObject(),
56  Surface(std::move(htrans)),
57  m_bounds(std::move(dbounds)) {}
58 
59 Acts::DiscSurface::DiscSurface(const std::shared_ptr<const DiscBounds>& dbounds,
60  const DetectorElementBase& detelement)
61  : GeometryObject(), Surface(detelement), m_bounds(dbounds) {
62  throw_assert(dbounds, "nullptr as DiscBounds");
63 }
64 
65 Acts::DiscSurface& Acts::DiscSurface::operator=(const DiscSurface& other) {
66  if (this != &other) {
68  m_bounds = other.m_bounds;
69  }
70  return *this;
71 }
72 
73 Acts::Surface::SurfaceType Acts::DiscSurface::type() const {
74  return Surface::Disc;
75 }
76 
77 void Acts::DiscSurface::localToGlobal(const GeometryContext& gctx,
78  const Vector2D& lposition,
79  const Vector3D& /*gmom*/,
80  Vector3D& position) const {
81  // create the position in the local 3d frame
82  Vector3D loc3Dframe(lposition[Acts::eLOC_R] * cos(lposition[Acts::eLOC_PHI]),
83  lposition[Acts::eLOC_R] * sin(lposition[Acts::eLOC_PHI]),
84  0.);
85  // transport it to the globalframe (very unlikely that this is not needed)
86  position = transform(gctx) * loc3Dframe;
87 }
88 
89 bool Acts::DiscSurface::globalToLocal(const GeometryContext& gctx,
90  const Vector3D& position,
91  const Vector3D& /*gmom*/,
92  Vector2D& lposition) const {
93  // transport it to the globalframe (very unlikely that this is not needed)
94  Vector3D loc3Dframe = (transform(gctx).inverse()) * position;
95  lposition = Acts::Vector2D(perp(loc3Dframe), phi(loc3Dframe));
96  return ((std::abs(loc3Dframe.z()) > s_onSurfaceTolerance) ? false : true);
97 }
98 
99 const Acts::Vector2D Acts::DiscSurface::localPolarToLocalCartesian(
100  const Vector2D& locpol) const {
101  const DiscTrapezoidBounds* dtbo =
102  dynamic_cast<const Acts::DiscTrapezoidBounds*>(&(bounds()));
103  if (dtbo != nullptr) {
104  double rMedium = dtbo->rCenter();
105  double phi = dtbo->get(DiscTrapezoidBounds::eAveragePhi);
106 
107  Vector2D polarCenter(rMedium, phi);
108  Vector2D cartCenter = localPolarToCartesian(polarCenter);
109  Vector2D cartPos = localPolarToCartesian(locpol);
110  Vector2D Pos = cartPos - cartCenter;
111 
112  Acts::Vector2D locPos(
113  Pos[Acts::eLOC_X] * sin(phi) - Pos[Acts::eLOC_Y] * cos(phi),
114  Pos[Acts::eLOC_Y] * sin(phi) + Pos[Acts::eLOC_X] * cos(phi));
115  return Vector2D(locPos[Acts::eLOC_X], locPos[Acts::eLOC_Y]);
116  }
117  return Vector2D(locpol[Acts::eLOC_R] * cos(locpol[Acts::eLOC_PHI]),
118  locpol[Acts::eLOC_R] * sin(locpol[Acts::eLOC_PHI]));
119 }
120 
121 const Acts::Vector3D Acts::DiscSurface::localCartesianToGlobal(
122  const GeometryContext& gctx, const Vector2D& lposition) const {
123  Vector3D loc3Dframe(lposition[Acts::eLOC_X], lposition[Acts::eLOC_Y], 0.);
124  return Vector3D(transform(gctx) * loc3Dframe);
125 }
126 
127 const Acts::Vector2D Acts::DiscSurface::globalToLocalCartesian(
128  const GeometryContext& gctx, const Vector3D& position,
129  double /*unused*/) const {
130  Vector3D loc3Dframe = (transform(gctx).inverse()) * position;
131  return Vector2D(loc3Dframe.x(), loc3Dframe.y());
132 }
133 
134 std::string Acts::DiscSurface::name() const {
135  return "Acts::DiscSurface";
136 }
137 
138 const Acts::SurfaceBounds& Acts::DiscSurface::bounds() const {
139  if (m_bounds) {
140  return (*(m_bounds.get()));
141  }
142  return s_noBounds;
143 }
144 
145 Acts::Polyhedron Acts::DiscSurface::polyhedronRepresentation(
146  const GeometryContext& gctx, size_t lseg) const {
147  // Prepare vertices and faces
148  std::vector<Vector3D> vertices;
149  std::vector<Polyhedron::FaceType> faces;
150  std::vector<Polyhedron::FaceType> triangularMesh;
151 
152  // Understand the disc
153  bool fullDisc = m_bounds->coversFullAzimuth();
154  bool toCenter = m_bounds->rMin() < s_onSurfaceTolerance;
155  // If you have bounds you can create a polyhedron representation
156  if (m_bounds) {
157  auto vertices2D = m_bounds->vertices(lseg);
158  vertices.reserve(vertices2D.size() + 1);
159  Vector3D wCenter(0., 0., 0);
160  for (const auto& v2D : vertices2D) {
161  vertices.push_back(transform(gctx) * Vector3D(v2D.x(), v2D.y(), 0.));
162  wCenter += (*vertices.rbegin());
163  }
164  // These are convex shapes, use the helper method
165  // For rings there's a sweet spot when this stops working
166  if (m_bounds->type() == SurfaceBounds::eDiscTrapezoid or toCenter or
167  not fullDisc) {
168  // Transformt hem into the vertex frame
169  wCenter *= 1. / vertices.size();
170  vertices.push_back(wCenter);
171  auto facesMesh = detail::FacesHelper::convexFaceMesh(vertices, true);
172  faces = facesMesh.first;
173  triangularMesh = facesMesh.second;
174  } else {
175  // Two concentric rings, we use the pure concentric method momentarily,
176  // but that creates too many unneccesarry faces, when only two
177  // are needed to descibe the mesh, @todo investigate merging flag
178  auto facesMesh = detail::FacesHelper::cylindricalFaceMesh(vertices, true);
179  faces = facesMesh.first;
180  triangularMesh = facesMesh.second;
181  }
182  } else {
183  throw std::domain_error(
184  "Polyhedron repr of boundless surface not possible.");
185  }
186  return Polyhedron(vertices, faces, triangularMesh);
187 }