EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ConeSurface.ipp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file ConeSurface.ipp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2018 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 
9 inline detail::RealQuadraticEquation ConeSurface::intersectionSolver(
10  const GeometryContext& gctx, const Vector3D& position,
11  const Vector3D& direction) const {
12  // Transform into the local frame
13  Transform3D invTrans = transform(gctx).inverse();
14  Vector3D point1 = invTrans * position;
15  Vector3D dir1 = invTrans.linear() * direction;
16 
17  // See file header for the formula derivation
18  double tan2Alpha = bounds().tanAlpha() * bounds().tanAlpha(),
19  A = dir1.x() * dir1.x() + dir1.y() * dir1.y() -
20  tan2Alpha * dir1.z() * dir1.z(),
21  B = 2 * (dir1.x() * point1.x() + dir1.y() * point1.y() -
22  tan2Alpha * dir1.z() * point1.z()),
23  C = point1.x() * point1.x() + point1.y() * point1.y() -
24  tan2Alpha * point1.z() * point1.z();
25  if (A == 0.) {
26  A += 1e-16; // avoid division by zero
27  }
28 
29  return detail::RealQuadraticEquation(A, B, C);
30 }
31 
33  const GeometryContext& gctx, const Vector3D& position,
34  const Vector3D& direction, const BoundaryCheck& bcheck) const {
35  // Solve the quadratic equation
36  auto qe = intersectionSolver(gctx, position, direction);
37 
38  // If no valid solution return a non-valid surfaceIntersection
39  if (qe.solutions == 0) {
40  return SurfaceIntersection();
41  }
42 
43  // Check the validity of the first solution
44  Vector3D solution1 = position + qe.first * direction;
45  Intersection3D::Status status1 =
46  (qe.first * qe.first < s_onSurfaceTolerance * s_onSurfaceTolerance)
47  ? Intersection3D::Status::onSurface
48  : Intersection3D::Status::reachable;
49 
50  if (bcheck and not isOnSurface(gctx, solution1, direction, bcheck)) {
51  status1 = Intersection3D::Status::missed;
52  }
53 
54  // Check the validity of the second solution
55  Vector3D solution2 = position + qe.first * direction;
56  Intersection3D::Status status2 =
57  (qe.second * qe.second < s_onSurfaceTolerance * s_onSurfaceTolerance)
58  ? Intersection3D::Status::onSurface
59  : Intersection3D::Status::reachable;
60  if (bcheck and not isOnSurface(gctx, solution2, direction, bcheck)) {
61  status2 = Intersection3D::Status::missed;
62  }
63 
64  const auto& tf = transform(gctx);
65  // Set the intersection
66  Intersection3D first(tf * solution1, qe.first, status1);
67  Intersection3D second(tf * solution2, qe.second, status2);
68  SurfaceIntersection cIntersection(first, this);
69  // Check one if its valid or neither is valid
70  bool check1 = status1 != Intersection3D::Status::missed or
71  (status1 == Intersection3D::Status::missed and
72  status2 == Intersection3D::Status::missed);
73  // Check and (eventually) go with the first solution
74  if ((check1 and qe.first * qe.first < qe.second * qe.second) or
75  status2 == Intersection3D::Status::missed) {
76  // And add the alternative
77  if (qe.solutions > 1) {
78  cIntersection.alternative = second;
79  }
80  } else {
81  // And add the alternative
82  if (qe.solutions > 1) {
83  cIntersection.alternative = first;
84  }
85  cIntersection.intersection = second;
86  }
87  return cIntersection;
88 }
89 
91 ConeSurface::localCartesianToBoundLocalDerivative(
92  const GeometryContext& gctx, const Vector3D& position) const {
93  using VectorHelpers::perp;
94  using VectorHelpers::phi;
95  // The local frame transform
96  const auto& sTransform = transform(gctx);
97  // calculate the transformation to local coorinates
98  const Vector3D localPos = sTransform.inverse() * position;
99  const double lr = perp(localPos);
100  const double lphi = phi(localPos);
101  const double lcphi = std::cos(lphi);
102  const double lsphi = std::sin(lphi);
103  // Solve for radius R
104  const double R = localPos.z() * bounds().tanAlpha();
105  LocalCartesianToBoundLocalMatrix loc3DToLocBound =
106  LocalCartesianToBoundLocalMatrix::Zero();
107  loc3DToLocBound << -R * lsphi / lr, R * lcphi / lr,
108  lphi * bounds().tanAlpha(), 0, 0, 1;
109 
110  return loc3DToLocBound;
111 }