File indexing completed on 2025-01-19 09:23:31
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/container/flat_set.hpp>
0010
0011 template <typename SpacePoint>
0012 Acts::CylindricalSpacePointGrid<SpacePoint>
0013 Acts::CylindricalSpacePointGridCreator::createGrid(
0014 const Acts::CylindricalSpacePointGridConfig& config,
0015 const Acts::CylindricalSpacePointGridOptions& options) {
0016 if (!config.isInInternalUnits) {
0017 throw std::runtime_error(
0018 "CylindricalSpacePointGridConfig not in ACTS internal units in "
0019 "CylindricalSpacePointGridCreator::createGrid");
0020 }
0021 if (!options.isInInternalUnits) {
0022 throw std::runtime_error(
0023 "CylindricalSpacePointGridOptions not in ACTS internal units in "
0024 "CylindricalSpacePointGridCreator::createGrid");
0025 }
0026 using AxisScalar = Acts::Vector3::Scalar;
0027 using namespace Acts::UnitLiterals;
0028
0029 int phiBins = 0;
0030
0031 if (options.bFieldInZ == 0) {
0032 phiBins = 100;
0033 } else {
0034
0035 float minHelixRadius =
0036 config.minPt /
0037 (1_T * 1e6 *
0038 options.bFieldInZ);
0039
0040
0041
0042 if (minHelixRadius < config.rMax / 2) {
0043 throw std::domain_error(
0044 "The value of minHelixRadius cannot be smaller than rMax / 2. Please "
0045 "check the configuration of bFieldInZ and minPt");
0046 }
0047
0048 float maxR2 = config.rMax * config.rMax;
0049 float xOuter = maxR2 / (2 * minHelixRadius);
0050 float yOuter = std::sqrt(maxR2 - xOuter * xOuter);
0051 float outerAngle = std::atan(xOuter / yOuter);
0052
0053
0054 float innerAngle = 0;
0055 float rMin = config.rMax;
0056 if (config.rMax > config.deltaRMax) {
0057 rMin = config.rMax - config.deltaRMax;
0058 float innerCircleR2 =
0059 (config.rMax - config.deltaRMax) * (config.rMax - config.deltaRMax);
0060 float xInner = innerCircleR2 / (2 * minHelixRadius);
0061 float yInner = std::sqrt(innerCircleR2 - xInner * xInner);
0062 innerAngle = std::atan(xInner / yInner);
0063 }
0064
0065
0066 float deltaAngleWithMaxD0 =
0067 std::abs(std::asin(config.impactMax / (rMin)) -
0068 std::asin(config.impactMax / config.rMax));
0069
0070
0071
0072
0073
0074
0075
0076
0077 float deltaPhi = (outerAngle - innerAngle + deltaAngleWithMaxD0) /
0078 config.phiBinDeflectionCoverage;
0079
0080
0081
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
0089
0090 phiBins = static_cast<int>(std::ceil(2 * M_PI / deltaPhi));
0091
0092
0093
0094
0095
0096
0097 if (phiBins > config.maxPhiBins) {
0098 phiBins = config.maxPhiBins;
0099 }
0100 }
0101
0102 Acts::detail::Axis<detail::AxisType::Equidistant,
0103 detail::AxisBoundaryType::Closed>
0104 phiAxis(config.phiMin, config.phiMax, phiBins);
0105
0106
0107 std::vector<AxisScalar> zValues;
0108
0109
0110 if (config.zBinEdges.empty()) {
0111
0112
0113
0114
0115 float zBinSize = config.cotThetaMax * config.deltaRMax;
0116 float zBins =
0117 std::max(1.f, std::floor((config.zMax - config.zMin) / zBinSize));
0118
0119 zValues.reserve(static_cast<int>(zBins));
0120 for (int bin = 0; bin <= static_cast<int>(zBins); bin++) {
0121 AxisScalar edge =
0122 config.zMin + bin * ((config.zMax - config.zMin) / zBins);
0123 zValues.push_back(edge);
0124 }
0125
0126 } else {
0127
0128 zValues.reserve(config.zBinEdges.size());
0129 for (float bin : config.zBinEdges) {
0130 zValues.push_back(bin);
0131 }
0132 }
0133
0134 detail::Axis<detail::AxisType::Variable, detail::AxisBoundaryType::Bound>
0135 zAxis(std::move(zValues));
0136 return Acts::CylindricalSpacePointGrid<SpacePoint>(
0137 std::make_tuple(std::move(phiAxis), std::move(zAxis)));
0138 }
0139
0140 template <typename external_spacepoint_t,
0141 typename external_spacepoint_iterator_t, typename callable_t>
0142 void Acts::CylindricalSpacePointGridCreator::fillGrid(
0143 const Acts::SeedFinderConfig<external_spacepoint_t>& config,
0144 const Acts::SeedFinderOptions& options,
0145 Acts::CylindricalSpacePointGrid<external_spacepoint_t>& grid,
0146 external_spacepoint_iterator_t spBegin,
0147 external_spacepoint_iterator_t spEnd, callable_t&& toGlobal,
0148 Acts::Extent& rRangeSPExtent) {
0149 using iterated_value_t =
0150 typename std::iterator_traits<external_spacepoint_iterator_t>::value_type;
0151 using iterated_t = typename std::remove_const<
0152 typename std::remove_pointer<iterated_value_t>::type>::type;
0153 static_assert(std::is_pointer<iterated_value_t>::value,
0154 "Iterator must contain pointers to space points");
0155 static_assert(std::is_same<iterated_t, external_spacepoint_t>::value,
0156 "Iterator does not contain type this class was templated with");
0157
0158 if (!config.isInInternalUnits) {
0159 throw std::runtime_error(
0160 "SeedFinderConfig not in ACTS internal units in BinnedSPGroup");
0161 }
0162 if (config.seedFilter == nullptr) {
0163 throw std::runtime_error("SeedFinderConfig has a null SeedFilter object");
0164 }
0165 if (!options.isInInternalUnits) {
0166 throw std::runtime_error(
0167 "SeedFinderOptions not in ACTS internal units in BinnedSPGroup");
0168 }
0169
0170
0171 float phiMin = config.phiMin;
0172 float phiMax = config.phiMax;
0173 float zMin = config.zMin;
0174 float zMax = config.zMax;
0175
0176
0177
0178
0179
0180
0181 std::size_t numRBins = static_cast<std::size_t>(
0182 (config.rMax + options.beamPos.norm()) / config.binSizeR);
0183
0184
0185 boost::container::flat_set<std::size_t> rBinsIndex;
0186
0187 std::size_t counter = 0ul;
0188 for (external_spacepoint_iterator_t it = spBegin; it != spEnd;
0189 it++, ++counter) {
0190 if (*it == nullptr) {
0191 continue;
0192 }
0193 const external_spacepoint_t& sp = **it;
0194 const auto& [spPosition, variance, spTime] =
0195 toGlobal(sp, config.zAlign, config.rAlign, config.sigmaError);
0196
0197 float spX = spPosition[0];
0198 float spY = spPosition[1];
0199 float spZ = spPosition[2];
0200
0201
0202 rRangeSPExtent.extend({spX, spY, spZ});
0203
0204
0205 if (spZ > zMax || spZ < zMin) {
0206 continue;
0207 }
0208 float spPhi = std::atan2(spY, spX);
0209 if (spPhi > phiMax || spPhi < phiMin) {
0210 continue;
0211 }
0212
0213 auto isp = std::make_unique<InternalSpacePoint<external_spacepoint_t>>(
0214 counter, sp, spPosition, options.beamPos, variance, spTime);
0215
0216
0217 std::size_t rIndex =
0218 static_cast<std::size_t>(isp->radius() / config.binSizeR);
0219
0220 if (rIndex >= numRBins) {
0221 continue;
0222 }
0223
0224
0225 Acts::Vector2 spLocation(isp->phi(), isp->z());
0226 std::vector<std::unique_ptr<InternalSpacePoint<external_spacepoint_t>>>&
0227 rbin = grid.atPosition(spLocation);
0228 rbin.push_back(std::move(isp));
0229
0230
0231
0232 if (rbin.size() > 1) {
0233 rBinsIndex.insert(grid.globalBinFromPosition(spLocation));
0234 }
0235 }
0236
0237
0238 for (auto& binIndex : rBinsIndex) {
0239 auto& rbin = grid.atPosition(binIndex);
0240 std::sort(rbin.begin(), rbin.end(), [](const auto& a, const auto& b) {
0241 return a->radius() < b->radius();
0242 });
0243 }
0244 }