Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CylinderBounds.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file CylinderBounds.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 
14 
15 #include <algorithm>
16 #include <cmath>
17 #include <iomanip>
18 #include <iostream>
19 #include <utility>
20 
23 
26 }
27 
29  const Acts::Vector2& lposition) const {
30  return {Acts::detail::radian_sym((lposition[Acts::eBoundLoc0] / get(eR)) -
31  get(eAveragePhi)),
32  lposition[Acts::eBoundLoc1]};
33 }
34 
37  j(0, eBoundLoc0) = 1 / get(eR);
38  j(0, eBoundLoc1) = 0;
39  j(1, eBoundLoc0) = 0;
40  j(1, eBoundLoc1) = 1;
41  return j;
42 }
43 
44 bool Acts::CylinderBounds::inside(const Vector2& lposition,
45  const BoundaryCheck& bcheck) const {
46  double bevelMinZ = get(eBevelMinZ);
47  double bevelMaxZ = get(eBevelMaxZ);
48 
49  double halfLengthZ = get(eHalfLengthZ);
50  double halfPhi = get(eHalfPhiSector);
51  if (bevelMinZ != 0. && bevelMaxZ != 0.) {
52  double radius = get(eR);
53  // Beleved sides will unwrap to a trapezoid
55  // ________
56  // /| . . |\ r/phi
57  // \|______|/ r/phi
58  // -Z 0 Z
60  float localx =
61  lposition[0] > radius ? 2 * radius - lposition[0] : lposition[0];
62  Vector2 shiftedlposition = shifted(lposition);
63  if ((std::fabs(shiftedlposition[0]) <= halfPhi &&
64  std::fabs(shiftedlposition[1]) <= halfLengthZ)) {
65  return true;
66  } else if ((lposition[1] >=
67  -(localx * std::tan(bevelMinZ) + halfLengthZ)) &&
68  (lposition[1] <= (localx * std::tan(bevelMaxZ) + halfLengthZ))) {
69  return true;
70  } else {
71  // check within tolerance
72  auto boundaryCheck = bcheck.transformed(jacobian());
73 
74  Vector2 lowerLeft = {-radius, -halfLengthZ};
75  Vector2 middleLeft = {0., -(halfLengthZ + radius * std::tan(bevelMinZ))};
76  Vector2 upperLeft = {radius, -halfLengthZ};
77  Vector2 upperRight = {radius, halfLengthZ};
78  Vector2 middleRight = {0., (halfLengthZ + radius * std::tan(bevelMaxZ))};
79  Vector2 lowerRight = {-radius, halfLengthZ};
80  Vector2 vertices[] = {lowerLeft, middleLeft, upperLeft,
81  upperRight, middleRight, lowerRight};
82  Vector2 closestPoint =
83  boundaryCheck.computeClosestPointOnPolygon(lposition, vertices);
84 
85  return boundaryCheck.isTolerated(closestPoint - lposition);
86  }
87  } else {
88  return bcheck.transformed(jacobian())
89  .isInside(shifted(lposition), Vector2(-halfPhi, -halfLengthZ),
90  Vector2(halfPhi, halfLengthZ));
91  }
92 }
93 
95  const BoundaryCheck& bcheck) const {
96  // additional tolerance from the boundary check if configured
97  bool checkAbsolute = bcheck.m_type == BoundaryCheck::Type::eAbsolute;
98 
99  // this fast check only applies to closed cylindrical bounds
100  double addToleranceR =
101  (checkAbsolute && m_closed) ? bcheck.m_tolerance[0] : 0.;
102  double addToleranceZ = checkAbsolute ? bcheck.m_tolerance[1] : 0.;
103  // check if the position compatible with the radius
104  if ((s_onSurfaceTolerance + addToleranceR) <=
105  std::abs(perp(position) - get(eR))) {
106  return false;
107  } else if (checkAbsolute && m_closed) {
108  double bevelMinZ = get(eBevelMinZ);
109  double bevelMaxZ = get(eBevelMaxZ);
110 
111  double addedMinZ =
112  bevelMinZ != 0. ? position.y() * std::sin(bevelMinZ) : 0.;
113  double addedMaxZ =
114  bevelMinZ != 0. ? position.y() * std::sin(bevelMaxZ) : 0.;
115 
116  return ((s_onSurfaceTolerance + addToleranceZ + get(eHalfLengthZ) +
117  addedMinZ) >= position.z()) &&
118  ((s_onSurfaceTolerance + addToleranceZ + get(eHalfLengthZ) +
119  addedMaxZ) <= position.z());
120  }
121  // detailed, but slower check
122  Vector2 lpos(detail::radian_sym(phi(position) - get(eAveragePhi)),
123  position.z());
124  return bcheck.transformed(jacobian())
125  .isInside(lpos, Vector2(-get(eHalfPhiSector), -get(eHalfLengthZ)),
126  Vector2(get(eHalfPhiSector), get(eHalfLengthZ)));
127 }
128 
129 std::ostream& Acts::CylinderBounds::toStream(std::ostream& sl) const {
130  sl << std::setiosflags(std::ios::fixed);
131  sl << std::setprecision(7);
132  sl << "Acts::CylinderBounds: (radius, halfLengthZ, halfPhiSector, "
133  "averagePhi, bevelMinZ, bevelMaxZ) = ";
134  sl << "(" << get(eR) << ", " << get(eHalfLengthZ) << ", ";
135  sl << get(eHalfPhiSector) << ", " << get(eAveragePhi) << ", ";
136  sl << get(eBevelMinZ) << ", " << get(eBevelMaxZ) << ")";
137  sl << std::setprecision(-1);
138  return sl;
139 }
140 
141 std::vector<Acts::Vector3> Acts::CylinderBounds::createCircles(
142  const Transform3 ctrans, size_t lseg) const {
143  std::vector<Vector3> vertices;
144 
145  double avgPhi = get(eAveragePhi);
146  double halfPhi = get(eHalfPhiSector);
147 
148  bool fullCylinder = coversFullAzimuth();
149 
150  // Get the phi segments from the helper - ensures extra points
151  auto phiSegs = fullCylinder ? detail::VerticesHelper::phiSegments()
153  avgPhi - halfPhi, avgPhi + halfPhi,
154  {static_cast<ActsScalar>(avgPhi)});
155 
156  // Write the two bows/circles on either side
157  std::vector<int> sides = {-1, 1};
158  for (auto& side : sides) {
159  for (size_t iseg = 0; iseg < phiSegs.size() - 1; ++iseg) {
160  int addon = (iseg == phiSegs.size() - 2 and not fullCylinder) ? 1 : 0;
163  vertices, {get(eR), get(eR)}, phiSegs[iseg], phiSegs[iseg + 1], lseg,
164  addon, Vector3(0., 0., side * get(eHalfLengthZ)), ctrans);
165  }
166  }
167 
168  double bevelMinZ = get(eBevelMinZ);
169  double bevelMaxZ = get(eBevelMaxZ);
170 
171  // Modify the vertices position if bevel is defined
172  if ((bevelMinZ != 0. || bevelMaxZ != 0.) && vertices.size() % 2 == 0) {
173  auto halfWay = vertices.end() - vertices.size() / 2;
174  double mult{1};
175  auto invCtrans = ctrans.inverse();
176  auto func = [&mult, &ctrans, &invCtrans](Vector3& v) {
177  v = invCtrans * v;
178  v(2) += v(1) * mult;
179  v = ctrans * v;
180  };
181  if (bevelMinZ != 0.) {
182  mult = std::tan(-bevelMinZ);
183  std::for_each(vertices.begin(), halfWay, func);
184  }
185  if (bevelMaxZ != 0.) {
186  mult = std::tan(bevelMaxZ);
187  std::for_each(halfWay, vertices.end(), func);
188  }
189  }
190  return vertices;
191 }