Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-08-02 08:24:07

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
0008 
0009 #include "Acts/Surfaces/ConeBounds.hpp"
0010 
0011 #include "Acts/Definitions/Tolerance.hpp"
0012 #include "Acts/Surfaces/detail/VerticesHelper.hpp"
0013 #include "Acts/Utilities/detail/OstreamStateGuard.hpp"
0014 #include "Acts/Utilities/detail/periodic.hpp"
0015 
0016 #include <cmath>
0017 #include <iomanip>
0018 #include <iostream>
0019 #include <limits>
0020 #include <optional>
0021 
0022 namespace Acts {
0023 
0024 ConeBounds::ConeBounds(double alpha, bool symm, double halfphi,
0025                        double avphi) noexcept(false)
0026     : m_values({alpha, symm ? -std::numeric_limits<double>::infinity() : 0,
0027                 std::numeric_limits<double>::infinity(), halfphi, avphi}),
0028       m_tanAlpha(std::tan(alpha)) {
0029   checkConsistency();
0030 }
0031 
0032 ConeBounds::ConeBounds(double alpha, double minz, double maxz, double halfphi,
0033                        double avphi) noexcept(false)
0034     : m_values({alpha, minz, maxz, halfphi, avphi}),
0035       m_tanAlpha(std::tan(alpha)) {
0036   checkConsistency();
0037 }
0038 
0039 ConeBounds::ConeBounds(const std::array<double, eSize>& values) noexcept(false)
0040     : m_values(values), m_tanAlpha(std::tan(values[eAlpha])) {
0041   checkConsistency();
0042 }
0043 
0044 std::vector<double> ConeBounds::values() const {
0045   return {m_values.begin(), m_values.end()};
0046 }
0047 
0048 void ConeBounds::checkConsistency() noexcept(false) {
0049   if (get(eAlpha) < 0. || get(eAlpha) >= std::numbers::pi) {
0050     throw std::invalid_argument("ConeBounds: invalid open angle.");
0051   }
0052   if (get(eMinZ) > get(eMaxZ) ||
0053       std::abs(get(eMinZ) - get(eMaxZ)) < s_epsilon) {
0054     throw std::invalid_argument("ConeBounds: invalid z range setup.");
0055   }
0056   if (get(eHalfPhiSector) < 0. || std::abs(eHalfPhiSector) > std::numbers::pi) {
0057     throw std::invalid_argument("ConeBounds: invalid phi sector setup.");
0058   }
0059   if (get(eAveragePhi) != detail::radian_sym(get(eAveragePhi))) {
0060     throw std::invalid_argument("ConeBounds: invalid phi positioning.");
0061   }
0062 }
0063 
0064 Vector2 ConeBounds::shifted(const Vector2& lposition) const {
0065   using detail::radian_sym;
0066 
0067   auto x = r(lposition[1]);  // cone radius at the local position
0068   Vector2 shifted;
0069   shifted[1] = lposition[1];
0070   shifted[0] = std::isnormal(x)
0071                    ? (x * radian_sym((lposition[0] / x) - get(eAveragePhi)))
0072                    : lposition[0];
0073   return shifted;
0074 }
0075 
0076 bool ConeBounds::inside(const Vector2& lposition) const {
0077   auto rphiHalf = r(lposition[1]) * get(eHalfPhiSector);
0078   return detail::VerticesHelper::isInsideRectangle(
0079       shifted(lposition), Vector2(-rphiHalf, get(eMinZ)),
0080       Vector2(rphiHalf, get(eMaxZ)));
0081 }
0082 
0083 Vector2 ConeBounds::closestPoint(const Vector2& lposition,
0084                                  const SquareMatrix2& metric) const {
0085   auto rphiHalf = r(lposition[1]) * get(eHalfPhiSector);
0086   return detail::VerticesHelper::computeClosestPointOnAlignedBox(
0087       Vector2(-rphiHalf, get(eMinZ)), Vector2(rphiHalf, get(eMaxZ)),
0088       shifted(lposition), metric);
0089 }
0090 
0091 Vector2 ConeBounds::center() const {
0092   // Centroid in z is at the middle of the z range
0093   double zCentroid = 0.5 * (get(eMinZ) + get(eMaxZ));
0094   // In phi, centroid is at the average phi position
0095   double phiCentroid = get(eAveragePhi);
0096   return Vector2(phiCentroid, zCentroid);
0097 }
0098 
0099 std::ostream& ConeBounds::toStream(std::ostream& sl) const {
0100   detail::OstreamStateGuard guard{sl};
0101   sl << std::fixed << std::setprecision(7);
0102   sl << "Acts::ConeBounds: (tanAlpha, minZ, maxZ, halfPhiSector, averagePhi) "
0103         "= ";
0104   sl << "(" << m_tanAlpha << ", " << get(eMinZ) << ", " << get(eMaxZ) << ", "
0105      << get(eHalfPhiSector) << ", " << get(eAveragePhi) << ")";
0106   return sl;
0107 }
0108 
0109 }  // namespace Acts