Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-07-26 08:22:01

0001 /** TRACCC library, part of the ACTS project (R&D line)
0002  *
0003  * (c) 2021-2025 CERN for the benefit of the ACTS project
0004  *
0005  * Mozilla Public License Version 2.0
0006  */
0007 
0008 #pragma once
0009 
0010 // Project include(s).
0011 #include "traccc/definitions/math.hpp"
0012 #include "traccc/edm/spacepoint_collection.hpp"
0013 #include "traccc/seeding/detail/seeding_config.hpp"
0014 #include "traccc/seeding/detail/singlet.hpp"
0015 #include "traccc/seeding/detail/spacepoint_grid.hpp"
0016 
0017 // VecMem include(s).
0018 #include <vecmem/memory/memory_resource.hpp>
0019 
0020 namespace traccc {
0021 
0022 inline std::pair<axis2::circular<>, axis2::regular<>> get_axes(
0023     const spacepoint_grid_config& grid_config, vecmem::memory_resource& mr) {
0024   detray::dindex phiBins;
0025   if (grid_config.bFieldInZ == 0) {
0026     phiBins = 100;
0027   } else {
0028     // calculate circle intersections of helix and max detector radius
0029     scalar minHelixRadius = grid_config.minPt / grid_config.bFieldInZ;
0030 
0031     // sanity check: if yOuter takes the square root of a negative number
0032     if (minHelixRadius < grid_config.rMax / 2) {
0033       throw std::domain_error(
0034           "The value of minHelixRadius cannot be smaller than rMax / 2. "
0035           "Please "
0036           "check the configuration of bFieldInZ and minPt");
0037     }
0038     scalar maxR2 = grid_config.rMax * grid_config.rMax;
0039     scalar xOuter = maxR2 / (2 * minHelixRadius);
0040     scalar yOuter = std::sqrt(maxR2 - xOuter * xOuter);
0041     scalar outerAngle = std::atan(xOuter / yOuter);
0042 
0043     // intersection of helix and max detector radius minus maximum R
0044     // distance from middle SP to top SP
0045     scalar innerAngle = 0;
0046     scalar rMin = grid_config.rMax;
0047     if (grid_config.rMax > grid_config.deltaRMax) {
0048       rMin = grid_config.rMax - grid_config.deltaRMax;
0049       scalar innerCircleR2 = (grid_config.rMax - grid_config.deltaRMax) *
0050                              (grid_config.rMax - grid_config.deltaRMax);
0051       scalar xInner = innerCircleR2 / (2 * minHelixRadius);
0052       scalar yInner = std::sqrt(innerCircleR2 - xInner * xInner);
0053       innerAngle = std::atan(xInner / yInner);
0054     }
0055 
0056     // evaluating the azimutal deflection including the maximum impact
0057     // parameter
0058     scalar deltaAngleWithMaxD0 =
0059         math::fabs(std::asin(grid_config.impactMax / (rMin)) -
0060                    std::asin(grid_config.impactMax / grid_config.rMax));
0061 
0062     // evaluating delta Phi based on the inner and outer angle, and the
0063     // azimutal deflection including the maximum impact parameter Divide by
0064     // config.phiBinDeflectionCoverage since we combine
0065     // config.phiBinDeflectionCoverage number of consecutive phi bins in the
0066     // seed making step. So each individual bin should cover
0067     // 1/config.phiBinDeflectionCoverage of the maximum expected azimutal
0068     // deflection
0069     scalar deltaPhi = (outerAngle - innerAngle + deltaAngleWithMaxD0) /
0070                       static_cast<scalar>(grid_config.phiBinDeflectionCoverage);
0071 
0072     // sanity check: if the delta phi is equal to or less than zero, we'll
0073     // be creating an infinite or a negative number of bins, which would be
0074     // bad!
0075     if (deltaPhi <= 0.) {
0076       throw std::domain_error(
0077           "Delta phi value is equal to or less than zero, leading to an "
0078           "impossible number of bins (negative or infinite)");
0079     }
0080 
0081     // divide 2pi by angle delta to get number of phi-bins
0082     // size is always 2pi even for regions of interest
0083     phiBins =
0084         static_cast<detray::dindex>(std::llround(2 * M_PI / deltaPhi + 0.5));
0085     // need to scale the number of phi bins accordingly to the number of
0086     // consecutive phi bins in the seed making step.
0087     // Each individual bin should be approximately a fraction (depending on
0088     // this number) of the maximum expected azimutal deflection.
0089   }
0090 
0091   axis2::circular m_phi_axis{phiBins, grid_config.phiMin, grid_config.phiMax,
0092                              mr};
0093 
0094   // TODO: can probably be optimized using smaller z bins
0095   // and returning (multiple) neighbors only in one z-direction for forward
0096   // seeds
0097   // FIXME: zBinSize must include scattering
0098 
0099   scalar zBinSize = grid_config.cotThetaMax * grid_config.deltaRMax;
0100   detray::dindex zBins = std::max(
0101       static_cast<detray::dindex>(1),
0102       static_cast<detray::dindex>(
0103           std::floor((grid_config.zMax - grid_config.zMin) / zBinSize)));
0104 
0105   axis2::regular m_z_axis{zBins, grid_config.zMin, grid_config.zMax, mr};
0106 
0107   return {m_phi_axis, m_z_axis};
0108 }
0109 
0110 template <typename T>
0111 inline TRACCC_HOST_DEVICE bool is_valid_sp(const seedfinder_config& config,
0112                                            const edm::spacepoint<T>& sp) {
0113   if (sp.z() > config.zMax || sp.z() < config.zMin) {
0114     return false;
0115   }
0116   scalar spPhi = math::atan2(sp.y(), sp.x());
0117   if (spPhi > config.phiMax || spPhi < config.phiMin) {
0118     return false;
0119   }
0120 
0121   return (static_cast<size_t>(vector::perp(vector2{
0122               sp.x() - config.beamPos[0], sp.y() - config.beamPos[1]})) <
0123           config.get_num_rbins());
0124 }
0125 
0126 }  // namespace traccc