ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ParameterSetTests.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file ParameterSetTests.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2016-2018 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
9 #include <boost/test/unit_test.hpp>
10 
11 #include <cmath>
12 #include <memory>
13 #include <random>
14 
18 
19 using namespace Acts::detail;
20 
24 namespace Acts {
28 namespace Test {
30 namespace {
31 // tolerance used for floating point comparison in this translation unit
32 const double tol = 1e-6;
33 
34 double get_cyclic_value(double value, double min, double max) {
35  return value - (max - min) * std::floor((value - min) / (max - min));
36 }
37 
38 double get_cyclic_difference(double a, double b, double min, double max) {
39  const double period = max - min;
40  const double half_period = period / 2;
41  a = get_cyclic_value(a, min, max);
42  b = get_cyclic_value(b, min, max);
43  double raw_diff = a - b;
44  double diff =
45  (raw_diff > half_period)
46  ? raw_diff - period
47  : ((raw_diff < -half_period) ? period + raw_diff : raw_diff);
48  return diff;
49 }
50 
51 void check_residuals_for_bound_parameters() {
52  const double max = BoundParameterType<eBoundTheta>::max;
53  const double min = BoundParameterType<eBoundTheta>::min;
54  double theta_1 = 0.7 * M_PI;
55  double theta_2 = 0.4 * M_PI;
56  ActsVectorD<1> dTheta;
57  dTheta << (theta_1 - theta_2);
58 
59  // both parameters inside bounds, difference is positive
60  ParameterSet<eBoundTheta> bound1(std::nullopt, theta_1);
61  ParameterSet<eBoundTheta> bound2(std::nullopt, theta_2);
62  CHECK_CLOSE_REL(bound1.residual(bound2), dTheta, tol);
63 
64  // both parameters inside bound, difference negative
65  dTheta << (theta_2 - theta_1);
66  CHECK_CLOSE_REL(bound2.residual(bound1), dTheta, tol);
67 
68  // one parameter above upper bound, difference positive
69  theta_1 = max + 1;
70  bound1.setParameter<eBoundTheta>(theta_1);
71  dTheta << max - theta_2;
72  CHECK_CLOSE_REL(bound1.residual(bound2), dTheta, tol);
73 
74  // one parameter above upper bound, difference negative
75  dTheta << theta_2 - max;
76  CHECK_CLOSE_REL(bound2.residual(bound1), dTheta, tol);
77 
78  // one parameter below lower bound, difference positive
79  theta_1 = min - 1;
80  bound1.setParameter<eBoundTheta>(theta_1);
81  dTheta << theta_2 - min;
82  CHECK_CLOSE_REL(bound2.residual(bound1), dTheta, tol);
83 
84  // one parameter below lower bound, difference negative
85  dTheta << min - theta_2;
86  CHECK_CLOSE_REL(bound1.residual(bound2), dTheta, tol);
87 
88  // both parameters outside bounds, both below
89  theta_1 = min - 1;
90  theta_2 = min - 2;
91  bound1.setParameter<eBoundTheta>(theta_1);
92  bound2.setParameter<eBoundTheta>(theta_2);
93  CHECK_SMALL(bound1.residual(bound2), tol);
94 
95  // both parameters outside bounds, both above
96  theta_1 = max + 1;
97  theta_2 = max + 2;
98  bound1.setParameter<eBoundTheta>(theta_1);
99  bound2.setParameter<eBoundTheta>(theta_2);
100  CHECK_SMALL(bound1.residual(bound2), tol);
101 
102  // both parameters outside bounds, one above, one below
103  theta_1 = max + 1;
104  theta_2 = min - 2;
105  bound1.setParameter<eBoundTheta>(theta_1);
106  bound2.setParameter<eBoundTheta>(theta_2);
107  dTheta << max - min;
108  CHECK_CLOSE_REL(bound1.residual(bound2), dTheta, tol);
109  dTheta << min - max;
110  CHECK_CLOSE_REL(bound2.residual(bound1), dTheta, tol);
111 }
112 
113 void check_residuals_for_cyclic_parameters() {
114  const double max = BoundParameterType<eBoundPhi>::max;
115  const double min = BoundParameterType<eBoundPhi>::min;
116 
117  double phi_1 = 0.7 * M_PI;
118  double phi_2 = 0.4 * M_PI;
119  ActsVectorD<1> dPhi;
120  dPhi << (phi_1 - phi_2);
121 
122  ParameterSet<eBoundPhi> cyclic1(std::nullopt, phi_1);
123  ParameterSet<eBoundPhi> cyclic2(std::nullopt, phi_2);
124 
125  // no boundary crossing, difference is positive
126  CHECK_CLOSE_REL(cyclic1.residual(cyclic2), dPhi, tol);
127 
128  // no boundary crossing, difference is negative
129  CHECK_CLOSE_REL(cyclic2.residual(cyclic1), -dPhi, tol);
130 
131  // forward boundary crossing
132  phi_1 = -0.9 * M_PI;
133  cyclic1.setParameter<eBoundPhi>(phi_1);
134  dPhi << get_cyclic_difference(phi_1, phi_2, min, max);
135  CHECK_CLOSE_REL(cyclic1.residual(cyclic2), dPhi, tol);
136  CHECK_CLOSE_REL(cyclic2.residual(cyclic1), -dPhi, tol);
137 
138  // backward boundary crossing
139  phi_1 = 0.7 * M_PI;
140  phi_2 = -0.9 * M_PI;
141  cyclic1.setParameter<eBoundPhi>(phi_1);
142  cyclic2.setParameter<eBoundPhi>(phi_2);
143  dPhi << get_cyclic_difference(phi_1, phi_2, min, max);
144  CHECK_CLOSE_REL(cyclic1.residual(cyclic2), dPhi, tol);
145  CHECK_CLOSE_REL(cyclic2.residual(cyclic1), -dPhi, tol);
146 }
147 
148 void random_residual_tests() {
149  // random number generators
150  std::default_random_engine e;
151  std::uniform_real_distribution<float> uniform_dist(-1000, 300);
152 
153  const double theta_max = BoundParameterType<eBoundTheta>::max;
154  const double theta_min = BoundParameterType<eBoundTheta>::min;
155  const double phi_max = BoundParameterType<eBoundPhi>::max;
156  const double phi_min = BoundParameterType<eBoundPhi>::min;
157 
158  BoundVector parValues_1;
159  BoundVector parValues_2;
160  FullParameterSet parSet_1(std::nullopt, parValues_1);
161  FullParameterSet parSet_2(std::nullopt, parValues_2);
162  BoundVector residual;
163  const unsigned int toys = 1000;
164  for (unsigned int i = 0; i < toys; ++i) {
165  const double loc0_1 = uniform_dist(e);
166  const double loc1_1 = uniform_dist(e);
167  const double phi_1 = uniform_dist(e);
168  const double theta_1 = uniform_dist(e);
169  const double qop_1 = uniform_dist(e);
170  parValues_1 << loc0_1, loc1_1, phi_1, theta_1, qop_1, 0.;
171  parSet_1.setParameters(parValues_1);
172 
173  const double loc0_2 = uniform_dist(e);
174  const double loc1_2 = uniform_dist(e);
175  const double phi_2 = uniform_dist(e);
176  const double theta_2 = uniform_dist(e);
177  const double qop_2 = uniform_dist(e);
178  parValues_2 << loc0_2, loc1_2, phi_2, theta_2, qop_2, 0.;
179  parSet_2.setParameters(parValues_2);
180 
181  const double delta_loc0 = loc0_1 - loc0_2;
182  const double delta_loc1 = loc1_1 - loc1_2;
183  // for theta make sure that the difference calculation considers the
184  // restricted value range
185  const double delta_theta =
186  (theta_1 > theta_max ? theta_max
187  : (theta_1 < theta_min ? theta_min : theta_1)) -
188  (theta_2 > theta_max ? theta_max
189  : (theta_2 < theta_min ? theta_min : theta_2));
190  const double delta_qop = qop_1 - qop_2;
191  residual = parSet_1.residual(parSet_2);
192 
193  // local parameters are unbound -> check for usual difference
194  if (std::abs(residual(0) - delta_loc0) > tol) {
195  BOOST_CHECK(false);
196  break;
197  }
198  if (std::abs(residual(1) - delta_loc1) > tol) {
199  BOOST_CHECK(false);
200  break;
201  }
202  // phi is a cyclic parameter -> check that (unsigned) difference is not
203  // larger than half period
204  // check that corrected(corrected(phi_2) + residual) == corrected(phi_1)
205  if (std::abs(get_cyclic_value(
206  get_cyclic_value(phi_2, phi_min, phi_max) + residual(2),
207  phi_min, phi_max) -
208  get_cyclic_value(phi_1, phi_min, phi_max)) > tol or
209  std::abs(residual(2)) > (phi_max - phi_min) / 2) {
210  BOOST_CHECK(false);
211  break;
212  }
213  // theta is bound -> check that (unsigned) difference is not larger then
214  // allowed range, check corrected difference
215  if (std::abs(residual(3) - delta_theta) > tol or
216  std::abs(residual(3)) > (theta_max - theta_min)) {
217  BOOST_CHECK(false);
218  break;
219  }
220  // qop is unbound -> check usual difference
221  if (std::abs(residual(4) - delta_qop) > tol) {
222  BOOST_CHECK(false);
223  break;
224  }
225  }
226 }
227 } // namespace
229 
243 BOOST_AUTO_TEST_CASE(parset_consistency_tests) {
244  // check template parameter based information
245  BOOST_CHECK((ParameterSet<eBoundLoc0, eBoundLoc1>::size() == 2));
246 
247  // covariance matrix
248  ActsSymMatrixD<3> cov;
249  cov << 1, 0, 0, 0, 1.2, 0.2, 0, 0.2, 0.7;
250 
251  // parameter values
252  double loc0 = 0.5;
253  double loc1 = -0.2;
254  double phi = 0.3 * M_PI; // this should be within [-M_PI,M_PI) to avoid
255  // failed tests due to angle range corrections
256  ActsVectorD<3> parValues(loc0, loc1, phi);
257 
258  // parameter set with covariance matrix
259  ParameterSet<eBoundLoc0, eBoundLoc1, eBoundPhi> parSet_with_cov(cov, loc0,
260  loc1, phi);
261 
262  // check number and type of stored parameters
263  BOOST_CHECK(parSet_with_cov.size() == 3);
264  BOOST_CHECK(parSet_with_cov.contains<eBoundLoc0>());
265  BOOST_CHECK(parSet_with_cov.contains<eBoundLoc1>());
266  BOOST_CHECK(parSet_with_cov.contains<eBoundPhi>());
267  BOOST_CHECK(not parSet_with_cov.contains<eBoundTheta>());
268  BOOST_CHECK(not parSet_with_cov.contains<eBoundQOverP>());
269  BOOST_CHECK(not parSet_with_cov.contains<eBoundTime>());
270 
271  // check stored parameter values
272  BOOST_CHECK(parSet_with_cov.getParameter<eBoundLoc0>() == loc0);
273  BOOST_CHECK(parSet_with_cov.getParameter<eBoundLoc1>() == loc1);
274  BOOST_CHECK(parSet_with_cov.getParameter<eBoundPhi>() == phi);
275  BOOST_CHECK(parSet_with_cov.getParameters() == parValues);
276 
277  // check stored covariance
278  BOOST_CHECK(parSet_with_cov.getCovariance());
279  BOOST_CHECK(*parSet_with_cov.getCovariance() == cov);
280  BOOST_CHECK(parSet_with_cov.getUncertainty<eBoundLoc0>() == sqrt(cov(0, 0)));
281  BOOST_CHECK(parSet_with_cov.getUncertainty<eBoundLoc1>() == sqrt(cov(1, 1)));
282  BOOST_CHECK(parSet_with_cov.getUncertainty<eBoundPhi>() == sqrt(cov(2, 2)));
283 
284  // same parameter set without covariance matrix
286  std::nullopt, parValues);
287 
288  BOOST_CHECK(!parSet_without_cov.getCovariance());
289  BOOST_CHECK(parSet_without_cov.getUncertainty<eBoundLoc0>() < 0);
290  BOOST_CHECK(parSet_without_cov.getUncertainty<eBoundLoc1>() < 0);
291  BOOST_CHECK(parSet_without_cov.getUncertainty<eBoundPhi>() < 0);
292  BOOST_CHECK(parSet_without_cov.getParameters() ==
293  parSet_with_cov.getParameters());
294 
295  // set new covariance matrix
296  parSet_without_cov.setCovariance(cov);
297 
298  BOOST_CHECK(parSet_without_cov.getCovariance());
299  BOOST_CHECK(*parSet_without_cov.getCovariance() == cov);
300 
301  // set new parameter values
302  double newLoc0 = 0.1;
303  double newLoc1 = 0.6;
304  double newPhi = -0.15 * M_PI;
305  parValues << newLoc0, newLoc1, newPhi;
306  parSet_with_cov.setParameter<eBoundLoc0>(newLoc0);
307  parSet_with_cov.setParameter<eBoundLoc1>(newLoc1);
308  parSet_with_cov.setParameter<eBoundPhi>(newPhi);
309 
310  BOOST_CHECK(parSet_with_cov.getParameter<eBoundLoc0>() == newLoc0);
311  BOOST_CHECK(parSet_with_cov.getParameter<eBoundLoc1>() == newLoc1);
312  BOOST_CHECK(parSet_with_cov.getParameter<eBoundPhi>() == newPhi);
313  BOOST_CHECK(parSet_with_cov.getParameters() == parValues);
314 }
315 
324 BOOST_AUTO_TEST_CASE(parset_copy_assignment_tests) {
325  // covariance matrix
326  ActsSymMatrixD<3> cov;
327  cov << 1, 0, 0, 0, 1.2, 0.2, 0, 0.2, 0.7;
328 
329  // parameter values
330  double loc0 = 0.5;
331  double loc1 = -0.2;
332  double phi = 0.3 * M_PI; // this should be within [-M_PI,M_PI) to avoid
333  // failed tests due to angle range corrections
334  ActsVectorD<3> first_parValues(loc0, loc1, phi);
335 
336  // parameter set with covariance matrix
337  ParameterSet<eBoundLoc0, eBoundLoc1, eBoundPhi> first(cov, loc0, loc1, phi);
338 
339  // check copy constructor
341  BOOST_CHECK(first == copy);
342 
343  // check move constructor
345  BOOST_CHECK(first == moved);
346 
347  // check assignment operator
349  BOOST_CHECK(assigned == moved);
350 
351  ParameterSet<eBoundLoc0, eBoundLoc1, eBoundPhi> other(std::nullopt, 0, 1.7,
352  -0.15);
353  BOOST_CHECK(assigned != other);
354  assigned = other;
355  BOOST_CHECK(assigned == other);
356 
357  // check move assignment
358  BOOST_CHECK(first != assigned);
360  BOOST_CHECK(first == assigned);
361 
362  // check swap method
363  ParameterSet<eBoundLoc0, eBoundLoc1, eBoundPhi> lhs(cov, loc0, loc1, phi);
364  ParameterSet<eBoundLoc0, eBoundLoc1, eBoundPhi> rhs(std::nullopt, 2 * loc0,
365  2 * loc1, 2 * phi);
368 
369  BOOST_CHECK(lhs != rhs && lhs == lhs_copy && rhs == rhs_copy);
370  using std::swap;
371  swap(lhs, rhs);
372  BOOST_CHECK(lhs != rhs && rhs == lhs_copy && lhs == rhs_copy);
373 }
374 
380 BOOST_AUTO_TEST_CASE(parset_comparison_tests) {
381  // covariance matrix
382  ActsSymMatrixD<3> cov;
383  cov << 1, 0, 0, 0, 1.2, 0.2, 0, 0.2, 0.7;
384 
385  // parameter values
386  double loc0 = 0.5;
387  double loc1 = -0.2;
388  double phi = 0.3 * M_PI; // this should be within [-M_PI,M_PI) to avoid
389  // failed tests due to angle range corrections
390 
391  // parameter set with covariance matrix
392  ParameterSet<eBoundLoc0, eBoundLoc1, eBoundPhi> first(cov, loc0, loc1, phi);
394  2 * loc1, 2 * phi);
395 
396  // check self comparison
397  BOOST_CHECK(first == first);
398  BOOST_CHECK(not(first != first));
399 
400  // check mutual exclusivity
401  BOOST_CHECK(first != second);
402  BOOST_CHECK(not(first == second));
403  first = second;
404  BOOST_CHECK(first == second);
405 
406  // check that comparison fails for unequal parameter values
407  second.setParameter<eBoundLoc0>(3 * loc0);
408  BOOST_CHECK(first != second);
409  first = second;
410  BOOST_CHECK(first == second);
411 
412  second.setParameter<eBoundLoc1>(3 * loc1);
413  BOOST_CHECK(first != second);
414  first = second;
415  BOOST_CHECK(first == second);
416 
417  second.setParameter<eBoundPhi>(3 * phi);
418  BOOST_CHECK(first != second);
419  first = second;
420  BOOST_CHECK(first == second);
421 
422  // check that comparison fails for unequal covariance matrices
423  second.setCovariance(cov);
424  BOOST_CHECK(first != second);
425  first = second;
426  BOOST_CHECK(first == second);
427 
428  cov(0, 0) = 2 * cov(0, 0);
429  second.setCovariance(cov);
430  BOOST_CHECK(first != second);
431  first = second;
432  BOOST_CHECK(first == second);
433 }
434 
444 BOOST_AUTO_TEST_CASE(parset_projection_tests) {
446  phi_proj << 0, 0, 1, 0, 0, 0;
447 
449  loc0_qop_proj << 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0;
450 
451  ActsMatrixD<2, eBoundParametersSize> loc1_theta_proj;
452  loc1_theta_proj << 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0;
453 
454  ActsMatrixD<3, eBoundParametersSize> loc0_loc1_phi_proj;
455  loc0_loc1_phi_proj << 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0;
456 
457  ActsMatrixD<4, eBoundParametersSize> loc0_phi_theta_qop_proj;
458  loc0_phi_theta_qop_proj << 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0,
459  0, 0, 0, 0, 0, 1, 0;
460 
461  ActsMatrixD<5, eBoundParametersSize> loc0_loc1_phi_theta_qop_proj;
462  loc0_loc1_phi_theta_qop_proj << 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1,
463  0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0;
464 
466  loc0_loc1_phi_theta_qop_t_proj;
467  loc0_loc1_phi_theta_qop_t_proj << 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1,
468  0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1;
469 
470  BOOST_CHECK((ParameterSet<eBoundPhi>::projector() == phi_proj));
471  BOOST_CHECK(
473  BOOST_CHECK(
474  (ParameterSet<eBoundLoc1, eBoundTheta>::projector() == loc1_theta_proj));
476  loc0_loc1_phi_proj));
477  BOOST_CHECK(
479  eBoundQOverP>::projector() == loc0_phi_theta_qop_proj));
481  eBoundQOverP>::projector() ==
482  loc0_loc1_phi_theta_qop_proj));
484  eBoundQOverP, eT>::projector() ==
485  loc0_loc1_phi_theta_qop_t_proj));
486 }
487 
499 BOOST_AUTO_TEST_CASE(parset_residual_tests) {
500  // check unbound parameter type
501  const double large_number = 12443534120;
502  const double small_number = -924342675;
503  const double normal_number = 1.234;
505  std::nullopt, small_number, large_number, normal_number);
506  BOOST_CHECK(unbound.getParameter<eBoundLoc0>() == small_number);
507  BOOST_CHECK(unbound.getParameter<eBoundLoc1>() == large_number);
508  BOOST_CHECK(unbound.getParameter<eBoundQOverP>() == normal_number);
509 
510  // check bound parameter type
511  ParameterSet<eBoundTheta> bound(std::nullopt, small_number);
512  BOOST_CHECK((bound.getParameter<eBoundTheta>() ==
514  bound.setParameter<eBoundTheta>(large_number);
515  BOOST_CHECK((bound.getParameter<eBoundTheta>() ==
517  bound.setParameter<eBoundTheta>(normal_number);
518  BOOST_CHECK((bound.getParameter<eBoundTheta>() == normal_number));
519 
520  // check cyclic parameter type
521  ParameterSet<eBoundPhi> cyclic(std::nullopt, small_number);
522  // calculate expected results
523  const double min = BoundParameterType<eBoundPhi>::min;
524  const double max = BoundParameterType<eBoundPhi>::max;
525  // check that difference between original phi and stored phi is a multiple
526  // of the cyclic period
527  double multiple =
528  (cyclic.getParameter<eBoundPhi>() - small_number) / (max - min);
529  BOOST_CHECK(cyclic.getParameter<eBoundPhi>() >= min);
530  BOOST_CHECK(cyclic.getParameter<eBoundPhi>() < max);
531  BOOST_CHECK(std::abs(multiple - std::floor(multiple + 0.5)) < tol);
532 
533  cyclic.setParameter<eBoundPhi>(large_number);
534  multiple = (cyclic.getParameter<eBoundPhi>() - large_number) / (max - min);
535  BOOST_CHECK(cyclic.getParameter<eBoundPhi>() >= min);
536  BOOST_CHECK(cyclic.getParameter<eBoundPhi>() < max);
537  BOOST_CHECK(std::abs(multiple - std::floor(multiple + 0.5)) < tol);
538 
539  cyclic.setParameter<eBoundPhi>(normal_number);
540  multiple = (cyclic.getParameter<eBoundPhi>() - normal_number) / (max - min);
541  BOOST_CHECK(cyclic.getParameter<eBoundPhi>() >= min);
542  BOOST_CHECK(cyclic.getParameter<eBoundPhi>() < max);
543  BOOST_CHECK(std::abs(multiple - std::floor(multiple + 0.5)) < tol);
544 
545  // check residual calculation
546 
547  // input numbers
548  const double first_loc0 = 0.3;
549  const double first_phi = 0.9 * M_PI;
550  const double first_theta = 0.7 * M_PI;
551 
552  const double second_loc0 = 2.7;
553  const double second_phi = -0.9 * M_PI;
554  const double second_theta = 0.35 * M_PI;
555 
556  // expected results for residual second wrt first
557  const double delta_loc0 = second_loc0 - first_loc0;
558  const double delta_phi =
559  get_cyclic_difference(second_phi, first_phi, min, max);
560  const double delta_theta = second_theta - first_theta;
561  ActsVectorD<3> residuals(delta_loc0, delta_phi, delta_theta);
562 
564  std::nullopt, first_loc0, first_phi, first_theta);
566  std::nullopt, second_loc0, second_phi, second_theta);
567  CHECK_CLOSE_REL(residuals, second.residual(first), 1e-6);
568 
569  // some more checks for bound variables
570  check_residuals_for_bound_parameters();
571 
572  // some more checks for cyclic variables
573  check_residuals_for_cyclic_parameters();
574 
575  // inspecific residual tests with random numbers
576  random_residual_tests();
577 }
578 
579 template <ParID_t... params>
580 using ParSet = ParameterSet<params...>;
581 
588 BOOST_AUTO_TEST_CASE(parset_parID_mapping) {
589  // check logic for type-based access
591  eT>::getIndex<eBoundLoc0>() == 0));
593  eT>::getIndex<eBoundLoc1>() == 1));
595  eT>::getIndex<eBoundPhi>() == 2));
597  eT>::getIndex<eBoundQOverP>() == 3));
599  eT>::getIndex<eT>() == 4));
600 
601  // check logic for index-based access
603  eT>::getParID<0>() == eBoundLoc0));
605  eT>::getParID<1>() == eBoundLoc1));
607  eT>::getParID<2>() == eBoundPhi));
609  eT>::getParID<3>() == eBoundQOverP));
611  eT>::getParID<4>() == eT));
612 
613  // check consistency
614  using FullSet = FullParameterSet;
615  BOOST_CHECK((FullSet::getIndex<FullSet::getParID<0>()>() == 0));
616  BOOST_CHECK((FullSet::getIndex<FullSet::getParID<1>()>() == 1));
617  BOOST_CHECK((FullSet::getIndex<FullSet::getParID<2>()>() == 2));
618  BOOST_CHECK((FullSet::getIndex<FullSet::getParID<3>()>() == 3));
619  BOOST_CHECK((FullSet::getIndex<FullSet::getParID<4>()>() == 4));
620  BOOST_CHECK((FullSet::getIndex<FullSet::getParID<5>()>() == 5));
621 
622  BOOST_CHECK(
623  (FullSet::getParID<FullSet::getIndex<eBoundLoc0>()>() == eBoundLoc0));
624  BOOST_CHECK(
625  (FullSet::getParID<FullSet::getIndex<eBoundLoc1>()>() == eBoundLoc1));
626  BOOST_CHECK(
627  (FullSet::getParID<FullSet::getIndex<eBoundPhi>()>() == eBoundPhi));
628  BOOST_CHECK(
629  (FullSet::getParID<FullSet::getIndex<eBoundTheta>()>() == eBoundTheta));
630  BOOST_CHECK(
631  (FullSet::getParID<FullSet::getIndex<eBoundQOverP>()>() == eBoundQOverP));
632  BOOST_CHECK((FullSet::getParID<FullSet::getIndex<eT>()>() == eT));
633 
634  // consistency of types
635  BOOST_CHECK((std::is_same<std::remove_cv<decltype(
637  decltype(eBoundLoc0)>::value));
638  BOOST_CHECK((std::is_same<decltype(FullSet::getParID<0>()),
639  decltype(eBoundLoc0)>::value));
640 }
641 } // namespace Test
642 } // namespace Acts