Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
BinnedSPGroup.ipp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file BinnedSPGroup.ipp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2023 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
9 // Binned SP Group Iterator
10 
11 #include <boost/container/flat_set.hpp>
12 
13 template <typename external_spacepoint_t>
16  : m_group(group), m_max_localBins(m_group->m_grid->numLocalBins()) {
17  m_max_localBins[INDEX::PHI] += 1;
18  m_current_localBins[INDEX::Z] = m_group->skipZMiddleBin();
19  if (index == m_group->m_grid->size()) {
21  } else {
22  // Go to the next not-empty bin
24  }
25 }
26 
27 template <typename external_spacepoint_t>
30  // Increase the position by one
31  // if we were on the edge, go up one phi bin and reset z bin
32  if (++m_current_localBins[INDEX::Z] == m_max_localBins[INDEX::Z]) {
33  ++m_current_localBins[INDEX::PHI];
34  m_current_localBins[INDEX::Z] = m_group->skipZMiddleBin();
35  }
36 
37  // Get the next not-empty bin in the grid
38  findNotEmptyBin();
39  return *this;
40 }
41 
42 template <typename external_spacepoint_t>
45  return m_group.ptr == other.m_group.ptr and
46  m_current_localBins[INDEX::PHI] ==
47  other.m_current_localBins[INDEX::PHI] and
48  m_current_localBins[INDEX::Z] == other.m_current_localBins[INDEX::Z];
49 }
50 
51 template <typename external_spacepoint_t>
54  return not(*this == other);
55 }
56 
57 template <typename external_spacepoint_t>
58 std::tuple<boost::container::small_vector<size_t, 9>, std::size_t,
59  boost::container::small_vector<size_t, 9>>
61  // Global Index
62  std::size_t global_index = m_group->m_grid->globalBinFromLocalBins(
63  {m_current_localBins[INDEX::PHI],
64  m_group->m_bins[m_current_localBins[INDEX::Z]]});
65 
66  boost::container::small_vector<size_t, 9> bottoms =
67  m_group->m_bottomBinFinder->findBins(
68  m_current_localBins[INDEX::PHI],
69  m_group->m_bins[m_current_localBins[INDEX::Z]],
70  m_group->m_grid.get());
71  boost::container::small_vector<size_t, 9> tops =
72  m_group->m_topBinFinder->findBins(
73  m_current_localBins[INDEX::PHI],
74  m_group->m_bins[m_current_localBins[INDEX::Z]],
75  m_group->m_grid.get());
76 
77  // GCC12+ in Release throws an overread warning here due to the move.
78  // This is from inside boost code, so best we can do is to suppress it.
79 #if defined(__GNUC__) && __GNUC__ >= 12 && !defined(__clang__)
80 #pragma GCC diagnostic push
81 #pragma GCC diagnostic ignored "-Wstringop-overread"
82 #endif
83  return std::make_tuple(std::move(bottoms), global_index, std::move(tops));
84 #if defined(__GNUC__) && __GNUC__ >= 12 && !defined(__clang__)
85 #pragma GCC diagnostic pop
86 #endif
87 }
88 
89 template <typename external_spacepoint_t>
90 inline void
92  // Iterate on the grid till we find a not-empty bin
93  // We start from the current bin configuration and move forward
94 
95  for (std::size_t phiBin(m_current_localBins[INDEX::PHI]);
96  phiBin < m_max_localBins[INDEX::PHI]; ++phiBin) {
97  // 0 is the underflow - skip
98  if (phiBin == 0) {
99  continue;
100  }
101 
102  for (std::size_t zBin(m_current_localBins[INDEX::Z]);
103  zBin < m_max_localBins[INDEX::Z]; ++zBin) {
104  std::size_t zBinIndex = m_group->m_bins[zBin];
105  std::size_t index =
106  m_group->m_grid->globalBinFromLocalBins({phiBin, zBinIndex});
107  // Check if there are entries in this bin
108  if (m_group->m_grid->at(index).empty()) {
109  continue;
110  }
111 
112  // Set the new current bins
113  m_current_localBins[INDEX::PHI] = phiBin;
114  m_current_localBins[INDEX::Z] = zBin;
115  return;
116  }
117  // Reset z-index
118  m_current_localBins[INDEX::Z] = m_group->skipZMiddleBin();
119  }
120 
121  // Could find nothing ... setting this to end()
122  m_current_localBins = m_max_localBins;
123 }
124 
125 // Binned SP Group
126 template <typename external_spacepoint_t>
127 template <typename spacepoint_iterator_t, typename callable_t>
129  spacepoint_iterator_t spBegin, spacepoint_iterator_t spEnd,
130  callable_t&& toGlobal,
131  std::shared_ptr<const Acts::BinFinder<external_spacepoint_t>> botBinFinder,
132  std::shared_ptr<const Acts::BinFinder<external_spacepoint_t>> tBinFinder,
134  Acts::Extent& rRangeSPExtent,
136  const SeedFinderOptions& options) {
137  if (not config.isInInternalUnits) {
138  throw std::runtime_error(
139  "SeedFinderConfig not in ACTS internal units in BinnedSPGroup");
140  }
141  if (not options.isInInternalUnits) {
142  throw std::runtime_error(
143  "SeedFinderOptions not in ACTS internal units in BinnedSPGroup");
144  }
145  static_assert(
146  std::is_same<
148  const external_spacepoint_t*>::value,
149  "Iterator does not contain type this class was templated with");
150 
151  // get region of interest (or full detector if configured accordingly)
152  float phiMin = config.phiMin;
153  float phiMax = config.phiMax;
154  float zMin = config.zMin;
155  float zMax = config.zMax;
156 
157  // sort by radius
158  // add magnitude of beamPos to rMax to avoid excluding measurements
159  // create number of bins equal to number of millimeters rMax
160  // (worst case minR: configured minR + 1mm)
161  // binSizeR allows to increase or reduce numRBins if needed
162  size_t numRBins = static_cast<size_t>((config.rMax + options.beamPos.norm()) /
163  config.binSizeR);
164 
165  // keep track of changed bins while sorting
166  boost::container::flat_set<size_t> rBinsIndex;
167 
168  std::size_t counter = 0;
169  for (spacepoint_iterator_t it = spBegin; it != spEnd; it++, ++counter) {
170  if (*it == nullptr) {
171  continue;
172  }
173  const external_spacepoint_t& sp = **it;
174  const auto& [spPosition, variance] =
175  toGlobal(sp, config.zAlign, config.rAlign, config.sigmaError);
176 
177  float spX = spPosition[0];
178  float spY = spPosition[1];
179  float spZ = spPosition[2];
180 
181  // store x,y,z values in extent
182  rRangeSPExtent.extend({spX, spY, spZ});
183 
184  // remove SPs outside z and phi region
185  if (spZ > zMax || spZ < zMin) {
186  continue;
187  }
188  float spPhi = std::atan2(spY, spX);
189  if (spPhi > phiMax || spPhi < phiMin) {
190  continue;
191  }
192 
193  auto isp = std::make_unique<InternalSpacePoint<external_spacepoint_t>>(
194  counter, sp, spPosition, options.beamPos, variance);
195  // calculate r-Bin index and protect against overflow (underflow not
196  // possible)
197  size_t rIndex = static_cast<size_t>(isp->radius() / config.binSizeR);
198  // if index out of bounds, the SP is outside the region of interest
199  if (rIndex >= numRBins) {
200  continue;
201  }
202 
203  // fill rbins into grid
204  Acts::Vector2 spLocation(isp->phi(), isp->z());
205  std::vector<std::unique_ptr<InternalSpacePoint<external_spacepoint_t>>>&
206  rbin = grid->atPosition(spLocation);
207  rbin.push_back(std::move(isp));
208 
209  // keep track of the bins we modify so that we can later sort the SPs in
210  // those bins only
211  if (rbin.size() > 1) {
212  rBinsIndex.insert(grid->globalBinFromPosition(spLocation));
213  }
214  }
215 
216  // sort SPs in R for each filled (z, phi) bin
217  for (auto& binIndex : rBinsIndex) {
218  std::vector<std::unique_ptr<InternalSpacePoint<external_spacepoint_t>>>&
219  rbin = grid->atPosition(binIndex);
220  std::sort(
221  rbin.begin(), rbin.end(),
222  [](std::unique_ptr<InternalSpacePoint<external_spacepoint_t>>& a,
223  std::unique_ptr<InternalSpacePoint<external_spacepoint_t>>& b) {
224  return a->radius() < b->radius();
225  });
226  }
227 
228  m_grid = std::move(grid);
229  m_bottomBinFinder = botBinFinder;
230  m_topBinFinder = tBinFinder;
231 
232  m_skipZMiddleBin = config.skipZMiddleBinSearch;
233  m_bins = config.zBinsCustomLooping;
234  if (m_bins.empty()) {
235  std::size_t nZbins = m_grid->numLocalBins()[1];
236  m_bins.reserve(nZbins);
237  for (std::size_t i(0); i < nZbins; ++i) {
238  m_bins.push_back(i + 1);
239  }
240  }
241 }
242 
243 template <typename external_spacepoint_t>
245  return m_grid->size();
246 }
247 
248 template <typename external_spacepoint_t>
251  return {*this, 0};
252 }
253 
254 template <typename external_spacepoint_t>
257  return {*this, m_grid->size()};
258 }