LArSoft  v10_04_05
Liquid Argon Software toolkit - https://larsoft.org/
geo_vectors_utils.h
Go to the documentation of this file.
1 
15 #ifndef LARCOREALG_GEOMETRY_GEO_VECTORS_UTILS_H
16 #define LARCOREALG_GEOMETRY_GEO_VECTORS_UTILS_H
17 
18 // LArSoft libraries
21 
22 // ROOT libraries
23 #include "Math/GenVector/DisplacementVector2D.h"
24 #include "Math/GenVector/DisplacementVector3D.h"
25 #include "Math/GenVector/LorentzVector.h"
26 #include "Math/GenVector/PositionVector2D.h"
27 #include "Math/GenVector/PositionVector3D.h"
28 
29 // C/C++ standard library
30 #include <array>
31 #include <cassert>
32 #include <functional> // std::mem_fn()
33 #include <iterator> // std::back_inserter()
34 #include <type_traits> // std::declval(), std::is_same<>, ...
35 #include <vector>
36 
38  template <typename T>
39  struct Point2D;
40  template <typename T>
41  struct Point3D;
42 }
43 
44 namespace geo {
45 
53  namespace vect {
54 
55  //--------------------------------------------------------------------------
56  namespace details {
57  //------------------------------------------------------------------------
58  template <typename Op, typename... T>
60 
61  template <typename Op, typename First, typename Second, typename... Others>
62  struct AccumulateImpl<Op, First, Second, Others...> {
63  static auto compute(Op op, First&& a, Second&& b, Others&&... others) -> decltype(auto)
64  {
65  return op(a,
67  op, std::forward<Second>(b), std::forward<Others>(others)...));
68  }
69  }; // AccumulateImpl<>
70 
71  template <typename Op, typename T>
72  struct AccumulateImpl<Op, T> {
73  static auto compute(Op, T&& v) -> decltype(auto) { return std::forward<T>(v); }
74  };
75 
76  template <typename Op, typename... T>
77  auto extended_accumulate(Op op, T&&... args)
78  {
79  return AccumulateImpl<Op, T...>::compute(op, std::forward<T>(args)...);
80  }
81 
82  template <typename... T>
83  auto extended_and(T... args) -> decltype(auto)
84  {
85  auto and_op = [](auto&& a, auto&& b) { return a && b; };
86  return extended_accumulate(and_op, std::forward<T>(args)...);
87  }
88 
89  //------------------------------------------------------------------------
90  //
91  // These two pages of metaprogramming madness are aimed to have objects
92  // that can provide a uniform coordinate get/set for any type of vector,
93  // with the minimal run-time overhead.
94  // Complications arise from the fact that TVector3 setter returns void,
95  // while GenVector vectors return a reference to the vector itself
96  // (hence the need of the additional SetterResult template parameter,
97  // and of quite some code to autodetect its value).
98  // The makeXxxx() functions are aimed to enclose the additional
99  // autodetection overlay, which should become unnecessary with C++17.
100  //
101 
102  template <typename Vector>
103  struct VectorScalar {
104  using type = typename Vector::Scalar;
105  };
106 
107  template <typename Vector>
109 
110  //------------------------------------------------------------------------
111  template <typename Vector>
112  struct HasGetter {
113  private:
114  template <typename Class>
115  static constexpr bool TestX(decltype(std::declval<Class>().X())*)
116  {
117  return true;
118  }
119  template <typename Class>
120  static constexpr bool TestX(...)
121  {
122  return false;
123  }
124  template <typename Class>
125  static constexpr bool TestY(decltype(std::declval<Class>().Y())*)
126  {
127  return true;
128  }
129  template <typename Class>
130  static constexpr bool TestY(...)
131  {
132  return false;
133  }
134  template <typename Class>
135  static constexpr bool TestZ(decltype(std::declval<Class>().Z())*)
136  {
137  return true;
138  }
139  template <typename Class>
140  static constexpr bool TestZ(...)
141  {
142  return false;
143  }
144  template <typename Class>
145  static constexpr bool TestT(decltype(std::declval<Class>().T())*)
146  {
147  return true;
148  }
149  template <typename Class>
150  static constexpr bool TestT(...)
151  {
152  return false;
153  }
154 
155  public:
156  static constexpr bool X = TestX<Vector>(nullptr);
157  static constexpr bool Y = TestY<Vector>(nullptr);
158  static constexpr bool Z = TestZ<Vector>(nullptr);
159  static constexpr bool T = TestT<Vector>(nullptr);
160  }; // struct HasGetter<>
161 
162  template <typename Vector>
163  constexpr bool HasX()
164  {
165  return HasGetter<Vector>::X;
166  }
167  template <typename Vector>
168  constexpr bool HasY()
169  {
170  return HasGetter<Vector>::Y;
171  }
172  template <typename Vector>
173  constexpr bool HasZ()
174  {
175  return HasGetter<Vector>::Z;
176  }
177  template <typename Vector>
178  constexpr bool HasT()
179  {
180  return HasGetter<Vector>::T;
181  }
182 
183  template <typename Vector, typename = void>
185 
186  template <typename Vector>
187  constexpr unsigned int dimension()
188  {
190  }
191 
193  template <typename Vector>
194  using CoordinateArray_t = std::array<VectorScalar_t<Vector>, dimension<Vector>()>;
195 
196  template <typename T>
198  // with C++17 `result_type` is deprecated,
199  // and a different way will be needed
200  using type = typename decltype(std::mem_fn(std::declval<T>()))::result_type;
201  }; // MemberFuncReturnType
202 
203  template <typename T>
205 
206  template <typename T>
208 
209  template <typename Class, typename Func>
210  struct MemberFuncClassType<Func Class::*> {
211  using type = Class;
212  };
213 
214  template <typename T>
216 
217  template <typename Vector, typename SetterType = void>
219 
220  template <typename Vector>
221  struct BaseCoordTypes<Vector, void> {
222  using Vector_t = std::decay_t<Vector>;
224  using Getter_t = Scalar_t (Vector_t::*)() const;
225  }; // struct BaseCoordTypes<void>
226 
227  template <typename Vector, typename SetterType>
228  struct BaseCoordTypes {
229  private:
231 
232  public:
233  using Scalar_t = typename BaseTypes_t::Scalar_t;
234  using Vector_t = typename BaseTypes_t::Vector_t;
235  using Getter_t = typename BaseTypes_t::Getter_t;
236  using Setter_t = SetterType;
238  static_assert(std::is_same<Setter_t, SetterReturn_t (Vector_t::*)(Scalar_t)>(),
239  "Invalid setter type");
240  }; // struct BaseCoordTypes<>
241 
242  template <typename Vector>
244  private:
246 
247  public:
248  using Vector_t = typename BaseTypes_t::Vector_t;
249  using Scalar_t = typename BaseTypes_t::Scalar_t;
250  using Getter_t = typename BaseTypes_t::Getter_t;
251  }; // struct CoordGetterTraits
252 
254  template <typename Vector>
255  class CoordGetter {
257 
258  public:
259  using Vector_t = typename Traits_t::Vector_t;
260  using Scalar_t = typename Traits_t::Scalar_t;
261  using Getter_t = typename Traits_t::Getter_t;
262 
264  constexpr CoordGetter(Getter_t getter) : fGetter(getter) {}
265 
267  Scalar_t operator()(Vector_t const& v) const { return get(v); }
268 
270  Scalar_t get(Vector_t const& v) const { return (v.*fGetter)(); }
271 
272  private:
274 
275  }; // class CoordGetter<>
276 
277  template <typename Getter>
278  constexpr auto makeCoordReader(Getter getter)
279  {
280  using Vector_t = std::remove_reference_t<MemberFuncClass_t<Getter>>;
281  return CoordGetter<Vector_t>{getter};
282  }
283 
284  template <typename Vector, typename SetterType>
286  private:
288 
289  public:
290  using Vector_t = typename BaseTypes_t::Vector_t;
291  using Scalar_t = typename BaseTypes_t::Scalar_t;
292  using Getter_t = typename BaseTypes_t::Getter_t;
293  using Setter_t = typename BaseTypes_t::Setter_t;
294  }; // struct VectorCoordManagerTraits<>
295 
297  template <typename Vector, typename SetterType>
298  class CoordManager : public CoordGetter<Vector> {
301 
302  public:
303  using Vector_t = typename Traits_t::Vector_t; // this is not constant
304  using Scalar_t = typename Traits_t::Scalar_t;
305  using Getter_t = typename Traits_t::Getter_t;
306  using Setter_t = typename Traits_t::Setter_t;
307 
309  constexpr CoordManager(Getter_t getter, Setter_t setter) : Base_t(getter), fSetter(setter)
310  {}
311 
313  void operator()(Vector_t& v, Scalar_t c) const { set(v, c); }
314 
316  void set(Vector_t& v, Scalar_t c) const { (v.*fSetter)(c); }
317 
319  void incr(Vector_t& v, Scalar_t c) const { set(v, Base_t::get(v) + c); }
320 
322  void decr(Vector_t& v, Scalar_t c) const { set(v, Base_t::get(v) - c); }
323 
325  void mult(Vector_t& v, Scalar_t f) const { set(v, Base_t::get(v) * f); }
326 
328  void div(Vector_t& v, Scalar_t f) const { set(v, Base_t::get(v) / f); }
329 
330  private:
332  }; // class CoordManager<>
333 
334  template <typename Getter, typename Setter>
335  constexpr auto makeCoordManager(Getter getter, Setter setter)
336  {
337  using Vector_t = std::remove_reference_t<MemberFuncClass_t<Getter>>;
338  return CoordManager<Vector_t, Setter>{getter, setter};
339  }
340 
341  template <typename CoordHelper, typename StoredVector>
343 
344  public:
345  using Stored_t = StoredVector;
346 
347  using CoordHelper_t = CoordHelper;
349  using Scalar_t = typename CoordHelper_t::Scalar_t;
350  using Getter_t = typename CoordHelper_t::Getter_t;
351 
353  BoundCoordGetter(Stored_t& v, CoordHelper_t coordManager) : fCoord(coordManager), fVector(v)
354  {}
355 
357  BoundCoordGetter(Stored_t& v, Getter_t getter) : fCoord(getter), fVector(v) {}
358 
360  Scalar_t get() const { return manager().get(vector()); }
361 
363  Scalar_t operator()() const { return get(); }
364 
366  operator Scalar_t() const { return manager().get(vector()); }
367 
368  protected:
369  CoordHelper_t const& manager() const { return fCoord; }
370  Stored_t& vector() const { return fVector; }
371 
372  private:
375  }; // class VectorCoordGetter<>
376 
377  template <typename CoordHelper, typename StoredVector>
378  class BoundCoordManager : public BoundCoordGetter<CoordHelper, StoredVector> {
380 
381  public:
382  using typename Base_t::Stored_t;
383 
384  using CoordHelper_t = CoordHelper;
386  using Scalar_t = typename CoordHelper_t::Scalar_t;
387  using Getter_t = typename CoordHelper_t::Getter_t;
388  using Setter_t = typename CoordHelper_t::Setter_t;
389 
392 
395  : Base_t(v, CoordHelper_t(getter, setter))
396  {}
397 
400  {
401  Base_t::manager().set(Base_t::vector(), c);
402  return *this;
403  }
404 
407  {
408  Base_t::manager().incr(Base_t::vector(), c);
409  return *this;
410  }
411 
414  {
415  Base_t::manager().decr(Base_t::vector(), c);
416  return *this;
417  }
418 
421  {
422  Base_t::manager().mult(Base_t::vector(), f);
423  return *this;
424  }
425 
428  {
429  Base_t::manager().div(Base_t::vector(), f);
430  return *this;
431  }
432 
433  }; // class BoundCoordManager
434 
435  //------------------------------------------------------------------------
436 
437  } // namespace details
438 
439  // BEGIN Geometry group ------------------------------------------------------
442 
444  namespace extra {
445 
447  template <typename T>
448  constexpr T roundValue0(T value, T tol)
449  {
450  return (std::abs(value) < tol) ? T{} : value;
451  } // roundValue0()
452 
454  template <typename T>
455  constexpr T roundValue01(T value, T tol)
456  {
457  if (std::abs(value) < tol) return 0.;
458  if (std::abs(std::abs(value) - 1.) < tol) return (value > 0.) ? 1. : -1.;
459  return value;
460  } // roundValue01()
461 
462  } // namespace extra
463 
464  // --- BEGIN Vector coordinate access abstraction --------------------------
466 
619  template <typename Vector>
621  constexpr unsigned int dimension()
622  {
623  return details::dimension<Vector>();
624  }
625  template <typename Vector>
626  constexpr unsigned int dimension(Vector&&)
627  {
628  return dimension<Vector>();
629  }
631 
633  template <typename Vector>
635  constexpr std::array<std::size_t, vect::dimension<Vector>()> indices();
636  template <typename Vector>
637  constexpr auto indices(Vector const&) -> decltype(indices<Vector>());
639 
641  template <typename Vector>
643 
665  template <typename Vector, typename Coords>
666  constexpr Vector makeFromCoords(Coords&& coords);
667 
680  template <typename Vector, typename Coords>
681  unsigned int fillCoords(Coords& dest, Vector const& src);
682 
684  template <typename Vector>
686 
688  template <typename Vector>
689  using CoordManager_t = decltype(details::makeCoordManager(&Vector::X, &Vector::SetX));
690 
712  template <typename Vector>
713  static constexpr auto XcoordManager = details::makeCoordManager(&Vector::X, &Vector::SetX);
714 
736  template <typename Vector>
738 
741  template <typename Vector>
742  static constexpr auto const YcoordManager =
743  details::makeCoordManager(&Vector::Y, &Vector::SetY);
744 
747  template <typename Vector>
749 
752  template <typename Vector>
753  static constexpr auto ZcoordManager = details::makeCoordManager(&Vector::Z, &Vector::SetZ);
754 
757  template <typename Vector>
759 
762  template <typename Vector>
763  static constexpr auto TcoordManager = details::makeCoordManager(&Vector::T, &Vector::SetT);
764 
767  template <typename Vector>
768  static constexpr auto TcoordManager<Vector const> = details::makeCoordReader(&Vector::T);
769 
810  template <typename Vector>
811  constexpr auto coordManager(unsigned int n);
812 
824  template <typename Vector>
825  constexpr auto coordManager(unsigned int n, Vector& v);
826 
828  template <typename Vector>
830  constexpr auto coordManagers();
831  template <typename Vector>
832  constexpr auto coordManagers(Vector&&);
834 
836  template <typename Vector>
838  constexpr auto coordReaders();
839  template <typename Vector>
840  constexpr auto coordReaders(Vector&&);
842 
844  template <typename Vector>
845  constexpr auto bindCoord(Vector const& v, CoordReader_t<Vector> helper)
846  {
847  return details::BoundCoordGetter<CoordReader_t<Vector>, Vector const>(v, helper);
848  }
849 
851  template <typename Vector>
852  auto bindCoord(Vector& v, CoordManager_t<Vector> helper)
854  {
855  return {v, helper};
856  }
857 
868  template <typename Vector>
869  auto Xcoord(Vector& v)
870  {
871  return bindCoord(v, XcoordManager<Vector>);
872  }
873 
884  template <typename Vector>
885  auto Ycoord(Vector& v)
886  {
887  return bindCoord<Vector>(v, YcoordManager<Vector>);
888  }
889 
900  template <typename Vector>
901  auto Zcoord(Vector& v)
902  {
903  return bindCoord<Vector>(v, ZcoordManager<Vector>);
904  }
905 
916  template <typename Vector>
917  auto Tcoord(Vector& v)
918  {
919  return bindCoord<Vector>(v, TcoordManager<Vector>);
920  }
921 
933  template <typename Vector>
934  auto coord(Vector& v, unsigned int n) noexcept;
935 
936  template <typename Vector>
937  auto coord(Vector& v, Coordinate n) noexcept;
938 
941  template <typename Vector>
942  constexpr auto bindCoordManagers(Vector& v);
943 
946  template <typename Vector>
947  constexpr auto bindCoordReaders(Vector const& v);
948 
955  template <typename Vector>
957 
958  public:
960 
961  private:
962  using Vector_t = Vector;
965 
966  Vector* v = nullptr;
967  unsigned int index = std::numeric_limits<unsigned int>::max();
968 
969  decltype(auto) access(unsigned int c) const { return vect::bindCoord(v, index); }
970 
971  iterator_t copy() const { return *this; }
972 
973  public:
977  using value_type = std::remove_cv_t<Coord_t>;
978  using difference_type = std::ptrdiff_t;
980  using pointer = Coord_t const*;
981  using iterator_category = std::random_access_iterator_tag;
984 
986  CoordConstIterator() = default;
987 
989  CoordConstIterator(Vector& v, unsigned int index = 0) : v(&v), index(index) {}
990 
991  // --- BEGIN Access ----------------------------------------------------------
994 
996  reference operator*() const { return vect::coord(*v, index); }
997 
999  reference operator[](difference_type n) const { return vect::coord(*v, index + n); }
1000 
1002  // --- END Access ------------------------------------------------------------
1003 
1004  // --- BEGIN Moving ----------------------------------------------------------
1007 
1010  {
1011  ++index;
1012  return *this;
1013  }
1014 
1017  {
1018  iterator_t it(*this);
1019  ++index;
1020  return it;
1021  }
1022 
1025  {
1026  --index;
1027  return *this;
1028  }
1029 
1032  {
1033  iterator_t it(*this);
1034  --index;
1035  return it;
1036  }
1037 
1040  {
1041  index += d;
1042  return *this;
1043  }
1044 
1046  iterator_t operator+(difference_type d) const { return (copy() += d); }
1047 
1050  {
1051  index -= d;
1052  return *this;
1053  }
1054 
1056  iterator_t operator-(difference_type d) const { return (copy() -= d); }
1057 
1059  iterator_t operator-(iterator_t const& other) const { return index - other.index; }
1060 
1062  // --- END Moving ------------------------------------------------------------
1063 
1064  // --- BEGIN Comparison operators --------------------------------------------
1069 
1070  bool operator==(iterator_t const& other) const
1071  {
1072  return (v == other.v) && (index == other.index);
1073  }
1074 
1075  bool operator!=(iterator_t const& other) const
1076  {
1077  return (v != other.v) || (index != other.index);
1078  }
1079 
1080  bool operator<=(iterator_t const& other) const
1081  {
1082  return (v == other.v) && (index <= other.index);
1083  }
1084 
1085  bool operator>=(iterator_t const& other) const
1086  {
1087  return (v == other.v) && (index >= other.index);
1088  }
1089 
1090  bool operator<(iterator_t const& other) const
1091  {
1092  return (v == other.v) && (index < other.index);
1093  }
1094 
1095  bool operator>(iterator_t const& other) const
1096  {
1097  return (v == other.v) && (index > other.index);
1098  }
1099 
1101  // --- END Comparison operators ----------------------------------------------
1102 
1103  }; // class CoordConstIterator
1104 
1105  template <typename Vector>
1107  CoordConstIterator<Vector> const& v)
1108  {
1109  return v + n;
1110  }
1111 
1113  template <typename Vector>
1114  auto vector_cbegin(Vector const& v)
1115  {
1116  return CoordConstIterator(v, 0);
1117  }
1118 
1120  template <typename Vector>
1121  auto vector_cend(Vector const& v)
1122  {
1123  return CoordConstIterator(v, vect::dimension(v));
1124  }
1125 
1136  template <typename Dest, typename Source>
1137  Dest convertTo(Source const& v);
1138 
1154  template <typename Dest, typename Source>
1155  std::vector<Dest> convertCollTo(std::vector<Source> const& coll);
1156 
1168  template <typename Vector, typename Pred>
1169  Vector transformCoords(Vector const& v, Pred&& pred);
1170 
1172  // --- END Vector coordinate access abstraction ----------------------------
1173 
1174  // --- BEGIN Functions for common vector operations ------------------------
1176 
1206  template <typename Vector, typename Scalar>
1208  Vector rounded0(Vector const& v, Scalar tol)
1209  {
1210  return transformCoords(v, [tol](auto c) { return extra::roundValue0(c, tol); });
1211  }
1212 
1214  template <typename Vector, typename Scalar>
1215  void round0(Vector& v, Scalar tol)
1216  {
1217  v = rounded0(v, tol);
1218  }
1219 
1221  template <typename Vector, typename Scalar>
1222  Vector rounded01(Vector const& v, Scalar tol)
1223  {
1224  return transformCoords(v, [tol](auto c) { return extra::roundValue01(c, tol); });
1225  }
1226 
1228  template <typename Vector, typename Scalar>
1229  void round01(Vector& v, Scalar tol)
1230  {
1231  v = rounded01(v, tol);
1232  }
1233 
1235  template <typename Vector>
1236  bool isfinite(Vector const& v);
1237 
1239  template <typename Vector>
1240  Vector normalize(Vector const& v)
1241  {
1242  return v.Unit();
1243  }
1244 
1246  template <typename Vector>
1247  Vector cross(Vector const& a, Vector const& b)
1248  {
1249  return a.Cross(b);
1250  }
1251 
1253  template <typename Vector, typename OtherVector>
1254  constexpr auto dot(Vector const& a, OtherVector const& b)
1255  {
1256  return a.Dot(b);
1257  }
1258 
1260  template <typename Vector>
1261  auto mag2(Vector const& v)
1262  {
1263  return v.Mag2();
1264  }
1265 
1267  template <typename Vector>
1268  auto norm(Vector const& v)
1269  {
1270  return v.Mag();
1271  }
1272 
1275  template <typename Vector>
1276  auto mixedProduct(Vector const& a, Vector const& b, Vector const& c)
1277  {
1278  return dot(cross(a, b), c);
1279  }
1280 
1282  // --- END Functions for common vector operations --------------------------
1283 
1314  template <unsigned int N = 3U>
1316  static constexpr unsigned int Dim = N;
1317  std::array<Length_t, Dim> fSums;
1318  double fW = 0.0;
1319 
1320  public:
1322  MiddlePointAccumulatorDim() { fSums.fill(0.); }
1323 
1332  template <typename BeginIter, typename EndIter>
1334  {
1335  add(begin, end);
1336  }
1337 
1338  // --- BEGIN Result query ------------------------------------------------
1341 
1343  bool empty() const { return fW == 0.0; }
1344 
1346  double weight() const { return fW; }
1347 
1359  template <typename Point>
1361  // { return { fSums[0] / fW, fSums[1] / fW, fSums[2] / fW }; }
1362  {
1363  return makeWeightedPoint<Point>(1.0 / fW);
1364  }
1365 
1368  Point_t middlePoint() const { return middlePointAs<Point_t>(); }
1369 
1371  // --- END Result query --------------------------------------------------
1372 
1373  // --- BEGIN Addition of points ------------------------------------------
1376 
1384  template <typename Point>
1385  void add(Point const& p)
1386  {
1387  std::size_t ic = 0U;
1388  for (auto c : vect::bindCoordManagers(p))
1389  fSums[ic++] += c();
1390  fW += 1.0;
1391  }
1392 
1399  template <typename Point>
1400  void add(Point const& p, double weight)
1401  {
1402  std::size_t ic = 0U;
1403  for (auto c : vect::bindCoordManagers(p))
1404  fSums[ic++] += weight * c();
1405  fW += weight;
1406  }
1407 
1417  template <typename BeginIter, typename EndIter>
1418  void add(BeginIter begin, EndIter end)
1419  {
1420  std::for_each(begin, end, [this](auto const& p) { this->add(p); });
1421  }
1422 
1424  void clear()
1425  {
1426  fSums.fill(0.);
1427  fW = 0.0;
1428  }
1429 
1431  // --- END Addition of points --------------------------------------------
1432 
1433  private:
1434  using IndexSequence_t = std::make_index_sequence<Dim>;
1435 
1436  template <typename Point, std::size_t... I>
1437  Point makePointImpl(std::index_sequence<I...>) const
1438  {
1439  return {fSums.operator[](I)...};
1440  }
1441 
1442  template <typename Point, std::size_t... I>
1443  Point makeWeightedPointImpl(double w, std::index_sequence<I...>) const
1444  {
1445  return {(fSums.operator[](I) * w)...};
1446  }
1447 
1449  template <typename Point>
1451  {
1452  return vect::makeFromCoords<Point>(fSums);
1453  }
1454 
1457  template <typename Point>
1458  Point makeWeightedPoint(double w) const
1459  {
1460  return makeWeightedPointImpl<Point>(w, IndexSequence_t{});
1461  }
1462 
1463  }; // MiddlePointAccumulatorDim()
1464 
1467 
1468  // --- BEGIN Middle point functions ----------------------------------------
1471 
1495  template <typename Point, typename BeginIter, typename EndIter>
1496  Point middlePointAs(BeginIter begin, EndIter end)
1497  {
1498  constexpr auto Dim = vect::dimension<Point>();
1499  return MiddlePointAccumulatorDim<Dim>(begin, end).template middlePointAs<Point>();
1500  }
1501 
1523  template <typename BeginIter, typename EndIter>
1524  Point_t middlePoint(BeginIter begin, EndIter end)
1525  {
1526  return middlePointAs<Point_t>(begin, end);
1527  }
1528 
1545  template <typename Point>
1546  Point middlePoint(std::initializer_list<Point> points)
1547  {
1548  constexpr auto Dim = vect::dimension<Point>();
1549  return MiddlePointAccumulatorDim<Dim>(points.begin(), points.end())
1550  .template middlePointAs<Point>();
1551  }
1552 
1554  // --- END Middle point functions ------------------------------------------
1555 
1556  // --- BEGIN Support for LArSoft geometry vectors --------------------------
1559 
1561  template <typename Point>
1563  {
1564  return vect::convertTo<Point_t>(p);
1565  }
1566 
1568  template <typename Vector>
1569  Vector_t toVector(Vector const& v)
1570  {
1571  return vect::convertTo<Vector_t>(v);
1572  }
1573 
1576  template <typename Point>
1577  std::vector<Point_t> convertCollToPoint(std::vector<Point> const& coll)
1578  {
1579  return convertCollTo<Point_t>(coll);
1580  }
1581 
1584  template <typename Vector>
1585  std::vector<Vector_t> convertCollToVector(std::vector<Vector> const& coll)
1586  {
1587  return convertCollTo<Vector_t>(coll);
1588  }
1589 
1591  template <typename Coords>
1593  {
1594  return makeFromCoords<Point_t>(std::forward<Coords>(coords));
1595  }
1596 
1598  template <typename Coords>
1600  {
1601  return makeFromCoords<Vector_t>(std::forward<Coords>(coords));
1602  }
1603 
1605  // --- END Support for LArSoft geometry vectors ----------------------------
1606 
1608  // END Geometry group ------------------------------------------------------
1609 
1610  } // namespace vect
1611 
1612 } // namespace geo
1613 
1614 //------------------------------------------------------------------------------
1615 //--- STL specialization for ROOT GenVector vectors
1616 //------------------------------------------------------------------------------
1617 namespace ROOT::Math {
1618 
1621 
1622  // --- BEGIN 2D vectors ------------------------------------------------------
1623  template <class CoordSystem, class Tag>
1624  decltype(auto) begin(ROOT::Math::PositionVector2D<CoordSystem, Tag> const& v)
1625  {
1626  return geo::vect::vector_cbegin(v);
1627  }
1628 
1629  template <class CoordSystem, class Tag>
1630  decltype(auto) cbegin(ROOT::Math::PositionVector2D<CoordSystem, Tag> const& v)
1631  {
1632  return geo::vect::vector_cbegin(v);
1633  }
1634 
1635  template <class CoordSystem, class Tag>
1636  decltype(auto) end(ROOT::Math::PositionVector2D<CoordSystem, Tag> const& v)
1637  {
1638  return geo::vect::vector_cend(v);
1639  }
1640 
1641  template <class CoordSystem, class Tag>
1642  decltype(auto) cend(ROOT::Math::PositionVector2D<CoordSystem, Tag> const& v)
1643  {
1644  return geo::vect::vector_cend(v);
1645  }
1646 
1647  template <class CoordSystem, class Tag>
1648  decltype(auto) begin(ROOT::Math::DisplacementVector2D<CoordSystem, Tag> const& v)
1649  {
1650  return geo::vect::vector_cbegin(v);
1651  }
1652 
1653  template <class CoordSystem, class Tag>
1654  decltype(auto) cbegin(ROOT::Math::DisplacementVector2D<CoordSystem, Tag> const& v)
1655  {
1656  return geo::vect::vector_cbegin(v);
1657  }
1658 
1659  template <class CoordSystem, class Tag>
1660  decltype(auto) end(ROOT::Math::DisplacementVector2D<CoordSystem, Tag> const& v)
1661  {
1662  return geo::vect::vector_cend(v);
1663  }
1664 
1665  template <class CoordSystem, class Tag>
1666  decltype(auto) cend(ROOT::Math::DisplacementVector2D<CoordSystem, Tag> const& v)
1667  {
1668  return geo::vect::vector_cend(v);
1669  }
1670 
1671  // --- END 2D vectors --------------------------------------------------------
1672 
1673  // --- BEGIN 3D vectors ------------------------------------------------------
1674  template <class CoordSystem, class Tag>
1675  decltype(auto) begin(ROOT::Math::PositionVector3D<CoordSystem, Tag> const& v)
1676  {
1677  return geo::vect::vector_cbegin(v);
1678  }
1679 
1680  template <class CoordSystem, class Tag>
1681  decltype(auto) cbegin(ROOT::Math::PositionVector3D<CoordSystem, Tag> const& v)
1682  {
1683  return geo::vect::vector_cbegin(v);
1684  }
1685 
1686  template <class CoordSystem, class Tag>
1687  decltype(auto) end(ROOT::Math::PositionVector3D<CoordSystem, Tag> const& v)
1688  {
1689  return geo::vect::vector_cend(v);
1690  }
1691 
1692  template <class CoordSystem, class Tag>
1693  decltype(auto) cend(ROOT::Math::PositionVector3D<CoordSystem, Tag> const& v)
1694  {
1695  return geo::vect::vector_cend(v);
1696  }
1697 
1698  template <class CoordSystem, class Tag>
1699  decltype(auto) begin(ROOT::Math::DisplacementVector3D<CoordSystem, Tag> const& v)
1700  {
1701  return geo::vect::vector_cbegin(v);
1702  }
1703 
1704  template <class CoordSystem, class Tag>
1705  decltype(auto) cbegin(ROOT::Math::DisplacementVector3D<CoordSystem, Tag> const& v)
1706  {
1707  return geo::vect::vector_cbegin(v);
1708  }
1709 
1710  template <class CoordSystem, class Tag>
1711  decltype(auto) end(ROOT::Math::DisplacementVector3D<CoordSystem, Tag> const& v)
1712  {
1713  return geo::vect::vector_cend(v);
1714  }
1715 
1716  template <class CoordSystem, class Tag>
1717  decltype(auto) cend(ROOT::Math::DisplacementVector3D<CoordSystem, Tag> const& v)
1718  {
1719  return geo::vect::vector_cend(v);
1720  }
1721 
1722  // --- END 3D vectors --------------------------------------------------------
1723 
1724  // --- BEGIN 4D vectors ------------------------------------------------------
1725  template <class CoordSystem>
1726  decltype(auto) begin(ROOT::Math::LorentzVector<CoordSystem> const& v)
1727  {
1728  return geo::vect::vector_cbegin(v);
1729  }
1730 
1731  template <class CoordSystem>
1732  decltype(auto) cbegin(ROOT::Math::LorentzVector<CoordSystem> const& v)
1733  {
1734  return geo::vect::vector_cbegin(v);
1735  }
1736 
1737  template <class CoordSystem>
1738  decltype(auto) end(ROOT::Math::LorentzVector<CoordSystem> const& v)
1739  {
1740  return geo::vect::vector_cend(v);
1741  }
1742 
1743  template <class CoordSystem>
1744  decltype(auto) cend(ROOT::Math::LorentzVector<CoordSystem> const& v)
1745  {
1746  return geo::vect::vector_cend(v);
1747  }
1748 
1749  // --- END 4D vectors --------------------------------------------------------
1750 
1752 
1753 } // namespace ROOT::Math
1754 
1755 //------------------------------------------------------------------------------
1756 
1757 //------------------------------------------------------------------------------
1758 //--- template specializations for standard geometry vectors
1759 //---
1760 namespace geo::vect {
1761 
1762  //----------------------------------------------------------------------------
1763  template <>
1764  inline auto norm(geo::Vector_t const& v)
1765  {
1766  return v.R();
1767  }
1768 
1769  //----------------------------------------------------------------------------
1770 
1771 } // namespace geo::vect
1772 
1773 //------------------------------------------------------------------------------
1774 //--- template implementation
1775 
1776 namespace geo::vect::details {
1777 
1778  //----------------------------------------------------------------------------
1779  template <typename>
1780  struct AlwaysFalse : std::false_type {};
1781 
1782  // constexpr variant of forward (from StackExchange)
1783  template <typename T>
1784  constexpr T&& constexpr_forward(std::remove_reference_t<T>& t)
1785  {
1786  return static_cast<T&&>(t);
1787  }
1788 
1789  template <typename T>
1790  constexpr T&& constexpr_forward(std::remove_reference_t<T>&& t)
1791  {
1792  static_assert(!std::is_lvalue_reference<T>(),
1793  "template argument substituting T is an lvalue reference type");
1794  return static_cast<T&&>(t);
1795  }
1796 
1797  //----------------------------------------------------------------------------
1798  template <typename Vector, typename /* = void */>
1799  struct DimensionImpl : public std::integral_constant<unsigned int,
1800  HasT<Vector>() ? 4U :
1801  HasZ<Vector>() ? 3U :
1802  HasY<Vector>() ? 2U :
1803  HasX<Vector>() ? 1U :
1804  0U> {};
1805 
1806  template <typename Array>
1807  struct DimensionImpl<Array, std::enable_if_t<(std::extent_v < Array >> 0)>>
1808  : public std::integral_constant<unsigned int, std::extent_v<Array>> {};
1809 
1810  template <typename T, std::size_t Dim>
1811  struct DimensionImpl<std::array<T, Dim>, void>
1812  : public std::integral_constant<unsigned int, Dim> {};
1813 
1814  template <typename T>
1815  struct DimensionImpl<lar::util::simple_geo::Point2D<T>, void>
1816  : public std::integral_constant<unsigned int, 2> {};
1817 
1818  template <typename T>
1820  : public std::integral_constant<unsigned int, 3> {};
1821 
1822  //----------------------------------------------------------------------------
1824  template <typename Vector>
1825  using VectorIndices_t = std::make_index_sequence<dimension<Vector>()>;
1826 
1827  template <typename Vector>
1828  constexpr auto makeVectorIndices()
1829  {
1830  return VectorIndices_t<Vector>{};
1831  }
1832 
1833  template <typename Vector>
1834  constexpr auto makeVectorIndices(Vector&&)
1835  {
1836  return makeVectorIndices<Vector>();
1837  }
1838 
1839  template <typename T, T... Indices>
1840  constexpr auto makeIndexSeqImpl(std::integer_sequence<T, Indices...>)
1841  // BUG the double brace syntax is required to work around clang bug 21629
1842  // (https://bugs.llvm.org/show_bug.cgi?id=21629)
1843  {
1844  return std::array<T, sizeof...(Indices)>{{Indices...}};
1845  }
1846 
1847  // fill a sequence object with the first `N` values of type `T`.
1848  template <typename T, T N>
1849  constexpr auto makeIndexSeq()
1850  {
1851  return makeIndexSeqImpl<T>(std::make_integer_sequence<T, N>{});
1852  }
1853 
1854  //----------------------------------------------------------------------------
1855  template <std::size_t I, typename Data>
1856  constexpr auto accessElement(Data&& data)
1857  {
1858  return data[I];
1859  }
1860 
1861  template <typename Vector, typename Coords, std::size_t... Indices>
1862  constexpr Vector makeFromCoordsImpl(Coords&& coords, std::index_sequence<Indices...>)
1863  {
1864  return {accessElement<Indices>(constexpr_forward<Coords>(coords))...};
1865  }
1866 
1867  //----------------------------------------------------------------------------
1868  template <typename Vector>
1869  constexpr CoordManager_t<Vector> NoCoordManager{nullptr, nullptr};
1870 
1871  template <typename Vector, unsigned int Dim = dimension<Vector>()>
1873 
1874  template <typename Vector>
1875  struct CoordManagerImpl<Vector, 1U> {
1876  static auto get(unsigned int n) noexcept
1877  {
1878  return (n == 0) ? XcoordManager<Vector> : NoCoordManager<Vector>;
1879  }
1880  };
1881 
1882  template <typename Vector>
1883  struct CoordManagerImpl<Vector, 2U> {
1884  static auto get(unsigned int n) noexcept
1885  {
1886  return (n == 1) ? YcoordManager<Vector> : CoordManagerImpl<Vector, 1U>::get(n);
1887  }
1888  };
1889 
1890  template <typename Vector>
1891  struct CoordManagerImpl<Vector, 3U> {
1892  static auto get(unsigned int n) noexcept
1893  {
1894  return (n == 2) ? ZcoordManager<Vector> : CoordManagerImpl<Vector, 2U>::get(n);
1895  }
1896  };
1897 
1898  template <typename Vector>
1899  struct CoordManagerImpl<Vector, 4U> {
1900  static auto get(unsigned int n) noexcept
1901  {
1902  return (n == 3) ? TcoordManager<Vector> : CoordManagerImpl<Vector, 3U>::get(n);
1903  }
1904  };
1905 
1906  //----------------------------------------------------------------------------
1907  template <typename Vector, unsigned int N>
1909  static constexpr unsigned int Dim = N;
1910 
1911  using Manager_t = decltype(XcoordManager<Vector>);
1912  using Return_t = std::array<Manager_t, Dim>;
1913 
1914  static_assert(dimension<Vector>() == Dim, "Inconsistent vector size.");
1915  };
1916 
1917  template <typename Vector, unsigned int N>
1919 
1920  template <typename Vector>
1921  struct CoordManagersImpl<Vector, 2U> : private CoordManagersImplBase<Vector, 2U> {
1923  using typename Base_t::Return_t;
1924  static constexpr Return_t get()
1925  {
1926  // BUG the double brace syntax is required to work around clang bug 21629
1927  // (https://bugs.llvm.org/show_bug.cgi?id=21629)
1928  return {{XcoordManager<Vector>, YcoordManager<Vector>}};
1929  }
1930  };
1931 
1932  template <typename Vector>
1933  struct CoordManagersImpl<Vector, 3U> : private CoordManagersImplBase<Vector, 3U> {
1935  using typename Base_t::Return_t;
1936  static constexpr Return_t get()
1937  {
1938  // BUG the double brace syntax is required to work around clang bug 21629
1939  // (https://bugs.llvm.org/show_bug.cgi?id=21629)
1940  return {{XcoordManager<Vector>, YcoordManager<Vector>, ZcoordManager<Vector>}};
1941  }
1942  };
1943 
1944  template <typename Vector>
1945  struct CoordManagersImpl<Vector, 4U> : private CoordManagersImplBase<Vector, 4U> {
1947  using typename Base_t::Return_t;
1948  static constexpr Return_t get()
1949  {
1950  // BUG the double brace syntax is required to work around clang bug 21629
1951  // (https://bugs.llvm.org/show_bug.cgi?id=21629)
1952  return {{XcoordManager<Vector>,
1953  YcoordManager<Vector>,
1954  ZcoordManager<Vector>,
1955  TcoordManager<Vector>}};
1956  }
1957  };
1958 
1959  //----------------------------------------------------------------------------
1960  template <typename Vector, unsigned int N>
1962  static constexpr unsigned int Dim = N;
1963 
1964  using Manager_t = decltype(Xcoord(std::declval<Vector>()));
1965  using Return_t = std::array<Manager_t, Dim>;
1966 
1967  static_assert(dimension<Vector>() == Dim, "Inconsistent vector size.");
1968  };
1969 
1970  template <typename Vector, unsigned int N>
1972 
1973  template <typename Vector>
1974  struct BindCoordManagersImpl<Vector, 2U> : private BindCoordManagersImplBase<Vector, 2U> {
1976  using typename Base_t::Return_t;
1977  static Return_t bind(Vector& v)
1978  {
1979  // BUG the double brace syntax is required to work around clang bug 21629
1980  // (https://bugs.llvm.org/show_bug.cgi?id=21629)
1981  return {{Xcoord(v), Ycoord(v)}};
1982  }
1983  };
1984 
1985  template <typename Vector>
1986  struct BindCoordManagersImpl<Vector, 3U> : private BindCoordManagersImplBase<Vector, 3U> {
1988  using typename Base_t::Return_t;
1989  static Return_t bind(Vector& v)
1990  {
1991  // BUG the double brace syntax is required to work around clang bug 21629
1992  // (https://bugs.llvm.org/show_bug.cgi?id=21629)
1993  return {{Xcoord(v), Ycoord(v), Zcoord(v)}};
1994  }
1995  };
1996 
1997  template <typename Vector>
1998  struct BindCoordManagersImpl<Vector, 4U> : private BindCoordManagersImplBase<Vector, 4U> {
2000  using typename Base_t::Return_t;
2001  static Return_t bind(Vector& v)
2002  {
2003  // BUG the double brace syntax is required to work around clang bug 21629
2004  // (https://bugs.llvm.org/show_bug.cgi?id=21629)
2005  return {{Xcoord(v), Ycoord(v), Zcoord(v), Tcoord(v)}};
2006  }
2007  };
2008 
2009  //----------------------------------------------------------------------------
2010  template <typename Dest, typename Source>
2012  static_assert(dimension<Source>() == dimension<Dest>(),
2013  "Source and destination vectors must have the same dimension.");
2014  };
2015 
2016  template <typename Dest, typename Source, unsigned int Dim>
2017  struct ConvertArrayTo : private ConvertToImplBase<Dest, Source> {
2018  static_assert(std::is_arithmetic_v<std::decay_t<decltype(std::declval<Source>()[0])>>);
2019  static Dest convert(Source const& v) { return geo::vect::makeFromCoords<Dest>(v); }
2020  };
2021 
2022  // will handle cases with specific dimensionality
2023  template <typename Dest, typename Source, unsigned int Dim>
2025 
2026  template <typename Dest, typename Source>
2027  struct ConvertToImpl : public ConvertToImplDim<Dest, Source, dimension<Source>()> {};
2028 
2029  template <typename Dest, typename T, std::size_t Dim>
2030  struct ConvertToImpl<Dest, std::array<T, Dim>>
2031  : public ConvertArrayTo<Dest, std::array<T, Dim>, Dim> {};
2032 
2033  template <typename Dest, typename T, std::size_t Dim>
2034  struct ConvertToImpl<Dest, T[Dim]> : public ConvertArrayTo<Dest, T[Dim], Dim> {};
2035 
2036  // special special implementation for T*, since we can't guess its dimension
2037  template <typename Dest, typename T>
2038  struct ConvertToImpl<Dest, T*> {
2039  static_assert(std::is_arithmetic_v<T>);
2040  static Dest convert(T* v) { return geo::vect::makeFromCoords<Dest>(v); }
2041  }; // struct ConvertToImpl<T*>
2042 
2043  // handled cases with specific dimensionality
2044  template <typename Dest, typename Source, unsigned int Dim>
2045  struct ConvertToImplDim {
2046  // trivial to do: open a feature request!
2047  static_assert(AlwaysFalse<Dest>(), "This vector dimensionality is not implemented yet.");
2048  };
2049 
2050  template <typename Dest, typename Source>
2051  struct ConvertToImplDim<Dest, Source, 2U> : private ConvertToImplBase<Dest, Source> {
2052  static Dest convert(Source const& v) { return {Xcoord(v)(), Ycoord(v)()}; }
2053  };
2054 
2055  template <typename Dest, typename Source>
2056  struct ConvertToImplDim<Dest, Source, 3U> : private ConvertToImplBase<Dest, Source> {
2057  static Dest convert(Source const& v) { return {Xcoord(v)(), Ycoord(v)(), Zcoord(v)()}; }
2058  };
2059 
2060  template <typename Dest, typename Source>
2061  struct ConvertToImplDim<Dest, Source, 4U> : private ConvertToImplBase<Dest, Source> {
2062  static Dest convert(Source const& v)
2063  {
2064  return {Xcoord(v)(), Ycoord(v)(), Zcoord(v)(), Tcoord(v)()};
2065  }
2066  };
2067 
2068  template <typename Dest, typename Source>
2069  struct ConvertToDispatcher : public ConvertToImpl<Dest, Source> {};
2070 
2071  // special pass-through case
2072  template <typename Vector>
2073  struct ConvertToDispatcher<Vector, Vector> {
2074  static constexpr decltype(auto) convert(Vector const& v) { return v; }
2075  };
2076 
2077  //----------------------------------------------------------------------------
2078  template <typename Point, std::size_t... I>
2079  bool isfiniteImpl(Point const& point, std::index_sequence<I...>)
2080  {
2081  return extended_and(std::isfinite(coord(point, I).get())...);
2082  }
2083 
2084  //----------------------------------------------------------------------------
2085 
2086 } // namespace geo::vect::details
2087 
2088 //------------------------------------------------------------------------------
2089 template <typename Vector>
2090 constexpr std::array<std::size_t, geo::vect::dimension<Vector>()> geo::vect::indices()
2091 {
2092  return details::makeIndexSeq<std::size_t, dimension<Vector>()>();
2093 }
2094 
2095 template <typename Vector>
2096 constexpr auto geo::vect::indices(Vector const&) -> decltype(indices<Vector>())
2097 {
2098  return indices<Vector>();
2099 }
2100 
2101 //------------------------------------------------------------------------
2102 template <typename Vector, typename Coords>
2103 constexpr Vector geo::vect::makeFromCoords(Coords&& coords)
2104 {
2105  using namespace geo::vect::details;
2106  return makeFromCoordsImpl<Vector>(constexpr_forward<Coords>(coords), makeVectorIndices<Vector>());
2107 }
2108 
2109 //------------------------------------------------------------------------------
2110 template <typename Vector>
2111 constexpr auto geo::vect::coordManager(unsigned int n)
2112 {
2114 }
2115 
2116 //------------------------------------------------------------------------------
2117 template <typename Vector>
2118 auto geo::vect::coord(Vector& v, unsigned int n) noexcept
2119 {
2120  return vect::bindCoord<Vector>(v, coordManager<Vector>(n));
2121 }
2122 
2123 //------------------------------------------------------------------------------
2124 template <typename Vector>
2125 auto geo::vect::coord(Vector& v, Coordinate coord) noexcept
2126 {
2127  return coord(v, to_int(coord));
2128 }
2129 
2130 //------------------------------------------------------------------------
2131 template <typename Vector, typename Coords>
2132 unsigned int geo::vect::fillCoords(Coords& dest, Vector const& src)
2133 {
2134  // this is simpler than makeFromCoords() because doesn't attempt constexpr
2135  for (std::size_t i = 0; i < vect::dimension(src); ++i)
2136  dest[i] = vect::coord(src, i);
2137  return vect::dimension(src);
2138 }
2139 
2140 //------------------------------------------------------------------------------
2141 template <typename Vector>
2143 {
2144  using PlainVector = std::remove_reference_t<Vector>;
2146 }
2147 
2148 template <typename Vector>
2149 constexpr auto geo::vect::coordManagers(Vector&&)
2150 {
2151  return coordManagers<Vector>();
2152 }
2153 
2154 template <typename Vector>
2155 constexpr auto geo::vect::coordReaders()
2156 {
2157  using ConstVector = std::add_const_t<std::remove_reference_t<Vector>>;
2159 }
2160 
2161 template <typename Vector>
2162 constexpr auto geo::vect::coordReaders(Vector&&)
2163 {
2164  return coordReaders<Vector>();
2165 }
2166 
2167 //------------------------------------------------------------------------------
2168 template <typename Vector>
2169 constexpr auto geo::vect::bindCoordManagers(Vector& v)
2170 {
2172 }
2173 
2174 template <typename Vector>
2175 constexpr auto geo::vect::bindCoordReaders(Vector const& v)
2176 {
2177  using ConstVector = std::add_const_t<std::remove_reference_t<Vector>>;
2179 }
2180 
2181 //------------------------------------------------------------------------------
2182 template <typename Dest, typename Source>
2183 Dest geo::vect::convertTo(Source const& v)
2184 {
2186 }
2187 
2188 //----------------------------------------------------------------------------
2189 template <typename Dest, typename Source>
2190 std::vector<Dest> geo::vect::convertCollTo(std::vector<Source> const& coll)
2191 {
2192  std::vector<Dest> dest;
2193  dest.reserve(coll.size());
2194  std::transform(
2195  coll.begin(), coll.end(), std::back_inserter(dest), geo::vect::convertTo<Dest, Source>);
2196  return dest;
2197 }
2198 
2199 //------------------------------------------------------------------------
2200 template <typename Vector, typename Pred>
2201 Vector geo::vect::transformCoords(Vector const& v, Pred&& pred)
2202 {
2204  unsigned int i = 0;
2205  for (auto c : bindCoordReaders(v))
2206  values[i++] = pred(c());
2207  return makeFromCoords<Vector>(values);
2208 }
2209 
2210 //------------------------------------------------------------------------------
2211 template <typename Vector>
2212 bool geo::vect::isfinite(Vector const& v)
2213 {
2214  return details::isfiniteImpl(v, details::makeVectorIndices<Vector>());
2215 }
2216 
2217 //------------------------------------------------------------------------------
2218 
2219 #endif // LARCOREALG_GEOMETRY_GEO_VECTORS_UTILS_H
Double32_t Coord_t
Definition: TrackingTypes.h:23
void operator()(Vector_t &v, Scalar_t c) const
Setter: assigns a value to the bound coordinate of specified vector.
constexpr auto coordManager(unsigned int n)
Returns an object that can be bound to a vector to manage one of its coordinates. ...
constexpr T && constexpr_forward(std::remove_reference_t< T > &&t)
constexpr auto coordManager(unsigned int n, Vector &v)
Returns an object that can be bound to a vector to manage one of its coordinates. ...
static constexpr bool TestZ(...)
void round01(Vector &v, Scalar tol)
Returns a vector with all components rounded if close to 0, -1 or +1.
static constexpr auto XcoordManager< Vector const >
Object that can be bound to a vector to access its X coordinate.
decltype(auto) cbegin(ROOT::Math::LorentzVector< CoordSystem > const &v)
Constant iterator to vector coordinates.
Coordinate
Enumerate the possible plane projections.
Definition: geo_types.h:122
typename BaseTypes_t::Scalar_t Scalar_t
BoundCoordManager(Stored_t &v, CoordHelper_t coordManager)
Constructor: manage the specified coordinate of specified vector.
typename Traits_t::Getter_t Getter_t
void clear()
Resets the status of the object to no accumulated points.
typename CoordHelper_t::Getter_t Getter_t
Point makePoint() const
Converts the internal sums into a Point.
constexpr auto accessElement(Data &&data)
CoordConstIterator(Vector &v, unsigned int index=0)
Constructor: points to index coordinate of vector v.
Point middlePointAs() const
Returns the middle point, NaN components if no point.
auto Zcoord(Vector &v)
Returns an object to manage the coordinate Z of the vector v.
2D point (x, y) (by default, with double precision)
constexpr auto makeVectorIndices(Vector &&)
static constexpr bool TestX(...)
constexpr auto makeIndexSeq()
static auto compute(Op, T &&v) -> decltype(auto)
constexpr std::array< std::size_t, vect::dimension< Vector >)> indices()
Returns a sequence of indices valid for a vector of the specified type.
static constexpr auto XcoordManager
Object that can be bound to a vector to manage its X coordinate.
Point makePointImpl(std::index_sequence< I... >) const
vect::coordinate_t< Vector_t > Coord_t
Type of vector coordinate.
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Vector_t
Type for representation of momenta in 3D space.
Definition: geo_vectors.h:160
std::vector< Dest > convertCollTo(std::vector< Source > const &coll)
Returns a vector of type Dest with the same content as a Src.
void mult(Vector_t &v, Scalar_t f) const
Multiplies the coordinate by the specified amount.
static constexpr auto YcoordManager< Vector const >
static constexpr auto const YcoordManager
typename BaseTypes_t::Vector_t Vector_t
auto mixedProduct(Vector const &a, Vector const &b, Vector const &c)
GENVECTOR_CONSTEXPR Point_t makePointFromCoords(Coords &&coords)
Creates a geo::Point_t from its coordinates (see makeFromCoords()).
auto coord(Vector &v, unsigned int n) noexcept
Returns an object to manage the coordinate n of a vector.
constexpr auto bindCoordReaders(Vector const &v)
Helper class to compute the middle point in a point set.
bool operator<=(iterator_t const &other) const
constexpr auto indices(Vector const &) -> decltype(indices< Vector >())
Returns a sequence of indices valid for a vector of the specified type.
constexpr auto makeCoordReader(Getter getter)
Float_t Y
Definition: plot.C:37
typename Traits_t::Setter_t Setter_t
std::vector< Vector_t > convertCollToVector(std::vector< Vector > const &coll)
constexpr auto makeIndexSeqImpl(std::integer_sequence< T, Indices... >)
typename MemberFuncReturnType< T >::type MemberFuncReturn_t
::fhicl::TupleAs< Point(::geo::Length_t,::geo::Length_t,::geo::Length_t)> Point3D
Atom object for reading a 3D point or vector (centimeters).
double weight() const
Returns the total weight (number of points if all have weight 1).
constexpr bool HasX()
iterator_t operator-(iterator_t const &other) const
Returns the distance from another iterator.
constexpr auto abs(T v)
Returns the absolute value of the argument.
static constexpr auto TcoordManager
std::remove_cv_t< Coord_t > value_type
BoundCoordManager & operator+=(Scalar_t c)
Increments by the specified amount.
STL namespace.
GENVECTOR_CONSTEXPR Vector_t makeVectorFromCoords(Coords &&coords)
Creates a geo::Vector_t from its coordinates (see makeFromCoords()).
BoundCoordManager(Stored_t &v, Getter_t getter, Setter_t setter)
Constructor: manage the specified vector with specified methods.
static constexpr auto ZcoordManager
decltype(Xcoord(std::declval< Vector >())) Manager_t
iterator_t operator-(difference_type d) const
Returns an iterator decremented by d positions (unchecked).
auto coord(Vector &v, Coordinate n) noexcept
typename BaseTypes_t::Getter_t Getter_t
typename BaseTypes_t::Setter_t Setter_t
constexpr auto coordManagers()
Returns an array with all coordinate managers for a type of vector.
void round0(Vector &v, Scalar tol)
Returns a vector with all components rounded if close to 0.
Helper class for read/write of a single vector coordinate.
typename CoordHelper_t::Vector_t Vector_t
bool operator>(iterator_t const &other) const
typename MemberFuncClassType< T >::type MemberFuncClass_t
BoundCoordGetter(Stored_t &v, Getter_t getter)
Constructor: manage the specified vector with specified methods.
std::array< Length_t, Dim > fSums
Sum of each of the point components.
void add(Point const &p)
Accumulates a point.
Point middlePoint(std::initializer_list< Point > points)
Returns the middle of the specified points.
static constexpr auto ZcoordManager< Vector const >
static auto compute(Op op, First &&a, Second &&b, Others &&...others) -> decltype(auto)
unsigned int fillCoords(Coords &dest, Vector const &src)
Fills a coordinate array with the coordinates of a vector.
typename BaseTypes_t::Scalar_t Scalar_t
Point middlePointAs(BeginIter begin, EndIter end)
Returns the middle of the specified points.
void add(Point const &p, double weight)
Accumulates a point.
Float_t Z
Definition: plot.C:37
iterator_t operator+(difference_type d) const
Returns an iterator incremented by d positions (unchecked).
static constexpr bool TestX(decltype(std::declval< Class >().X())*)
TFile f
Definition: plotHisto.C:6
typename VectorScalar< Vector >::type VectorScalar_t
typename Traits_t::Vector_t Vector_t
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:289
iterator_t operator--(int)
Points to previous coordinate (unchecked), returns the previous iterator.
std::random_access_iterator_tag iterator_category
constexpr auto coordReaders()
Returns an array with all coordinate readers for a type of vector.
BoundCoordManager & operator/=(Scalar_t f)
Divides by the specified amount.
void decr(Vector_t &v, Scalar_t c) const
Decrements the coordinate by the specified amount.
Utilities to manipulate geometry vectors.The utilities include generic vector interface facilities al...
bool isfinite(Vector const &v)
Returns whether all components of the vector are finite.
typename BaseTypes_t::Vector_t Vector_t
auto array(Array const &a)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:250
typename Traits_t::Scalar_t Scalar_t
Getter_t fGetter
Member function returning the coordinate value.
constexpr CoordManager_t< Vector > NoCoordManager
void add(BeginIter begin, EndIter end)
Adds a sequence of points.
bool empty() const
Returns whether the total weight is zero (usually means no points).
typename BaseTypes_t::Vector_t Vector_t
void incr(Vector_t &v, Scalar_t c) const
Increments the coordinate by the specified amount.
iterator_t & operator--()
Points to the previous coordinate (unchecked).
Point2D< T > operator+(Point2D< T > const &a, Point2D< T > const &b)
Definition: SimpleGeo.h:71
Definitions of geometry vector data types.
auto vector_cend(Vector const &v)
Returns a const-iterator pointing after the last coordinate of v.
constexpr Vector makeFromCoordsImpl(Coords &&coords, std::index_sequence< Indices... >)
constexpr CoordGetter(Getter_t getter)
Constructor: sets getter and setter functions.
typename BaseTypes_t::Scalar_t Scalar_t
decltype(auto) values(Coll &&coll)
Range-for loop helper iterating across the values of the specified collection.
MiddlePointAccumulatorDim(BeginIter begin, EndIter end)
Constructor: starts with accumulating a sequence of points.
auto extended_and(T...args) -> decltype(auto)
typename CoordHelper_t::Setter_t Setter_t
decltype(auto) begin(ROOT::Math::LorentzVector< CoordSystem > const &v)
typename CoordHelper_t::Scalar_t Scalar_t
bool operator>=(iterator_t const &other) const
Simple class definitions for geometry concepts.
MemberFuncReturn_t< Setter_t > SetterReturn_t
constexpr auto makeCoordManager(Getter getter, Setter setter)
constexpr T roundValue0(T value, T tol)
Returns value, rounded to 0 if closer than tol.
3D point (x, y, z) (by default, with double precision)
constexpr int to_int(Coordinate const coord) noexcept
Enumerate the possible plane projections.
Definition: geo_types.h:124
Float_t d
Definition: plot.C:235
void LorentzVector(Stream &&out, TLorentzVector const &v)
Print a TLorentzVector to an output stream.
iterator_t & operator++()
Points to the next coordinate (unchecked).
BoundCoordManager & operator*=(Scalar_t f)
Multiplies by the specified amount.
Point_t toPoint(Point const &p)
Convert the specified point into a geo::Point_t.
auto Ycoord(Vector &v)
Returns an object to manage the coordinate Y of the vector v.
typename decltype(std::mem_fn(std::declval< T >()))::result_type type
static constexpr bool TestY(...)
decltype(details::makeCoordManager(&Vector::X,&Vector::SetX)) CoordManager_t
Type of a coordinate manager for a vector type.
constexpr bool HasT()
bool isfiniteImpl(Point const &point, std::index_sequence< I... >)
constexpr auto dot(Vector const &a, OtherVector const &b)
Return cross product of two vectors.
Vector transformCoords(Vector const &v, Pred &&pred)
Returns a new vector applying a predicate to each component.
constexpr auto coordReaders(Vector &&)
Returns an array with all coordinate readers for a type of vector.
Definition of data types for geometry description.
CoordHelper_t fCoord
Helper to manage a specific coordinate.
Vector_t toVector(Vector const &v)
Convert the specified vector into a geo::Vector_t.
double value
Definition: spectrum.C:18
Vector rounded01(Vector const &v, Scalar tol)
Returns a vector with all components rounded if close to 0, -1 or +1.
auto mag2(Vector const &v)
Return norm of the specified vector.
auto Xcoord(Vector &v)
Returns an object to manage the coordinate X of the vector v.
BoundCoordManager & operator-=(Scalar_t c)
Decrements by the specified amount.
typename BaseTypes_t::Getter_t Getter_t
Point makeWeightedPointImpl(double w, std::index_sequence< I... >) const
BoundCoordGetter(Stored_t &v, CoordHelper_t coordManager)
Constructor: manage the specified coordinate of specified vector.
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
Definition: geo_vectors.h:180
Scalar_t operator()(Vector_t const &v) const
Returns the value of the bound coordinate.
constexpr bool HasZ()
double weight
Definition: plottest35.C:25
auto Tcoord(Vector &v)
Returns an object to manage the coordinate T of the vector v.
decltype(auto) get(T &&obj)
ADL-aware version of std::to_string.
Definition: StdUtils.h:120
constexpr bool HasY()
CoordHelper_t const & manager() const
auto extended_accumulate(Op op, T &&...args)
BoundCoordManager & operator=(Scalar_t c)
Setter: assigns a value to the bound coordinate of specified vector.
typename BaseTypes_t::Getter_t Getter_t
Float_t norm
LArSoft-specific namespace.
std::make_index_sequence< Dim > IndexSequence_t
static constexpr auto TcoordManager< Vector const >
auto vector_cbegin(Vector const &v)
Returns a const-iterator pointing to the first coordinate of v.
std::array< VectorScalar_t< Vector >, dimension< Vector >()> CoordinateArray_t
A STL array suitable to contain all coordinate values of a Vector.
std::tuple< double, double, const reco::ClusterHit3D * > Point
Definitions used by the VoronoiDiagram algorithm.
Definition: DCEL.h:42
decltype(details::makeCoordReader(&Vector::X)) CoordReader_t
Type of a coordinate reader for a vector type.
decltype(auto) end(ROOT::Math::LorentzVector< CoordSystem > const &v)
Scalar_t operator()() const
Returns the value of the bound coordinate.
constexpr T roundValue01(T value, T tol)
Returns value, rounded to 0, -1 or +1 if closer than tol.
constexpr auto bindCoordManagers(Vector &v)
constexpr CoordManager(Getter_t getter, Setter_t setter)
Constructor: sets getter and setter functions.
constexpr auto coordManagers(Vector &&)
Returns an array with all coordinate managers for a type of vector.
Setter_t fSetter
Member function setting the coordinate value.
reference operator[](difference_type n) const
Access the current coordinate.
bool operator==(iterator_t const &other) const
Stored_t & fVector
The vector to manage the coordinate of.
MiddlePointAccumulatorDim()
Default constructor: starts with no accumulated point.
Helper class for read of a single vector coordinate.
bool operator!=(iterator_t const &other) const
Char_t n[5]
details::VectorScalar_t< Vector > coordinate_t
Type of coordinate of the specified vector type.
#define GENVECTOR_CONSTEXPR
A declaration is made constexpr if GenVector supports it.
Definition: geo_vectors.h:45
constexpr unsigned int dimension(Vector &&)
Returns the dimension of the specified vector type.
std::vector< Point_t > convertCollToPoint(std::vector< Point > const &coll)
constexpr Vector makeFromCoords(Coords &&coords)
Creates a Vector object with coordinates from coords.
static constexpr bool TestT(...)
std::make_index_sequence< dimension< Vector >()> VectorIndices_t
Type of sequence of indices up to Vector size.
Vector cross(Vector const &a, Vector const &b)
Return cross product of two vectors.
Vector normalize(Vector const &v)
Returns a vector parallel to v and with norm 1.
Dest convertTo(Source const &v)
Returns a vector of type Dest with the same content as a Src.
Eigen::Vector3f Coords
Definition: DCEL.h:44
void div(Vector_t &v, Scalar_t f) const
Divides the coordinate by the specified amount.
Vector rounded0(Vector const &v, Scalar tol)
Returns a vector with all components rounded if close to 0.
reference operator*() const
Access the current coordinate.
auto bindCoord(Vector &v, CoordManager_t< Vector > helper) -> details::BoundCoordManager< CoordManager_t< Vector >, Vector >
Binds the specified vector to the coordinate manager.
iterator_t & operator+=(difference_type d)
Increments the iterator by d positions (unchecked).
Float_t X
Definition: plot.C:37
ROOT libraries.
Float_t w
Definition: plot.C:20
recob::tracking::Vector_t Vector_t
static Dest convert(Source const &v)
decltype(auto) cend(ROOT::Math::LorentzVector< CoordSystem > const &v)
iterator_t & operator-=(difference_type d)
Decrements the iterator by d positions (unchecked).
iterator_t operator++(int)
Points to the next coordinate (unchecked), returns the previous iterator.
bool operator<(iterator_t const &other) const
static constexpr bool TestY(decltype(std::declval< Class >().Y())*)
static constexpr bool TestZ(decltype(std::declval< Class >().Z())*)
static constexpr bool TestT(decltype(std::declval< Class >().T())*)