File indexing completed on 2025-07-09 07:49:42
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "Acts/Seeding/detail/CylindricalSpacePointGrid.hpp"
0012
0013 #include <concepts>
0014 #include <numbers>
0015
0016 namespace Acts {
0017
0018 template <typename external_spacepoint_t>
0019 CylindricalSpacePointGrid<external_spacepoint_t>
0020 CylindricalSpacePointGridCreator::createGrid(
0021 const CylindricalSpacePointGridConfig& config,
0022 const CylindricalSpacePointGridOptions& options, const Logger& logger) {
0023 config.checkConfig();
0024
0025 using AxisScalar = Vector3::Scalar;
0026 using namespace UnitLiterals;
0027
0028 int phiBins = 0;
0029
0030 if (options.bFieldInZ == 0) {
0031 phiBins = 100;
0032 ACTS_VERBOSE(
0033 "B-Field is 0 (z-coordinate), setting the number of bins in phi to "
0034 << phiBins);
0035 } else {
0036
0037
0038 float minHelixRadius = config.minPt / options.bFieldInZ;
0039
0040
0041 if (minHelixRadius < config.rMax * 0.5) {
0042 throw std::domain_error(
0043 "The value of minHelixRadius cannot be smaller than rMax / 2. Please "
0044 "check the configuration of bFieldInZ and minPt");
0045 }
0046
0047 float maxR2 = config.rMax * config.rMax;
0048 float xOuter = maxR2 / (2 * minHelixRadius);
0049 float yOuter = std::sqrt(maxR2 - xOuter * xOuter);
0050 float outerAngle = std::atan(xOuter / yOuter);
0051
0052
0053 float innerAngle = 0;
0054 float rMin = config.rMax;
0055 if (config.rMax > config.deltaRMax) {
0056 rMin = config.rMax - config.deltaRMax;
0057 float innerCircleR2 =
0058 (config.rMax - config.deltaRMax) * (config.rMax - config.deltaRMax);
0059 float xInner = innerCircleR2 / (2 * minHelixRadius);
0060 float yInner = std::sqrt(innerCircleR2 - xInner * xInner);
0061 innerAngle = std::atan(xInner / yInner);
0062 }
0063
0064
0065 float deltaAngleWithMaxD0 =
0066 std::abs(std::asin(config.impactMax / (rMin)) -
0067 std::asin(config.impactMax / config.rMax));
0068
0069
0070
0071
0072
0073
0074
0075
0076 float deltaPhi = (outerAngle - innerAngle + deltaAngleWithMaxD0) /
0077 config.phiBinDeflectionCoverage;
0078
0079
0080
0081 if (deltaPhi <= 0.f) {
0082 throw std::domain_error(
0083 "Delta phi value is equal to or less than zero, leading to an "
0084 "impossible number of bins (negative or infinite)");
0085 }
0086
0087
0088
0089 phiBins = static_cast<int>(std::ceil(2 * std::numbers::pi / deltaPhi));
0090
0091
0092
0093
0094
0095
0096 phiBins = std::min(phiBins, config.maxPhiBins);
0097 }
0098
0099 Axis<AxisType::Equidistant, AxisBoundaryType::Closed> phiAxis(
0100 config.phiMin, config.phiMax, phiBins);
0101
0102
0103 std::vector<AxisScalar> zValues{};
0104
0105
0106 if (config.zBinEdges.empty()) {
0107
0108
0109
0110
0111 float zBinSize = config.cotThetaMax * config.deltaRMax;
0112 float zBins =
0113 std::max(1.f, std::floor((config.zMax - config.zMin) / zBinSize));
0114
0115 zValues.reserve(static_cast<int>(zBins));
0116 for (int bin = 0; bin <= static_cast<int>(zBins); bin++) {
0117 AxisScalar edge =
0118 config.zMin + bin * ((config.zMax - config.zMin) / zBins);
0119 zValues.push_back(edge);
0120 }
0121
0122 } else {
0123
0124 zValues.reserve(config.zBinEdges.size());
0125 for (float bin : config.zBinEdges) {
0126 zValues.push_back(bin);
0127 }
0128 }
0129
0130 std::vector<AxisScalar> rValues{};
0131 rValues.reserve(std::max(2ul, config.rBinEdges.size()));
0132 if (config.rBinEdges.empty()) {
0133 rValues = {config.rMin, config.rMax};
0134 } else {
0135 rValues.insert(rValues.end(), config.rBinEdges.begin(),
0136 config.rBinEdges.end());
0137 }
0138
0139 Axis<AxisType::Variable, AxisBoundaryType::Open> zAxis(std::move(zValues));
0140 Axis<AxisType::Variable, AxisBoundaryType::Open> rAxis(std::move(rValues));
0141
0142 ACTS_VERBOSE("Defining Grid:");
0143 ACTS_VERBOSE("- Phi Axis: " << phiAxis);
0144 ACTS_VERBOSE("- Z axis : " << zAxis);
0145 ACTS_VERBOSE("- R axis : " << rAxis);
0146
0147 return CylindricalSpacePointGrid<external_spacepoint_t>(
0148 std::make_tuple(std::move(phiAxis), std::move(zAxis), std::move(rAxis)));
0149 }
0150
0151 template <typename external_spacepoint_t,
0152 typename external_spacepoint_iterator_t>
0153 void CylindricalSpacePointGridCreator::fillGrid(
0154 const SeedFinderConfig<external_spacepoint_t>& config,
0155 const SeedFinderOptions& options,
0156 CylindricalSpacePointGrid<external_spacepoint_t>& grid,
0157 external_spacepoint_iterator_t spBegin,
0158 external_spacepoint_iterator_t spEnd, const Logger& logger) {
0159 (void)options;
0160
0161 if (config.seedFilter == nullptr) {
0162 throw std::runtime_error("SeedFinderConfig has a null SeedFilter object");
0163 }
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176 std::vector<bool> usedBinIndex(grid.size(), false);
0177 std::vector<std::size_t> rBinsIndex;
0178 rBinsIndex.reserve(grid.size());
0179
0180 ACTS_VERBOSE("Fetching " << std::distance(spBegin, spEnd)
0181 << " space points to the grid");
0182 std::size_t counter = 0ul;
0183 for (external_spacepoint_iterator_t it = spBegin; it != spEnd; ++it) {
0184 const external_spacepoint_t& sp = *it;
0185
0186
0187 if (!config.spacePointSelector(sp)) {
0188 continue;
0189 }
0190
0191
0192 Vector3 position(sp.phi(), sp.z(), sp.radius());
0193 if (!grid.isInside(position)) {
0194 continue;
0195 }
0196
0197 std::size_t globIndex = grid.globalBinFromPosition(position);
0198 auto& rbin = grid.at(globIndex);
0199 rbin.push_back(&sp);
0200 ++counter;
0201
0202
0203
0204 if (rbin.size() > 1 && !usedBinIndex[globIndex]) {
0205 usedBinIndex[globIndex] = true;
0206 rBinsIndex.push_back(globIndex);
0207 }
0208 }
0209
0210
0211 for (std::size_t binIndex : rBinsIndex) {
0212 auto& rbin = grid.atPosition(binIndex);
0213 std::ranges::sort(rbin, {}, [](const auto& rb) { return rb->radius(); });
0214 }
0215
0216 ACTS_VERBOSE(
0217 "Number of space points inserted (within grid range): " << counter);
0218 }
0219
0220 template <typename external_spacepoint_t, typename external_collection_t>
0221 requires std::ranges::range<external_collection_t> &&
0222 std::same_as<typename external_collection_t::value_type,
0223 external_spacepoint_t>
0224 void CylindricalSpacePointGridCreator::fillGrid(
0225 const SeedFinderConfig<external_spacepoint_t>& config,
0226 const SeedFinderOptions& options,
0227 CylindricalSpacePointGrid<external_spacepoint_t>& grid,
0228 const external_collection_t& collection, const Logger& logger) {
0229 CylindricalSpacePointGridCreator::fillGrid<external_spacepoint_t>(
0230 config, options, grid, std::ranges::begin(collection),
0231 std::ranges::end(collection), logger);
0232 }
0233
0234 }