Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-07-26 08:18:56

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/Seeding/detail/SpacePointGridPhiBinning.hpp"
0010 
0011 #include "Acts/Utilities/MathHelpers.hpp"
0012 
0013 #include <algorithm>
0014 #include <cmath>
0015 #include <numbers>
0016 #include <stdexcept>
0017 
0018 namespace Acts::detail {
0019 
0020 int computeSpacePointGridPhiBins(const SpacePointGridPhiBinningConfig& config,
0021                                  const Logger& logger) {
0022   if (config.bFieldInZ == 0) {
0023     // for no magnetic field, use the maximum number of phi bins
0024     ACTS_VERBOSE(
0025         "B-Field is 0 (z-coordinate), setting the number of bins in phi to "
0026         << config.maxPhiBins);
0027     return config.maxPhiBins;
0028   }
0029 
0030   // calculate circle intersections of helix and max detector radius in mm.
0031   // bFieldInZ is in (pT/radius) natively, no need for conversion
0032   const float minHelixRadius = config.minPt / config.bFieldInZ;
0033 
0034   // sanity check: if yOuter takes the square root of a negative number
0035   if (minHelixRadius < config.rMax * 0.5) {
0036     throw std::domain_error(
0037         "The value of minHelixRadius cannot be smaller than rMax / 2. Please "
0038         "check the configuration of bFieldInZ and minPt");
0039   }
0040 
0041   // x = rMax^2 / (2 * minHelixRadius)
0042   // y = cathetus(rMax, x)
0043   // R / x = 2 * minHelixRadius / R
0044   // outerAngle = x / y = x / sqrt(rMax^2 - x^2) = 1 / cath(rMax / x, 1)
0045   //            = 1 / cath(2 * minHelixRadius / rMax, 1)
0046   const float outerAngle =
0047       std::atan(1.f / fastCathetus(2 * minHelixRadius / config.rMax, 1));
0048   // intersection of helix and max detector radius minus maximum R distance
0049   // from middle SP to top SP
0050   float innerAngle = 0;
0051   float rMin = config.rMax;
0052   if (config.rMax > config.deltaRMax) {
0053     const float innerCircleR = config.rMax - config.deltaRMax;
0054     rMin = innerCircleR;
0055     innerAngle =
0056         std::atan(1.f / fastCathetus(2 * minHelixRadius / innerCircleR, 1));
0057   }
0058 
0059   // evaluating the azimutal deflection including the maximum impact
0060   // parameter. A track with |d0| >= r cannot reach radius r, so the azimuthal
0061   // deflection saturates at pi/2: clamp the asin arguments to [0, 1] so that
0062   // impactMax >= (rMax - deltaRMax) falls back to coarse / full-2pi phi
0063   // coverage instead of producing a NaN (and hence a zero phi-bin count and a
0064   // "Invalid binning" exception).
0065   const float sinInner = std::min(1.f, config.impactMax / rMin);
0066   const float sinOuter = std::min(1.f, config.impactMax / config.rMax);
0067   const float deltaAngleWithMaxD0 =
0068       std::abs(std::asin(sinInner) - std::asin(sinOuter));
0069 
0070   // evaluating delta Phi based on the inner and outer angle, and the azimutal
0071   // deflection including the maximum impact parameter
0072   // Divide by config.phiBinDeflectionCoverage since we combine
0073   // config.phiBinDeflectionCoverage number of consecutive phi bins in the
0074   // seed making step. So each individual bin should cover
0075   // 1/config.phiBinDeflectionCoverage of the maximum expected azimutal
0076   // deflection
0077   const float deltaPhi = (outerAngle - innerAngle + deltaAngleWithMaxD0) /
0078                          config.phiBinDeflectionCoverage;
0079 
0080   // sanity check: if the delta phi is equal to or less than zero, we'll be
0081   // creating an infinite or a negative number of bins, which would be bad!
0082   if (deltaPhi <= 0.f) {
0083     throw std::domain_error(
0084         "Delta phi value is equal to or less than zero, leading to an "
0085         "impossible number of bins (negative or infinite)");
0086   }
0087 
0088   // divide 2pi by angle delta to get number of phi-bins
0089   // size is always 2pi even for regions of interest
0090   const int phiBins =
0091       static_cast<int>(std::ceil(2 * std::numbers::pi / deltaPhi));
0092 
0093   // set protection for large number of bins, by default it is large
0094   return std::min(phiBins, config.maxPhiBins);
0095 }
0096 
0097 }  // namespace Acts::detail