readoutdatacontainers_test.cxx
Go to the documentation of this file.
1 /**
2  * @file readoutdatacontainers_test.cxx
3  * @brief Unit test for `ReadoutDataContainers.h` library.
4  * @author Gianluca Petrillo (petrillo@slac.stanford.edu)
5  * @date September 7, 2019
6  */
7 
8 // Boost libraries
9 #define BOOST_TEST_MODULE (readout data containers test)
10 #include <boost/test/unit_test.hpp>
11 
12 // LArSoft libraries
16 
17 
18 //------------------------------------------------------------------------------
19 template <typename T>
20 struct Summer {
21 
22  T sum = T { 0 };
23 
24  void operator() (T v) { sum += v; }
25 
26  T get() const { return sum; }
27  void reset() { sum = T{0}; }
28 
29 }; // struct Summer
30 
31 //------------------------------------------------------------------------------
33  readout::TPCsetDataContainer<int> data, // copy is intentional
34  std::size_t const NCryostats,
35  std::size_t const NTPCsets
36 ) {
37 
38  std::size_t const N = NCryostats * NTPCsets;
39 
40  BOOST_TEST(!data.empty());
41  BOOST_TEST(data.size() == N);
42  BOOST_TEST(data.capacity() >= N);
43 
44  for (auto c: util::counter<unsigned int>(NCryostats))
45  for (auto s: util::counter<unsigned short int>(NTPCsets))
46  BOOST_TEST((data[{ c, s }]) == 0);
47 
48  BOOST_TEST(data.firstID() == readout::TPCsetID(0, 0));
49  BOOST_TEST(data.lastID() == readout::TPCsetID(1, 2));
50 
51 
52  std::size_t expected_index = 0U;
53 
54  // simple R/W iteration test
55  for (auto& value: data) {
56  static_assert(std::is_same_v<decltype(value), decltype(data)::reference>);
57 
58  readout::TPCsetID const expected_ID = data.mapper().ID(expected_index);
59  BOOST_TEST(value == data[expected_ID]);
60 
61  ++expected_index;
62  } // for
63  BOOST_TEST(data.size() == expected_index);
64 
65  // ID/data pair R/W iteration test
66  expected_index = 0U;
67  for (auto&& [ ID, value ]: data.items()) {
68  static_assert(std::is_same_v<decltype(ID), readout::TPCsetID>);
69  static_assert(std::is_same_v<decltype(value), decltype(data)::reference>);
70 
71  readout::TPCsetID const expected_ID = data.mapper().ID(expected_index);
72  BOOST_TEST(ID == expected_ID);
73  BOOST_TEST(value == data[expected_ID]);
74 
75  ++expected_index;
76  } // for
77  BOOST_TEST(data.size() == expected_index);
78 
79  BOOST_TEST( data.hasTPCset({ 0, 0}));
80  BOOST_TEST( data.hasTPCset({ 0, 1}));
81  BOOST_TEST( data.hasTPCset({ 0, 2}));
82  BOOST_TEST(!data.hasTPCset({ 0, 3}));
83  BOOST_TEST(!data.hasTPCset({ 0, 4}));
84  BOOST_TEST( data.hasTPCset({ 1, 0}));
85  BOOST_TEST( data.hasTPCset({ 1, 1}));
86  BOOST_TEST( data.hasTPCset({ 1, 2}));
87  BOOST_TEST(!data.hasTPCset({ 1, 3}));
88  BOOST_TEST(!data.hasTPCset({ 1, 4}));
89  BOOST_TEST(!data.hasTPCset({ 2, 0}));
90  BOOST_TEST(!data.hasTPCset({ 2, 1}));
91  BOOST_TEST(!data.hasTPCset({ 2, 2}));
92  BOOST_TEST(!data.hasTPCset({ 2, 3}));
93  BOOST_TEST(!data.hasTPCset({ 2, 4}));
94 
95  BOOST_TEST( data.hasCryostat(readout::TPCsetID{ 0, 0}));
96  BOOST_TEST( data.hasCryostat(readout::TPCsetID{ 0, 1}));
97  BOOST_TEST( data.hasCryostat(readout::TPCsetID{ 0, 2}));
98  BOOST_TEST( data.hasCryostat(readout::TPCsetID{ 0, 3}));
99  BOOST_TEST( data.hasCryostat(readout::TPCsetID{ 0, 4}));
100  BOOST_TEST( data.hasCryostat(readout::TPCsetID{ 1, 0}));
101  BOOST_TEST( data.hasCryostat(readout::TPCsetID{ 1, 1}));
102  BOOST_TEST( data.hasCryostat(readout::TPCsetID{ 1, 2}));
103  BOOST_TEST( data.hasCryostat(readout::TPCsetID{ 1, 3}));
104  BOOST_TEST( data.hasCryostat(readout::TPCsetID{ 1, 4}));
105  BOOST_TEST(!data.hasCryostat(readout::TPCsetID{ 2, 0}));
106  BOOST_TEST(!data.hasCryostat(readout::TPCsetID{ 2, 1}));
107  BOOST_TEST(!data.hasCryostat(readout::TPCsetID{ 2, 2}));
108  BOOST_TEST(!data.hasCryostat(readout::TPCsetID{ 2, 3}));
109  BOOST_TEST(!data.hasCryostat(readout::TPCsetID{ 2, 4}));
110 
111  data[{0, 0}] = 4;
112  BOOST_TEST((data[{0, 0}]) == 4);
113  BOOST_TEST(data.at({0, 0}) == 4);
114  data[{0, 0}] = 5;
115  BOOST_TEST((data[{0, 0}]) == 5);
116  BOOST_TEST(data.at({0, 0}) == 5);
117 
118  data[{0, 1}] = 6;
119  BOOST_TEST((data[{0, 1}]) == 6);
120  BOOST_TEST(data.at({0, 1}) == 6);
121 
122  BOOST_TEST((data[{0, 0}]) == 5);
123 
124  data[{0, 2}] = 7;
125  BOOST_TEST((data[{0, 2}]) == 7);
126  BOOST_TEST(data.at({0, 2}) == 7);
127 
128  BOOST_TEST((data[{0, 0}]) == 5);
129  BOOST_TEST((data[{0, 1}]) == 6);
130 
131  data[{1, 0}] = 15;
132  BOOST_TEST((data[{1, 0}]) == 15);
133  BOOST_TEST(data.at({1, 0}) == 15);
134 
135  BOOST_TEST((data[{0, 0}]) == 5);
136  BOOST_TEST((data[{0, 1}]) == 6);
137  BOOST_TEST((data[{0, 2}]) == 7);
138 
139  data[{1, 1}] = 16;
140  BOOST_TEST((data[{1, 1}]) == 16);
141  BOOST_TEST(data.at({1, 1}) == 16);
142 
143  BOOST_TEST((data[{0, 0}]) == 5);
144  BOOST_TEST((data[{0, 1}]) == 6);
145  BOOST_TEST((data[{0, 2}]) == 7);
146  BOOST_TEST((data[{1, 0}]) == 15);
147 
148  data[{1, 2}] = 17;
149  BOOST_TEST((data[{1, 2}]) == 17);
150  BOOST_TEST(data.at({1, 2}) == 17);
151 
152  BOOST_TEST((data[{0, 0}]) == 5);
153  BOOST_TEST((data[{0, 1}]) == 6);
154  BOOST_TEST((data[{0, 2}]) == 7);
155  BOOST_TEST((data[{1, 0}]) == 15);
156  BOOST_TEST((data[{1, 1}]) == 16);
157 
158  BOOST_CHECK_THROW(data.at({0, 3}), std::out_of_range);
159  BOOST_CHECK_THROW(data.at({0, 4}), std::out_of_range);
160  BOOST_CHECK_THROW(data.at({1, 3}), std::out_of_range);
161  BOOST_CHECK_THROW(data.at({1, 4}), std::out_of_range);
162  BOOST_CHECK_THROW(data.at({2, 0}), std::out_of_range);
163  BOOST_CHECK_THROW(data.at({2, 1}), std::out_of_range);
164  BOOST_CHECK_THROW(data.at({2, 2}), std::out_of_range);
165  BOOST_CHECK_THROW(data.at({2, 3}), std::out_of_range);
166  BOOST_CHECK_THROW(data.at({2, 4}), std::out_of_range);
167 
168  BOOST_TEST(data.first() == 5);
169  data.first() = -5;
170  BOOST_TEST((data[{0, 0}]) == -5);
171  BOOST_TEST(data.first() == -5);
172  data.first() = 5;
173 
174  BOOST_TEST(data.last() == 17);
175  data.last() = -17;
176  BOOST_TEST((data[{1U, 2U}]) == -17);
177  BOOST_TEST(data.last() == -17);
178  data.last() = 17;
179 
180  auto const& constData = data;
181 
182  BOOST_TEST
183  (std::addressof(constData.first()) == std::addressof(data.first()));
184  BOOST_TEST
185  (std::addressof(constData.last()) == std::addressof(data.last()));
186 
187  BOOST_TEST((constData[{0, 0}]) == (data[{0, 0}]));
188  BOOST_TEST((constData[{0, 1}]) == (data[{0, 1}]));
189  BOOST_TEST((constData[{0, 2}]) == (data[{0, 2}]));
190  BOOST_TEST((constData[{1, 0}]) == (data[{1, 0}]));
191  BOOST_TEST((constData[{1, 1}]) == (data[{1, 1}]));
192  BOOST_TEST((constData[{1, 2}]) == (data[{1, 2}]));
193  BOOST_TEST(constData.at({0, 0}) == data.at({0, 0}));
194  BOOST_TEST(constData.at({0, 1}) == data.at({0, 1}));
195  BOOST_TEST(constData.at({0, 2}) == data.at({0, 2}));
196  BOOST_TEST(constData.at({1, 0}) == data.at({1, 0}));
197  BOOST_TEST(constData.at({1, 1}) == data.at({1, 1}));
198  BOOST_TEST(constData.at({1, 2}) == data.at({1, 2}));
199 
200  BOOST_CHECK_THROW(constData.at({0, 3}), std::out_of_range);
201  BOOST_CHECK_THROW(constData.at({0, 4}), std::out_of_range);
202  BOOST_CHECK_THROW(constData.at({1, 3}), std::out_of_range);
203  BOOST_CHECK_THROW(constData.at({1, 4}), std::out_of_range);
204  BOOST_CHECK_THROW(constData.at({2, 0}), std::out_of_range);
205  BOOST_CHECK_THROW(constData.at({2, 1}), std::out_of_range);
206  BOOST_CHECK_THROW(constData.at({2, 2}), std::out_of_range);
207  BOOST_CHECK_THROW(constData.at({2, 3}), std::out_of_range);
208  BOOST_CHECK_THROW(constData.at({2, 4}), std::out_of_range);
209 
210 
211  auto const cb = constData.begin();
212  auto const ce = constData.end();
213  BOOST_TEST(static_cast<size_t>(ce - cb) == N);
214 
215  // simple read-only iteration test
216  expected_index = 0U;
217  for (auto& value: constData) {
218  static_assert(std::is_same_v
219  <decltype(value), std::decay_t<decltype(constData)>::const_reference>
220  );
221 
222  readout::TPCsetID const expected_ID = constData.mapper().ID(expected_index);
223  BOOST_TEST(value == constData[expected_ID]);
224 
225  ++expected_index;
226  } // for
227  BOOST_TEST(constData.size() == expected_index);
228 
229  // ID/data pair read-only iteration test
230  expected_index = 0U;
231  for (auto&& [ ID, value ]: constData.items()) {
232  static_assert(std::is_same_v<decltype(ID), readout::TPCsetID>);
233  static_assert(std::is_same_v
234  <decltype(value), std::decay_t<decltype(constData)>::const_reference>
235  );
236 
237  readout::TPCsetID const expected_ID = constData.mapper().ID(expected_index);
238  BOOST_TEST(ID == expected_ID);
239  BOOST_TEST(value == constData[expected_ID]);
240 
241  ++expected_index;
242  } // for
243  BOOST_TEST(constData.size() == expected_index);
244 
245 
246  data.fill(14);
247  for (auto c: util::counter<unsigned int>(NCryostats))
248  for (auto s: util::counter<unsigned short int>(NTPCsets))
249  BOOST_TEST((data[{ c, s }]) == 14);
250 
251  data.apply([](int& v){ v *= 2; });
252  for (auto c: util::counter<unsigned int>(NCryostats))
253  for (auto s: util::counter<unsigned short int>(NTPCsets))
254  BOOST_TEST((data[{ c, s }]) == 28);
255 
256  Summer<int> summer;
257  static_assert(std::is_same_v<decltype(data.apply(summer)), Summer<int>&>);
258  data.apply(summer);
259  BOOST_TEST(summer.get() == N * 28);
260 
261  summer.reset();
262  static_assert
263  (std::is_same_v<decltype(constData.apply(summer)), Summer<int>&>);
264  constData.apply(summer);
265  BOOST_TEST(summer.get() == N * 28);
266 
267  auto summer1 = data.apply(Summer<int>{});
268  BOOST_TEST(summer1.get() == N * 28);
269 
270  auto summer2 = constData.apply(Summer<int>{});
271  BOOST_TEST(summer2.get() == N * 28);
272 
273  data.reset();
274  for (auto c: util::counter<unsigned int>(NCryostats))
275  for (auto s: util::counter<unsigned short int>(NTPCsets))
276  BOOST_TEST((data[{ c, s }]) == 0);
277 
278  data.clear();
279  BOOST_TEST(data.empty());
280 
281 } // TPCsetDataContainerTest()
282 
283 
284 //------------------------------------------------------------------------------
286  readout::ROPDataContainer<int> data, // copy is intentional
287  std::size_t const NCryostats,
288  std::size_t const NTPCsets,
289  std::size_t const NROPs
290 ) {
291 
292  std::size_t const N = NCryostats * NTPCsets * NROPs;
293 
294  BOOST_TEST(!data.empty());
295  BOOST_TEST(data.size() == N);
296  BOOST_TEST(data.capacity() >= N);
297 
298  for (auto c: util::counter<unsigned int>(NCryostats))
299  for (auto s: util::counter<unsigned short int>(NTPCsets))
300  for (auto r: util::counter<unsigned int>(NROPs))
301  BOOST_TEST((data[{ c, s, r }]) == 0);
302 
303  BOOST_TEST(data.firstID() == readout::ROPID(0, 0, 0));
304  BOOST_TEST(data.lastID() == readout::ROPID(1, 2, 1));
305 
306 
307  std::size_t expected_index = 0U;
308 
309  // simple R/W iteration test
310  for (auto& value: data) {
311  static_assert(std::is_same_v<decltype(value), decltype(data)::reference>);
312 
313  readout::ROPID const expected_ID = data.mapper().ID(expected_index);
314  BOOST_TEST(value == data[expected_ID]);
315 
316  ++expected_index;
317  } // for
318  BOOST_TEST(data.size() == expected_index);
319 
320  // ID/data pair R/W iteration test
321  expected_index = 0U;
322  for (auto&& [ ID, value ]: data.items()) {
323  static_assert(std::is_same_v<decltype(ID), readout::ROPID>);
324  static_assert(std::is_same_v<decltype(value), decltype(data)::reference>);
325 
326  readout::ROPID const expected_ID = data.mapper().ID(expected_index);
327  BOOST_TEST(ID == expected_ID);
328  BOOST_TEST(value == data[expected_ID]);
329 
330  ++expected_index;
331  } // for
332  BOOST_TEST(data.size() == expected_index);
333 
334 
335  BOOST_TEST( data.hasROP({ 0, 0, 0}));
336  BOOST_TEST( data.hasROP({ 0, 0, 1}));
337  BOOST_TEST(!data.hasROP({ 0, 0, 2}));
338  BOOST_TEST( data.hasROP({ 0, 1, 0}));
339  BOOST_TEST( data.hasROP({ 0, 1, 1}));
340  BOOST_TEST(!data.hasROP({ 0, 1, 2}));
341  BOOST_TEST( data.hasROP({ 0, 2, 0}));
342  BOOST_TEST( data.hasROP({ 0, 2, 1}));
343  BOOST_TEST(!data.hasROP({ 0, 2, 2}));
344  BOOST_TEST(!data.hasROP({ 0, 3, 0}));
345  BOOST_TEST(!data.hasROP({ 0, 3, 1}));
346  BOOST_TEST(!data.hasROP({ 0, 3, 2}));
347  BOOST_TEST(!data.hasROP({ 0, 4, 0}));
348  BOOST_TEST(!data.hasROP({ 0, 4, 1}));
349  BOOST_TEST(!data.hasROP({ 0, 4, 2}));
350  BOOST_TEST( data.hasROP({ 1, 0, 0}));
351  BOOST_TEST( data.hasROP({ 1, 0, 1}));
352  BOOST_TEST(!data.hasROP({ 1, 0, 2}));
353  BOOST_TEST( data.hasROP({ 1, 1, 0}));
354  BOOST_TEST( data.hasROP({ 1, 1, 1}));
355  BOOST_TEST(!data.hasROP({ 1, 1, 2}));
356  BOOST_TEST( data.hasROP({ 1, 2, 0}));
357  BOOST_TEST( data.hasROP({ 1, 2, 1}));
358  BOOST_TEST(!data.hasROP({ 1, 2, 2}));
359  BOOST_TEST(!data.hasROP({ 1, 3, 0}));
360  BOOST_TEST(!data.hasROP({ 1, 3, 1}));
361  BOOST_TEST(!data.hasROP({ 1, 3, 2}));
362  BOOST_TEST(!data.hasROP({ 1, 4, 0}));
363  BOOST_TEST(!data.hasROP({ 1, 4, 1}));
364  BOOST_TEST(!data.hasROP({ 1, 4, 2}));
365  BOOST_TEST(!data.hasROP({ 2, 0, 0}));
366  BOOST_TEST(!data.hasROP({ 2, 0, 1}));
367  BOOST_TEST(!data.hasROP({ 2, 0, 2}));
368  BOOST_TEST(!data.hasROP({ 2, 1, 0}));
369  BOOST_TEST(!data.hasROP({ 2, 1, 1}));
370  BOOST_TEST(!data.hasROP({ 2, 1, 2}));
371  BOOST_TEST(!data.hasROP({ 2, 2, 0}));
372  BOOST_TEST(!data.hasROP({ 2, 2, 1}));
373  BOOST_TEST(!data.hasROP({ 2, 2, 2}));
374  BOOST_TEST(!data.hasROP({ 2, 3, 0}));
375  BOOST_TEST(!data.hasROP({ 2, 3, 1}));
376  BOOST_TEST(!data.hasROP({ 2, 3, 2}));
377  BOOST_TEST(!data.hasROP({ 2, 4, 0}));
378  BOOST_TEST(!data.hasROP({ 2, 4, 1}));
379  BOOST_TEST(!data.hasROP({ 2, 4, 2}));
380 
381  BOOST_TEST( data.hasTPCset(readout::ROPID{ 0, 0, 0}));
382  BOOST_TEST( data.hasTPCset(readout::ROPID{ 0, 0, 1}));
383  BOOST_TEST( data.hasTPCset(readout::ROPID{ 0, 0, 2}));
384  BOOST_TEST( data.hasTPCset(readout::ROPID{ 0, 1, 0}));
385  BOOST_TEST( data.hasTPCset(readout::ROPID{ 0, 1, 1}));
386  BOOST_TEST( data.hasTPCset(readout::ROPID{ 0, 1, 2}));
387  BOOST_TEST( data.hasTPCset(readout::ROPID{ 0, 2, 0}));
388  BOOST_TEST( data.hasTPCset(readout::ROPID{ 0, 2, 1}));
389  BOOST_TEST( data.hasTPCset(readout::ROPID{ 0, 2, 2}));
390  BOOST_TEST(!data.hasTPCset(readout::ROPID{ 0, 3, 0}));
391  BOOST_TEST(!data.hasTPCset(readout::ROPID{ 0, 3, 1}));
392  BOOST_TEST(!data.hasTPCset(readout::ROPID{ 0, 3, 2}));
393  BOOST_TEST(!data.hasTPCset(readout::ROPID{ 0, 4, 0}));
394  BOOST_TEST(!data.hasTPCset(readout::ROPID{ 0, 4, 1}));
395  BOOST_TEST(!data.hasTPCset(readout::ROPID{ 0, 4, 2}));
396  BOOST_TEST( data.hasTPCset(readout::ROPID{ 1, 0, 0}));
397  BOOST_TEST( data.hasTPCset(readout::ROPID{ 1, 0, 1}));
398  BOOST_TEST( data.hasTPCset(readout::ROPID{ 1, 0, 2}));
399  BOOST_TEST( data.hasTPCset(readout::ROPID{ 1, 1, 0}));
400  BOOST_TEST( data.hasTPCset(readout::ROPID{ 1, 1, 1}));
401  BOOST_TEST( data.hasTPCset(readout::ROPID{ 1, 1, 2}));
402  BOOST_TEST( data.hasTPCset(readout::ROPID{ 1, 2, 0}));
403  BOOST_TEST( data.hasTPCset(readout::ROPID{ 1, 2, 1}));
404  BOOST_TEST( data.hasTPCset(readout::ROPID{ 1, 2, 2}));
405  BOOST_TEST(!data.hasTPCset(readout::ROPID{ 1, 3, 0}));
406  BOOST_TEST(!data.hasTPCset(readout::ROPID{ 1, 3, 1}));
407  BOOST_TEST(!data.hasTPCset(readout::ROPID{ 1, 3, 2}));
408  BOOST_TEST(!data.hasTPCset(readout::ROPID{ 1, 4, 0}));
409  BOOST_TEST(!data.hasTPCset(readout::ROPID{ 1, 4, 1}));
410  BOOST_TEST(!data.hasTPCset(readout::ROPID{ 1, 4, 2}));
411  BOOST_TEST(!data.hasTPCset(readout::ROPID{ 2, 0, 0}));
412  BOOST_TEST(!data.hasTPCset(readout::ROPID{ 2, 0, 1}));
413  BOOST_TEST(!data.hasTPCset(readout::ROPID{ 2, 0, 2}));
414  BOOST_TEST(!data.hasTPCset(readout::ROPID{ 2, 1, 0}));
415  BOOST_TEST(!data.hasTPCset(readout::ROPID{ 2, 1, 1}));
416  BOOST_TEST(!data.hasTPCset(readout::ROPID{ 2, 1, 2}));
417  BOOST_TEST(!data.hasTPCset(readout::ROPID{ 2, 2, 0}));
418  BOOST_TEST(!data.hasTPCset(readout::ROPID{ 2, 2, 1}));
419  BOOST_TEST(!data.hasTPCset(readout::ROPID{ 2, 2, 2}));
420  BOOST_TEST(!data.hasTPCset(readout::ROPID{ 2, 3, 0}));
421  BOOST_TEST(!data.hasTPCset(readout::ROPID{ 2, 3, 1}));
422  BOOST_TEST(!data.hasTPCset(readout::ROPID{ 2, 3, 2}));
423  BOOST_TEST(!data.hasTPCset(readout::ROPID{ 2, 4, 0}));
424  BOOST_TEST(!data.hasTPCset(readout::ROPID{ 2, 4, 1}));
425  BOOST_TEST(!data.hasTPCset(readout::ROPID{ 2, 4, 2}));
426 
427  BOOST_TEST( data.hasCryostat(readout::ROPID{ 0, 0, 0}));
428  BOOST_TEST( data.hasCryostat(readout::ROPID{ 0, 0, 1}));
429  BOOST_TEST( data.hasCryostat(readout::ROPID{ 0, 0, 2}));
430  BOOST_TEST( data.hasCryostat(readout::ROPID{ 0, 1, 0}));
431  BOOST_TEST( data.hasCryostat(readout::ROPID{ 0, 1, 1}));
432  BOOST_TEST( data.hasCryostat(readout::ROPID{ 0, 1, 2}));
433  BOOST_TEST( data.hasCryostat(readout::ROPID{ 0, 2, 0}));
434  BOOST_TEST( data.hasCryostat(readout::ROPID{ 0, 2, 1}));
435  BOOST_TEST( data.hasCryostat(readout::ROPID{ 0, 2, 2}));
436  BOOST_TEST( data.hasCryostat(readout::ROPID{ 0, 3, 0}));
437  BOOST_TEST( data.hasCryostat(readout::ROPID{ 0, 3, 1}));
438  BOOST_TEST( data.hasCryostat(readout::ROPID{ 0, 3, 2}));
439  BOOST_TEST( data.hasCryostat(readout::ROPID{ 0, 4, 0}));
440  BOOST_TEST( data.hasCryostat(readout::ROPID{ 0, 4, 1}));
441  BOOST_TEST( data.hasCryostat(readout::ROPID{ 0, 4, 2}));
442  BOOST_TEST( data.hasCryostat(readout::ROPID{ 1, 0, 0}));
443  BOOST_TEST( data.hasCryostat(readout::ROPID{ 1, 0, 1}));
444  BOOST_TEST( data.hasCryostat(readout::ROPID{ 1, 0, 2}));
445  BOOST_TEST( data.hasCryostat(readout::ROPID{ 1, 1, 0}));
446  BOOST_TEST( data.hasCryostat(readout::ROPID{ 1, 1, 1}));
447  BOOST_TEST( data.hasCryostat(readout::ROPID{ 1, 1, 2}));
448  BOOST_TEST( data.hasCryostat(readout::ROPID{ 1, 2, 0}));
449  BOOST_TEST( data.hasCryostat(readout::ROPID{ 1, 2, 1}));
450  BOOST_TEST( data.hasCryostat(readout::ROPID{ 1, 2, 2}));
451  BOOST_TEST( data.hasCryostat(readout::ROPID{ 1, 3, 0}));
452  BOOST_TEST( data.hasCryostat(readout::ROPID{ 1, 3, 1}));
453  BOOST_TEST( data.hasCryostat(readout::ROPID{ 1, 3, 2}));
454  BOOST_TEST( data.hasCryostat(readout::ROPID{ 1, 4, 0}));
455  BOOST_TEST( data.hasCryostat(readout::ROPID{ 1, 4, 1}));
456  BOOST_TEST( data.hasCryostat(readout::ROPID{ 1, 4, 2}));
457  BOOST_TEST(!data.hasCryostat(readout::ROPID{ 2, 0, 0}));
458  BOOST_TEST(!data.hasCryostat(readout::ROPID{ 2, 0, 1}));
459  BOOST_TEST(!data.hasCryostat(readout::ROPID{ 2, 0, 2}));
460  BOOST_TEST(!data.hasCryostat(readout::ROPID{ 2, 1, 0}));
461  BOOST_TEST(!data.hasCryostat(readout::ROPID{ 2, 1, 1}));
462  BOOST_TEST(!data.hasCryostat(readout::ROPID{ 2, 1, 2}));
463  BOOST_TEST(!data.hasCryostat(readout::ROPID{ 2, 2, 0}));
464  BOOST_TEST(!data.hasCryostat(readout::ROPID{ 2, 2, 1}));
465  BOOST_TEST(!data.hasCryostat(readout::ROPID{ 2, 2, 2}));
466  BOOST_TEST(!data.hasCryostat(readout::ROPID{ 2, 3, 0}));
467  BOOST_TEST(!data.hasCryostat(readout::ROPID{ 2, 3, 1}));
468  BOOST_TEST(!data.hasCryostat(readout::ROPID{ 2, 3, 2}));
469  BOOST_TEST(!data.hasCryostat(readout::ROPID{ 2, 4, 0}));
470  BOOST_TEST(!data.hasCryostat(readout::ROPID{ 2, 4, 1}));
471  BOOST_TEST(!data.hasCryostat(readout::ROPID{ 2, 4, 2}));
472 
473 
474  data[{0, 0, 0}] = 4;
475  BOOST_TEST( (data[{0, 0, 0}]) == 4);
476  BOOST_TEST(data.at({0, 0, 0}) == 4);
477  data[{0, 0, 0}] = 5;
478  BOOST_TEST( (data[{0, 0, 0}]) == 5);
479  BOOST_TEST(data.at({0, 0, 0}) == 5);
480 
481  data[{0, 0, 1}] = 6;
482  BOOST_TEST( (data[{0, 0, 1}]) == 6);
483  BOOST_TEST(data.at({0, 0, 1}) == 6);
484 
485  BOOST_TEST( (data[{0, 0, 0}]) == 5);
486 
487  data[{0, 1, 0}] = 15;
488  BOOST_TEST( (data[{0, 1, 0}]) == 15);
489  BOOST_TEST(data.at({0, 1, 0}) == 15);
490 
491  BOOST_TEST( (data[{0, 0, 0}]) == 5);
492  BOOST_TEST( (data[{0, 0, 1}]) == 6);
493 
494  data[{0, 1, 1}] = 16;
495  BOOST_TEST( (data[{0, 1, 1}]) == 16);
496  BOOST_TEST(data.at({0, 1, 1}) == 16);
497 
498  BOOST_TEST( (data[{0, 0, 0}]) == 5);
499  BOOST_TEST( (data[{0, 0, 1}]) == 6);
500  BOOST_TEST( (data[{0, 1, 0}]) == 15);
501 
502  data[{0, 2, 0}] = 25;
503  BOOST_TEST( (data[{0, 2, 0}]) == 25);
504  BOOST_TEST(data.at({0, 2, 0}) == 25);
505 
506  BOOST_TEST( (data[{0, 0, 0}]) == 5);
507  BOOST_TEST( (data[{0, 0, 1}]) == 6);
508  BOOST_TEST( (data[{0, 1, 0}]) == 15);
509  BOOST_TEST( (data[{0, 1, 1}]) == 16);
510 
511  data[{0, 2, 1}] = 26;
512  BOOST_TEST( (data[{0, 2, 1}]) == 26);
513  BOOST_TEST(data.at({0, 2, 1}) == 26);
514 
515  BOOST_TEST( (data[{0, 0, 0}]) == 5);
516  BOOST_TEST( (data[{0, 0, 1}]) == 6);
517  BOOST_TEST( (data[{0, 1, 0}]) == 15);
518  BOOST_TEST( (data[{0, 1, 1}]) == 16);
519  BOOST_TEST( (data[{0, 2, 0}]) == 25);
520 
521  data[{1, 0, 0}] = 105;
522  BOOST_TEST( (data[{1, 0, 0}]) == 105);
523  BOOST_TEST(data.at({1, 0, 0}) == 105);
524 
525  BOOST_TEST( (data[{0, 0, 0}]) == 5);
526  BOOST_TEST( (data[{0, 0, 1}]) == 6);
527  BOOST_TEST( (data[{0, 1, 0}]) == 15);
528  BOOST_TEST( (data[{0, 1, 1}]) == 16);
529  BOOST_TEST( (data[{0, 2, 0}]) == 25);
530  BOOST_TEST( (data[{0, 2, 1}]) == 26);
531 
532  data[{1, 0, 1}] = 106;
533  BOOST_TEST( (data[{1, 0, 1}]) == 106);
534  BOOST_TEST(data.at({1, 0, 1}) == 106);
535 
536  BOOST_TEST( (data[{0, 0, 0}]) == 5);
537  BOOST_TEST( (data[{0, 0, 1}]) == 6);
538  BOOST_TEST( (data[{0, 1, 0}]) == 15);
539  BOOST_TEST( (data[{0, 1, 1}]) == 16);
540  BOOST_TEST( (data[{0, 2, 0}]) == 25);
541  BOOST_TEST( (data[{0, 2, 1}]) == 26);
542  BOOST_TEST( (data[{1, 0, 0}]) == 105);
543 
544  data[{1, 1, 0}] = 115;
545  BOOST_TEST( (data[{1, 1, 0}]) == 115);
546  BOOST_TEST(data.at({1, 1, 0}) == 115);
547 
548  BOOST_TEST( (data[{0, 0, 0}]) == 5);
549  BOOST_TEST( (data[{0, 0, 1}]) == 6);
550  BOOST_TEST( (data[{0, 1, 0}]) == 15);
551  BOOST_TEST( (data[{0, 1, 1}]) == 16);
552  BOOST_TEST( (data[{0, 2, 0}]) == 25);
553  BOOST_TEST( (data[{0, 2, 1}]) == 26);
554  BOOST_TEST( (data[{1, 0, 0}]) == 105);
555  BOOST_TEST( (data[{1, 0, 1}]) == 106);
556 
557  data[{1, 1, 1}] = 116;
558  BOOST_TEST( (data[{1, 1, 1}]) == 116);
559  BOOST_TEST(data.at({1, 1, 1}) == 116);
560 
561  BOOST_TEST( (data[{0, 0, 0}]) == 5);
562  BOOST_TEST( (data[{0, 0, 1}]) == 6);
563  BOOST_TEST( (data[{0, 1, 0}]) == 15);
564  BOOST_TEST( (data[{0, 1, 1}]) == 16);
565  BOOST_TEST( (data[{0, 2, 0}]) == 25);
566  BOOST_TEST( (data[{0, 2, 1}]) == 26);
567  BOOST_TEST( (data[{1, 0, 0}]) == 105);
568  BOOST_TEST( (data[{1, 0, 1}]) == 106);
569  BOOST_TEST( (data[{1, 1, 0}]) == 115);
570 
571  data[{1, 2, 0}] = 125;
572  BOOST_TEST( (data[{1, 2, 0}]) == 125);
573  BOOST_TEST(data.at({1, 2, 0}) == 125);
574 
575  BOOST_TEST( (data[{0, 0, 0}]) == 5);
576  BOOST_TEST( (data[{0, 0, 1}]) == 6);
577  BOOST_TEST( (data[{0, 1, 0}]) == 15);
578  BOOST_TEST( (data[{0, 1, 1}]) == 16);
579  BOOST_TEST( (data[{0, 2, 0}]) == 25);
580  BOOST_TEST( (data[{0, 2, 1}]) == 26);
581  BOOST_TEST( (data[{1, 0, 0}]) == 105);
582  BOOST_TEST( (data[{1, 0, 1}]) == 106);
583  BOOST_TEST( (data[{1, 1, 0}]) == 115);
584  BOOST_TEST( (data[{1, 1, 1}]) == 116);
585 
586  data[{1, 2, 1}] = 126;
587  BOOST_TEST( (data[{1, 2, 1}]) == 126);
588  BOOST_TEST(data.at({1, 2, 1}) == 126);
589 
590  BOOST_TEST( (data[{0, 0, 0}]) == 5);
591  BOOST_TEST( (data[{0, 0, 1}]) == 6);
592  BOOST_TEST( (data[{0, 1, 0}]) == 15);
593  BOOST_TEST( (data[{0, 1, 1}]) == 16);
594  BOOST_TEST( (data[{0, 2, 0}]) == 25);
595  BOOST_TEST( (data[{0, 2, 1}]) == 26);
596  BOOST_TEST( (data[{1, 0, 0}]) == 105);
597  BOOST_TEST( (data[{1, 0, 1}]) == 106);
598  BOOST_TEST( (data[{1, 1, 0}]) == 115);
599  BOOST_TEST( (data[{1, 1, 1}]) == 116);
600  BOOST_TEST( (data[{1, 2, 0}]) == 125);
601 
602 
603  BOOST_CHECK_THROW(data.at({0, 3, 0}), std::out_of_range);
604  BOOST_CHECK_THROW(data.at({0, 4, 0}), std::out_of_range);
605  BOOST_CHECK_THROW(data.at({1, 3, 0}), std::out_of_range);
606  BOOST_CHECK_THROW(data.at({1, 4, 0}), std::out_of_range);
607  BOOST_CHECK_THROW(data.at({2, 0, 0}), std::out_of_range);
608  BOOST_CHECK_THROW(data.at({2, 1, 0}), std::out_of_range);
609  BOOST_CHECK_THROW(data.at({2, 2, 0}), std::out_of_range);
610  BOOST_CHECK_THROW(data.at({2, 3, 0}), std::out_of_range);
611  BOOST_CHECK_THROW(data.at({2, 4, 0}), std::out_of_range);
612  BOOST_CHECK_THROW(data.at({0, 3, 1}), std::out_of_range);
613  BOOST_CHECK_THROW(data.at({0, 4, 1}), std::out_of_range);
614  BOOST_CHECK_THROW(data.at({1, 3, 1}), std::out_of_range);
615  BOOST_CHECK_THROW(data.at({1, 4, 1}), std::out_of_range);
616  BOOST_CHECK_THROW(data.at({2, 0, 1}), std::out_of_range);
617  BOOST_CHECK_THROW(data.at({2, 1, 1}), std::out_of_range);
618  BOOST_CHECK_THROW(data.at({2, 2, 1}), std::out_of_range);
619  BOOST_CHECK_THROW(data.at({2, 3, 1}), std::out_of_range);
620  BOOST_CHECK_THROW(data.at({2, 4, 1}), std::out_of_range);
621  BOOST_CHECK_THROW(data.at({0, 0, 2}), std::out_of_range);
622  BOOST_CHECK_THROW(data.at({0, 1, 2}), std::out_of_range);
623  BOOST_CHECK_THROW(data.at({0, 2, 2}), std::out_of_range);
624  BOOST_CHECK_THROW(data.at({0, 3, 2}), std::out_of_range);
625  BOOST_CHECK_THROW(data.at({1, 0, 2}), std::out_of_range);
626  BOOST_CHECK_THROW(data.at({1, 1, 2}), std::out_of_range);
627  BOOST_CHECK_THROW(data.at({1, 2, 2}), std::out_of_range);
628  BOOST_CHECK_THROW(data.at({1, 3, 2}), std::out_of_range);
629  BOOST_CHECK_THROW(data.at({2, 0, 2}), std::out_of_range);
630  BOOST_CHECK_THROW(data.at({2, 1, 2}), std::out_of_range);
631  BOOST_CHECK_THROW(data.at({2, 2, 2}), std::out_of_range);
632  BOOST_CHECK_THROW(data.at({2, 3, 2}), std::out_of_range);
633 
634  BOOST_TEST(data.first() == 5);
635  data.first() = -5;
636  BOOST_TEST((data[{0, 0, 0}]) == -5);
637  BOOST_TEST(data.first() == -5);
638  data.first() = 5;
639 
640  BOOST_TEST(data.last() == 126);
641  data.last() = -126;
642  BOOST_TEST((data[{1U, 2U, 1U}]) == -126);
643  BOOST_TEST(data.last() == -126);
644  data.last() = 126;
645 
646  auto const& constData = data;
647 
648  BOOST_TEST
649  (std::addressof(constData.first()) == std::addressof(data.first()));
650  BOOST_TEST
651  (std::addressof(constData.last()) == std::addressof(data.last()));
652 
653  BOOST_TEST((constData[{0, 0, 0}]) == (data[{0, 0, 0}]));
654  BOOST_TEST((constData[{0, 0, 1}]) == (data[{0, 0, 1}]));
655  BOOST_TEST((constData[{0, 1, 0}]) == (data[{0, 1, 0}]));
656  BOOST_TEST((constData[{0, 1, 1}]) == (data[{0, 1, 1}]));
657  BOOST_TEST((constData[{0, 2, 0}]) == (data[{0, 2, 0}]));
658  BOOST_TEST((constData[{0, 2, 1}]) == (data[{0, 2, 1}]));
659  BOOST_TEST((constData[{1, 0, 0}]) == (data[{1, 0, 0}]));
660  BOOST_TEST((constData[{1, 0, 1}]) == (data[{1, 0, 1}]));
661  BOOST_TEST((constData[{1, 1, 0}]) == (data[{1, 1, 0}]));
662  BOOST_TEST((constData[{1, 1, 1}]) == (data[{1, 1, 1}]));
663  BOOST_TEST((constData[{1, 2, 0}]) == (data[{1, 2, 0}]));
664  BOOST_TEST((constData[{1, 2, 1}]) == (data[{1, 2, 1}]));
665  BOOST_TEST(constData.at({0, 0, 0}) == data.at({0, 0, 0}));
666  BOOST_TEST(constData.at({0, 0, 1}) == data.at({0, 0, 1}));
667  BOOST_TEST(constData.at({0, 1, 0}) == data.at({0, 1, 0}));
668  BOOST_TEST(constData.at({0, 1, 1}) == data.at({0, 1, 1}));
669  BOOST_TEST(constData.at({0, 2, 0}) == data.at({0, 2, 0}));
670  BOOST_TEST(constData.at({0, 2, 1}) == data.at({0, 2, 1}));
671  BOOST_TEST(constData.at({1, 0, 0}) == data.at({1, 0, 0}));
672  BOOST_TEST(constData.at({1, 0, 1}) == data.at({1, 0, 1}));
673  BOOST_TEST(constData.at({1, 1, 0}) == data.at({1, 1, 0}));
674  BOOST_TEST(constData.at({1, 1, 1}) == data.at({1, 1, 1}));
675  BOOST_TEST(constData.at({1, 2, 0}) == data.at({1, 2, 0}));
676  BOOST_TEST(constData.at({1, 2, 1}) == data.at({1, 2, 1}));
677 
678  BOOST_CHECK_THROW(constData.at({0, 3, 0}), std::out_of_range);
679  BOOST_CHECK_THROW(constData.at({0, 4, 0}), std::out_of_range);
680  BOOST_CHECK_THROW(constData.at({1, 3, 0}), std::out_of_range);
681  BOOST_CHECK_THROW(constData.at({1, 4, 0}), std::out_of_range);
682  BOOST_CHECK_THROW(constData.at({2, 0, 0}), std::out_of_range);
683  BOOST_CHECK_THROW(constData.at({2, 1, 0}), std::out_of_range);
684  BOOST_CHECK_THROW(constData.at({2, 2, 0}), std::out_of_range);
685  BOOST_CHECK_THROW(constData.at({2, 3, 0}), std::out_of_range);
686  BOOST_CHECK_THROW(constData.at({2, 4, 0}), std::out_of_range);
687  BOOST_CHECK_THROW(constData.at({0, 3, 1}), std::out_of_range);
688  BOOST_CHECK_THROW(constData.at({0, 4, 1}), std::out_of_range);
689  BOOST_CHECK_THROW(constData.at({1, 3, 1}), std::out_of_range);
690  BOOST_CHECK_THROW(constData.at({1, 4, 1}), std::out_of_range);
691  BOOST_CHECK_THROW(constData.at({2, 0, 1}), std::out_of_range);
692  BOOST_CHECK_THROW(constData.at({2, 1, 1}), std::out_of_range);
693  BOOST_CHECK_THROW(constData.at({2, 2, 1}), std::out_of_range);
694  BOOST_CHECK_THROW(constData.at({2, 3, 1}), std::out_of_range);
695  BOOST_CHECK_THROW(constData.at({2, 4, 1}), std::out_of_range);
696  BOOST_CHECK_THROW(constData.at({0, 0, 2}), std::out_of_range);
697  BOOST_CHECK_THROW(constData.at({0, 1, 2}), std::out_of_range);
698  BOOST_CHECK_THROW(constData.at({0, 2, 2}), std::out_of_range);
699  BOOST_CHECK_THROW(constData.at({0, 3, 2}), std::out_of_range);
700  BOOST_CHECK_THROW(constData.at({1, 0, 2}), std::out_of_range);
701  BOOST_CHECK_THROW(constData.at({1, 1, 2}), std::out_of_range);
702  BOOST_CHECK_THROW(constData.at({1, 2, 2}), std::out_of_range);
703  BOOST_CHECK_THROW(constData.at({1, 3, 2}), std::out_of_range);
704  BOOST_CHECK_THROW(constData.at({2, 0, 2}), std::out_of_range);
705  BOOST_CHECK_THROW(constData.at({2, 1, 2}), std::out_of_range);
706  BOOST_CHECK_THROW(constData.at({2, 2, 2}), std::out_of_range);
707  BOOST_CHECK_THROW(constData.at({2, 3, 2}), std::out_of_range);
708 
709 
710  auto const cb = constData.begin();
711  auto const ce = constData.end();
712  BOOST_TEST(static_cast<size_t>(ce - cb) == N);
713 
714  // simple read-only iteration test
715  expected_index = 0U;
716  for (auto& value: constData) {
717  static_assert(std::is_same_v
718  <decltype(value), std::decay_t<decltype(constData)>::const_reference>
719  );
720 
721  readout::ROPID const expected_ID = constData.mapper().ID(expected_index);
722  BOOST_TEST(value == constData[expected_ID]);
723 
724  ++expected_index;
725  } // for
726  BOOST_TEST(constData.size() == expected_index);
727 
728  // ID/data pair read-only iteration test
729  expected_index = 0U;
730  for (auto&& [ ID, value ]: constData.items()) {
731  static_assert(std::is_same_v<decltype(ID), readout::ROPID>);
732  static_assert(std::is_same_v
733  <decltype(value), std::decay_t<decltype(constData)>::const_reference>
734  );
735 
736  readout::ROPID const expected_ID = constData.mapper().ID(expected_index);
737  BOOST_TEST(ID == expected_ID);
738  BOOST_TEST(value == constData[expected_ID]);
739 
740  ++expected_index;
741  } // for
742  BOOST_TEST(constData.size() == expected_index);
743 
744 
745  data.fill(14);
746  for (auto c: util::counter<unsigned int>(NCryostats))
747  for (auto s: util::counter<unsigned short int>(NTPCsets))
748  for (auto r: util::counter<unsigned int>(NROPs))
749  BOOST_TEST((data[{ c, s, r }]) == 14);
750 
751  data.apply([](int& v){ v *= 2; });
752  for (auto c: util::counter<unsigned int>(NCryostats))
753  for (auto s: util::counter<unsigned short int>(NTPCsets))
754  for (auto r: util::counter<unsigned int>(NROPs))
755  BOOST_TEST((data[{ c, s, r }]) == 28);
756 
757  Summer<int> summer;
758  static_assert(std::is_same_v<decltype(data.apply(summer)), Summer<int>&>);
759  data.apply(summer);
760  BOOST_TEST(summer.get() == N * 28);
761 
762  summer.reset();
763  static_assert
764  (std::is_same_v<decltype(constData.apply(summer)), Summer<int>&>);
765  constData.apply(summer);
766  BOOST_TEST(summer.get() == N * 28);
767 
768  auto summer1 = data.apply(Summer<int>{});
769  BOOST_TEST(summer1.get() == N * 28);
770 
771  auto summer2 = constData.apply(Summer<int>{});
772  BOOST_TEST(summer2.get() == N * 28);
773 
774  data.reset();
775  for (auto c: util::counter<unsigned int>(NCryostats))
776  for (auto s: util::counter<unsigned short int>(NTPCsets))
777  for (auto r: util::counter<unsigned int>(NROPs))
778  BOOST_TEST((data[{ c, s, r }]) == 0);
779 
780  data.clear();
781  BOOST_TEST(data.empty());
782 
783 
784 } // ROPDataContainerTest()
785 
786 
787 BOOST_AUTO_TEST_SUITE(readoutdatacontainers_test)
788 
789 //------------------------------------------------------------------------------
790 BOOST_AUTO_TEST_CASE(TPCsetDataContainerTestCase) {
791 
792  constexpr std::size_t NCryostats = 2U;
793  constexpr std::size_t NTPCsets = 3U;
794 
795  //
796  // size constructor
797  //
798  readout::TPCsetDataContainer<int> data1(NCryostats, NTPCsets);
799  TPCsetDataContainerTest(data1, NCryostats, NTPCsets);
800 
801  //
802  // default constructor + resize
803  //
805  BOOST_TEST(data2.empty());
806 
807  data2.resizeAs(data1);
808  TPCsetDataContainerTest(data2, NCryostats, NTPCsets);
809 
810 } // TPCsetDataContainerTestCase
811 
812 
813 //------------------------------------------------------------------------------
814 BOOST_AUTO_TEST_CASE(ROPDataContainerTestCase) {
815 
816  constexpr std::size_t NCryostats = 2U;
817  constexpr std::size_t NTPCsets = 3U;
818  constexpr std::size_t NROPs = 2U;
819 
820  //
821  // size constructor
822  //
823  readout::ROPDataContainer<int> data1(NCryostats, NTPCsets, NROPs);
824  ROPDataContainerTest(data1, NCryostats, NTPCsets, NROPs);
825 
826  //
827  // default constructor + resize
828  //
830  BOOST_TEST(data2.empty());
831 
832  data2.resizeAs(data1);
833  ROPDataContainerTest(data2, NCryostats, NTPCsets, NROPs);
834 
835 } // ROPDataContainerTestCase
836 
837 
838 //------------------------------------------------------------------------------
839 
840 BOOST_AUTO_TEST_SUITE_END()
Container with one element per readout TPC set.
GeoID firstID() const
Returns the ID of the first element with GeoID type.
GeoID lastID() const
Returns the ID of the last covered element with GeoID type.
Classes identifying readout-related concepts.
unsigned int ID
Container with one element per readout plane.
size_type capacity() const
Returns the number of elements the container has memory for.
Class identifying a set of TPC sharing readout channels.
Definition: readout_types.h:70
void TPCsetDataContainerTest(readout::TPCsetDataContainer< int > data, std::size_t const NCryostats, std::size_t const NTPCsets)
readout::ROPID ROPID
BOOST_AUTO_TEST_CASE(TPCsetDataContainerTestCase)
IDparameter< readout::TPCsetID > TPCsetID
Member type of validated readout::TPCsetID parameter.
Test of util::counter and support utilities.
Class identifying a set of planes sharing readout channels.
size_type size() const
Returns the number of elements in the container.
void ROPDataContainerTest(readout::ROPDataContainer< int > data, std::size_t const NCryostats, std::size_t const NTPCsets, std::size_t const NROPs)
bool empty() const
Returns whether the container has no elements (false by assumptions).
void resizeAs(geo::GeoIDdataContainer< OT, Mapper_t > const &other)
Prepares the container with default-constructed data.
Containers to hold one datum per TPC set or readout plane.
static QCString * s
Definition: config.cpp:1042