File indexing completed on 2025-01-18 09:11:28
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Surfaces/detail/MergeHelper.hpp"
0010
0011 #include "Acts/Definitions/Units.hpp"
0012 #include "Acts/Utilities/detail/periodic.hpp"
0013
0014 #include <numbers>
0015
0016 namespace Acts::detail {
0017
0018 std::tuple<double, double, bool> mergedPhiSector(double hlPhi1, double avgPhi1,
0019 double hlPhi2, double avgPhi2,
0020 const Logger& logger,
0021 double tolerance) {
0022 using namespace UnitLiterals;
0023
0024 if (std::abs(hlPhi1 - std::numbers::pi / 2.) < tolerance &&
0025 std::abs(hlPhi2 - std::numbers::pi / 2.) < tolerance) {
0026 ACTS_VERBOSE("Both phi sectors cover a half circle");
0027
0028 ACTS_VERBOSE("-> distance between sectors: " << detail::difference_periodic(
0029 avgPhi1, avgPhi2,
0030 2 * std::numbers::pi) /
0031 1_degree);
0032
0033 if (std::abs(std::abs(detail::difference_periodic(avgPhi1, avgPhi2,
0034 2 * std::numbers::pi)) -
0035 std::numbers::pi) > tolerance) {
0036 throw std::invalid_argument(
0037 "Phi sectors cover half a circle but are not opposite");
0038 }
0039
0040 double newAvgPhi = detail::radian_sym(avgPhi1 + std::numbers::pi / 2.);
0041 double newHlPhi = std::numbers::pi;
0042 ACTS_VERBOSE("merged: ["
0043 << detail::radian_sym(newAvgPhi - newHlPhi) / 1_degree << ", "
0044 << detail::radian_sym(newAvgPhi + newHlPhi) / 1_degree
0045 << "] ~> " << newAvgPhi / 1_degree << " +- "
0046 << newHlPhi / 1_degree);
0047 return {newHlPhi, newAvgPhi, false};
0048 }
0049
0050 double minPhi1 = detail::radian_sym(-hlPhi1 + avgPhi1);
0051 double maxPhi1 = detail::radian_sym(hlPhi1 + avgPhi1);
0052
0053 ACTS_VERBOSE("one: [" << minPhi1 / 1_degree << ", " << maxPhi1 / 1_degree
0054 << "] ~> " << avgPhi1 / 1_degree << " +- "
0055 << hlPhi1 / 1_degree);
0056
0057 double maxPhi2 = detail::radian_sym(hlPhi2 + avgPhi2);
0058 double minPhi2 = detail::radian_sym(-hlPhi2 + avgPhi2);
0059
0060 ACTS_VERBOSE("two: [" << minPhi2 / 1_degree << ", " << maxPhi2 / 1_degree
0061 << "] ~> " << avgPhi2 / 1_degree << " +- "
0062 << hlPhi2 / 1_degree);
0063
0064 ACTS_VERBOSE("Checking for CCW or CW ordering");
0065 auto same = [tolerance](double a, double b) {
0066 return std::abs(a - b) < tolerance;
0067 };
0068
0069 double newMaxPhi{}, newMinPhi{};
0070 double newHlPhi = hlPhi1 + hlPhi2;
0071
0072 bool reversed = false;
0073 if (same(minPhi1, maxPhi2)) {
0074 ACTS_VERBOSE("-> CCW ordering: one is 'right' of two");
0075
0076 newMinPhi = minPhi2;
0077 newMaxPhi = maxPhi1;
0078 } else if (same(maxPhi1, minPhi2)) {
0079 ACTS_VERBOSE("-> CW ordering: one is 'left' of two");
0080 newMinPhi = minPhi1;
0081 newMaxPhi = maxPhi2;
0082 reversed = true;
0083 } else {
0084 ACTS_ERROR("Phi ranges are incompatible");
0085 throw std::invalid_argument("Phi ranges are incompatible");
0086 }
0087
0088 double newAvgPhi = detail::radian_sym(newMinPhi + newHlPhi);
0089
0090 ACTS_VERBOSE("merged: [" << newMinPhi / 1_degree << ", "
0091 << newMaxPhi / 1_degree << "] ~> "
0092 << newAvgPhi / 1_degree << " +- "
0093 << newHlPhi / 1_degree);
0094
0095 return {newHlPhi, newAvgPhi, reversed};
0096 }
0097
0098 }