EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SurfaceArray.hpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file SurfaceArray.hpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2017-2020 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 #pragma once
14 #include "Acts/Utilities/IAxis.hpp"
17 
18 #include <iostream>
19 #include <type_traits>
20 #include <vector>
21 
22 namespace Acts {
23 
24 using SurfaceVector = std::vector<const Surface*>;
25 
32 class SurfaceArray {
33  public:
38 
40  virtual void fill(const GeometryContext& gctx,
41  const SurfaceVector& surfaces) = 0;
42 
47 
50  virtual size_t completeBinning(const GeometryContext& gctx,
51  const SurfaceVector& surfaces) = 0;
52 
56  virtual SurfaceVector& lookup(const Vector3D& position) = 0;
57 
62  virtual const SurfaceVector& lookup(const Vector3D& position) const = 0;
63 
68  virtual SurfaceVector& lookup(size_t bin) = 0;
69 
74  virtual const SurfaceVector& lookup(size_t bin) const = 0;
75 
80  virtual const SurfaceVector& neighbors(const Vector3D& position) const = 0;
81 
85  virtual size_t size() const = 0;
86 
90  virtual Vector3D getBinCenter(size_t bin) const = 0;
91 
95  virtual std::vector<const IAxis*> getAxes() const = 0;
96 
99  virtual size_t dimensions() const = 0;
100 
106  virtual bool isValidBin(size_t bin) const = 0;
107 
110  virtual std::vector<BinningValue> binningValues() const { return {}; };
111 
113  virtual ~ISurfaceGridLookup() = 0;
114  };
115 
118  template <class... Axes>
120  static constexpr size_t DIM = sizeof...(Axes);
121 
122  public:
126  using point_t =
127  std::conditional_t<DIM == 1, std::array<double, 1>, ActsVectorD<DIM>>;
128  using Grid_t = detail::Grid<SurfaceVector, Axes...>;
129 
139  SurfaceGridLookup(std::function<point_t(const Vector3D&)> globalToLocal,
140  std::function<Vector3D(const point_t&)> localToGlobal,
141  std::tuple<Axes...> axes,
142  std::vector<BinningValue> bValues = {})
143  : m_globalToLocal(std::move(globalToLocal)),
144  m_localToGlobal(std::move(localToGlobal)),
145  m_grid(std::move(axes)),
146  m_binValues(bValues) {
147  m_neighborMap.resize(m_grid.size());
148  }
149 
159  void fill(const GeometryContext& gctx,
160  const SurfaceVector& surfaces) override {
161  for (const auto& srf : surfaces) {
162  Vector3D pos = srf->binningPosition(gctx, binR);
163  lookup(pos).push_back(srf);
164  }
165 
167  }
168 
177  const SurfaceVector& surfaces) override {
178  size_t binCompleted = 0;
179  size_t nBins = size();
180  double minPath, curPath;
181  const Surface* minSrf;
182 
183  for (size_t b = 0; b < nBins; ++b) {
184  if (!isValidBin(b)) {
185  continue;
186  }
187  std::vector<const Surface*>& binContent = lookup(b);
188  // only complete if we have an empty bin
189  if (!binContent.empty()) {
190  continue;
191  }
192 
193  Vector3D binCtr = getBinCenter(b);
195  for (const auto& srf : surfaces) {
196  curPath = (binCtr - srf->binningPosition(gctx, binR)).norm();
197 
198  if (curPath < minPath) {
199  minPath = curPath;
200  minSrf = srf;
201  }
202  }
203 
204  binContent.push_back(minSrf);
205  ++binCompleted;
206  }
207 
208  // recreate neighborcache
210  return binCompleted;
211  }
212 
216  SurfaceVector& lookup(const Vector3D& position) override {
217  return m_grid.atPosition(m_globalToLocal(position));
218  }
219 
224  const SurfaceVector& lookup(const Vector3D& position) const override {
225  return m_grid.atPosition(m_globalToLocal(position));
226  }
227 
232  SurfaceVector& lookup(size_t bin) override { return m_grid.at(bin); }
233 
238  const SurfaceVector& lookup(size_t bin) const override {
239  return m_grid.at(bin);
240  }
241 
246  const SurfaceVector& neighbors(const Vector3D& position) const override {
247  auto lposition = m_globalToLocal(position);
248  return m_neighborMap.at(m_grid.globalBinFromPosition(lposition));
249  }
250 
254  size_t size() const override { return m_grid.size(); }
255 
258  std::vector<BinningValue> binningValues() const override {
259  return m_binValues;
260  }
261 
265  Vector3D getBinCenter(size_t bin) const override {
266  return getBinCenterImpl(bin);
267  }
268 
272  std::vector<const IAxis*> getAxes() const override {
273  auto arr = m_grid.axes();
274  return std::vector<const IAxis*>(arr.begin(), arr.end());
275  }
276 
279  size_t dimensions() const override { return DIM; }
280 
286  bool isValidBin(size_t bin) const override {
287  std::array<size_t, DIM> indices = m_grid.localBinsFromGlobalBin(bin);
288  std::array<size_t, DIM> nBins = m_grid.numLocalBins();
289  for (size_t i = 0; i < indices.size(); ++i) {
290  size_t idx = indices.at(i);
291  if (idx <= 0 || idx >= nBins.at(i) + 1) {
292  return false;
293  }
294  }
295 
296  return true;
297  }
298 
299  private:
301  // calculate neighbors for every bin and store in map
302  for (size_t i = 0; i < m_grid.size(); i++) {
303  if (!isValidBin(i)) {
304  continue;
305  }
307  auto neighborIdxs = m_grid.neighborHoodIndices(loc, 1u);
308  std::vector<const Surface*>& neighbors = m_neighborMap.at(i);
309  neighbors.clear();
310 
311  for (const auto& idx : neighborIdxs) {
312  const std::vector<const Surface*>& binContent = m_grid.at(idx);
313  std::copy(binContent.begin(), binContent.end(),
314  std::back_inserter(neighbors));
315  }
316  }
317  }
318 
329  template <size_t D = DIM, std::enable_if_t<D != 1, int> = 0>
330  Vector3D getBinCenterImpl(size_t bin) const {
333  }
334 
337  template <size_t D = DIM, std::enable_if_t<D == 1, int> = 0>
338  Vector3D getBinCenterImpl(size_t bin) const {
340  return m_localToGlobal(pos);
341  }
342 
343  std::function<point_t(const Vector3D&)> m_globalToLocal;
344  std::function<Vector3D(const point_t&)> m_localToGlobal;
346  std::vector<BinningValue> m_binValues;
347  std::vector<SurfaceVector> m_neighborMap;
348  };
349 
356  : m_element({element}) {}
357 
361  SurfaceVector& lookup(const Vector3D& /*position*/) override {
362  return m_element;
363  }
364 
368  const SurfaceVector& lookup(const Vector3D& /*position*/) const override {
369  return m_element;
370  }
371 
375  SurfaceVector& lookup(size_t /*bin*/) override { return m_element; }
376 
380  const SurfaceVector& lookup(size_t /*bin*/) const override {
381  return m_element;
382  }
383 
387  const SurfaceVector& neighbors(
388  const Vector3D& /*position*/) const override {
389  return m_element;
390  }
391 
394  size_t size() const override { return 1; }
395 
399  Vector3D getBinCenter(size_t /*bin*/) const override {
400  return Vector3D(0, 0, 0);
401  }
402 
405  std::vector<const IAxis*> getAxes() const override { return {}; }
406 
409  size_t dimensions() const override { return 0; }
410 
413  void fill(const GeometryContext& /*gctx*/,
414  const SurfaceVector& /*surfaces*/) override {}
415 
418  size_t completeBinning(const GeometryContext& /*gctx*/,
419  const SurfaceVector& /*surfaces*/) override {
420  return 0;
421  }
422 
426  bool isValidBin(size_t /*bin*/) const override { return true; }
427 
428  private:
429  SurfaceVector m_element;
430  };
431 
439  SurfaceArray(std::unique_ptr<ISurfaceGridLookup> gridLookup,
440  std::vector<std::shared_ptr<const Surface>> surfaces,
442 
453  SurfaceArray(std::shared_ptr<const Surface> srf);
454 
459  return p_gridLookup->lookup(position);
460  }
461 
466  const SurfaceVector& at(const Vector3D& position) const {
467  return p_gridLookup->lookup(position);
468  }
469 
473  SurfaceVector& at(size_t bin) { return p_gridLookup->lookup(bin); }
474 
478  const SurfaceVector& at(size_t bin) const {
479  return p_gridLookup->lookup(bin);
480  }
481 
490  return p_gridLookup->neighbors(position);
491  }
492 
496  size_t size() const { return p_gridLookup->size(); }
497 
501  Vector3D getBinCenter(size_t bin) { return p_gridLookup->getBinCenter(bin); }
502 
508  const SurfaceVector& surfaces() const { return m_surfacesRawPointers; }
509 
514  std::vector<const IAxis*> getAxes() const { return p_gridLookup->getAxes(); }
515 
521  bool isValidBin(size_t bin) const { return p_gridLookup->isValidBin(bin); }
522 
523  const Transform3D& transform() const { return m_transform; }
524 
527  std::vector<BinningValue> binningValues() const {
528  return p_gridLookup->binningValues();
529  };
530 
535  std::ostream& toStream(const GeometryContext& gctx, std::ostream& sl) const;
536 
537  private:
538  std::unique_ptr<ISurfaceGridLookup> p_gridLookup;
539  // this vector makes sure we have shared ownership over the surfaces
540  std::vector<std::shared_ptr<const Surface>> m_surfaces;
541  // this vector is returned, so that (expensive) copying of the shared_ptr
542  // vector does not happen by default
544  // this is only used to keep info on transform applied
545  // by l2g and g2l
547 };
548 
549 } // namespace Acts