EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SurfaceArrayCreator.hpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file SurfaceArrayCreator.hpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2016-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 
18 #include "Acts/Utilities/Units.hpp"
19 
20 #include <optional>
21 
22 namespace Acts {
23 namespace Test {
24 struct SurfaceArrayCreatorFixture;
25 }
26 
27 using SurfaceMatcher = std::function<bool(
28  const GeometryContext& gctx, BinningValue, const Surface*, const Surface*)>;
29 
30 using SurfaceVector = std::vector<const Surface*>;
31 using SurfaceMatrix = std::vector<SurfaceVector>;
32 
33 using V3Vector = std::vector<Vector3D>;
34 using V3Matrix = std::vector<V3Vector>;
35 
42  public:
44  friend Acts::SurfaceArray;
45 
46  struct ProtoAxis {
49  size_t nBins;
50  double min;
51  double max;
52  std::vector<double> binEdges;
53 
54  size_t getBin(double x) const {
55  if (binEdges.empty()) {
56  // equidistant
57  double w = (max - min) / nBins;
58  return std::floor((x - min) / w);
59  } else {
60  // variable
61  const auto it =
62  std::upper_bound(std::begin(binEdges), std::end(binEdges), x);
63  return std::distance(std::begin(binEdges), it) - 1;
64  }
65  }
66  };
67 
68  // Configuration struct
69  struct Config {
73 
78  };
79 
83  SurfaceArrayCreator(std::unique_ptr<const Logger> logger = getDefaultLogger(
84  "SurfaceArrayCreator", Logging::INFO))
85  : m_cfg(Config()), m_logger(std::move(logger)) {}
91  std::unique_ptr<const Logger> logger = getDefaultLogger(
92  "SurfaceArrayCreator", Logging::INFO))
93  : m_cfg(cfg), m_logger(std::move(logger)) {}
94 
96  virtual ~SurfaceArrayCreator() = default;
97 
114  std::unique_ptr<SurfaceArray> surfaceArrayOnCylinder(
115  const GeometryContext& gctx,
116  std::vector<std::shared_ptr<const Surface>> surfaces, size_t binsPhi,
117  size_t binsZ, std::optional<ProtoLayer> protoLayerOpt = std::nullopt,
118  const Transform3D& transform = s_idTransform) const;
119 
137  std::unique_ptr<Acts::SurfaceArray> surfaceArrayOnCylinder(
138  const GeometryContext& gctx,
139  std::vector<std::shared_ptr<const Surface>> surfaces,
140  BinningType bTypePhi = equidistant, BinningType bTypeZ = equidistant,
141  std::optional<ProtoLayer> protoLayerOpt = std::nullopt,
142  const Transform3D& transform = s_idTransform) const;
143 
160  std::unique_ptr<SurfaceArray> surfaceArrayOnDisc(
161  const GeometryContext& gctx,
162  std::vector<std::shared_ptr<const Surface>> surfaces, size_t binsR,
163  size_t binsPhi, std::optional<ProtoLayer> protoLayerOpt = std::nullopt,
164  const Transform3D& transform = s_idTransform) const;
165 
186  std::unique_ptr<Acts::SurfaceArray> surfaceArrayOnDisc(
187  const GeometryContext& gctx,
188  std::vector<std::shared_ptr<const Surface>> surfaces, BinningType bTypeR,
189  BinningType bTypePhi,
190  std::optional<ProtoLayer> protoLayerOpt = std::nullopt,
191  const Transform3D& transform = s_idTransform) const;
192 
213  std::unique_ptr<SurfaceArray> surfaceArrayOnPlane(
214  const GeometryContext& gctx,
215  std::vector<std::shared_ptr<const Surface>> surfaces, size_t bins1,
216  size_t bins2, BinningValue bValue,
217  std::optional<ProtoLayer> protoLayerOpt = std::nullopt,
218  const Transform3D& transform = s_idTransform) const;
219 
227  BinningValue bValue, const Surface* a,
228  const Surface* b) {
229  using namespace UnitLiterals;
230  using VectorHelpers::perp;
231 
232  if (bValue == Acts::binPhi) {
233  // Take the two binning positions
234  auto pos1 = a->binningPosition(gctx, binR),
235  pos2 = b->binningPosition(gctx, binR);
236 
237  // Project them on the (x, y) plane, where Phi angles are calculated
238  auto proj1 = pos1.head<2>(), proj2 = pos2.head<2>();
239 
240  // Basic dot and cross products identities give us the cosine and sine
241  // of these angles, time the squared vector norm
242  auto cos_dPhi_n2 = proj1.dot(proj2);
243  auto sin_dPhi_n2 = proj1.x() * proj2.y() - proj2.x() * proj1.y();
244 
245  // ...so by injecting them into atan2, we get the angle between them
246  auto dPhi = std::atan2(sin_dPhi_n2, cos_dPhi_n2);
247  return std::abs(dPhi) < M_PI / 180.;
248  }
249 
250  if (bValue == Acts::binZ) {
251  return (std::abs(a->binningPosition(gctx, binR).z() -
252  b->binningPosition(gctx, binR).z()) < 1_um);
253  }
254 
255  if (bValue == Acts::binR) {
256  return (std::abs(perp(a->binningPosition(gctx, binR)) -
257  perp(b->binningPosition(gctx, binR))) < 1_um);
258  }
259 
260  return false;
261  }
262 
265  void setLogger(std::unique_ptr<const Logger> logger) {
266  m_logger = std::move(logger);
267  }
268 
269  private:
272 
274  const Logger& logger() const { return *m_logger; }
275 
276  std::vector<const Surface*> findKeySurfaces(
277  const std::vector<const Surface*>& surfaces,
278  const std::function<bool(const Surface*, const Surface*)>& equal) const;
279 
280  size_t determineBinCount(const GeometryContext& gctx,
281  const std::vector<const Surface*>& surfaces,
282  BinningValue bValue) const;
283 
305  ProtoAxis createVariableAxis(const GeometryContext& gctx,
306  const std::vector<const Surface*>& surfaces,
307  BinningValue bValue, ProtoLayer protoLayer,
308  Transform3D& transform) const;
309 
331  ProtoAxis createEquidistantAxis(const GeometryContext& gctx,
332  const std::vector<const Surface*>& surfaces,
333  BinningValue bValue, ProtoLayer protoLayer,
335  size_t nBins = 0) const;
336 
350  typename F1, typename F2>
351  static std::unique_ptr<SurfaceArray::ISurfaceGridLookup>
352  makeSurfaceGridLookup2D(F1 globalToLocal, F2 localToGlobal, ProtoAxis pAxisA,
353  ProtoAxis pAxisB) {
355  std::unique_ptr<ISGL> ptr;
356 
357  // this becomes completely unreadable otherwise
358  // clang-format off
359  if (pAxisA.bType == equidistant && pAxisB.bType == equidistant) {
360 
361  detail::Axis<detail::AxisType::Equidistant, bdtA> axisA(pAxisA.min, pAxisA.max, pAxisA.nBins);
362  detail::Axis<detail::AxisType::Equidistant, bdtB> axisB(pAxisB.min, pAxisB.max, pAxisB.nBins);
363 
365  ptr = std::unique_ptr<ISGL>(static_cast<ISGL*>(
366  new SGL(globalToLocal, localToGlobal, std::make_tuple(axisA, axisB), {pAxisA.bValue, pAxisB.bValue})));
367 
368  } else if (pAxisA.bType == equidistant && pAxisB.bType == arbitrary) {
369 
370  detail::Axis<detail::AxisType::Equidistant, bdtA> axisA(pAxisA.min, pAxisA.max, pAxisA.nBins);
371  detail::Axis<detail::AxisType::Variable, bdtB> axisB(pAxisB.binEdges);
372 
374  ptr = std::unique_ptr<ISGL>(static_cast<ISGL*>(
375  new SGL(globalToLocal, localToGlobal, std::make_tuple(axisA, axisB), {pAxisA.bValue, pAxisB.bValue})));
376 
377  } else if (pAxisA.bType == arbitrary && pAxisB.bType == equidistant) {
378 
379  detail::Axis<detail::AxisType::Variable, bdtA> axisA(pAxisA.binEdges);
380  detail::Axis<detail::AxisType::Equidistant, bdtB> axisB(pAxisB.min, pAxisB.max, pAxisB.nBins);
381 
383  ptr = std::unique_ptr<ISGL>(static_cast<ISGL*>(
384  new SGL(globalToLocal, localToGlobal, std::make_tuple(axisA, axisB), {pAxisA.bValue, pAxisB.bValue})));
385 
386  } else /*if (pAxisA.bType == arbitrary && pAxisB.bType == arbitrary)*/ {
387 
388  detail::Axis<detail::AxisType::Variable, bdtA> axisA(pAxisA.binEdges);
389  detail::Axis<detail::AxisType::Variable, bdtB> axisB(pAxisB.binEdges);
390 
392  ptr = std::unique_ptr<ISGL>(static_cast<ISGL*>(
393  new SGL(globalToLocal, localToGlobal, std::make_tuple(axisA, axisB), {pAxisA.bValue, pAxisB.bValue})));
394  }
395  // clang-format on
396 
397  return ptr;
398  }
399 
401  std::unique_ptr<const Logger> m_logger;
402 
422  const std::vector<const Surface*>& surfaces) const {
423  ACTS_VERBOSE(
424  "Complete binning by filling closest neighbour surfaces into "
425  "empty bins.");
426 
427  size_t binCompleted = sl.completeBinning(gctx, surfaces);
428 
429  ACTS_VERBOSE(" filled : " << binCompleted
430  << " (includes under/overflow)");
431  }
432 
439  std::vector<Acts::Vector3D> makeGlobalVertices(
440  const GeometryContext& gctx, const Acts::Surface& surface,
441  const std::vector<Acts::Vector2D>& locVertices) const;
442 };
443 
444 } // namespace Acts