geo_vectors_utils_test.cc
Go to the documentation of this file.
1 /**
2  * @file geo_vectors_utils_test.cc
3  * @brief Test of geo_vectors_utils.h utilities.
4  * @author Gianluca Petrillo (petrillo@fnal.gov)
5  * @date March 23, 2017
6  */
7 
8 
9 // Boost libraries
10 #define BOOST_TEST_MODULE ( geo_vectors_test )
11 #include <boost/test/unit_test.hpp>
12 
13 // LArSoft libraries
17 
18 // ROOT libraries
19 #include "TVector2.h"
20 #include "TVector3.h"
21 #include "TLorentzVector.h"
22 
23 // C/C++ standard library
24 #include <iostream>
25 #include <sstream>
26 #include <string>
27 #include <array>
28 #include <vector>
29 #include <numeric> // std::iota()
30 #include <type_traits> // std::is_same, std::decay_t
31 #include <stdexcept> // std::runtime_error
32 #include <cmath> // std::nan
33 
35 
36 //------------------------------------------------------------------------------
37 template <typename PointA, typename PointB>
38 void CheckPoint(PointA const& test, PointB const& ref, std::string tag = "")
39 {
40  auto const tol = 0.001% tolerance();
41 
42  if (!tag.empty()) BOOST_TEST_CHECKPOINT(tag);
43 
44  for (auto ic: geo::vect::indices(test)) {
45  BOOST_TEST_CHECKPOINT(" coordinate #" << ic);
46  BOOST_TEST
47  (geo::vect::coord(test, ic)() == geo::vect::coord(ref, ic)(), tol);
48  }
49 
50 } // CheckPoint()
51 
52 
53 //------------------------------------------------------------------------------
55 
56  geo::Point_t expected(2., 4., 6.);
57 
58  std::vector<geo::Point_t> points {
59  geo::Point_t(1., 2., 3.),
60  geo::Point_t(2., 4., 6.),
61  geo::Point_t(3., 6., 9.)
62  };
63  TVector3 another(expected.X(), expected.Y(), expected.Z());
64 
65  //
66  // default construction, then bulk addition
67  //
69  BOOST_TEST(acc.empty());
70  BOOST_TEST(acc.weight() == 0.0, 0.001% tolerance());
71  // add a single point
72  acc.add(another);
73  BOOST_TEST(!acc.empty());
74  BOOST_TEST(acc.weight() == 1.0, 0.001% tolerance());
75  CheckPoint(acc.middlePoint(), expected, "Single add");
76  // add many points
77  acc.add(points.begin(), points.end());
78  BOOST_TEST(!acc.empty());
79  BOOST_TEST(acc.weight() == 1.0 + points.size(), 0.001% tolerance());
80  CheckPoint(acc.middlePoint(), expected, "Single add plus sequence");
81 
82  //
83  // clear test
84  //
85  acc.clear();
86  BOOST_TEST(acc.empty());
87  acc.add(geo::Point_t{ expected.X() + 1.0, expected.Z(), expected.Y() });
88  CheckPoint(
89  acc.middlePoint(),
90  geo::Point_t{ expected.X() + 1.0, expected.Z(), expected.Y() },
91  "clear test"
92  );
93 
94  //
95  // start over (same accumulator)
96  //
97  acc.clear();
98  // add many points
99  acc.add(points.begin(), points.end());
100  BOOST_TEST(!acc.empty());
101  CheckPoint(acc.middlePoint(), expected, "Sequence add");
102  // add another one
103  acc.add(another);
104  BOOST_TEST(!acc.empty());
105  CheckPoint(acc.middlePoint(), expected, "Sequence add plus single point");
106 
107 } // test_MiddlePointAccumulator_defaultConstructor()
108 
109 
111 
112  geo::Point_t expected(2., 4., 6.);
113 
114  std::vector<geo::Point_t> points {
115  geo::Point_t(1., 2., 3.),
116  geo::Point_t(2., 4., 6.),
117  geo::Point_t(3., 6., 9.)
118  };
119  TVector3 another(expected.X(), expected.Y(), expected.Z());
120 
121  //
122  // sequence constructor
123  //
124  geo::vect::MiddlePointAccumulator acc(points.begin(), points.end());
125  BOOST_TEST(!acc.empty());
126  CheckPoint(acc.middlePoint(), expected, "Sequence construction");
127  // add another one
128  acc.add(another);
129  BOOST_TEST(!acc.empty());
130  CheckPoint(acc.middlePoint(), expected, "Sequence construction plus single");
131 
132 } // test_MiddlePointAccumulator_sequenceConstructor()
133 
134 
135 //------------------------------------------------------------------------------
136 template <typename Point>
138 
139  constexpr unsigned int Dim = geo::vect::dimension<Point>();
140  using Scalar_t = geo::vect::coordinate_t<Point>;
141 
142  // prepare the input from larger dimension input data
143  constexpr unsigned int MaxDim = 4U;
144 
145  static_assert(Dim < MaxDim, "This test supports only up to dimension 4");
146  using GenType = std::array<Scalar_t, MaxDim>;
147  // BUG the double brace syntax is required to work around clang bug 21629
148  // (https://bugs.llvm.org/show_bug.cgi?id=21629)
149  GenType const genExpected{{ 2., 4., 6., 8. }};
150 
151  // BUG the double brace syntax is required to work around clang bug 21629
152  // (https://bugs.llvm.org/show_bug.cgi?id=21629)
153  std::vector<GenType> genPoints {
154  GenType{{ 1., 2., 3., 4. }},
155  GenType{{ 2., 4., 6., 8. }},
156  GenType{{ 3., 6., 9., 12. }}
157  };
158 
159  std::vector<Point> points;
160  for (auto const& genPoint: genPoints)
161  points.push_back(geo::vect::makeFromCoords<Point>(genPoint.data()));
162  auto const expected = geo::vect::makeFromCoords<Point>(genExpected.data());
163  auto const another = expected;
164 
165  //
166  // default construction, then bulk addition
167  //
169  BOOST_TEST(acc.empty());
170  BOOST_TEST(acc.weight() == 0.0, 0.001% tolerance());
171  // add a single point
172  acc.add(another);
173  BOOST_TEST(!acc.empty());
174  BOOST_TEST(acc.weight() == 1.0, 0.001% tolerance());
175  CheckPoint(acc.middlePoint(), expected, "Single add");
176  // add many points
177  acc.add(points.begin(), points.end());
178  BOOST_TEST(!acc.empty());
179  BOOST_TEST(acc.weight() == 1.0 + points.size(), 0.001% tolerance());
180  CheckPoint(acc.middlePoint(), expected, "Single add plus sequence");
181 
182  //
183  // clear test
184  //
185  acc.clear();
186  BOOST_TEST(acc.empty());
187  acc.add(geo::Point_t{ expected.X() + 1.0, expected.Z(), expected.Y() });
188  CheckPoint(
189  acc.middlePoint(),
190  geo::Point_t{ expected.X() + 1.0, expected.Z(), expected.Y() },
191  "clear test"
192  );
193 
194  //
195  // start over (same accumulator)
196  //
197  acc.clear();
198  // add many points
199  acc.add(points.begin(), points.end());
200  BOOST_TEST(!acc.empty());
201  CheckPoint(acc.middlePoint(), expected, "Sequence add");
202  // add another one
203  acc.add(another);
204  BOOST_TEST(!acc.empty());
205  CheckPoint(acc.middlePoint(), expected, "Sequence add plus single point");
206 
207 } // test_MiddlePointAccumulator_generic()
208 
209 
211 
212  geo::Point_t expected { 0.0, 1.0, 0.0 };
213  /*
214  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
215  * std::array<geo::Point_t, 4> const points = {
216  * geo::Point_t{ 0.0, 1.0, 2.0 },
217  * geo::Point_t{ 0.0, -1.0, 2.0 },
218  * geo::Point_t{ 0.0, 1.0, -2.0 },
219  * geo::Point_t{ 0.0, -1.0, -2.0 }
220  * };
221  *
222  * geo::vect::MiddlePointAccumulator pointsAboveGround;
223  * for (auto const& point: points)
224  * if (point.Y() > 0.0) pointsAboveGround.add(point);
225  *
226  * if (pointsAboveGround.empty())
227  * throw std::runtime_error("No point above ground!");
228  *
229  * auto middleAboveGround = pointsAboveGround.middlePoint();
230  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
231  */
232  // BUG the double brace syntax is required to work around clang bug 21629
233  // (https://bugs.llvm.org/show_bug.cgi?id=21629)
234  std::array<geo::Point_t, 4> const points = {{
235  geo::Point_t{ 0.0, 1.0, 2.0 },
236  geo::Point_t{ 0.0, -1.0, 2.0 },
237  geo::Point_t{ 0.0, 1.0, -2.0 },
238  geo::Point_t{ 0.0, -1.0, -2.0 }
239  }};
240 
241  geo::vect::MiddlePointAccumulator pointsAboveGround;
242  for (auto const& point: points)
243  if (point.Y() > 0.0) pointsAboveGround.add(point);
244 
245  if (pointsAboveGround.empty())
246  throw std::runtime_error("No point above ground!");
247 
248  auto middleAboveGround = pointsAboveGround.middlePoint();
249 
250 
251  static_assert(std::is_same<decltype(middleAboveGround), geo::Point_t>::value,
252  "unexpected return type for geo::vect::MiddlePointAccumulator::middlePoint()");
253  CheckPoint
254  (middleAboveGround, expected, "MiddlePointAccumulator::middlePoint()");
255 
256 } // test_MiddlePointAccumulator_documentation_middlePointAs()
257 
258 
260 
261  //
262  // middlePointAs()
263  //
265  accumulator.add(geo::Point_t());
266 
267  /*
268  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
269  * auto mp = accumulator.middlePointAs<TVector3>();
270  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
271  */
272  auto mp = accumulator.middlePointAs<TVector3>();
273 
274  CheckPoint(mp, geo::Point_t(), "MiddlePointAccumulator::middlePointAs()");
275 
276 } // test_MiddlePointAccumulator_documentation_middlePointAs()
277 
278 
280 
283 
284 } // test_MiddlePointAccumulator_documentation()
285 
286 
287 //------------------------------------------------------------------------------
289 
290  geo::Point_t expected(2., 4., 6.);
291 
292  std::vector<geo::Point_t> points {
293  geo::Point_t(1., 2., 3.),
294  geo::Point_t(2., 4., 6.),
295  geo::Point_t(3., 6., 9.)
296  };
297 
298  //
299  // sequence
300  //
301  CheckPoint
302  (geo::vect::middlePoint(points.begin(), points.end()), expected, "iterators");
303 
304 
305  //
306  // points (initializer list)
307  //
308  CheckPoint(
309  geo::vect::middlePoint({ points[0], points[1], points[2] }), expected,
310  "initializer list"
311  );
312 
313 
314  //
315  // middlePointAs() (sequence)
316  //
317  auto const mp3 = geo::vect::middlePointAs<TVector3>(points.begin(), points.end());
318  static_assert(
319  std::is_same<std::decay_t<decltype(mp3)>, TVector3>::value,
320  "geo::vect::middlePointAs<TVector3> does not return a TVector3!"
321  );
322  CheckPoint(mp3, expected, "geo::vect::middlePointAs(sequence)");
323 
324 
325 } // test_middlePoint()
326 
327 
329 
330  /*
331  * std::vector<geo::Point_t> points {
332  * geo::Point_t(1., 2., 3.),
333  * geo::Point_t(2., 4., 6.),
334  * geo::Point_t(3., 6., 9.)
335  * };
336  * auto mp = geo::vect::middlePointAs<geo::Vector_t>(points.begin(), points.end());
337  */
338  std::vector<geo::Point_t> points {
339  geo::Point_t(1., 2., 3.),
340  geo::Point_t(2., 4., 6.),
341  geo::Point_t(3., 6., 9.)
342  };
343  auto mp = geo::vect::middlePointAs<geo::Vector_t>(points.begin(), points.end());
344 
345  static_assert(std::is_same<std::decay_t<decltype(mp)>, geo::Vector_t>::value,
346  "geo::vect::middlePointAs<geo::Vector_t> result is not geo::Vector_t");
347  CheckPoint(mp, geo::Vector_t(2., 4., 6.));
348 
349 } // test_middlePointAs_documentation()
350 
351 
353 
354  /*
355  * std::vector<geo::Point_t> points {
356  * geo::Point_t(1., 2., 3.),
357  * geo::Point_t(2., 4., 6.),
358  * geo::Point_t(3., 6., 9.)
359  * };
360  *
361  * auto mp = geo::vect::middlePoint(points.begin(), points.end());
362  */
363 
364  std::vector<geo::Point_t> points {
365  geo::Point_t(1., 2., 3.),
366  geo::Point_t(2., 4., 6.),
367  geo::Point_t(3., 6., 9.)
368  };
369 
370  auto mp = geo::vect::middlePoint(points.begin(), points.end());
371 
372  static_assert(std::is_same<std::decay_t<decltype(mp)>, geo::Point_t>::value,
373  "geo::vect::middlePoint() result is not geo::Point_t");
374  CheckPoint(mp, geo::Point_t(2., 4., 6.));
375 
376 } // test_middlePoint_iterators_documentation()
377 
378 
380 
381  /*
382  * auto mp = geo::vect::middlePoint
383  * ({ geo::Point_t(1., 2., 3.), geo::Point_t(3., 6., 9.) });
384  *
385  */
386 
387  auto mp = geo::vect::middlePoint
388  ({ geo::Point_t(1., 2., 3.), geo::Point_t(3., 6., 9.) });
389 
390  static_assert(std::is_same<std::decay_t<decltype(mp)>, geo::Point_t>::value,
391  "geo::vect::middlePoint() result is not geo::Point_t");
392  CheckPoint(mp, geo::Point_t(2., 4., 6.));
393 
394 } // test_middlePoint_initlist_documentation()
395 
396 
397 //------------------------------------------------------------------------------
398 template <typename Vector>
400 
402  // BUG the double brace syntax is required to work around clang bug 21629
403  // (https://bugs.llvm.org/show_bug.cgi?id=21629)
404  std::array<double, 3U> const coords = {{ 1.0, 5.0, 9.0 }};
405  Vector v{ coords[0], coords[1], coords[2] };
406 
407  unsigned int iCoord = 0;
408  for(auto coordMan: geo::vect::coordManagers<Vector>()) {
409  auto const expected = coords[iCoord++];
410  auto mc = geo::vect::bindCoord(v, coordMan);
411  BOOST_TEST(mc() == expected);
412  BOOST_TEST(mc == expected);
413  } // for
414  BOOST_TEST(iCoord == 3U);
415 
416  auto x = geo::vect::Xcoord(v);
417  auto c0 = geo::vect::coord(v, 0U);
418  auto mx = geo::vect::bindCoord(v, geo::vect::XcoordManager<Vector>);
419  auto mc0 = geo::vect::bindCoord(v, geo::vect::coordManager<Vector>(0U));
420  BOOST_TEST(x() == 1.0);
421  BOOST_TEST(x == 1.0);
422  BOOST_TEST(x() == v.X());
423  BOOST_TEST(c0() == v.X());
424  BOOST_TEST(mx() == 1.0);
425  BOOST_TEST(mx == 1.0);
426  BOOST_TEST(mx() == v.X());
427  BOOST_TEST(mc0() == v.X());
428 
429  x = 2.0;
430  BOOST_TEST(x() == 2.0);
431  BOOST_TEST(x == 2.0);
432  BOOST_TEST(x() == v.X());
433  BOOST_TEST(c0() == v.X());
434  BOOST_TEST(mx() == 2.0);
435  BOOST_TEST(mx == 2.0);
436  BOOST_TEST(mx() == v.X());
437  BOOST_TEST(mc0() == v.X());
438 
439  x += 2.0;
440  BOOST_TEST(x() == 4.0);
441  BOOST_TEST(x == 4.0);
442  BOOST_TEST(x() == v.X());
443  BOOST_TEST(c0() == v.X());
444  BOOST_TEST(mx() == 4.0);
445  BOOST_TEST(mx == 4.0);
446  BOOST_TEST(mx() == v.X());
447  BOOST_TEST(mc0() == v.X());
448 
449  x -= 2.0;
450  BOOST_TEST(x() == 2.0);
451  BOOST_TEST(x == 2.0);
452  BOOST_TEST(x() == v.X());
453  BOOST_TEST(c0() == v.X());
454  BOOST_TEST(mx() == 2.0);
455  BOOST_TEST(mx == 2.0);
456  BOOST_TEST(mx() == v.X());
457  BOOST_TEST(mc0() == v.X());
458 
459  x *= 4.0;
460  BOOST_TEST(x() == 8.0);
461  BOOST_TEST(x == 8.0);
462  BOOST_TEST(x() == v.X());
463  BOOST_TEST(c0() == v.X());
464  BOOST_TEST(mx() == 8.0);
465  BOOST_TEST(mx == 8.0);
466  BOOST_TEST(mx() == v.X());
467  BOOST_TEST(mc0() == v.X());
468 
469  x /= 4.0;
470  BOOST_TEST(x() == 2.0);
471  BOOST_TEST(x == 2.0);
472  BOOST_TEST(x() == v.X());
473  BOOST_TEST(c0() == v.X());
474  BOOST_TEST(mx() == 2.0);
475  BOOST_TEST(mx == 2.0);
476  BOOST_TEST(mx() == v.X());
477  BOOST_TEST(mc0() == v.X());
478 
479  auto y = geo::vect::Ycoord(v);
480  auto c1 = geo::vect::coord(v, 1U);
481  auto my = geo::vect::bindCoord(v, geo::vect::YcoordManager<Vector>);
482  auto mc1 = geo::vect::bindCoord(v, geo::vect::coordManager<Vector>(1U));
483  BOOST_TEST(y() == 5.0);
484  BOOST_TEST(y == 5.0);
485  BOOST_TEST(y() == v.Y());
486  BOOST_TEST(c1() == v.Y());
487  BOOST_TEST(my() == 5.0);
488  BOOST_TEST(my == 5.0);
489  BOOST_TEST(my() == v.Y());
490  BOOST_TEST(mc1() == v.Y());
491 
492  y = 2.0;
493  BOOST_TEST(y() == 2.0);
494  BOOST_TEST(y == 2.0);
495  BOOST_TEST(y() == v.Y());
496  BOOST_TEST(c1() == v.Y());
497  BOOST_TEST(my() == 2.0);
498  BOOST_TEST(my == 2.0);
499  BOOST_TEST(my() == v.Y());
500  BOOST_TEST(mc1() == v.Y());
501 
502  y += 2.0;
503  BOOST_TEST(y() == 4.0);
504  BOOST_TEST(y == 4.0);
505  BOOST_TEST(y() == v.Y());
506  BOOST_TEST(c1() == v.Y());
507  BOOST_TEST(my() == 4.0);
508  BOOST_TEST(my == 4.0);
509  BOOST_TEST(my() == v.Y());
510  BOOST_TEST(mc1() == v.Y());
511 
512  y -= 2.0;
513  BOOST_TEST(y() == 2.0);
514  BOOST_TEST(y == 2.0);
515  BOOST_TEST(y() == v.Y());
516  BOOST_TEST(c1() == v.Y());
517  BOOST_TEST(my() == 2.0);
518  BOOST_TEST(my == 2.0);
519  BOOST_TEST(my() == v.Y());
520  BOOST_TEST(mc1() == v.Y());
521 
522  y *= 4.0;
523  BOOST_TEST(y() == 8.0);
524  BOOST_TEST(y == 8.0);
525  BOOST_TEST(y() == v.Y());
526  BOOST_TEST(c1() == v.Y());
527  BOOST_TEST(my() == 8.0);
528  BOOST_TEST(my == 8.0);
529  BOOST_TEST(my() == v.Y());
530  BOOST_TEST(mc1() == v.Y());
531 
532  y /= 4.0;
533  BOOST_TEST(y() == 2.0);
534  BOOST_TEST(y == 2.0);
535  BOOST_TEST(y() == v.Y());
536  BOOST_TEST(c1() == v.Y());
537  BOOST_TEST(my() == 2.0);
538  BOOST_TEST(my == 2.0);
539  BOOST_TEST(my() == v.Y());
540  BOOST_TEST(mc1() == v.Y());
541 
542  auto z = geo::vect::Zcoord(v);
543  auto c2 = geo::vect::coord(v, 2U);
544  auto mz = geo::vect::bindCoord(v, geo::vect::ZcoordManager<Vector>);
545  auto mc2 = geo::vect::bindCoord(v, geo::vect::coordManager<Vector>(2U));
546  BOOST_TEST(z() == 9.0);
547  BOOST_TEST(z == 9.0);
548  BOOST_TEST(z() == v.Z());
549  BOOST_TEST(c2() == v.Z());
550  BOOST_TEST(mz() == 9.0);
551  BOOST_TEST(mz == 9.0);
552  BOOST_TEST(mz() == v.Z());
553  BOOST_TEST(mc2() == v.Z());
554 
555  z = 2.0;
556  BOOST_TEST(z() == 2.0);
557  BOOST_TEST(z == 2.0);
558  BOOST_TEST(z() == v.Z());
559  BOOST_TEST(c2() == v.Z());
560  BOOST_TEST(mz() == 2.0);
561  BOOST_TEST(mz == 2.0);
562  BOOST_TEST(mz() == v.Z());
563  BOOST_TEST(mc2() == v.Z());
564 
565  z += 2.0;
566  BOOST_TEST(z() == 4.0);
567  BOOST_TEST(z == 4.0);
568  BOOST_TEST(z() == v.Z());
569  BOOST_TEST(c2() == v.Z());
570  BOOST_TEST(mz() == 4.0);
571  BOOST_TEST(mz == 4.0);
572  BOOST_TEST(mz() == v.Z());
573  BOOST_TEST(mc2() == v.Z());
574 
575  z -= 2.0;
576  BOOST_TEST(z() == 2.0);
577  BOOST_TEST(z == 2.0);
578  BOOST_TEST(z() == v.Z());
579  BOOST_TEST(c2() == v.Z());
580  BOOST_TEST(mz() == 2.0);
581  BOOST_TEST(mz == 2.0);
582  BOOST_TEST(mz() == v.Z());
583  BOOST_TEST(mc2() == v.Z());
584 
585  z *= 4.0;
586  BOOST_TEST(z() == 8.0);
587  BOOST_TEST(z == 8.0);
588  BOOST_TEST(z() == v.Z());
589  BOOST_TEST(c2() == v.Z());
590  BOOST_TEST(mz() == 8.0);
591  BOOST_TEST(mz == 8.0);
592  BOOST_TEST(mz() == v.Z());
593  BOOST_TEST(mc2() == v.Z());
594 
595  z /= 4.0;
596  BOOST_TEST(z() == 2.0);
597  BOOST_TEST(z == 2.0);
598  BOOST_TEST(z() == v.Z());
599  BOOST_TEST(c2() == v.Z());
600  BOOST_TEST(mz() == 2.0);
601  BOOST_TEST(mz == 2.0);
602  BOOST_TEST(mz() == v.Z());
603  BOOST_TEST(mc2() == v.Z());
604 
605  } // test_vectorAccess()
606 
607 }; // struct test_vectorAccess
608 
609 
610 template <typename Vector>
612 
614 
615  // BUG the double brace syntax is required to work around clang bug 21629
616  // (https://bugs.llvm.org/show_bug.cgi?id=21629)
617  std::array<double, 3U> const coords = {{ 1.0, 5.0, 9.0 }};
618  Vector const v{ coords[0], coords[1], coords[2] };
619 
620  unsigned int iCoord = 0;
621  for(auto coordMan: geo::vect::coordReaders<Vector>()) {
622  auto const expected = coords[iCoord++];
623  auto mc = geo::vect::bindCoord(v, coordMan);
624  BOOST_TEST(mc() == expected);
625  BOOST_TEST(mc == expected);
626  } // for
627  BOOST_TEST(iCoord == 3U);
628 
629  auto x = geo::vect::Xcoord(v);
630  auto c0 = geo::vect::coord(v, 0U);
631  auto mx = geo::vect::bindCoord(v, geo::vect::XcoordManager<Vector>);
632  auto mc0 = geo::vect::bindCoord(v, geo::vect::coordManager<Vector>(0U));
633  BOOST_TEST(x() == 1.0);
634  BOOST_TEST(x == 1.0);
635  BOOST_TEST(x() == v.X());
636  BOOST_TEST(c0() == v.X());
637  BOOST_TEST(mx() == 1.0);
638  BOOST_TEST(mx == 1.0);
639  BOOST_TEST(mx() == v.X());
640  BOOST_TEST(mc0() == v.X());
641 
642  auto y = geo::vect::Ycoord(v);
643  auto c1 = geo::vect::coord(v, 1U);
644  auto my = geo::vect::bindCoord(v, geo::vect::YcoordManager<Vector>);
645  auto mc1 = geo::vect::bindCoord(v, geo::vect::coordManager<Vector>(1U));
646  BOOST_TEST(y() == 5.0);
647  BOOST_TEST(y == 5.0);
648  BOOST_TEST(y() == v.Y());
649  BOOST_TEST(c1() == v.Y());
650  BOOST_TEST(my() == 5.0);
651  BOOST_TEST(my == 5.0);
652  BOOST_TEST(my() == v.Y());
653  BOOST_TEST(mc1() == v.Y());
654 
655 
656  auto z = geo::vect::Zcoord(v);
657  auto c2 = geo::vect::coord(v, 2U);
658  auto mz = geo::vect::bindCoord(v, geo::vect::ZcoordManager<Vector>);
659  auto mc2 = geo::vect::bindCoord(v, geo::vect::coordManager<Vector>(2U));
660  BOOST_TEST(z() == 9.0);
661  BOOST_TEST(z == 9.0);
662  BOOST_TEST(z() == v.Z());
663  BOOST_TEST(c2() == v.Z());
664  BOOST_TEST(mz() == 9.0);
665  BOOST_TEST(mz == 9.0);
666  BOOST_TEST(mz() == v.Z());
667  BOOST_TEST(mc2() == v.Z());
668 
669  } // test_vectorAccess()
670 }; // struct test_vectorAccess<const>
671 
672 
673 
674 //------------------------------------------------------------------------------
675 template <typename Vector, unsigned int Dim = geo::vect::dimension<Vector>()>
677 
678 template <typename Vector>
679 struct IsfiniteTester<Vector, 4U> {
681  {
682  BOOST_TEST( geo::vect::isfinite(Vector{ 1.0, 2.0, 3.0, 4.0 }));
683  BOOST_TEST( geo::vect::isfinite(Vector{ 0.0, 2.0, 3.0, 4.0 }));
684  BOOST_TEST( geo::vect::isfinite(Vector{ 1.0, 0.0, 3.0, 4.0 }));
685  BOOST_TEST( geo::vect::isfinite(Vector{ 1.0, 2.0, 0.0, 4.0 }));
686  BOOST_TEST( geo::vect::isfinite(Vector{ 1.0, 2.0, 3.0, 0.0 }));
687 
688  BOOST_TEST(!geo::vect::isfinite(Vector{ std::nan(""), 2.0, 3.0, 4.0 }));
689  BOOST_TEST(!geo::vect::isfinite(Vector{ 1.0, std::nan(""), 3.0, 4.0 }));
690  BOOST_TEST(!geo::vect::isfinite(Vector{ 1.0, 2.0, std::nan(""), 4.0 }));
691  BOOST_TEST(!geo::vect::isfinite(Vector{ 1.0, 2.0, 3.0, std::nan("") }));
692 
693  BOOST_TEST(!geo::vect::isfinite(Vector{ std::nan(""), std::nan(""), 3.0, 4.0 }));
694  BOOST_TEST(!geo::vect::isfinite(Vector{ std::nan(""), 2.0, std::nan(""), 4.0 }));
695  BOOST_TEST(!geo::vect::isfinite(Vector{ std::nan(""), 2.0, 3.0, std::nan("") }));
696  BOOST_TEST(!geo::vect::isfinite(Vector{ 1.0, std::nan(""), std::nan(""), 4.0 }));
697  BOOST_TEST(!geo::vect::isfinite(Vector{ 1.0, std::nan(""), 3.0, std::nan("") }));
698  BOOST_TEST(!geo::vect::isfinite(Vector{ 1.0, 2.0, std::nan(""), std::nan("") }));
699 
700  BOOST_TEST(!geo::vect::isfinite(Vector{ 1.0, std::nan(""), std::nan(""), std::nan("") }));
701  BOOST_TEST(!geo::vect::isfinite(Vector{ std::nan(""), 2.0, std::nan(""), std::nan("") }));
702  BOOST_TEST(!geo::vect::isfinite(Vector{ std::nan(""), std::nan(""), 3.0, std::nan("") }));
703  BOOST_TEST(!geo::vect::isfinite(Vector{ std::nan(""), std::nan(""), std::nan(""), 4.0 }));
704 
705  BOOST_TEST(!geo::vect::isfinite(Vector{ std::nan(""), std::nan(""), std::nan(""), std::nan("") }));
706  }
707 };
708 
709 template <typename Vector>
710 struct IsfiniteTester<Vector, 3U> {
712  {
713  BOOST_TEST( geo::vect::isfinite(Vector{ 1.0, 2.0, 3.0 }));
714  BOOST_TEST( geo::vect::isfinite(Vector{ 0.0, 2.0, 3.0 }));
715  BOOST_TEST( geo::vect::isfinite(Vector{ 1.0, 0.0, 3.0 }));
716  BOOST_TEST( geo::vect::isfinite(Vector{ 1.0, 2.0, 0.0 }));
717  BOOST_TEST( geo::vect::isfinite(Vector{ 1.0, 2.0, 3.0 }));
718 
719  BOOST_TEST(!geo::vect::isfinite(Vector{ std::nan(""), 2.0, 3.0 }));
720  BOOST_TEST(!geo::vect::isfinite(Vector{ 1.0, std::nan(""), 3.0 }));
721  BOOST_TEST(!geo::vect::isfinite(Vector{ 1.0, 2.0, std::nan("") }));
722 
723  BOOST_TEST(!geo::vect::isfinite(Vector{ 1.0, std::nan(""), std::nan("") }));
724  BOOST_TEST(!geo::vect::isfinite(Vector{ std::nan(""), 2.0, std::nan("") }));
725  BOOST_TEST(!geo::vect::isfinite(Vector{ std::nan(""), std::nan(""), 3.0 }));
726 
727  BOOST_TEST(!geo::vect::isfinite(Vector{ std::nan(""), std::nan(""), std::nan("") }));
728  }
729 };
730 
731 template <typename Vector>
732 struct IsfiniteTester<Vector, 2U> {
734  {
735  BOOST_TEST( geo::vect::isfinite(Vector{ 1.0, 2.0 }));
736  BOOST_TEST( geo::vect::isfinite(Vector{ 0.0, 2.0 }));
737  BOOST_TEST( geo::vect::isfinite(Vector{ 1.0, 0.0 }));
738 
739  BOOST_TEST(!geo::vect::isfinite(Vector{ std::nan(""), 2.0 }));
740  BOOST_TEST(!geo::vect::isfinite(Vector{ 1.0, std::nan("") }));
741 
742  BOOST_TEST(!geo::vect::isfinite(Vector{ std::nan(""), std::nan("") }));
743  }
744 };
745 
746 
747 template <typename Vector>
749 
750  (void) IsfiniteTester<Vector>();
751 
752 } // test_vectorProcessing()
753 
754 
755 //------------------------------------------------------------------------------
756 template <typename Source, typename Dest>
758 
759  // BUG the double brace syntax is required to work around clang bug 21629
760  // (https://bugs.llvm.org/show_bug.cgi?id=21629)
761  std::array<double, 4U> srcData {{ 1.0, 5.0, 9.0, 16.0 }};
762 
763  // BUG the double brace syntax is required to work around clang bug 21629
764  // (https://bugs.llvm.org/show_bug.cgi?id=21629)
765  // Source const src{ srcData[0], srcData[1] };
766  Source srcForClangBug;
767  if constexpr (util::is_STLarray_v<Source>)
768  srcForClangBug = Source{{ srcData[0], srcData[1] }};
769  else
770  srcForClangBug = Source{ srcData[0], srcData[1] };
771  Source const src { srcForClangBug };
772 
773  auto dest = geo::vect::convertTo<Dest>(src);
774 
775  static_assert
776  (std::is_same<decltype(dest), Dest>(), "Unexpected return type!");
777 
778  BOOST_TEST(geo::vect::Xcoord(dest) == srcData[0]);
779  BOOST_TEST(geo::vect::Ycoord(dest) == srcData[1]);
780 
781 } // test_vector2Dconvert()
782 
783 
784 //------------------------------------------------------------------------------
785 template <typename Source, typename Dest>
787 
788  // BUG the double brace syntax is required to work around clang bug 21629
789  // (https://bugs.llvm.org/show_bug.cgi?id=21629)
790  std::array<double, 4U> srcData {{ 1.0, 5.0, 9.0, 16.0 }};
791 
792  // BUG the double brace syntax is required to work around clang bug 21629
793  // (https://bugs.llvm.org/show_bug.cgi?id=21629)
794  // Source const src{ srcData[0], srcData[1], srcData[2] };
795  Source srcForClangBug;
796  if constexpr (util::is_STLarray_v<Source>)
797  srcForClangBug = Source{{ srcData[0], srcData[1], srcData[2] }};
798  else
799  srcForClangBug = Source{ srcData[0], srcData[1], srcData[2] };
800  Source const src { srcForClangBug };
801 
802  auto dest = geo::vect::convertTo<Dest>(src);
803 
804  static_assert
805  (std::is_same<decltype(dest), Dest>(), "Unexpected return type!");
806 
807  BOOST_TEST(geo::vect::Xcoord(dest) == srcData[0]);
808  BOOST_TEST(geo::vect::Ycoord(dest) == srcData[1]);
809  BOOST_TEST(geo::vect::Zcoord(dest) == srcData[2]);
810 
811 } // test_vector3Dconvert()
812 
813 
814 //------------------------------------------------------------------------------
815 template <typename Source, typename Dest>
817 
818  // BUG the double brace syntax is required to work around clang bug 21629
819  // (https://bugs.llvm.org/show_bug.cgi?id=21629)
820  std::array<double, 4U> srcData {{ 1.0, 5.0, 9.0, 16.0 }};
821 
822  // BUG the double brace syntax is required to work around clang bug 21629
823  // (https://bugs.llvm.org/show_bug.cgi?id=21629)
824  // Source const src{ srcData[0], srcData[1], srcData[2], srcData[3] };
825  Source srcForClangBug;
826  if constexpr (util::is_STLarray_v<Source>)
827  srcForClangBug = Source{{ srcData[0], srcData[1], srcData[2], srcData[3] }};
828  else
829  srcForClangBug = Source{ srcData[0], srcData[1], srcData[2], srcData[3] };
830  Source const src { srcForClangBug };
831 
832 
833  auto dest = geo::vect::convertTo<Dest>(src);
834 
835  static_assert
836  (std::is_same<decltype(dest), Dest>(), "Unexpected return type!");
837 
838  BOOST_TEST(geo::vect::Xcoord(dest) == srcData[0]);
839  BOOST_TEST(geo::vect::Ycoord(dest) == srcData[1]);
840  BOOST_TEST(geo::vect::Zcoord(dest) == srcData[2]);
841  BOOST_TEST(geo::vect::Tcoord(dest) == srcData[3]);
842 
843 } // test_vector4Dconvert()
844 
845 //------------------------------------------------------------------------------
847 
848  /*
849  * constexpr std::array<float, 5U> data { 2.0, 5.0, 7.0, 11.0, 15.5 };
850  * constexpr auto p = geo::vect::makeFromCoords<geo::Point_t>(data);
851  * auto v = geo::vect::makeFromCoords<geo::Vector_t>(data.data() + 1);
852  */
853  // BUG the double brace syntax is required to work around clang bug 21629
854  // (https://bugs.llvm.org/show_bug.cgi?id=21629)
855  constexpr std::array<float, 5U> data {{ 2.0, 5.0, 7.0, 11.0, 15.5 }};
856  auto const p = geo::vect::makeFromCoords<geo::Point_t>(data);
857  auto const v = geo::vect::makeFromCoords<geo::Vector_t>(data.data() + 1);
858 
859  BOOST_TEST(p == (geo::Point_t { 2.0, 5.0, 7.0 }));
860  BOOST_TEST(v == (geo::Vector_t{ 5.0, 7.0, 11.0 }));
861 
862 } // test_makeFromCoords_documentation()
863 
864 
865 //------------------------------------------------------------------------------
866 template <typename Vector>
868 
869  // BUG the double brace syntax is required to work around clang bug 21629
870  // (https://bugs.llvm.org/show_bug.cgi?id=21629)
871  std::array<float, 5U> data {{ 4.0, 5.0, 7.0, 11.0, 15.5 }};
872  auto const v = geo::vect::makeFromCoords<Vector>(data);
873 
874  auto const neg_v = geo::vect::transformCoords(v, [](auto c){ return -c; });
875  static_assert
876  (std::is_same<decltype(neg_v), decltype(v)>(), "Unexpected return type");
877  BOOST_TEST(neg_v == -v);
878 
879 } // test_transform()
880 
881 
882 //------------------------------------------------------------------------------
884  std::ostringstream expected, out;
885  /*
886  * // constant vectors get a "reader" (read-only manager):
887  * geo::Vector_t v { 1.0, 2.0, 3.0 };
888  *
889  * auto vx = geo::vect::bindCoord(v, geo::vect::XcoordManager<geo::Vector_t const>);
890  * std::cout << v << " has x=" << vx() << std::endl;
891  */
892 
893  // constant vectors get a "reader" (read-only manager):
894  geo::Vector_t v { 1.0, 2.0, 3.0 };
895 
896  auto vx = geo::vect::bindCoord(v, geo::vect::XcoordManager<geo::Vector_t const>);
897  std::cout << v << " has x=" << vx() << std::endl;
898  out << v << " has x=" << vx();
899  expected << v << " has x=" << v.X();
900 
901  BOOST_TEST(out.str() == expected.str());
902 
903  out.str("");
904  expected.str("");
905  /*
906  * // mutable vectors get a full-featured "manager":
907  * geo::Point_t p { 1.0, 2.0, 3.0 };
908  * auto px = geo::vect::bindCoord(p, geo::vect::XcoordManager<geo::Point_t>);
909  * px *= 5.0;
910  * std::cout << p << " has now x=" << px() << std::endl;
911  */
912 
913  // mutable vectors get a full-featured "manager":
914  geo::Point_t p { 1.0, 2.0, 3.0 };
915  auto px = geo::vect::bindCoord(p, geo::vect::XcoordManager<geo::Point_t>);
916  px *= 5.0;
917  std::cout << p << " has now x=" << px() << std::endl;
918  out << p << " has now x=" << px();
919  expected << p << " has now x=" << p.X();
920 
921  BOOST_TEST(out.str() == expected.str());
922 
923 } // test_XcoordManager_documentation()
924 
925 
926 //------------------------------------------------------------------------------
928  // artificial ter vector types
929  template <typename C>
930  struct Vector0D
931  { static constexpr unsigned int Dim = 0U; using Scalar = C; };
932  template <typename C>
933  struct Vector1D: public Vector0D<C>
934  { static constexpr unsigned int Dim = 1U; C X() const; };
935  template <typename C>
936  struct Vector2D: public Vector1D<C>
937  { static constexpr unsigned int Dim = 2U; C Y() const; };
938  template <typename C>
939  struct Vector3D: public Vector2D<C>
940  { static constexpr unsigned int Dim = 3U; C Z() const; };
941  template <typename C>
942  struct Vector4D: public Vector3D<C>
943  { static constexpr unsigned int Dim = 4U; C T() const; };
944  template <typename C>
945  struct Vector5D: public Vector4D<C>
946  { static constexpr unsigned int Dim = 5U; C U() const; };
947 
948  // the test on details is here just to facilitate debugging;
949  // failure of details tests is acceptable (and failing tests must be removed)
950  static_assert(!geo::vect::details::HasX<Vector0D<double>>(), "Unexpected 0D::X()");
951  static_assert( geo::vect::details::HasX<Vector1D<double>>(), "Unexpected 1D::X()");
952  static_assert( geo::vect::details::HasX<Vector2D<double>>(), "Unexpected 2D::X()");
953  static_assert( geo::vect::details::HasX<Vector3D<double>>(), "Unexpected 3D::X()");
954  static_assert( geo::vect::details::HasX<Vector4D<double>>(), "Unexpected 4D::X()");
955  static_assert( geo::vect::details::HasX<Vector5D<double>>(), "Unexpected 5D::X()");
956 
957  static_assert(!geo::vect::details::HasY<Vector0D<double>>(), "Unexpected 0D::Y()");
958  static_assert(!geo::vect::details::HasY<Vector1D<double>>(), "Unexpected 1D::Y()");
959  static_assert( geo::vect::details::HasY<Vector2D<double>>(), "Unexpected 2D::Y()");
960  static_assert( geo::vect::details::HasY<Vector3D<double>>(), "Unexpected 3D::Y()");
961  static_assert( geo::vect::details::HasY<Vector4D<double>>(), "Unexpected 4D::Y()");
962  static_assert( geo::vect::details::HasY<Vector5D<double>>(), "Unexpected 5D::Y()");
963 
964  static_assert(!geo::vect::details::HasZ<Vector0D<double>>(), "Unexpected 0D::Z()");
965  static_assert(!geo::vect::details::HasZ<Vector1D<double>>(), "Unexpected 1D::Z()");
966  static_assert(!geo::vect::details::HasZ<Vector2D<double>>(), "Unexpected 2D::Z()");
967  static_assert( geo::vect::details::HasZ<Vector3D<double>>(), "Unexpected 3D::Z()");
968  static_assert( geo::vect::details::HasZ<Vector4D<double>>(), "Unexpected 4D::Z()");
969  static_assert( geo::vect::details::HasZ<Vector5D<double>>(), "Unexpected 5D::Z()");
970 
971  static_assert(!geo::vect::details::HasT<Vector0D<double>>(), "Unexpected 0D::T()");
972  static_assert(!geo::vect::details::HasT<Vector1D<double>>(), "Unexpected 1D::T()");
973  static_assert(!geo::vect::details::HasT<Vector2D<double>>(), "Unexpected 2D::T()");
974  static_assert(!geo::vect::details::HasT<Vector3D<double>>(), "Unexpected 3D::T()");
975  static_assert( geo::vect::details::HasT<Vector4D<double>>(), "Unexpected 4D::T()");
976  static_assert( geo::vect::details::HasT<Vector5D<double>>(), "Unexpected 5D::T()");
977 
978  static_assert(geo::vect::dimension<Vector0D<double>>() == 0U, "Unexpected 0D dimension");
979  static_assert(geo::vect::dimension<Vector1D<double>>() == 1U, "Unexpected 1D dimension");
980  static_assert(geo::vect::dimension<Vector2D<double>>() == 2U, "Unexpected 2D dimension");
981  static_assert(geo::vect::dimension<Vector3D<double>>() == 3U, "Unexpected 3D dimension");
982  static_assert(geo::vect::dimension<Vector4D<double>>() == 4U, "Unexpected 4D dimension");
983  static_assert(geo::vect::dimension<Vector5D<double>>() == 4U, "Unexpected 5D dimension");
984 
985  //
986  // TVector2
987  //
988  static_assert( geo::vect::details::HasX<TVector2>(), "Unexpected TVector2::X()");
989  static_assert( geo::vect::details::HasY<TVector2>(), "Unexpected TVector2::Y()");
990  static_assert(!geo::vect::details::HasZ<TVector2>(), "Unexpected TVector2::Z()");
991  static_assert(!geo::vect::details::HasT<TVector2>(), "Unexpected TVector2::T()");
992  static_assert(geo::vect::dimension<TVector2>() == 2U, "Unexpected TVector2 dimension");
993  static_assert(std::is_same<geo::vect::coordinate_t<TVector2>, double>(), "Unexpected vector type");
994 
995  //
996  // TVector3
997  //
998  static_assert( geo::vect::details::HasX<TVector3>(), "Unexpected TVector3::X()");
999  static_assert( geo::vect::details::HasY<TVector3>(), "Unexpected TVector3::Y()");
1000  static_assert( geo::vect::details::HasZ<TVector3>(), "Unexpected TVector3::Z()");
1001  static_assert(!geo::vect::details::HasT<TVector3>(), "Unexpected TVector3::T()");
1002  static_assert(geo::vect::dimension<TVector3>() == 3U, "Unexpected TVector3 dimension");
1003  static_assert(std::is_same<geo::vect::coordinate_t<TVector3>, double>(), "Unexpected vector type");
1004 
1005  //
1006  // TLorentzVector
1007  //
1008  static_assert( geo::vect::details::HasX<TLorentzVector>(), "Unexpected TLorentzVector::X()");
1009  static_assert( geo::vect::details::HasY<TLorentzVector>(), "Unexpected TLorentzVector::Y()");
1010  static_assert( geo::vect::details::HasZ<TLorentzVector>(), "Unexpected TLorentzVector::Z()");
1011  static_assert( geo::vect::details::HasT<TLorentzVector>(), "Unexpected TLorentzVector::T()");
1012  static_assert(geo::vect::dimension<TLorentzVector>() == 4U, "Unexpected TLorentzVector dimension");
1013  static_assert(std::is_same<geo::vect::coordinate_t<TLorentzVector>, double>(),
1014  "Unexpected TLorentzVector coordinate type");
1015 
1016  //
1017  // geo::Vector_t
1018  //
1019  static_assert( geo::vect::details::HasX<geo::Vector_t>(), "Unexpected geo::Vector_t::X()");
1020  static_assert( geo::vect::details::HasY<geo::Vector_t>(), "Unexpected geo::Vector_t::Y()");
1021  static_assert( geo::vect::details::HasZ<geo::Vector_t>(), "Unexpected geo::Vector_t::Z()");
1022  static_assert(!geo::vect::details::HasT<geo::Vector_t>(), "Unexpected geo::Vector_t::T()");
1023  static_assert(geo::vect::dimension<geo::Vector_t>() == 3U, "Unexpected geo::Vector_t dimension");
1024  static_assert(std::is_same<geo::vect::coordinate_t<geo::Vector_t>, double>(),
1025  "Unexpected vector type");
1026 
1027  //
1028  // geo::Point_t
1029  //
1030  static_assert( geo::vect::details::HasX<geo::Point_t>(), "Unexpected geo::Point_t::X()");
1031  static_assert( geo::vect::details::HasY<geo::Point_t>(), "Unexpected geo::Point_t::Y()");
1032  static_assert( geo::vect::details::HasZ<geo::Point_t>(), "Unexpected geo::Point_t::Z()");
1033  static_assert(!geo::vect::details::HasT<geo::Point_t>(), "Unexpected geo::Point_t::T()");
1034  static_assert(geo::vect::dimension<geo::Point_t>() == 3U, "Unexpected geo::Point_t dimension");
1035  static_assert(std::is_same<geo::vect::coordinate_t<geo::Point_t>, double>(),
1036  "Unexpected vector type");
1037 
1038 }; // struct VectorTraitsTester
1039 
1040 
1041 //------------------------------------------------------------------------------
1042 template <typename Vector>
1044 
1045  using Vector_t = Vector;
1047 
1048  std::array<Coord_t, geo::vect::dimension<Vector_t>()> expected;
1049  std::iota(expected.begin(), expected.end(), Coord_t(1));
1050  auto const v = geo::vect::makeFromCoords<Vector_t>(expected);
1051 
1052  unsigned int index = 0;
1053  for (Coord_t c: geo::vect::iterateCoords(v)) {
1054  BOOST_TEST(c == expected[index]);
1055  ++index;
1056  } // for
1057 
1058  // same test as above,
1059  // but implicitly using ROOT::Math::cbegin()/cend() we provide
1060  index = 0;
1061  for (Coord_t c: v) {
1062  BOOST_TEST(c == expected[index]);
1063  ++index;
1064  } // for
1065 
1066 } // test_CoordConstIterator()
1067 
1068 
1069 //------------------------------------------------------------------------------
1070 template <typename Vector>
1072 
1073  using Vector_t = Vector;
1075 
1076  std::array<Coord_t, geo::vect::dimension<Vector_t>()> expected;
1077  std::iota(expected.begin(), expected.end(), Coord_t(1));
1078  auto const v = geo::vect::makeFromCoords<Vector_t>(expected);
1079 
1080  Coord_t coords[geo::vect::dimension<Vector_t>()];
1081  auto const dim = geo::vect::fillCoords(coords, v);
1082 
1083  BOOST_TEST(dim == expected.size());
1084 
1085  for (unsigned int index = 0; index < dim; ++index)
1086  BOOST_TEST(coords[index] == expected[index]);
1087 
1088 } // test_fillCoords()
1089 
1090 
1091 BOOST_AUTO_TEST_SUITE(geo_vectors_utils_test)
1092 
1093 //------------------------------------------------------------------------------
1094 BOOST_AUTO_TEST_CASE(MiddlePointAccumulator_test) {
1098  test_MiddlePointAccumulator_generic<TVector3>();
1099  test_MiddlePointAccumulator_generic<geo::Vector_t>();
1100  test_MiddlePointAccumulator_generic<geo::Point_t>();
1101 } // BOOST_AUTO_TEST_CASE(MiddlePointAccumulator_test)
1102 
1103 BOOST_AUTO_TEST_CASE(middlePoint_test) {
1104  test_middlePoint();
1105 }
1106 
1107 BOOST_AUTO_TEST_CASE(middlePoint_documentation_test) {
1111 }
1112 
1113 //------------------------------------------------------------------------------
1114 BOOST_AUTO_TEST_CASE(vectorAccess_test) {
1121 } // BOOST_AUTO_TEST_CASE(vectorAccess_test)
1122 
1123 //------------------------------------------------------------------------------
1124 BOOST_AUTO_TEST_CASE(vectorUtilDocumentation_test) {
1127 } // BOOST_AUTO_TEST_CASE(vectorUtilDocumentation_test)
1128 
1129 
1130 //------------------------------------------------------------------------------
1131 BOOST_AUTO_TEST_CASE(vectorProperties_test) {
1132  (void) VectorTraitsTester();
1133 } // BOOST_AUTO_TEST_CASE(vectorConversion_test)
1134 
1135 
1136 //------------------------------------------------------------------------------
1137 BOOST_AUTO_TEST_CASE(vectorProcessing_test) {
1138  test_vectorProcessing<TVector2>();
1139  test_vectorProcessing<geo::Point_t>();
1140  test_vectorProcessing<geo::Vector_t>();
1141  test_vectorProcessing<TVector3>();
1142  test_vectorProcessing<TLorentzVector>();
1143 } // BOOST_AUTO_TEST_CASE(vectorProcessing_test)
1144 
1145 
1146 //------------------------------------------------------------------------------
1147 BOOST_AUTO_TEST_CASE(vectorConversion_test) {
1148  // BUG until clang bug 21629 is fixed, the amount of work to make the *test*
1149  // work on double[N] vectors is not worth; HERE are some things to restore
1150  // when the bug is fixed:
1151  // (https://bugs.llvm.org/show_bug.cgi?id=21629)
1152 
1153  // 2D
1154  test_vector2Dconvert<TVector2 , TVector2 >();
1155  test_vector2Dconvert<std::array<double, 2U>, TVector2 >();
1156  // HERE
1157  // test_vector2Dconvert<double[2U] , TVector2 >();
1158 
1159  // 3D
1160  test_vector3Dconvert<std::array<double, 3U>, TVector3 >();
1161 
1162  // HERE
1163  // test_vector3Dconvert<double[3U] , TVector3 >();
1164  test_vector3Dconvert<TVector3 , TVector3 >();
1165  test_vector3Dconvert<geo::Point_t , TVector3 >();
1166  test_vector3Dconvert<geo::Vector_t , TVector3 >();
1167  test_vector3Dconvert<std::array<double, 3U>, geo::Point_t >();
1168  // HERE
1169  // test_vector3Dconvert<double[3U] , geo::Point_t >();
1170  test_vector3Dconvert<TVector3 , geo::Point_t >();
1171  test_vector3Dconvert<geo::Point_t , geo::Point_t >();
1172  test_vector3Dconvert<geo::Vector_t , geo::Point_t >();
1173  test_vector3Dconvert<std::array<double, 3U>, geo::Vector_t>();
1174  // HERE
1175  // test_vector3Dconvert<double[3U] , geo::Vector_t>();
1176  test_vector3Dconvert<TVector3 , geo::Vector_t>();
1177  test_vector3Dconvert<geo::Point_t , geo::Vector_t>();
1178  test_vector3Dconvert<geo::Vector_t , geo::Vector_t>();
1179 
1180  test_transform<TVector3>();
1181 
1182  // 4D
1183  test_vector4Dconvert<TLorentzVector , TLorentzVector>();
1184  test_vector4Dconvert<std::array<double, 4U>, TLorentzVector>();
1185  // HERE
1186  // test_vector4Dconvert<double[4U] , TLorentzVector>();
1187 
1188 } // BOOST_AUTO_TEST_CASE(vectorAccess_test)
1189 
1190 //------------------------------------------------------------------------------
1191 BOOST_AUTO_TEST_CASE(vectorCoordinateIteration_test) {
1192 
1193  test_CoordConstIterator<TVector2 >();
1194  test_CoordConstIterator<TVector3 >();
1195  test_CoordConstIterator<geo::Point_t >();
1196  test_CoordConstIterator<geo::Vector_t >();
1197  test_CoordConstIterator<TLorentzVector>();
1198 
1199  test_fillCoords<TVector2 >();
1200  test_fillCoords<TVector3 >();
1201  test_fillCoords<geo::Point_t >();
1202  test_fillCoords<geo::Vector_t >();
1203  test_fillCoords<TLorentzVector>();
1204 
1205 } // BOOST_AUTO_TEST_CASE(vectorCoordinateIteration_test)
1206 
1207 //------------------------------------------------------------------------------
1208 
1209 BOOST_AUTO_TEST_SUITE_END()
Utilities to extend the interface of geometry vectors.
void clear()
Resets the status of the object to no accumulated points.
vector< T > Vector
void test_vector4Dconvert()
auto Zcoord(Vector &v)
Returns an object to manage the coordinate Z of the vector v.
Point middlePointAs() const
Returns the middle point, NaN components if no point.
Basic C++ metaprogramming utilities.
BOOST_AUTO_TEST_CASE(MiddlePointAccumulator_test)
void test_vector3Dconvert()
const char expected[]
Definition: Exception_t.cc:22
std::string string
Definition: nybbler.cc:12
void test_MiddlePointAccumulator_defaultConstructor()
auto coord(Vector &v, unsigned int n) noexcept
Returns an object to manage the coordinate n of a vector.
auto const tol
Definition: SurfXYZTest.cc:16
Helper class to compute the middle point in a point set.
void CheckPoint(PointA const &test, PointB const &ref, std::string tag="")
auto const tolerance
double weight() const
Returns the total weight (number of points if all have weight 1).
constexpr bool HasX()
auto iterateCoords(Vector const &v)
Returns an object for ranged-for iteration on coordinates.
constexpr auto bindCoord(Vector const &v, CoordReader_t< Vector > helper)
Binds the specified constant vector to the coordinate reader.
enum geo::coordinates Coord_t
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Vector_t
Type for representation of momenta in 3D space.
Definition: geo_vectors.h:164
void test_middlePoint_iterators_documentation()
void add(Point const &p)
Accumulates a point.
constexpr unsigned int dimension()
Returns the dimension of the specified vector type.
unsigned int fillCoords(Coords &dest, Vector const &src)
Fills a coordinate array with the coordinates of a vector.
void test_middlePoint_initlist_documentation()
bool isfinite(Vector const &v)
Returns whether all components of the vector are finite.
bool empty() const
Returns whether the total weight is zero (usually means no points).
void test_middlePointAs_documentation()
constexpr std::array< std::size_t, geo::vect::dimension< Vector >)> indices()
Returns a sequence of indices valid for a vector of the specified type.
p
Definition: test.py:223
void test_MiddlePointAccumulator_documentation_middlePointAs()
void another()
void test_vectorProcessing()
auto Ycoord(Vector &v)
Returns an object to manage the coordinate Y of the vector v.
void test_MiddlePointAccumulator_sequenceConstructor()
constexpr bool HasT()
void test_fillCoords()
Vector transformCoords(Vector const &v, Pred &&pred)
Returns a new vector applying a predicate to each component.
void test_vector2Dconvert()
void test_MiddlePointAccumulator_generic()
Specializations of geo_vectors_utils.h for ROOT old vector types.
void test_transform()
auto Xcoord(Vector &v)
Returns an object to manage the coordinate X of the vector v.
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:184
constexpr bool HasZ()
auto Tcoord(Vector &v)
Returns an object to manage the coordinate T of the vector v.
constexpr bool HasY()
void test_MiddlePointAccumulator_documentation_class()
void test_MiddlePointAccumulator_documentation()
void test_CoordConstIterator()
void test_middlePoint()
list x
Definition: train.py:276
details::VectorScalar_t< Vector > coordinate_t
Type of coordinate of the specified vector type.
void test_XcoordManager_documentation()
void test_makeFromCoords_documentation()
recob::tracking::Vector_t Vector_t
geo::Point_t middlePoint(BeginIter begin, EndIter end)
Returns the middle of the specified points.
QTextStream & endl(QTextStream &s)