ECCE @ 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-2018 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 
10 // SurfaceArrayCreator.h, Acts project
12 
13 #pragma once
14 
22 #include "Acts/Utilities/Units.hpp"
23 
24 #include <optional>
25 
26 namespace Acts {
27 namespace Test {
28 struct SurfaceArrayCreatorFixture;
29 }
30 
31 using SurfaceMatcher = std::function<bool(
32  const GeometryContext& gctx, BinningValue, const Surface*, const Surface*)>;
33 
34 using SurfaceVector = std::vector<const Surface*>;
35 using SurfaceMatrix = std::vector<SurfaceVector>;
36 
37 using V3Vector = std::vector<Vector3D>;
38 using V3Matrix = std::vector<V3Vector>;
39 
46  public:
48  friend Acts::SurfaceArray;
49 
50  struct ProtoAxis {
53  size_t nBins;
54  double min;
55  double max;
56  std::vector<double> binEdges;
57 
58  size_t getBin(double x) const {
59  if (binEdges.empty()) {
60  // equidistant
61  double w = (max - min) / nBins;
62  return std::floor((x - min) / w);
63  } else {
64  // variable
65  const auto it =
66  std::upper_bound(std::begin(binEdges), std::end(binEdges), x);
67  return std::distance(std::begin(binEdges), it) - 1;
68  }
69  }
70  };
71 
72  // Configuration struct
73  struct Config {
77 
82  };
83 
87  SurfaceArrayCreator(std::unique_ptr<const Logger> logger = getDefaultLogger(
88  "SurfaceArrayCreator", Logging::INFO))
89  : m_cfg(Config()), m_logger(std::move(logger)) {}
95  std::unique_ptr<const Logger> logger = getDefaultLogger(
96  "SurfaceArrayCreator", Logging::INFO))
97  : m_cfg(cfg), m_logger(std::move(logger)) {}
98 
100  virtual ~SurfaceArrayCreator() = default;
101 
118  std::unique_ptr<SurfaceArray> surfaceArrayOnCylinder(
119  const GeometryContext& gctx,
120  std::vector<std::shared_ptr<const Surface>> surfaces, size_t binsPhi,
121  size_t binsZ, std::optional<ProtoLayer> protoLayerOpt = std::nullopt,
122  const std::shared_ptr<const Transform3D>& transformOpt = nullptr) const;
123 
141  std::unique_ptr<Acts::SurfaceArray> surfaceArrayOnCylinder(
142  const GeometryContext& gctx,
143  std::vector<std::shared_ptr<const Surface>> surfaces,
144  BinningType bTypePhi = equidistant, BinningType bTypeZ = equidistant,
145  std::optional<ProtoLayer> protoLayerOpt = std::nullopt,
146  const std::shared_ptr<const Transform3D>& transformOpt = nullptr) const;
147 
164  std::unique_ptr<SurfaceArray> surfaceArrayOnDisc(
165  const GeometryContext& gctx,
166  std::vector<std::shared_ptr<const Surface>> surfaces, size_t binsR,
167  size_t binsPhi, std::optional<ProtoLayer> protoLayerOpt = std::nullopt,
168  const std::shared_ptr<const Transform3D>& transformOpt = nullptr) const;
169 
190  std::unique_ptr<Acts::SurfaceArray> surfaceArrayOnDisc(
191  const GeometryContext& gctx,
192  std::vector<std::shared_ptr<const Surface>> surfaces, BinningType bTypeR,
193  BinningType bTypePhi,
194  std::optional<ProtoLayer> protoLayerOpt = std::nullopt,
195  const std::shared_ptr<const Transform3D>& transformOpt = nullptr) const;
196 
217  std::unique_ptr<SurfaceArray> surfaceArrayOnPlane(
218  const GeometryContext& gctx,
219  std::vector<std::shared_ptr<const Surface>> surfaces, size_t bins1,
220  size_t bins2, BinningValue bValue,
221  std::optional<ProtoLayer> protoLayerOpt = std::nullopt,
222  const std::shared_ptr<const Transform3D>& transformOpt = nullptr) const;
223 
231  BinningValue bValue, const Surface* a,
232  const Surface* b) {
233  using namespace UnitLiterals;
234  using VectorHelpers::perp;
235 
236  if (bValue == Acts::binPhi) {
237  // Take the two binning positions
238  auto pos1 = a->binningPosition(gctx, binR),
239  pos2 = b->binningPosition(gctx, binR);
240 
241  // Project them on the (x, y) plane, where Phi angles are calculated
242  auto proj1 = pos1.head<2>(), proj2 = pos2.head<2>();
243 
244  // Basic dot and cross products identities give us the cosine and sine
245  // of these angles, time the squared vector norm
246  auto cos_dPhi_n2 = proj1.dot(proj2);
247  auto sin_dPhi_n2 = proj1.x() * proj2.y() - proj2.x() * proj1.y();
248 
249  // ...so by injecting them into atan2, we get the angle between them
250  auto dPhi = std::atan2(sin_dPhi_n2, cos_dPhi_n2);
251  return std::abs(dPhi) < M_PI / 180.;
252  }
253 
254  if (bValue == Acts::binZ) {
255  return (std::abs(a->binningPosition(gctx, binR).z() -
256  b->binningPosition(gctx, binR).z()) < 1_um);
257  }
258 
259  if (bValue == Acts::binR) {
260  return (std::abs(perp(a->binningPosition(gctx, binR)) -
261  perp(b->binningPosition(gctx, binR))) < 1_um);
262  }
263 
264  return false;
265  }
266 
269  void setLogger(std::unique_ptr<const Logger> logger) {
270  m_logger = std::move(logger);
271  }
272 
273  private:
276 
278  const Logger& logger() const { return *m_logger; }
279 
280  std::vector<const Surface*> findKeySurfaces(
281  const std::vector<const Surface*>& surfaces,
282  const std::function<bool(const Surface*, const Surface*)>& equal) const;
283 
284  size_t determineBinCount(const GeometryContext& gctx,
285  const std::vector<const Surface*>& surfaces,
286  BinningValue bValue) const;
287 
309  ProtoAxis createVariableAxis(const GeometryContext& gctx,
310  const std::vector<const Surface*>& surfaces,
311  BinningValue bValue, ProtoLayer protoLayer,
312  Transform3D& transform) const;
313 
335  ProtoAxis createEquidistantAxis(const GeometryContext& gctx,
336  const std::vector<const Surface*>& surfaces,
337  BinningValue bValue, ProtoLayer protoLayer,
339  size_t nBins = 0) const;
340 
354  typename F1, typename F2>
355  static std::unique_ptr<SurfaceArray::ISurfaceGridLookup>
356  makeSurfaceGridLookup2D(F1 globalToLocal, F2 localToGlobal, ProtoAxis pAxisA,
357  ProtoAxis pAxisB) {
359  std::unique_ptr<ISGL> ptr;
360 
361  // this becomes completely unreadable otherwise
362  // clang-format off
363  if (pAxisA.bType == equidistant && pAxisB.bType == equidistant) {
364 
365  detail::Axis<detail::AxisType::Equidistant, bdtA> axisA(pAxisA.min, pAxisA.max, pAxisA.nBins);
366  detail::Axis<detail::AxisType::Equidistant, bdtB> axisB(pAxisB.min, pAxisB.max, pAxisB.nBins);
367 
369  ptr = std::unique_ptr<ISGL>(static_cast<ISGL*>(
370  new SGL(globalToLocal, localToGlobal, std::make_tuple(axisA, axisB))));
371 
372  } else if (pAxisA.bType == equidistant && pAxisB.bType == arbitrary) {
373 
374  detail::Axis<detail::AxisType::Equidistant, bdtA> axisA(pAxisA.min, pAxisA.max, pAxisA.nBins);
375  detail::Axis<detail::AxisType::Variable, bdtB> axisB(pAxisB.binEdges);
376 
378  ptr = std::unique_ptr<ISGL>(static_cast<ISGL*>(
379  new SGL(globalToLocal, localToGlobal, std::make_tuple(axisA, axisB))));
380 
381  } else if (pAxisA.bType == arbitrary && pAxisB.bType == equidistant) {
382 
383  detail::Axis<detail::AxisType::Variable, bdtA> axisA(pAxisA.binEdges);
384  detail::Axis<detail::AxisType::Equidistant, bdtB> axisB(pAxisB.min, pAxisB.max, pAxisB.nBins);
385 
387  ptr = std::unique_ptr<ISGL>(static_cast<ISGL*>(
388  new SGL(globalToLocal, localToGlobal, std::make_tuple(axisA, axisB))));
389 
390  } else /*if (pAxisA.bType == arbitrary && pAxisB.bType == arbitrary)*/ {
391 
392  detail::Axis<detail::AxisType::Variable, bdtA> axisA(pAxisA.binEdges);
393  detail::Axis<detail::AxisType::Variable, bdtB> axisB(pAxisB.binEdges);
394 
396  ptr = std::unique_ptr<ISGL>(static_cast<ISGL*>(
397  new SGL(globalToLocal, localToGlobal, std::make_tuple(axisA, axisB))));
398  }
399  // clang-format on
400 
401  return ptr;
402  }
403 
405  std::unique_ptr<const Logger> m_logger;
406 
426  const std::vector<const Surface*>& surfaces) const {
427  ACTS_VERBOSE(
428  "Complete binning by filling closest neighbour surfaces into "
429  "empty bins.");
430 
431  size_t binCompleted = sl.completeBinning(gctx, surfaces);
432 
433  ACTS_VERBOSE(" filled : " << binCompleted
434  << " (includes under/overflow)");
435  }
436 
443  std::vector<Acts::Vector3D> makeGlobalVertices(
444  const GeometryContext& gctx, const Acts::Surface& surface,
445  const std::vector<Acts::Vector2D>& locVertices) const;
446 };
447 
448 } // namespace Acts