ECCE @ 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
10 #include <iostream>
11 #include <type_traits>
12 #include <vector>
17 #include "Acts/Utilities/IAxis.hpp"
20 
21 namespace Acts {
22 
23 using SurfaceVector = std::vector<const Surface*>;
24 
31 class SurfaceArray {
32  public:
37 
39  virtual void fill(const GeometryContext& gctx,
40  const SurfaceVector& surfaces) = 0;
41 
46 
49  virtual size_t completeBinning(const GeometryContext& gctx,
50  const SurfaceVector& surfaces) = 0;
51 
55  virtual SurfaceVector& lookup(const Vector3D& position) = 0;
56 
61  virtual const SurfaceVector& lookup(const Vector3D& position) const = 0;
62 
67  virtual SurfaceVector& lookup(size_t bin) = 0;
68 
73  virtual const SurfaceVector& lookup(size_t bin) const = 0;
74 
79  virtual const SurfaceVector& neighbors(const Vector3D& position) const = 0;
80 
84  virtual size_t size() const = 0;
85 
89  virtual Vector3D getBinCenter(size_t bin) const = 0;
90 
94  virtual std::vector<const IAxis*> getAxes() const = 0;
95 
98  virtual size_t dimensions() const = 0;
99 
105  virtual bool isValidBin(size_t bin) const = 0;
106 
108  virtual ~ISurfaceGridLookup() = 0;
109  };
110 
113  template <class... Axes>
115  static constexpr size_t DIM = sizeof...(Axes);
116 
117  public:
121  using point_t =
122  std::conditional_t<DIM == 1, std::array<double, 1>, ActsVectorD<DIM>>;
123  using Grid_t = detail::Grid<SurfaceVector, Axes...>;
124 
134  std::function<Vector3D(const point_t&)> localToGlobal,
135  std::tuple<Axes...> axes)
136  : m_globalToLocal(std::move(globalToLocal)),
137  m_localToGlobal(std::move(localToGlobal)),
138  m_grid(std::move(axes)) {
139  m_neighborMap.resize(m_grid.size());
140  }
141 
152  void fill(const GeometryContext& gctx,
153  const SurfaceVector& surfaces) override {
154  for (const auto& srf : surfaces) {
155  Vector3D pos = srf->binningPosition(gctx, binR);
156  lookup(pos).push_back(srf);
157  }
158 
160  }
161 
170  const SurfaceVector& surfaces) override {
171  size_t binCompleted = 0;
172  size_t nBins = size();
173  double minPath, curPath;
174  const Surface* minSrf;
175 
176  for (size_t b = 0; b < nBins; ++b) {
177  if (!isValidBin(b)) {
178  continue;
179  }
180  std::vector<const Surface*>& binContent = lookup(b);
181  // only complete if we have an empty bin
182  if (!binContent.empty()) {
183  continue;
184  }
185 
186  Vector3D binCtr = getBinCenter(b);
188  for (const auto& srf : surfaces) {
189  curPath = (binCtr - srf->binningPosition(gctx, binR)).norm();
190 
191  if (curPath < minPath) {
192  minPath = curPath;
193  minSrf = srf;
194  }
195  }
196 
197  binContent.push_back(minSrf);
198  ++binCompleted;
199  }
200 
201  // recreate neighborcache
203  return binCompleted;
204  }
205 
209  SurfaceVector& lookup(const Vector3D& position) override {
210  return m_grid.atPosition(m_globalToLocal(position));
211  }
212 
217  const SurfaceVector& lookup(const Vector3D& position) const override {
218  return m_grid.atPosition(m_globalToLocal(position));
219  }
220 
225  SurfaceVector& lookup(size_t bin) override { return m_grid.at(bin); }
226 
231  const SurfaceVector& lookup(size_t bin) const override {
232  return m_grid.at(bin);
233  }
234 
239  const SurfaceVector& neighbors(const Vector3D& position) const override {
240  auto lposition = m_globalToLocal(position);
241  return m_neighborMap.at(m_grid.globalBinFromPosition(lposition));
242  }
243 
247  size_t size() const override { return m_grid.size(); }
248 
252  Vector3D getBinCenter(size_t bin) const override {
253  return getBinCenterImpl(bin);
254  }
255 
259  std::vector<const IAxis*> getAxes() const override {
260  auto arr = m_grid.axes();
261  return std::vector<const IAxis*>(arr.begin(), arr.end());
262  }
263 
266  size_t dimensions() const override { return DIM; }
267 
273  bool isValidBin(size_t bin) const override {
274  std::array<size_t, DIM> indices = m_grid.localBinsFromGlobalBin(bin);
275  std::array<size_t, DIM> nBins = m_grid.numLocalBins();
276  for (size_t i = 0; i < indices.size(); ++i) {
277  size_t idx = indices.at(i);
278  if (idx <= 0 || idx >= nBins.at(i) + 1) {
279  return false;
280  }
281  }
282 
283  return true;
284  }
285 
286  private:
288  // calculate neighbors for every bin and store in map
289  for (size_t i = 0; i < m_grid.size(); i++) {
290  if (!isValidBin(i)) {
291  continue;
292  }
294  auto neighborIdxs = m_grid.neighborHoodIndices(loc, 1u);
295  std::vector<const Surface*>& neighbors = m_neighborMap.at(i);
296  neighbors.clear();
297 
298  for (const auto& idx : neighborIdxs) {
299  const std::vector<const Surface*>& binContent = m_grid.at(idx);
300  std::copy(binContent.begin(), binContent.end(),
301  std::back_inserter(neighbors));
302  }
303  }
304  }
305 
316  template <size_t D = DIM, std::enable_if_t<D != 1, int> = 0>
317  Vector3D getBinCenterImpl(size_t bin) const {
320  }
321 
324  template <size_t D = DIM, std::enable_if_t<D == 1, int> = 0>
325  Vector3D getBinCenterImpl(size_t bin) const {
327  return m_localToGlobal(pos);
328  }
329 
330  std::function<point_t(const Vector3D&)> m_globalToLocal;
331  std::function<Vector3D(const point_t&)> m_localToGlobal;
333  std::vector<SurfaceVector> m_neighborMap;
334  };
335 
341  SingleElementLookup(SurfaceVector::value_type element)
342  : m_element({element}) {}
343 
347  SurfaceVector& lookup(const Vector3D& /*position*/) override {
348  return m_element;
349  }
350 
354  const SurfaceVector& lookup(const Vector3D& /*position*/) const override {
355  return m_element;
356  }
357 
361  SurfaceVector& lookup(size_t /*bin*/) override { return m_element; }
362 
366  const SurfaceVector& lookup(size_t /*bin*/) const override {
367  return m_element;
368  }
369 
373  const SurfaceVector& neighbors(
374  const Vector3D& /*position*/) const override {
375  return m_element;
376  }
377 
380  size_t size() const override { return 1; }
381 
385  Vector3D getBinCenter(size_t /*bin*/) const override {
386  return Vector3D(0, 0, 0);
387  }
388 
391  std::vector<const IAxis*> getAxes() const override { return {}; }
392 
395  size_t dimensions() const override { return 0; }
396 
399  void fill(const GeometryContext& /*gctx*/,
400  const SurfaceVector& /*surfaces*/) override {}
401 
404  size_t completeBinning(const GeometryContext& /*gctx*/,
405  const SurfaceVector& /*surfaces*/) override {
406  return 0;
407  }
408 
412  bool isValidBin(size_t /*bin*/) const override { return true; }
413 
414  private:
415  SurfaceVector m_element;
416  };
417 
425  SurfaceArray(std::unique_ptr<ISurfaceGridLookup> gridLookup,
426  std::vector<std::shared_ptr<const Surface>> surfaces,
427  std::shared_ptr<const Transform3D> transform = nullptr);
428 
439  SurfaceArray(std::shared_ptr<const Surface> srf);
440 
445  return p_gridLookup->lookup(position);
446  }
447 
452  const SurfaceVector& at(const Vector3D& position) const {
453  return p_gridLookup->lookup(position);
454  }
455 
459  SurfaceVector& at(size_t bin) { return p_gridLookup->lookup(bin); }
460 
464  const SurfaceVector& at(size_t bin) const {
465  return p_gridLookup->lookup(bin);
466  }
467 
476  return p_gridLookup->neighbors(position);
477  }
478 
482  size_t size() const { return p_gridLookup->size(); }
483 
487  Vector3D getBinCenter(size_t bin) { return p_gridLookup->getBinCenter(bin); }
488 
494  const SurfaceVector& surfaces() const { return m_surfacesRawPointers; }
495 
500  std::vector<const IAxis*> getAxes() const { return p_gridLookup->getAxes(); }
501 
507  bool isValidBin(size_t bin) const { return p_gridLookup->isValidBin(bin); }
508 
509  const Transform3D& transform() const { return *m_transform; }
510 
515  std::ostream& toStream(const GeometryContext& gctx, std::ostream& sl) const;
516 
517  private:
518  std::unique_ptr<ISurfaceGridLookup> p_gridLookup;
519  // this vector makes sure we have shared ownership over the surfaces
520  std::vector<std::shared_ptr<const Surface>> m_surfaces;
521  // this vector is returned, so that (expensive) copying of the shared_ptr
522  // vector does not happen by default
524  // this is only used to keep info on transform applied
525  // by l2g and g2l
526  std::shared_ptr<const Transform3D> m_transform;
527 };
528 
529 } // namespace Acts