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