readout_types_fhicl_test.cc
Go to the documentation of this file.
1 /**
2  * @file readout_types_fhicl_test.cc
3  * @brief Test of `larcoreobj/SimpleTypesAndConstants/readout_types_fhicl.h`.
4  * @author Gianluca Petrillo (petrillo@slac.stanford.edu)
5  * @date November 26, 2019
6  */
7 
8 // Boost libraries
9 #define BOOST_TEST_MODULE ( readout_types_fhicl_test )
10 #include "boost/test/unit_test.hpp"
11 
12 // LArSoft libraries
15 
16 // support libraries
17 #include "fhiclcpp/types/Table.h"
18 #include "fhiclcpp/ParameterSet.h"
19 
20 
21 // C/C++ standard libraries
22 #include <iostream>
23 #include <string>
24 #include <array>
25 #include <type_traits> // std::is_same_v<>
26 
27 
28 //------------------------------------------------------------------------------
29 template <typename Config>
32  pset = fhicl::ParameterSet::make(configStr);
33  fhicl::Table<Config> validatedConfig { fhicl::Name("validatedConfig") };
34 
35  std::cout << std::string(80, '-') << std::endl;
36  std::cout << "===> FHiCL configuration:";
37  if (configStr.empty()) std::cout << " <empty>";
38  else std::cout << "\n" << configStr;
39  std::cout << std::endl;
40  validatedConfig.print_allowed_configuration
41  (std::cout << "===> Expected configuration: ");
42  std::cout << std::endl;
43 
44  validatedConfig.validate_ParameterSet(pset);
45  return validatedConfig;
46 } // validateConfig()
47 
48 
49 // --- BEGIN -- Cryostat ID tests ----------------------------------------------
50 
52 
53  using ID_t = readout::CryostatID;
54  struct Config { readout::fhicl::CryostatID Cryo { fhicl::Name("Cryo") }; };
55 
56  std::string const configStr { "Cryo: { C:2 }" };
57  ID_t const expectedID { 2U };
58 
59  auto validatedConfig = validateConfig<Config>(configStr)();
60 
61  auto const id = geo::fhicl::readID(validatedConfig.Cryo);
62  static_assert(std::is_same_v<decltype(id), ID_t const>);
63  BOOST_TEST(id.isValid == expectedID.isValid);
64  if (expectedID.isValid) {
65  BOOST_TEST(validatedConfig.Cryo().ID() == expectedID);
66  BOOST_TEST(id == expectedID);
67  }
68 } // test_CryostatID_normal()
69 
70 
72 
73  using ID_t = readout::CryostatID;
74  struct Config { readout::fhicl::CryostatID Cryo { fhicl::Name("Cryo") }; };
75 
76  std::string const configStr { "Cryo: { isValid:false }" };
77  ID_t const expectedID {};
78 
79  auto validatedConfig = validateConfig<Config>(configStr)();
80 
81  auto const id = geo::fhicl::readID(validatedConfig.Cryo);
82  static_assert(std::is_same_v<decltype(id), ID_t const>);
83  BOOST_TEST(id.isValid == expectedID.isValid);
84  if (expectedID.isValid) {
85  BOOST_TEST(validatedConfig.Cryo().ID() == expectedID);
86  BOOST_TEST(id == expectedID);
87  }
88 } // test_CryostatID_invalid()
89 
90 
92 
93  using ID_t = readout::CryostatID;
94  struct Config
95  { readout::fhicl::OptionalCryostatID Cryo { fhicl::Name("Cryo") }; };
96 
97  std::string const configStr { "Cryo: { C:1 }" };
98  auto const expectedID = std::make_optional<ID_t>(1U);
99 
100  auto validatedConfig = validateConfig<Config>(configStr)();
101 
102  std::optional<ID_t> const id = readOptionalID(validatedConfig.Cryo);
103  BOOST_TEST(id.has_value() == expectedID.has_value());
104  if (expectedID.has_value()) {
105  BOOST_TEST(id->isValid == expectedID->isValid);
106  if (expectedID->isValid) BOOST_TEST(id.value() == expectedID.value());
107  }
108 
109 } // test_OptionalCryostatID_present()
110 
111 
113 
114  using ID_t = readout::CryostatID;
115  struct Config
116  { readout::fhicl::OptionalCryostatID Cryo { fhicl::Name("Cryo") }; };
117 
118  std::string const configStr { "" };
119 
120  std::optional<ID_t> const expectedID;
121 
122  auto validatedConfig = validateConfig<Config>(configStr)();
123 
124  std::optional<ID_t> const id
125  = geo::fhicl::readOptionalID(validatedConfig.Cryo);
126  BOOST_TEST(id.has_value() == expectedID.has_value());
127  if (expectedID.has_value()) {
128  BOOST_TEST(id->isValid == expectedID->isValid);
129  if (expectedID->isValid) BOOST_TEST(id.value() == expectedID.value());
130  }
131 
132 } // test_OptionalCryostatID_omitted()
133 
134 
136 
137  using ID_t = readout::CryostatID;
138  struct Config
139  { readout::fhicl::CryostatIDsequence Cryos { fhicl::Name("Cryos") }; };
140 
141  std::string const configStr { "Cryos: [ { C:0 }, { C:2 } ]" };
142  // BUG the double brace syntax is required to work around clang bug 21629
143 // std::array<ID_t, 2U> const expectedIDs { ID_t{ 0U }, ID_t{ 2U } };
144  std::array<ID_t, 2U> const expectedIDs {{ ID_t{ 0U }, ID_t{ 2U } }};
145 
146  auto validatedConfig = validateConfig<Config>(configStr)();
147 
148  auto ids = geo::fhicl::readIDsequence(validatedConfig.Cryos);
149  static_assert(std::is_same_v<decltype(ids), std::vector<ID_t>>);
150 
151  BOOST_TEST(ids.size() == expectedIDs.size());
152  auto const n = std::min(ids.size(), expectedIDs.size());
153  for (std::size_t i = 0; i < n; ++i) {
154  auto const& id = ids[i];
155  ID_t const& expectedID = expectedIDs[i];
156 
157  BOOST_TEST_CONTEXT("Item [" << i << "]") {
158  BOOST_TEST(id.isValid == expectedID.isValid);
159  if (expectedID.isValid) BOOST_TEST(id == expectedID);
160  } // BOOST_TEST_CONTEXT
161  } // for
162 
163 } // test_CryostatIDsequence_normal()
164 
165 
167 
168  using ID_t = readout::CryostatID;
169  struct Config
170  { readout::fhicl::CryostatIDsequence Cryos { fhicl::Name("Cryos") }; };
171 
172  std::string const configStr { "Cryos: []" };
173 
174  auto validatedConfig = validateConfig<Config>(configStr)();
175 
176  auto ids = geo::fhicl::readIDsequence(validatedConfig.Cryos);
177  static_assert(std::is_same_v<decltype(ids), std::vector<ID_t>>);
178 
179  BOOST_TEST(ids.size() == 0U);
180 
181 } // test_CryostatIDsequence_empty()
182 
183 
185 
186  using ID_t = readout::CryostatID;
187  struct Config
189 
190  std::string const configStr { "Cryos: [ { C:0 }, { C:2 } ]" };
191  std::optional<std::vector<ID_t>> const expectedIDs
192  (std::in_place, { ID_t{ 0U }, ID_t{ 2U } });
193 
194  auto validatedConfig = validateConfig<Config>(configStr)();
195 
196  auto ids = geo::fhicl::readOptionalIDsequence(validatedConfig.Cryos);
197  static_assert
198  (std::is_same_v<decltype(ids), std::optional<std::vector<ID_t>>>);
199 
200  BOOST_TEST(ids.has_value() == expectedIDs.has_value());
201  if (expectedIDs.has_value()) {
202  BOOST_TEST(ids->size() == expectedIDs->size());
203  auto const n = std::min(ids->size(), expectedIDs->size());
204  for (std::size_t i = 0; i < n; ++i) {
205  auto const& id = ids.value()[i];
206  ID_t const& expectedID = expectedIDs.value()[i];
207 
208  BOOST_TEST_CONTEXT("Item [" << i << "]") {
209  BOOST_TEST(id.isValid == expectedID.isValid);
210  if (expectedID.isValid) BOOST_TEST(id == expectedID);
211  } // BOOST_TEST_CONTEXT
212  } // for
213  }
214 
215 } // test_OptionalCryostatIDsequence_normal()
216 
217 
219 
220  using ID_t = readout::CryostatID;
221  struct Config
223 
224  std::string const configStr { "Cryos: []" };
225  std::optional<std::vector<ID_t>> const expectedIDs(std::in_place);
226 
227  auto validatedConfig = validateConfig<Config>(configStr)();
228 
229  auto ids = geo::fhicl::readOptionalIDsequence(validatedConfig.Cryos);
230  static_assert
231  (std::is_same_v<decltype(ids), std::optional<std::vector<ID_t>>>);
232 
233  BOOST_TEST(ids.has_value() == expectedIDs.has_value());
234  if (expectedIDs.has_value()) {
235  BOOST_TEST(ids->size() == expectedIDs->size());
236  auto const n = std::min(ids->size(), expectedIDs->size());
237  for (std::size_t i = 0; i < n; ++i) {
238  auto const& id = ids.value()[i];
239  ID_t const& expectedID = expectedIDs.value()[i];
240 
241  BOOST_TEST_CONTEXT("Item [" << i << "]") {
242  BOOST_TEST(id.isValid == expectedID.isValid);
243  if (expectedID.isValid) BOOST_TEST(id == expectedID);
244  } // BOOST_TEST_CONTEXT
245  } // for
246  }
247 
248 } // test_OptionalCryostatIDsequence_empty()
249 
250 
252 
253  using ID_t = readout::CryostatID;
254  struct Config
256 
257  std::string const configStr { "" };
258  std::optional<std::vector<ID_t>> const expectedIDs(std::nullopt);
259 
260  auto validatedConfig = validateConfig<Config>(configStr)();
261 
262  auto ids = geo::fhicl::readOptionalIDsequence(validatedConfig.Cryos);
263  static_assert
264  (std::is_same_v<decltype(ids), std::optional<std::vector<ID_t>>>);
265 
266  BOOST_TEST(ids.has_value() == expectedIDs.has_value());
267  if (expectedIDs.has_value()) {
268  BOOST_TEST(ids->size() == expectedIDs->size());
269  auto const n = std::min(ids->size(), expectedIDs->size());
270  for (std::size_t i = 0; i < n; ++i) {
271  auto const& id = ids.value()[i];
272  ID_t const& expectedID = expectedIDs.value()[i];
273 
274  BOOST_TEST_CONTEXT("Item [" << i << "]") {
275  BOOST_TEST(id.isValid == expectedID.isValid);
276  if (expectedID.isValid) BOOST_TEST(id == expectedID);
277  } // BOOST_TEST_CONTEXT
278  } // for
279  }
280 
281 } // test_OptionalCryostatIDsequence_omitted()
282 
283 
284 // --- END -- Cryostat ID tests ------------------------------------------------
285 
286 
287 
288 // --- BEGIN -- TPC set ID tests -----------------------------------------------
290 
291  using ID_t = readout::TPCsetID;
292  struct Config { readout::fhicl::TPCsetID TPCset { fhicl::Name("TPCset") }; };
293 
294  std::string const configStr { "TPCset: { C:2 S:3 }" };
295  ID_t const expectedID { 2U, 3U };
296 
297  auto validatedConfig = validateConfig<Config>(configStr)();
298 
299  auto const id = geo::fhicl::readID(validatedConfig.TPCset);
300  static_assert(std::is_same_v<decltype(id), ID_t const>);
301  BOOST_TEST(id.isValid == expectedID.isValid);
302  if (expectedID.isValid) {
303  BOOST_TEST(validatedConfig.TPCset().ID() == expectedID);
304  BOOST_TEST(id == expectedID);
305  }
306 } // test_TPCsetID_normal()
307 
308 
310 
311  using ID_t = readout::TPCsetID;
312  struct Config { readout::fhicl::TPCsetID TPCset { fhicl::Name("TPCset") }; };
313 
314  std::string const configStr { "TPCset: { isValid:false }" };
315  ID_t const expectedID {};
316 
317  auto validatedConfig = validateConfig<Config>(configStr)();
318 
319  auto const id = geo::fhicl::readID(validatedConfig.TPCset);
320  static_assert(std::is_same_v<decltype(id), ID_t const>);
321  BOOST_TEST(id.isValid == expectedID.isValid);
322  if (expectedID.isValid) {
323  BOOST_TEST(validatedConfig.TPCset().ID() == expectedID);
324  BOOST_TEST(id == expectedID);
325  }
326 } // test_TPCsetID_invalid()
327 
328 
330 
331  using ID_t = readout::TPCsetID;
332  struct Config
334 
335  std::string const configStr { "TPCset: { C:1 S:2 }" };
336  std::optional<ID_t> const expectedID { std::in_place, 1U, 2U };
337 
338  auto validatedConfig = validateConfig<Config>(configStr)();
339 
340  std::optional<ID_t> const id = readOptionalID(validatedConfig.TPC);
341  BOOST_TEST(id.has_value() == expectedID.has_value());
342  if (expectedID.has_value()) {
343  BOOST_TEST(id->isValid == expectedID->isValid);
344  if (expectedID->isValid) BOOST_TEST(id.value() == expectedID.value());
345  }
346 
347 } // test_OptionalTPCsetID_present()
348 
349 
351 
352  using ID_t = readout::TPCsetID;
353  struct Config
354  { readout::fhicl::OptionalTPCsetID TPCset { fhicl::Name("TPCset") }; };
355 
356  std::string const configStr { "" };
357 
358  std::optional<ID_t> const expectedID { std::nullopt };
359 
360  auto validatedConfig = validateConfig<Config>(configStr)();
361 
362  std::optional<ID_t> const id
363  = geo::fhicl::readOptionalID(validatedConfig.TPCset);
364  BOOST_TEST(id.has_value() == expectedID.has_value());
365  if (expectedID.has_value()) {
366  BOOST_TEST(id->isValid == expectedID->isValid);
367  if (expectedID->isValid) BOOST_TEST(id.value() == expectedID.value());
368  }
369 
370 } // test_OptionalTPCsetID_omitted()
371 
372 
374 
375  using ID_t = readout::TPCsetID;
376  struct Config
377  { readout::fhicl::TPCsetIDsequence TPCsets { fhicl::Name("TPCsets") }; };
378 
379  std::string const configStr { "TPCsets: [ { C:0 S:1 }, { C:2 S:3 } ]" };
380  // BUG the double brace syntax is required to work around clang bug 21629
381 // std::array<ID_t, 2U> const expectedIDs { ID_t{ 0U, 1U }, ID_t{ 2U, 3U } };
382  std::array<ID_t, 2U> const expectedIDs {{ ID_t{ 0U, 1U }, ID_t{ 2U, 3U } }};
383 
384  auto validatedConfig = validateConfig<Config>(configStr)();
385 
386  auto ids = geo::fhicl::readIDsequence(validatedConfig.TPCsets);
387  static_assert(std::is_same_v<decltype(ids), std::vector<ID_t>>);
388 
389  BOOST_TEST(ids.size() == expectedIDs.size());
390  auto const n = std::min(ids.size(), expectedIDs.size());
391  for (std::size_t i = 0; i < n; ++i) {
392  auto const& id = ids[i];
393  ID_t const& expectedID = expectedIDs[i];
394 
395  BOOST_TEST_CONTEXT("Item [" << i << "]") {
396  BOOST_TEST(id.isValid == expectedID.isValid);
397  if (expectedID.isValid) BOOST_TEST(id == expectedID);
398  } // BOOST_TEST_CONTEXT
399  } // for
400 
401 } // test_TPCsetIDsequence_normal()
402 
403 
405 
406  using ID_t = readout::TPCsetID;
407  struct Config
408  { readout::fhicl::TPCsetIDsequence TPCsets { fhicl::Name("TPCsets") }; };
409 
410  std::string const configStr { "TPCsets: []" };
411 
412  auto validatedConfig = validateConfig<Config>(configStr)();
413 
414  auto ids = geo::fhicl::readIDsequence(validatedConfig.TPCsets);
415  static_assert(std::is_same_v<decltype(ids), std::vector<ID_t>>);
416 
417  BOOST_TEST(ids.size() == 0U);
418 
419 } // test_TPCsetIDsequence_empty()
420 
421 
423 
424  using ID_t = readout::TPCsetID;
425  struct Config {
427  };
428 
429  std::string const configStr { "TPCsets: [ { C:0 S:1 }, { C:2 S:3 } ]" };
430  std::optional<std::vector<ID_t>> const expectedIDs
431  (std::in_place, { ID_t{ 0U, 1U }, ID_t{ 2U, 3U } });
432 
433  auto validatedConfig = validateConfig<Config>(configStr)();
434 
435  auto ids = geo::fhicl::readOptionalIDsequence(validatedConfig.TPCsets);
436  static_assert
437  (std::is_same_v<decltype(ids), std::optional<std::vector<ID_t>>>);
438 
439  BOOST_TEST(ids.has_value() == expectedIDs.has_value());
440  if (expectedIDs.has_value()) {
441  BOOST_TEST(ids->size() == expectedIDs->size());
442  auto const n = std::min(ids->size(), expectedIDs->size());
443  for (std::size_t i = 0; i < n; ++i) {
444  auto const& id = ids.value()[i];
445  ID_t const& expectedID = expectedIDs.value()[i];
446 
447  BOOST_TEST_CONTEXT("Item [" << i << "]") {
448  BOOST_TEST(id.isValid == expectedID.isValid);
449  if (expectedID.isValid) BOOST_TEST(id == expectedID);
450  } // BOOST_TEST_CONTEXT
451  } // for
452  }
453 
454 } // test_OptionalTPCsetIDsequence_normal()
455 
456 
458 
459  using ID_t = readout::TPCsetID;
460  struct Config {
462  };
463 
464  std::string const configStr { "TPCsets: []" };
465  std::optional<std::vector<ID_t>> const expectedIDs(std::in_place);
466 
467  auto validatedConfig = validateConfig<Config>(configStr)();
468 
469  auto ids = geo::fhicl::readOptionalIDsequence(validatedConfig.TPCsets);
470  static_assert
471  (std::is_same_v<decltype(ids), std::optional<std::vector<ID_t>>>);
472 
473  BOOST_TEST(ids.has_value() == expectedIDs.has_value());
474  if (expectedIDs.has_value()) {
475  BOOST_TEST(ids->size() == expectedIDs->size());
476  auto const n = std::min(ids->size(), expectedIDs->size());
477  for (std::size_t i = 0; i < n; ++i) {
478  auto const& id = ids.value()[i];
479  ID_t const& expectedID = expectedIDs.value()[i];
480 
481  BOOST_TEST_CONTEXT("Item [" << i << "]") {
482  BOOST_TEST(id.isValid == expectedID.isValid);
483  if (expectedID.isValid) BOOST_TEST(id == expectedID);
484  } // BOOST_TEST_CONTEXT
485  } // for
486  }
487 
488 } // test_OptionalTPCsetIDsequence_empty()
489 
490 
492 
493  using ID_t = readout::TPCsetID;
494  struct Config {
496  };
497 
498  std::string const configStr { "" };
499  std::optional<std::vector<ID_t>> const expectedIDs(std::nullopt);
500 
501  auto validatedConfig = validateConfig<Config>(configStr)();
502 
503  auto ids = geo::fhicl::readOptionalIDsequence(validatedConfig.TPCsets);
504  static_assert
505  (std::is_same_v<decltype(ids), std::optional<std::vector<ID_t>>>);
506 
507  BOOST_TEST(ids.has_value() == expectedIDs.has_value());
508  if (expectedIDs.has_value()) {
509  BOOST_TEST(ids->size() == expectedIDs->size());
510  auto const n = std::min(ids->size(), expectedIDs->size());
511  for (std::size_t i = 0; i < n; ++i) {
512  auto const& id = ids.value()[i];
513  ID_t const& expectedID = expectedIDs.value()[i];
514 
515  BOOST_TEST_CONTEXT("Item [" << i << "]") {
516  BOOST_TEST(id.isValid == expectedID.isValid);
517  if (expectedID.isValid) BOOST_TEST(id == expectedID);
518  } // BOOST_TEST_CONTEXT
519  } // for
520  }
521 
522 } // test_OptionalTPCsetIDsequence_omitted()
523 
524 // --- END -- TPC set ID tests -------------------------------------------------
525 
526 
527 
528 // --- BEGIN -- Readout plane ID tests -----------------------------------------
530 
531  using ID_t = readout::ROPID;
532  struct Config { readout::fhicl::ROPID ROP { fhicl::Name("ROP") }; };
533 
534  std::string const configStr { "ROP: { C:2 S:3 R:1 }" };
535  ID_t const expectedID { 2U, 3U, 1U };
536 
537  auto validatedConfig = validateConfig<Config>(configStr)();
538 
539  auto const id = geo::fhicl::readID(validatedConfig.ROP);
540  static_assert(std::is_same_v<decltype(id), ID_t const>);
541  BOOST_TEST(id.isValid == expectedID.isValid);
542  if (expectedID.isValid) {
543  BOOST_TEST(validatedConfig.ROP().ID() == expectedID);
544  BOOST_TEST(id == expectedID);
545  }
546 } // test_ROPID_normal()
547 
548 
550 
551  using ID_t = readout::ROPID;
552  struct Config { readout::fhicl::ROPID ROP { fhicl::Name("ROP") }; };
553 
554  std::string const configStr { "ROP: { isValid:false }" };
555  ID_t const expectedID {};
556 
557  auto validatedConfig = validateConfig<Config>(configStr)();
558 
559  auto const id = geo::fhicl::readID(validatedConfig.ROP);
560  static_assert(std::is_same_v<decltype(id), ID_t const>);
561  BOOST_TEST(id.isValid == expectedID.isValid);
562  if (expectedID.isValid) {
563  BOOST_TEST(validatedConfig.ROP().ID() == expectedID);
564  BOOST_TEST(id == expectedID);
565  }
566 } // test_ROPID_invalid()
567 
568 
570 
571  using ID_t = readout::ROPID;
572  struct Config { readout::fhicl::OptionalROPID ROP { fhicl::Name("ROP") }; };
573 
574  std::string const configStr { "ROP: { C:1 S:2 R:1 }" };
575  std::optional<ID_t> const expectedID { std::in_place, 1U, 2U, 1U };
576 
577  auto validatedConfig = validateConfig<Config>(configStr)();
578 
579  std::optional<ID_t> const id = readOptionalID(validatedConfig.ROP);
580  BOOST_TEST(id.has_value() == expectedID.has_value());
581  if (expectedID.has_value()) {
582  BOOST_TEST(id->isValid == expectedID->isValid);
583  if (expectedID->isValid) BOOST_TEST(id.value() == expectedID.value());
584  }
585 
586 } // test_OptionalROPID_present()
587 
588 
590 
591  using ID_t = readout::ROPID;
592  struct Config { readout::fhicl::OptionalROPID ROP { fhicl::Name("ROP") }; };
593 
594  std::string const configStr { "" };
595 
596  std::optional<ID_t> const expectedID { std::nullopt };
597 
598  auto validatedConfig = validateConfig<Config>(configStr)();
599 
600  std::optional<ID_t> const id
601  = geo::fhicl::readOptionalID(validatedConfig.ROP);
602  BOOST_TEST(id.has_value() == expectedID.has_value());
603  if (expectedID.has_value()) {
604  BOOST_TEST(id->isValid == expectedID->isValid);
605  if (expectedID->isValid) BOOST_TEST(id.value() == expectedID.value());
606  }
607 
608 } // test_OptionalROPID_omitted()
609 
610 
612 
613  using ID_t = readout::ROPID;
614  struct Config
615  { readout::fhicl::ROPIDsequence ROPs { fhicl::Name("ROPs") }; };
616 
617  std::string const configStr
618  { "ROPs: [ { C:0 S:1 R:1 }, { C:2 S:3 R:0 } ]" };
619  std::array<ID_t, 2U> const expectedIDs
620  // BUG the double brace syntax is required to work around clang bug 21629
621 // { ID_t{ 0U, 1U, 1U }, ID_t{ 2U, 3U, 0U } };
622  {{ ID_t{ 0U, 1U, 1U }, ID_t{ 2U, 3U, 0U } }};
623 
624  auto validatedConfig = validateConfig<Config>(configStr)();
625 
626  auto ids = geo::fhicl::readIDsequence(validatedConfig.ROPs);
627  static_assert(std::is_same_v<decltype(ids), std::vector<ID_t>>);
628 
629  BOOST_TEST(ids.size() == expectedIDs.size());
630  auto const n = std::min(ids.size(), expectedIDs.size());
631  for (std::size_t i = 0; i < n; ++i) {
632  auto const& id = ids[i];
633  ID_t const& expectedID = expectedIDs[i];
634 
635  BOOST_TEST_CONTEXT("Item [" << i << "]") {
636  BOOST_TEST(id.isValid == expectedID.isValid);
637  if (expectedID.isValid) BOOST_TEST(id == expectedID);
638  } // BOOST_TEST_CONTEXT
639  } // for
640 
641 } // test_ROPIDsequence_normal()
642 
643 
645 
646  using ID_t = readout::ROPID;
647  struct Config { readout::fhicl::ROPIDsequence ROPs { fhicl::Name("ROPs") }; };
648 
649  std::string const configStr { "ROPs: []" };
650 
651  auto validatedConfig = validateConfig<Config>(configStr)();
652 
653  auto ids = geo::fhicl::readIDsequence(validatedConfig.ROPs);
654  static_assert(std::is_same_v<decltype(ids), std::vector<ID_t>>);
655 
656  BOOST_TEST(ids.size() == 0U);
657 
658 } // test_ROPIDsequence_empty()
659 
660 
662 
663  using ID_t = readout::ROPID;
664  struct Config
666 
667  std::string const configStr
668  { "ROPs: [ { C:0 S:1 R:1 }, { C:2 S:3 R:0 } ]" };
669  std::optional<std::vector<ID_t>> const expectedIDs
670  (std::in_place, { ID_t{ 0U, 1U, 1U }, ID_t{ 2U, 3U, 0U } });
671 
672  auto validatedConfig = validateConfig<Config>(configStr)();
673 
674  auto ids = geo::fhicl::readOptionalIDsequence(validatedConfig.ROPs);
675  static_assert
676  (std::is_same_v<decltype(ids), std::optional<std::vector<ID_t>>>);
677 
678  BOOST_TEST(ids.has_value() == expectedIDs.has_value());
679  if (expectedIDs.has_value()) {
680  BOOST_TEST(ids->size() == expectedIDs->size());
681  auto const n = std::min(ids->size(), expectedIDs->size());
682  for (std::size_t i = 0; i < n; ++i) {
683  auto const& id = ids.value()[i];
684  ID_t const& expectedID = expectedIDs.value()[i];
685 
686  BOOST_TEST_CONTEXT("Item [" << i << "]") {
687  BOOST_TEST(id.isValid == expectedID.isValid);
688  if (expectedID.isValid) BOOST_TEST(id == expectedID);
689  } // BOOST_TEST_CONTEXT
690  } // for
691  }
692 
693 } // test_OptionalROPIDsequence_normal()
694 
695 
697 
698  using ID_t = readout::ROPID;
699  struct Config
701 
702  std::string const configStr { "ROPs: []" };
703  std::optional<std::vector<ID_t>> const expectedIDs(std::in_place);
704 
705  auto validatedConfig = validateConfig<Config>(configStr)();
706 
707  auto ids = geo::fhicl::readOptionalIDsequence(validatedConfig.ROPs);
708  static_assert
709  (std::is_same_v<decltype(ids), std::optional<std::vector<ID_t>>>);
710 
711  BOOST_TEST(ids.has_value() == expectedIDs.has_value());
712  if (expectedIDs.has_value()) {
713  BOOST_TEST(ids->size() == expectedIDs->size());
714  auto const n = std::min(ids->size(), expectedIDs->size());
715  for (std::size_t i = 0; i < n; ++i) {
716  auto const& id = ids.value()[i];
717  ID_t const& expectedID = expectedIDs.value()[i];
718 
719  BOOST_TEST_CONTEXT("Item [" << i << "]") {
720  BOOST_TEST(id.isValid == expectedID.isValid);
721  if (expectedID.isValid) BOOST_TEST(id == expectedID);
722  } // BOOST_TEST_CONTEXT
723  } // for
724  }
725 
726 } // test_OptionalROPIDsequence_empty()
727 
728 
730 
731  using ID_t = readout::ROPID;
732  struct Config
734 
735  std::string const configStr { "" };
736  std::optional<std::vector<ID_t>> const expectedIDs(std::nullopt);
737 
738  auto validatedConfig = validateConfig<Config>(configStr)();
739 
740  auto ids = geo::fhicl::readOptionalIDsequence(validatedConfig.ROPs);
741  static_assert
742  (std::is_same_v<decltype(ids), std::optional<std::vector<ID_t>>>);
743 
744  BOOST_TEST(ids.has_value() == expectedIDs.has_value());
745  if (expectedIDs.has_value()) {
746  BOOST_TEST(ids->size() == expectedIDs->size());
747  auto const n = std::min(ids->size(), expectedIDs->size());
748  for (std::size_t i = 0; i < n; ++i) {
749  auto const& id = ids.value()[i];
750  ID_t const& expectedID = expectedIDs.value()[i];
751 
752  BOOST_TEST_CONTEXT("Item [" << i << "]") {
753  BOOST_TEST(id.isValid == expectedID.isValid);
754  if (expectedID.isValid) BOOST_TEST(id == expectedID);
755  } // BOOST_TEST_CONTEXT
756  } // for
757  }
758 
759 } // test_OptionalROPIDsequence_omitted()
760 
761 
763 
764  using ID_t = readout::ROPID;
765  struct Config {
766 
767  readout::fhicl::ROPID ROP { fhicl::Name("ROP") };
768 
769  readout::fhicl::OptionalROPID MaybeROP { fhicl::Name("MaybeROP") };
770 
771  readout::fhicl::OptionalROPID NoROP { fhicl::Name("NoROP") };
772 
774 
775  readout::fhicl::OptionalROPIDsequence MaybeROPs { fhicl::Name("MaybeROPs") };
776 
778 
779  }; // struct Config
780 
781  std::string const configStr {
782  "ROP: { C:1 S:5 R:0 }"
783  "\nMaybeROP: { C:1 S:5 R:1 }"
784  "\n# NoROP: @nil"
785  "\n"
786  "\nROPs: [ { C:1 S:5 R:2 }, { C:1 S:5 R:3 } ] "
787  "\nMaybeROPs: [ { C:1 S:5 R:4 } ] "
788  "\n# NoROPs: @nil"
789  "\n"
790  };
791 
792  auto const& config = validateConfig<Config>(configStr);
793 
794  ID_t const expected1 { 1U, 5U, 0U };
795  ID_t const expected2 { 1U, 5U, 1U };
796  std::array<ID_t, 2U> const expected4
797  // BUG the double brace syntax is required to work around clang bug 21629
798 // { ID_t{ 1U, 5U, 2U }, ID_t{ 1U, 5U, 3U } };
799  {{ ID_t{ 1U, 5U, 2U }, ID_t{ 1U, 5U, 3U } }};
800  std::array<ID_t, 1U> const expected5
801  // BUG the double brace syntax is required to work around clang bug 21629
802 // { ID_t{ 1U, 5U, 4U } };
803  {{ ID_t{ 1U, 5U, 4U } }};
804 
805  ID_t const default3 { 1U, 5U, 5U };
806  auto default3value = default3;
807 
808  std::vector<ID_t> const default6({
809  ID_t{ 1U, 5U, 6U }, ID_t{ 1U, 5U, 7U }, ID_t{ 1U, 5U, 8U }
810  });
811  auto default6value = default6;
812 
813  //
814  // read simple atom
815  //
816  auto id11 = geo::fhicl::readParameter(config().ROP);
817  static_assert(std::is_same_v<decltype(id11), ID_t>);
818  BOOST_TEST(id11 == expected1);
819 
820  //
821  // read optional atom
822  //
823 
824  // this one is present (default values should be ignored):
825  auto id21 = geo::fhicl::readParameter(config().MaybeROP);
826  static_assert(std::is_same_v<decltype(id21), std::optional<ID_t>>);
827  BOOST_TEST(id21.has_value());
828  if (id21.has_value()) BOOST_TEST(id21.value() == expected2);
829 
830  default3value = default3;
831  auto id22 = geo::fhicl::readParameter(config().MaybeROP, default3);
832  static_assert(std::is_same_v<decltype(id22), ID_t>);
833  BOOST_TEST(id22 == expected2);
834  BOOST_TEST(default3value == default3);
835 
836  default3value = default3;
837  auto id23
838  = geo::fhicl::readParameter(config().MaybeROP, std::move(default3));
839  static_assert(std::is_same_v<decltype(id23), ID_t>);
840  BOOST_TEST(id23 == expected2);
841  BOOST_TEST(default3value == default3);
842 
843  // this one is omitted:
844  auto id31 = geo::fhicl::readParameter(config().NoROP);
845  static_assert(std::is_same_v<decltype(id31), std::optional<ID_t>>);
846  BOOST_TEST(!id31.has_value());
847 
848  default3value = default3;
849  auto id32 = geo::fhicl::readParameter(config().NoROP, default3);
850  static_assert(std::is_same_v<decltype(id32), ID_t>);
851  BOOST_TEST(id32 == default3);
852  BOOST_TEST(default3value == default3);
853 
854  default3value = default3;
855  auto id33 = geo::fhicl::readParameter(config().NoROP, std::move(default3));
856  static_assert(std::is_same_v<decltype(id33), ID_t>);
857  BOOST_TEST(id33 == default3);
858 
859  // test for compilation
860  auto id34 = geo::fhicl::readParameter(config().NoROP, { 1U, 3U, 6U });
861  BOOST_TEST(id34 == (readout::ROPID{ 1U, 3U, 6U }));
862 
863 
864  //
865  // read sequence
866  //
867  auto id41 = geo::fhicl::readParameter(config().ROPs);
868  static_assert(std::is_same_v<decltype(id41), std::vector<ID_t>>);
869  BOOST_TEST(id41.size() == expected4.size());
870  std::size_t max41 = std::max(id41.size(), expected4.size());
871  for (std::size_t i = 0U; i < max41; ++i) BOOST_TEST_CONTEXT("element " << i) {
872  BOOST_TEST(id41[i] == expected4[i]);
873  }
874 
875  //
876  // read optional sequence
877  //
878  // this one is present (default values should be ignored):
879  auto id51 = geo::fhicl::readParameter(config().MaybeROPs);
880  static_assert
881  (std::is_same_v<decltype(id51), std::optional<std::vector<ID_t>>>);
882  BOOST_TEST(id51.has_value());
883  if (id51.has_value()) {
884  BOOST_CHECK_EQUAL_COLLECTIONS
885  (id51->begin(), id51->end(), expected5.begin(), expected5.end());
886  }
887 
888  default6value = default6;
889  auto id52 = geo::fhicl::readParameter(config().MaybeROPs, default6value);
890  static_assert(std::is_same_v<decltype(id52), std::vector<ID_t>>);
891  BOOST_CHECK_EQUAL_COLLECTIONS
892  (id52.begin(), id52.end(), expected5.begin(), expected5.end());
893  BOOST_CHECK_EQUAL_COLLECTIONS(
894  default6value.begin(), default6value.end(),
895  default6.begin(), default6.end()
896  );
897 
898  default6value = default6;
899  auto id53
900  = geo::fhicl::readParameter(config().MaybeROPs, std::move(default6value));
901  static_assert(std::is_same_v<decltype(id53), std::vector<ID_t>>);
902  BOOST_CHECK_EQUAL_COLLECTIONS
903  (id53.begin(), id53.end(), expected5.begin(), expected5.end());
904  BOOST_CHECK_EQUAL_COLLECTIONS(
905  default6value.begin(), default6value.end(),
906  default6.begin(), default6.end()
907  );
908 
909  // this one is omitted:
910  auto id61 = geo::fhicl::readParameter(config().NoROPs);
911  static_assert
912  (std::is_same_v<decltype(id61), std::optional<std::vector<ID_t>>>);
913  BOOST_TEST(!id61.has_value());
914 
915  default6value = default6;
916  auto id62 = geo::fhicl::readParameter(config().NoROPs, default6value);
917  static_assert(std::is_same_v<decltype(id62), std::vector<ID_t>>);
918  BOOST_CHECK_EQUAL_COLLECTIONS
919  (id62.begin(), id62.end(), default6.begin(), default6.end());
920  BOOST_CHECK_EQUAL_COLLECTIONS(
921  default6value.begin(), default6value.end(),
922  default6.begin(), default6.end()
923  );
924 
925  default6value = default6;
926  auto id63
927  = geo::fhicl::readParameter(config().NoROPs, std::move(default6value));
928  static_assert(std::is_same_v<decltype(id63), std::vector<ID_t>>);
929  BOOST_CHECK_EQUAL_COLLECTIONS
930  (id63.begin(), id63.end(), default6.begin(), default6.end());
931  // this is a bit out of standard, since after moving an object is guaranteed
932  // only to be good for destruction; yet usually implementations of std::vector
933  // leave it as a fully valid empty vector:
934  BOOST_TEST(default6value.empty());
935 
936 } // test_ROPUnifiedInterface()
937 
938 
939 // --- END -- Readout plane ID tests -------------------------------------------
940 
941 
942 
943 //------------------------------------------------------------------------------
944 //
945 // CryostatID test
946 //
947 BOOST_AUTO_TEST_CASE(CryostatID_testcase) {
948 
951 
954 
957 
961 
962 } // BOOST_AUTO_TEST_CASE(CryostatID_testcase)
963 
964 
965 //------------------------------------------------------------------------------
966 //
967 // TPCsetID test
968 //
969 BOOST_AUTO_TEST_CASE(TPCsetID_testcase) {
970 
973 
976 
979 
983 
984 } // BOOST_AUTO_TEST_CASE(TPCsetID_testcase)
985 
986 
987 //------------------------------------------------------------------------------
988 //
989 // ROPID test
990 //
991 BOOST_AUTO_TEST_CASE(ROPID_testcase) {
992 
995 
998 
1001 
1006 
1007 } // BOOST_AUTO_TEST_CASE(ROPID_testcase)
1008 
1009 
1010 //------------------------------------------------------------------------------
void test_OptionalTPCsetIDsequence_empty()
void test_ROPID_invalid()
void test_ROPIDsequence_normal()
fhicl::Table< Config > validateConfig(std::string const &configStr)
OptionalID< readout::TPCsetID > OptionalTPCsetID
Member type of optional validated readout::TPCsetID parameter.
void test_OptionalROPIDsequence_omitted()
std::vector< ID > readIDsequence(IDsequence< SrcID > const &seq)
Returns a vector of IDs extracted from the specified ID sequence.
Classes identifying readout-related concepts.
std::string string
Definition: nybbler.cc:12
void test_OptionalCryostatID_present()
static ParameterSet make(intermediate_table const &tbl)
Definition: ParameterSet.cc:68
BOOST_AUTO_TEST_CASE(CryostatID_testcase)
IDparameter< readout::ROPID > ROPID
Member type of validated readout::ROPID parameter.
void test_OptionalCryostatID_omitted()
void test_OptionalROPID_present()
ChannelGroupService::Name Name
void test_TPCsetID_invalid()
void test_ROPIDsequence_empty()
OptionalID< readout::ROPID > OptionalROPID
Member type of optional validated readout::ROPID parameter.
OptionalIDsequence< readout::TPCsetID > OptionalTPCsetIDsequence
Member type of optional sequence of readout::TPCsetID parameters.
void test_OptionalCryostatIDsequence_omitted()
IDparameter< readout::CryostatID > CryostatID
Member type of validated readout::CryostatID parameter.
ID readID(IDparameter< SrcID > const &atom)
Returns an ID extracted from the specified ID atom.
IDsequence< readout::ROPID > ROPIDsequence
Member type of sequence of readout::ROPID parameters.
void test_OptionalCryostatIDsequence_normal()
OptionalIDsequence< readout::ROPID > OptionalROPIDsequence
Member type of optional sequence of readout::ROPID parameters.
void test_TPCsetIDsequence_normal()
typename config_impl< T >::type Config
Definition: ModuleMacros.h:52
void test_TPCsetIDsequence_empty()
readout::ROPID ROPID
OptionalIDsequence< readout::CryostatID > OptionalCryostatIDsequence
Member type of optional sequence of readout::CryostatID parameters.
void test_OptionalTPCsetID_omitted()
std::optional< ID > readOptionalID(OptionalID< SrcID > const &atom)
Returns an ID extracted from the specified optional ID atom.
static Config * config
Definition: config.cpp:1054
IDparameter< readout::TPCsetID > TPCsetID
Member type of validated readout::TPCsetID parameter.
std::void_t< T > n
void test_CryostatID_normal()
def move(depos, offset)
Definition: depos.py:107
Utilities for using readout IDs in FHiCL validated configuration.
std::optional< std::vector< ID > > readOptionalIDsequence(OptionalIDsequence< SrcID > const &seq)
Returns a vector of IDs extracted from the specified optional ID sequence.
void test_CryostatIDsequence_normal()
void test_OptionalROPIDsequence_empty()
static int max(int a, int b)
Class identifying a set of planes sharing readout channels.
void test_CryostatIDsequence_empty()
void test_OptionalROPID_omitted()
void test_OptionalCryostatIDsequence_empty()
OptionalID< readout::CryostatID > OptionalCryostatID
Member type of optional validated readout::CryostatID parameter.
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
Definition: statistics.h:55
void test_OptionalTPCsetIDsequence_normal()
void test_ROPUnifiedInterface()
IDsequence< readout::TPCsetID > TPCsetIDsequence
Member type of sequence of readout::TPCsetID parameters.
IDsequence< readout::CryostatID > CryostatIDsequence
Member type of sequence of readout::CryostatID parameters.
void test_OptionalTPCsetIDsequence_omitted()
void test_OptionalROPIDsequence_normal()
void test_TPCsetID_normal()
void test_ROPID_normal()
ID readParameter(IDparameter< SrcID > const &atom)
void test_CryostatID_invalid()
geo::CryostatID CryostatID
Definition: readout_types.h:59
QTextStream & endl(QTextStream &s)
void test_OptionalTPCsetID_present()