Analysis Software
Documentation for sPHENIX simulation 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 Vector3& position) = 0;
57 
62  virtual const SurfaceVector& lookup(const Vector3& 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 Vector3& position) const = 0;
81 
85  virtual size_t size() const = 0;
86 
90  virtual Vector3 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>, ActsVector<DIM>>;
128  using Grid_t = detail::Grid<SurfaceVector, Axes...>;
129 
139  SurfaceGridLookup(std::function<point_t(const Vector3&)> globalToLocal,
140  std::function<Vector3(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(std::move(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  Vector3 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 = 0;
181  double curPath = 0;
182  const Surface* minSrf = nullptr;
183 
184  for (size_t b = 0; b < nBins; ++b) {
185  if (!isValidBin(b)) {
186  continue;
187  }
188  std::vector<const Surface*>& binContent = lookup(b);
189  // only complete if we have an empty bin
190  if (!binContent.empty()) {
191  continue;
192  }
193 
194  Vector3 binCtr = getBinCenter(b);
195  minPath = std::numeric_limits<double>::max();
196  for (const auto& srf : surfaces) {
197  curPath = (binCtr - srf->binningPosition(gctx, binR)).norm();
198 
199  if (curPath < minPath) {
200  minPath = curPath;
201  minSrf = srf;
202  }
203  }
204 
205  binContent.push_back(minSrf);
206  ++binCompleted;
207  }
208 
209  // recreate neighborcache
211  return binCompleted;
212  }
213 
217  SurfaceVector& lookup(const Vector3& position) override {
218  return m_grid.atPosition(m_globalToLocal(position));
219  }
220 
225  const SurfaceVector& lookup(const Vector3& position) const override {
226  return m_grid.atPosition(m_globalToLocal(position));
227  }
228 
233  SurfaceVector& lookup(size_t bin) override { return m_grid.at(bin); }
234 
239  const SurfaceVector& lookup(size_t bin) const override {
240  return m_grid.at(bin);
241  }
242 
247  const SurfaceVector& neighbors(const Vector3& position) const override {
248  auto lposition = m_globalToLocal(position);
249  return m_neighborMap.at(m_grid.globalBinFromPosition(lposition));
250  }
251 
255  size_t size() const override { return m_grid.size(); }
256 
259  std::vector<BinningValue> binningValues() const override {
260  return m_binValues;
261  }
262 
266  Vector3 getBinCenter(size_t bin) const override {
267  return getBinCenterImpl(bin);
268  }
269 
273  std::vector<const IAxis*> getAxes() const override {
274  auto arr = m_grid.axes();
275  return std::vector<const IAxis*>(arr.begin(), arr.end());
276  }
277 
280  size_t dimensions() const override { return DIM; }
281 
287  bool isValidBin(size_t bin) const override {
288  std::array<size_t, DIM> indices = m_grid.localBinsFromGlobalBin(bin);
289  std::array<size_t, DIM> nBins = m_grid.numLocalBins();
290  for (size_t i = 0; i < indices.size(); ++i) {
291  size_t idx = indices.at(i);
292  if (idx <= 0 || idx >= nBins.at(i) + 1) {
293  return false;
294  }
295  }
296 
297  return true;
298  }
299 
300  private:
302  // calculate neighbors for every bin and store in map
303  for (size_t i = 0; i < m_grid.size(); i++) {
304  if (!isValidBin(i)) {
305  continue;
306  }
308  auto neighborIdxs = m_grid.neighborHoodIndices(loc, 1u);
309  std::vector<const Surface*>& neighbors = m_neighborMap.at(i);
310  neighbors.clear();
311 
312  for (const auto idx : neighborIdxs) {
313  const std::vector<const Surface*>& binContent = m_grid.at(idx);
314  std::copy(binContent.begin(), binContent.end(),
315  std::back_inserter(neighbors));
316  }
317  }
318  }
319 
330  template <size_t D = DIM, std::enable_if_t<D != 1, int> = 0>
331  Vector3 getBinCenterImpl(size_t bin) const {
334  }
335 
338  template <size_t D = DIM, std::enable_if_t<D == 1, int> = 0>
339  Vector3 getBinCenterImpl(size_t bin) const {
341  return m_localToGlobal(pos);
342  }
343 
344  std::function<point_t(const Vector3&)> m_globalToLocal;
345  std::function<Vector3(const point_t&)> m_localToGlobal;
347  std::vector<BinningValue> m_binValues;
348  std::vector<SurfaceVector> m_neighborMap;
349  };
350 
357  : m_element({element}) {}
358 
361  SingleElementLookup(const SurfaceVector& elements) : m_element(elements) {}
362 
366  SurfaceVector& lookup(const Vector3& position) override {
367  (void)position;
368  return m_element;
369  }
370 
374  const SurfaceVector& lookup(const Vector3& position) const override {
375  (void)position;
376  return m_element;
377  }
378 
382  SurfaceVector& lookup(size_t bin) override {
383  (void)bin;
384  return m_element;
385  }
386 
390  const SurfaceVector& lookup(size_t bin) const override {
391  (void)bin;
392  return m_element;
393  }
394 
398  const SurfaceVector& neighbors(const Vector3& position) const override {
399  (void)position;
400  return m_element;
401  }
402 
405  size_t size() const override { return 1; }
406 
410  Vector3 getBinCenter(size_t bin) const override {
411  (void)bin;
412  return Vector3(0, 0, 0);
413  }
414 
417  std::vector<const IAxis*> getAxes() const override { return {}; }
418 
421  size_t dimensions() const override { return 0; }
422 
425  void fill(const GeometryContext& /*gctx*/,
426  const SurfaceVector& /*surfaces*/) override {}
427 
430  size_t completeBinning(const GeometryContext& /*gctx*/,
431  const SurfaceVector& /*surfaces*/) override {
432  return 0;
433  }
434 
438  bool isValidBin(size_t bin) const override {
439  (void)bin;
440  return true;
441  }
442 
443  private:
444  SurfaceVector m_element;
445  };
446 
454  SurfaceArray(std::unique_ptr<ISurfaceGridLookup> gridLookup,
455  std::vector<std::shared_ptr<const Surface>> surfaces,
456  const Transform3& transform = Transform3::Identity());
457 
460  SurfaceArray(std::shared_ptr<const Surface> srf);
461 
466  return p_gridLookup->lookup(position);
467  }
468 
473  const SurfaceVector& at(const Vector3& position) const {
474  return p_gridLookup->lookup(position);
475  }
476 
480  SurfaceVector& at(size_t bin) { return p_gridLookup->lookup(bin); }
481 
485  const SurfaceVector& at(size_t bin) const {
486  return p_gridLookup->lookup(bin);
487  }
488 
495  const SurfaceVector& neighbors(const Vector3& position) const {
496  return p_gridLookup->neighbors(position);
497  }
498 
502  size_t size() const { return p_gridLookup->size(); }
503 
507  Vector3 getBinCenter(size_t bin) { return p_gridLookup->getBinCenter(bin); }
508 
514  const SurfaceVector& surfaces() const { return m_surfacesRawPointers; }
515 
520  std::vector<const IAxis*> getAxes() const { return p_gridLookup->getAxes(); }
521 
527  bool isValidBin(size_t bin) const { return p_gridLookup->isValidBin(bin); }
528 
529  const Transform3& transform() const { return m_transform; }
530 
533  std::vector<BinningValue> binningValues() const {
534  return p_gridLookup->binningValues();
535  };
536 
541  std::ostream& toStream(const GeometryContext& gctx, std::ostream& sl) const;
542 
543  private:
544  std::unique_ptr<ISurfaceGridLookup> p_gridLookup;
545  // this vector makes sure we have shared ownership over the surfaces
546  std::vector<std::shared_ptr<const Surface>> m_surfaces;
547  // this vector is returned, so that (expensive) copying of the shared_ptr
548  // vector does not happen by default
550  // this is only used to keep info on transform applied
551  // by l2g and g2l
553 };
554 
555 } // namespace Acts