ATLAS Offline Software
TableUtils.h
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 #ifndef TABLE_UTILS_H
5 #define TABLE_UTILS_H
6 
7 #include <array>
8 #include <string>
9 #include <cassert>
10 #include <iomanip>
11 #include <ostream>
12 #include <stdexcept>
13 #include <vector>
14 #include <utility>
15 #include <limits>
16 
17 class MsgStream;
18 
19 // Utility class to wrap a constant variable length array interface over static sized arrays
20 // This avoid duplication of compiled code for arrays which only differ
21 // by the number of elements.
22 // The interface is sufficient to allow using the wrapped arrays in range based for loops,
23 // and for random access.
24 namespace TableUtils {
25  template <typename T>
26  struct Range {
27  const T *m_ptr = nullptr;
28  std::size_t m_size = 0u;
29  std::size_t m_offset = 1u;
30 
31  struct const_iterator {
32  const_iterator &operator++() { m_ptr += m_offset; return *this; }
33  const T &operator*() const { return *m_ptr; }
34  bool operator!=(const const_iterator &other) const { return m_ptr != other.m_ptr; }
35  const T *m_ptr;
36  std::size_t m_offset;
37  };
38  const_iterator begin() const {
39  return const_iterator{ m_ptr, m_offset };
40  }
41  const_iterator end() const {
42  assert( (m_size % m_offset) == 0 );
43  return const_iterator{ m_ptr+m_size, m_offset };
44  }
45  const T &operator[](std::size_t index) const { assert(index<m_size && m_ptr); return m_ptr[index]; }
46 
47  std::size_t size() const { return m_size; }
48 
49  operator bool() const { return m_ptr != nullptr && m_size>0; }
50  template <typename T_Other>
51  bool equalSize(const T_Other &other_range) {
52  return m_size == other_range.m_size;
53  }
54  };
55 
56  // Utility class to wrap a constant two dimensional variable length array interface over static sized arrays
57  // This avoid duplication of compiled code for arrays which only differ
58  // by the number of elements in the two dimensions.
59  // The interface is sufficient to allow using the wrapped arrays in range based for loops,
60  // and for random access.
61  template <typename T>
62  struct Range2D {
63  const T *m_ptr = nullptr;
64  std::size_t m_rows = 0u;
65  std::size_t m_columns = 0u;
66  std::size_t m_columnOffset = 0u;
67  std::size_t m_firstColumnIndex = 0u;
68  std::size_t m_offset = 1u;
69 
70  struct const_iterator {
71  const_iterator &operator++() { m_ptr += m_columnOffset; return *this; }
72  Range<T> operator*() const { return Range<T> { m_ptr, m_columns, m_offset }; }
73  bool operator!=(const const_iterator &other) const { return m_ptr != other.m_ptr; }
74  const T *m_ptr;
75  std::size_t m_columns;
76  std::size_t m_columnOffset;
77  std::size_t m_firstColumnIndex;
78  std::size_t m_offset;
79  };
80 
83  }
84  const_iterator end() const {
86  }
87  Range<T> operator[](std::size_t index) const {
88  assert(index<m_rows && m_ptr);
90  }
91 
92  std::size_t nColumns() const { return m_columns; }
93  std::size_t nRows() const { return m_rows; }
94 
95  operator bool() { return m_ptr != nullptr && m_columns>0; }
96  template <typename T_Other>
97  bool equalSize(const T_Other &other_range) {
98  return m_rows == other_range.m_size;
99  }
100  };
101 
102  // Helper method to print wrapped static arrays in table form to an output stream
103  // The table will be composed of one column for row labels and one column for the data
104  template <class T_Stream, typename T_Counter>
105  T_Stream &dumpTable(T_Stream &out,
107  const Range<std::string>& label,
108  const std::string &label_prefix,
109  const std::size_t column_width,
110  const std::size_t min_label_width,
111  const bool dump_footer,
112  const bool separate_last_row,
113  const unsigned int precision) {
114  if (counter && label && counter.equalSize(label)) {
115  std::size_t max_size =min_label_width;
116  for (const std::string &name : label ) {
117  max_size = std::max(max_size, name.size());
118  }
119  const std::size_t total_size =max_size+3+2*2+column_width;
120  std::string line(total_size, '-');
121  std::array<std::size_t,3> vertical_line_pos{0u, max_size+3, line.size()-1};
122  for (std::size_t pos : vertical_line_pos) {
123  line[pos]='|';
124  }
125  out << line << std::endl;
126  std::size_t idx=0;
127  std::string empty;
128  auto default_precision = out.precision();
129  for (const T_Counter &a : counter) {
130  if (separate_last_row && idx+1 == label.size()) {
131  out << line << std::endl;
132  }
133  assert( idx < label.size());
134  out << "| " << (label_prefix.empty() ? std::left : std::right)
135  << std::setw(label_prefix.size()) << ( idx==0 ? label_prefix : empty)
136  << std::setw(max_size-label_prefix.size()) << label[idx] << std::right
137  << std::setprecision( precision != std::numeric_limits<unsigned int>::max() ? precision : default_precision)
138  << " | " << std::setw(column_width) << a << " |" << std::endl;
139  ++idx;
140  }
141  out << std::setprecision(default_precision);
142  if (dump_footer) {
143  out << line << std::endl;
144  }
145  }
146  return out;
147  }
148 
149  // Helper method to print wrapped static two dimensional arrays in table form to an output stream
150  // The table will be composed of a header showing column labels, one column for row labels and
151  // then column for each data item. The array is expected in row major order.
152  template <class T_Stream, typename T_Counter>
153  T_Stream &dumpTable(T_Stream &out,
155  const Range<std::string>& row_label,
156  const Range<std::string>& column_label,
157  const std::string &top_left_label,
158  const std::string &label_prefix,
159  const std::size_t column_width,
160  const std::size_t min_label_width,
161  const bool dump_header,
162  const bool dump_footer,
163  const bool separate_last_row,
164  const std::vector<unsigned int> &precision) {
165  if (counter && row_label && column_label
166  && counter.equalSize(row_label)
167  && counter.nColumns() == column_label.size()) {
168  std::size_t max_size =std::max(top_left_label.size(), static_cast<std::size_t>(min_label_width));
169  for (const std::string &name : row_label ) {
170  max_size = std::max(max_size, name.size() + label_prefix.size());
171  }
172  std::size_t the_width = column_width;
173  for (const std::string &name : column_label ) {
174  the_width = std::max(the_width, name.size());
175  }
176  std::size_t total_size =max_size+2*2;
177  for (std::size_t column_i=0; column_i<column_label.size(); ++column_i) {
178  total_size += the_width + 3;
179  }
180  std::string line(total_size, '-');
181  std::size_t pos=0;
182  line[pos]='|';
183  pos += max_size+3;
184  for (std::size_t column_i=0; column_i<column_label.size(); ++column_i) {
185  line[pos]='|';
186  pos += the_width + 3;
187  }
188  line[line.size()-1]='|';
189  if (dump_header) {
190  out << line << std::endl << "| " << std::setw(max_size) << top_left_label << " |" << std::left;
191  for (const std::string &header : column_label ) {
192  out << " " << std::setw(the_width) << header << " |";
193  }
194  out << std::right << std::endl;
195  }
196  out << line << std::endl;
197  std::size_t idx=0;
198  std::string empty;
199  auto default_precision = out.precision();
200  for (const Range<T_Counter> &a_row : counter) {
201  if (separate_last_row && idx+1 == row_label.size()) {
202  out << line << std::endl;
203  }
204  assert( idx < row_label.size());
205  out << "| " << (label_prefix.empty() ? std::left : std::right)
206  << std::setw(label_prefix.size()) << ( idx==0 ? label_prefix : empty)
207  << std::setw(max_size-label_prefix.size()) << row_label[idx] << std::right << " |";
208  unsigned int col_i=0;
209  for (const T_Counter &a : a_row) {
210  out << " "
211  << std::setprecision( (col_i < precision.size()
212  && precision[col_i] != std::numeric_limits<unsigned int>::max())
213  ? precision[col_i]
214  : default_precision)
215  << std::setw(the_width) << a << " |";
216  ++col_i;
217  }
218  out << std::endl;
219  ++idx;
220  }
221  out << std::setprecision(default_precision);
222  if (dump_footer) {
223  out << line;
224  }
225  }
226  return out;
227  }
228 
229  // Helper struct to wrap data that should be dumped in table from to an output stream
230  template <typename T>
231  struct StatTable {
234  StatTable &columnWidth(std::size_t value) { m_columnWidth=value; return *this;}
235  StatTable &minLabelWidth(std::size_t value) { m_minLabelWidth=value; return *this;}
236  StatTable &dumpHeader(bool value=true) { m_dumpHeader=value; return *this;}
237  StatTable &dumpFooter(bool value=true) { m_dumpFooter=value; return *this;}
238  StatTable &separateLastRow(bool value=true) { m_separateLastRow=value; return *this;}
239  StatTable &labelPrefix(const std::string& value) { m_labelPrefix=value; return *this;}
240  StatTable &precision(unsigned int precision) { m_precision=precision; return *this;}
241 
242  std::string m_labelPrefix {};
243  std::size_t m_columnWidth=12;
244  std::size_t m_minLabelWidth=0;
246  bool m_dumpHeader=true;
247  bool m_dumpFooter=true;
248  bool m_separateLastRow=false;
249  };
250  // Helper struct to wrap two dimensional data that should be dumped in table from to an output stream
251  template <typename T>
256  std::string m_topLeftLable;
257  MultiColumnTable &columnWidth(std::size_t value) { m_columnWidth=value; return *this;}
258  MultiColumnTable &minLabelWidth(std::size_t value) { m_minLabelWidth=value; return *this;}
259  MultiColumnTable &dumpHeader(bool value=true) { m_dumpHeader=value; return *this;}
260  MultiColumnTable &dumpFooter(bool value=true) { m_dumpFooter=value; return *this;}
262  MultiColumnTable &labelPrefix(const std::string& value) { m_labelPrefix=value; return *this;}
263  MultiColumnTable &precision(std::vector<unsigned int> &&precision) { m_precision=std::move(precision); return *this;}
264 
265  std::string m_labelPrefix {};
266  std::size_t m_columnWidth=12;
267  std::size_t m_minLabelWidth=0;
268  std::vector<unsigned int> m_precision{};
269  bool m_dumpHeader=true;
270  bool m_dumpFooter=true;
271  bool m_separateLastRow=false;
272  };
273 
274  template <typename T_index, class T_string>
275  std::vector<std::string> makeLabelVector(T_index n_entries,
276  std::initializer_list<std::pair<T_index, T_string> > a_list)
277  {
278  std::vector<std::string> labels;
279  labels.resize( n_entries );
280  if (a_list.size() != n_entries) {
281  throw std::logic_error("Expected number of entries and elements in the initializer lists do not match.");
282  }
283  for ( auto elm : a_list) {
284  labels.at(elm.first) = std::move(elm.second);
285  }
286  return labels;
287  }
288 
289  template<class T_Collection>
290  std::size_t maxLabelWidth( const T_Collection &col) {
291  std::size_t max_width=0u;
292  for (const auto &elm : col ) {
293  max_width = std::max( max_width, elm.size());
294  }
295  return max_width;
296  }
297 
298 
299  constexpr inline std::size_t categoryStride([[maybe_unused]] const std::size_t categories,
300  [[maybe_unused]] const std::size_t sub_categories,
301  [[maybe_unused]] const std::size_t n_counter) {
302  return 1;
303  }
304  constexpr inline std::size_t subCategoryStride([[maybe_unused]] const std::size_t categories,
305  [[maybe_unused]] const std::size_t sub_categories,
306  [[maybe_unused]] const std::size_t n_counter) {
307  return (categories+1) * n_counter;
308  }
309  constexpr inline std::size_t counterStride([[maybe_unused]] const std::size_t categories,
310  [[maybe_unused]] const std::size_t sub_categories,
311  [[maybe_unused]] const std::size_t n_counter) {
312  return (categories+1);
313  }
314 
315 
316  // change order of input statistics counter and compute projections
317  // - order: change from array[category*category_stride+sub_category][counter]
318  // to array[sub_category*sub_category_stride+counter*counter_stride+category]
319  // - projections: sum numbers in direction of category and sub_category direction, respectively.
320  // - dimension of the resulting vector: (categories+1) * (sub_categories+1) * N
321  template< typename T_Output, typename T_Input, const std::size_t N>
322  std::vector<T_Output> createCounterArrayWithProjections( const std::size_t categories,
323  const std::size_t sub_categories,
324  const std::vector< std::array<T_Input, N> > &input_counts) {
325  if (categories*sub_categories!= input_counts.size()) {
326  std::stringstream msg;
327  msg << "Category dimensions (" << categories << " * " << sub_categories << "="
328  << (categories * sub_categories) << ") and input counter container size "
329  << input_counts.size() << " do not match.";
330  throw std::logic_error(msg.str());
331  }
332  std::vector<T_Output> output_counts;
333  output_counts.resize((categories+1) * (sub_categories+1) * N);
334  const std::size_t sub_category_stride = subCategoryStride(categories, sub_categories, N);
335  const std::size_t counter_stride = counterStride(categories, sub_categories, N);
336  const std::size_t category_stride = categoryStride(categories, sub_categories, N);
337  // project seeds
338  for (std::size_t sub_category_i=0;
339  sub_category_i < sub_categories;
340  ++sub_category_i) {
341  for (std::size_t category_i=0; category_i<categories; ++category_i) {
342  std::size_t src_idx = category_i * sub_categories + sub_category_i;
343  std::size_t dest_idx_base = sub_category_i * sub_category_stride + 0 * counter_stride;
344  std::size_t dest_idx_project_categories_base = dest_idx_base;
345  dest_idx_base += category_i * category_stride;
346  dest_idx_project_categories_base += categories * category_stride;
347 
348  for (std::size_t counter_i=0; counter_i<N; ++counter_i) {
349  std::size_t dest_idx=dest_idx_base + counter_i * counter_stride;
350  assert( src_idx < input_counts.size() && counter_i < input_counts[src_idx].size());
351  assert( dest_idx < output_counts.size());
352  output_counts[dest_idx] = input_counts[src_idx][counter_i];
353  assert( dest_idx_project_categories_base + counter_i * counter_stride < output_counts.size());
354  output_counts[dest_idx_project_categories_base + counter_i * counter_stride] += output_counts[dest_idx];
355  }
356  }
357  }
358  // project eta bins
359  for (std::size_t category_i=0; category_i<=categories; ++category_i) {
360  for (std::size_t counter_i=0; counter_i<N; ++counter_i) {
361  std::size_t dest_idx_base = 0 * sub_category_stride + counter_i * counter_stride + category_i;
362  std::size_t dest_idx_project_sub_categories = sub_categories * sub_category_stride + dest_idx_base;
363  assert( dest_idx_project_sub_categories < output_counts.size() );
364  for (std::size_t sub_category_i=0;
365  sub_category_i<sub_categories;
366  ++sub_category_i) {
367  std::size_t sub_category_idx = dest_idx_base + sub_category_i * sub_category_stride;
368  assert( sub_category_idx < output_counts.size() );
369  output_counts[dest_idx_project_sub_categories] += output_counts[sub_category_idx];
370  }
371  }
372  }
373  return output_counts;
374  }
375 
376  using SummandDefinition = std::pair<std::size_t, int>;
377  using RatioDefinition = std::pair< std::vector< SummandDefinition >,
378  std::vector< SummandDefinition > >;
379 
380  // helper to create the sum definitions for the ratio of single counters
381  // this will lead to the computation of the simple ratio defined by counter[numerator] / counter[denominatpr]
382  template <typename T>
383  inline RatioDefinition
384  defineSimpleRatio(T numerator, T denominator) {
385  return std::make_pair( std::vector< SummandDefinition > { std::make_pair(static_cast<std::size_t>(numerator),1)},
386  std::vector< SummandDefinition > { std::make_pair(static_cast<std::size_t>(denominator),1)});
387  }
388 
389  // helper to create a named ratio definition for a ratio of two single counters
390  template <typename T>
391  inline std::tuple< std::string, RatioDefinition >
392  defineSimpleRatio(std::string &&name, T numerator, T denominator) {
393  return std::make_pair( std::move(name), defineSimpleRatio(numerator, denominator) );
394  }
395 
396 
397  // helper to create a single summand definition to be used in a ratio definition
398  // @param counter_idx the index of a counter
399  // @param multiplier a multiplier to be applied to the value of the referenced counter e.g. +1 or -1.
400  // @return the definition of a single summand to be appended to a vector
401  template <typename T>
402  inline SummandDefinition defineSummand(T counter_idx, int multiplier) {
403  return std::make_pair(static_cast<std::size_t>(counter_idx), multiplier) ;
404  }
405 
406  // compute the sum : sum_j stat[ eta_bin][stat_j][seed] * multiplier_j
407  // where the index stat_j is the first element of the pair, and the second element is multiplier_j
408  std::size_t computeSum( const std::vector< SummandDefinition > &sum_def,
409  std::size_t eta_offset,
410  std::size_t row_stride,
411  std::size_t seed_i,
412  const std::vector<std::size_t> &stat);
413 
414  inline float computeRatio(std::size_t numerator, std::size_t denominator) {
415  return numerator!=0 ? static_cast<float>(numerator/static_cast<double>(denominator)) : 0.f;
416  }
417 
418  // compute the ratio of two sums;
419  // @param ratio_def vectors which define summands for the numerator and denominator
420  // The first element of the pair defines the numberator, which is computed by summing the referenced
421  // counters (first element of the inner pair is the counter index) after multiplying them by the
422  // multiplier (second element of the inner pair). The second elment defines the denominator of
423  // the ratio.
424  inline float computeRatio( const RatioDefinition &ratio_def,
425  std::size_t eta_offset,
426  std::size_t row_stride,
427  std::size_t seed_i,
428  const std::vector<std::size_t> &stat) {
429  std::size_t numerator=computeSum(ratio_def.first, eta_offset, row_stride, seed_i, stat);
430  std::size_t denominator=!ratio_def.second.empty()
431  ? computeSum(ratio_def.second, eta_offset, row_stride, seed_i, stat)
432  : 1;
433  return computeRatio(numerator,denominator);
434  }
435 
436 
437  // helper function to define a named ratio
438  inline std::tuple< std::string, RatioDefinition> makeRatioDefinition(std::string &&name,
439  std::vector< SummandDefinition >&&numerator,
440  std::vector< SummandDefinition >&&denominator) {
441  return std::make_tuple(std::move(name),
442  std::make_pair(std::move(numerator),
443  std::move(denominator)));
444  }
445 
446  // helper function to split a list of named ratio definitions into a vector of labels and ratio definitions
447  inline std::tuple<std::vector<std::string>, std::vector<RatioDefinition> >
448  splitRatioDefinitionsAndLabels(std::initializer_list<std::tuple<std::string, RatioDefinition> > a_ratio_list)
449  {
450  std::tuple< std::vector<std::string>, std::vector<RatioDefinition> > splitted;
451  std::get<0>(splitted).reserve( a_ratio_list.size() );
452  for ( auto a_ratio : a_ratio_list) {
453  std::get<0>(splitted).emplace_back( std::move(std::get<0>(a_ratio)) );
454  }
455  std::get<1>(splitted).reserve( a_ratio_list.size() );
456  for ( auto a_ratio : a_ratio_list) {
457  std::get<1>(splitted).emplace_back( std::move(std::get<1>(a_ratio)) );
458  }
459  return splitted;
460  }
461 
462 
463  constexpr inline std::size_t categoryStride([[maybe_unused]] const std::size_t categories,
464  [[maybe_unused]] const std::size_t sub_categories,
465  [[maybe_unused]] const std::vector<RatioDefinition> &ratio_def) {
466  return 1;
467  }
468  inline std::size_t subCategoryStride([[maybe_unused]] const std::size_t categories,
469  [[maybe_unused]] const std::size_t sub_categories,
470  [[maybe_unused]] const std::vector<RatioDefinition> &ratio_def) {
471  return (categories) * ratio_def.size();
472  }
473  constexpr inline std::size_t ratioStride([[maybe_unused]] const std::size_t categories,
474  [[maybe_unused]] const std::size_t sub_categories,
475  [[maybe_unused]] const std::vector<RatioDefinition> &ratio_def) {
476  return (categories);
477  }
478 
479 
480  std::vector<float> computeRatios(const std::vector<RatioDefinition> &ratio_def,
481  const std::size_t categories,
482  const std::size_t sub_categories,
483  const std::vector< std::size_t> &counter);
484 
485  inline std::string makeBinLabel(const std::string &variable_name,
486  const std::vector<float> &bins,
487  std::size_t bin_i,
488  bool abs_value=false,
489  int precision=1) {
490  std::stringstream range_label;
491  range_label << std::fixed << std::setprecision(precision);
492  if (bin_i==bins.size()+1) {
493  range_label << " All " << variable_name;
494  }
495  else {
496  if (bin_i==0) {
497  std::stringstream value_str;
498  value_str << std::fixed << std::setprecision(precision) << 0.;
499  range_label << std::setw(4) << (abs_value ? value_str.str().c_str() : "-inf") << "-";
500  }
501  else {
502  range_label << std::setw(4) << bins.at(bin_i-1) <<"-";
503  }
504  if (bin_i>=bins.size()) {
505  range_label << std::setw(4) << "+inf";
506  }
507  else {
508  range_label << std::setw(4) << bins.at(bin_i);
509  }
510  }
511  return range_label.str();
512  }
513 
514  inline std::string makeEtaBinLabel(const std::vector<float> &eta_bins,
515  std::size_t eta_bin_i,
516  bool abs_eta=false) {
517  return TableUtils::makeBinLabel("eta",eta_bins, eta_bin_i,abs_eta, 1);
518  }
519 }
520 // Helper method to wrap data that should be dumped in table form to an output stream
521 // Usage: out << makeTable( array, labels);
522 template <typename T, std::size_t N>
524  const std::array<std::string, N> &label) {
525  return TableUtils::StatTable<T> {
526  TableUtils::Range<T> {counter.data(), counter.size()},
527  TableUtils::Range<std::string> {label.data(), label.size() }
528  };
529 }
530 
531 // Helper method to wrap two dimensional data that should be dumped in table form to an output stream
532 template <typename T, std::size_t Nrows, std::size_t Ncolumns>
533 TableUtils::MultiColumnTable<T> makeTable(const std::array<std::array<T, Ncolumns>, Nrows> &counter,
534  const std::array<std::string, Nrows> &row_label,
535  const std::array<std::string, Ncolumns> &column_label,
536  const std::string &top_left_label="") {
538  TableUtils::Range2D<T> {!counter.empty() ? counter[0].data() : nullptr,
539  counter.size(), column_label.size(),
540  !counter.empty() ? static_cast<std::size_t>(&counter[1][0] - &counter[0][0]) : 0u,
541  0u, // index of first column
542  1u}, // offset between columns
543  TableUtils::Range<std::string> {row_label.data(), row_label.size(), 1u},
544  TableUtils::Range<std::string> {column_label.data(), column_label.size(),1u},
545  top_left_label
546  };
547 }
548 
549 // Helper method to wrap two dimensional data that should be dumped in table form to an output stream
550 template <typename T>
552  std::size_t start_idx,
553  std::size_t row_stride,
554  const std::vector<std::string> &row_label,
555  const std::vector<std::string> &column_label,
556  const std::string &top_left_label="") {
557  if (start_idx + (row_label.size()-1) * row_stride >= counter.size() || row_stride < column_label.size()) {
558  std::stringstream msg;
559  msg << "Counter dimension and label dimensions (" << row_label.size() << " * " << column_label.size()
560  << ") do not match: [" << start_idx << ", "
561  << start_idx << " + " << (row_label.size()-1) << " * " << row_stride << " = "
562  << (start_idx + (row_label.size()-1) * row_stride)
563  << " !< " << counter.size();
564  msg << " [row_labels:";
565  for (const std::string &label : row_label) {
566  msg << " " << label;
567  }
568  msg << "; column_labels:";
569  for (const std::string &label : column_label) {
570  msg << " " << label;
571  }
572  msg << "]";
573  throw std::logic_error(msg.str());
574  }
576  TableUtils::Range2D<T> {!counter.empty() ? &counter[start_idx] : nullptr,
577  row_label.size(), // n-rows
578  column_label.size(), // n-columns
579  row_stride, // offset between rows
580  0u, // first column index
581  1u}, // offset between columns
582  TableUtils::Range<std::string> {row_label.data(), row_label.size() },
583  TableUtils::Range<std::string> {column_label.data(), column_label.size()},
584  top_left_label
585  };
586 }
587 
588 template <typename T, std::size_t N>
589 TableUtils::MultiColumnTable<T> makeTable(const std::vector<std::array<T,N> > &counter,
590  std::size_t start_row_idx,
591  std::size_t row_stride,
592  std::size_t start_column_idx,
593  std::size_t column_stride,
594  const std::vector<std::string> &row_label,
595  const std::vector<std::string> &column_label,
596  const std::string &top_left_label="") {
597  if (start_row_idx + (row_label.size()-1) * row_stride >= counter.size()*N
598  || start_column_idx + (column_label.size()-1) * column_stride >= counter.size()*N
599  || (row_stride*row_label.size()>column_stride && column_stride*column_label.size()>row_stride) ) {
600  std::stringstream msg;
601  msg << "Counter dimension and label dimensions (" << row_label.size() << " * " << column_label.size()
602  << ") do not match: [" << start_row_idx << ", "
603  << start_row_idx << " + " << (row_label.size()-1) << " * " << row_stride << " = "
604  << (start_row_idx + (row_label.size()-1) * row_stride)
605  << " or "
606  << start_column_idx << " + " << (column_label.size()-1) << " * " << column_stride << " = "
607  << (start_column_idx + (column_label.size()-1) * column_stride)
608  << " !< " << counter.size()
609  << std::endl
610  << (start_row_idx + (row_label.size()-1) * row_stride) << " >= " << (counter.size()*N)
611  << " || " << (start_column_idx + (column_label.size()-1) * column_stride) << " >= " << (counter.size()*N)
612  << " || ( " << (row_stride*row_label.size()) << " > " << column_stride << " && " << (column_stride*column_label.size()) << " > " << (row_stride)
613  << ")";
614  msg << " [row_labels:";
615  for (const std::string &label : row_label) {
616  msg << " " << label;
617  }
618  msg << "; column_labels:";
619  for (const std::string &label : column_label) {
620  msg << " " << label;
621  }
622  msg << "]";
623  throw std::logic_error(msg.str());
624  }
626  TableUtils::Range2D<T> {!counter.empty() && N>0 ? counter[start_row_idx].data() : nullptr,
627  row_label.size(), // n-rows
628  column_label.size(), // n-columns
629  row_stride, // offset between rows
630  start_column_idx, // first column index
631  column_stride}, // offset between columns
632  TableUtils::Range<std::string> {row_label.data(), row_label.size() },
633  TableUtils::Range<std::string> {column_label.data(), column_label.size()},
634  top_left_label};
635 }
636 
637 
638 // Helper method to wrap two dimensional data that should be dumped in table form to an output stream
639 template <typename T>
641  const std::vector<std::string> &row_label,
642  const std::vector<std::string> &column_label,
643  const std::string &top_left_label="") {
644  return makeTable(counter, 0u, column_label.size(), row_label, column_label, top_left_label);
645 }
646 
647 
648 // convenience method to dump wrapped arrays in table form to a MsgStream
649 // Usage: msg(MSG::INFO) << makeTable( array, labels);
650 // ATH_MSG_INFO( makeTable( array, labels) );
651 template <typename T>
652 inline MsgStream &operator<<(MsgStream &out,
654 {
655  return dumpTable(out,
656  stat.m_counter,
657  stat.m_label,
658  stat.m_labelPrefix,
659  stat.m_columnWidth,
660  stat.m_minLabelWidth,
661  stat.m_dumpFooter,
662  stat.m_separateLastRow,
663  stat.m_precision);
664 }
665 
666 // convenience method to dump wrapped two dimensional arrays in table form to a MsgStream
667 // Usage: msg(MSG::INFO) << makeTable( array2d, row_labels, column_labels);
668 // ATH_MSG_INFO( makeTable( array2d, row_labels, column_labels) );
669 template <typename T>
670 inline MsgStream &operator<<(MsgStream &out,
672 {
673  return dumpTable(out,
674  stat.m_counter,
675  stat.m_rowLabel,
676  stat.m_columnLabel,
677  stat.m_topLeftLable,
678  stat.m_labelPrefix,
679  stat.m_columnWidth,
680  stat.m_minLabelWidth,
681  stat.m_dumpHeader,
682  stat.m_dumpFooter,
683  stat.m_separateLastRow,
684  stat.m_precision);
685 }
686 
687 
688 // convenience method to dump wrapped two dimensional arrays in table form to a std output stream
689 // Usage: out << makeTable( array2d, row_labels, column_labels);
690 template <typename T>
691 inline std::ostream &operator<<(std::ostream &out,
693 {
694  return dumpTable(out,
695  stat.m_counter,
696  stat.m_label,
697  stat.m_labelPrefix,
698  stat.m_columnWidth,
699  stat.m_minLabelWidth,
700  stat.m_dumpFooter,
701  stat.m_separateLastRow,
702  stat.m_precision);
703 }
704 
705 // convenience method to dump wrapped two dimensional arrays in table form to a std output stream
706 // Usage: out << makeTable( array2d, row_labels, column_labels);
707 template <typename T>
708 inline std::ostream &operator<<(std::ostream &out,
710 {
711  return dumpTable(out,
712  stat.m_counter,
713  stat.m_rowLabel,
714  stat.m_columnLabel,
715  stat.m_topLeftLable,
716  stat.m_labelPrefix,
717  stat.m_columnWidth,
718  stat.m_minLabelWidth,
719  stat.m_dumpHeader,
720  stat.m_dumpFooter,
721  stat.m_separateLastRow,
722  stat.m_precision);
723 }
724 
725 #endif
TableUtils
Definition: TableUtils.h:24
TableUtils::Range2D::const_iterator::m_ptr
const T * m_ptr
Definition: TableUtils.h:74
TableUtils::Range2D::equalSize
bool equalSize(const T_Other &other_range)
Definition: TableUtils.h:97
TableUtils::MultiColumnTable::m_rowLabel
Range< std::string > m_rowLabel
Definition: TableUtils.h:254
TableUtils::StatTable::m_dumpHeader
bool m_dumpHeader
Definition: TableUtils.h:246
TableUtils::Range2D
Definition: TableUtils.h:62
header
Definition: hcg.cxx:526
TableUtils::Range2D::const_iterator::operator*
Range< T > operator*() const
Definition: TableUtils.h:72
TableUtils::MultiColumnTable
Definition: TableUtils.h:252
TableUtils::Range::const_iterator::m_offset
std::size_t m_offset
Definition: TableUtils.h:36
TableUtils::StatTable::minLabelWidth
StatTable & minLabelWidth(std::size_t value)
Definition: TableUtils.h:235
TableUtils::MultiColumnTable::m_minLabelWidth
std::size_t m_minLabelWidth
Definition: TableUtils.h:267
TableUtils::RatioDefinition
std::pair< std::vector< SummandDefinition >, std::vector< SummandDefinition > > RatioDefinition
Definition: TableUtils.h:378
TableUtils::Range2D::const_iterator
Definition: TableUtils.h:70
TableUtils::StatTable::m_columnWidth
std::size_t m_columnWidth
Definition: TableUtils.h:243
TableUtils::MultiColumnTable::dumpHeader
MultiColumnTable & dumpHeader(bool value=true)
Definition: TableUtils.h:259
TableUtils::StatTable::m_precision
unsigned int m_precision
Definition: TableUtils.h:245
index
Definition: index.py:1
max
constexpr double max()
Definition: ap_fixedTest.cxx:33
TableUtils::Range2D::m_ptr
const T * m_ptr
Definition: TableUtils.h:63
TableUtils::Range2D::const_iterator::m_columns
std::size_t m_columns
Definition: TableUtils.h:75
python.AthDsoLogger.out
out
Definition: AthDsoLogger.py:70
TableUtils::defineSimpleRatio
RatioDefinition defineSimpleRatio(T numerator, T denominator)
Definition: TableUtils.h:384
athena.value
value
Definition: athena.py:124
TableUtils::MultiColumnTable::columnWidth
MultiColumnTable & columnWidth(std::size_t value)
Definition: TableUtils.h:257
TableUtils::MultiColumnTable::m_precision
std::vector< unsigned int > m_precision
Definition: TableUtils.h:268
JetTiledMap::N
@ N
Definition: TiledEtaPhiMap.h:44
dq_defect_bulk_create_defects.line
line
Definition: dq_defect_bulk_create_defects.py:27
Trk::u
@ u
Enums for curvilinear frames.
Definition: ParamDefs.h:77
TableUtils::MultiColumnTable::separateLastRow
MultiColumnTable & separateLastRow(bool value=true)
Definition: TableUtils.h:261
TableUtils::Range::size
std::size_t size() const
Definition: TableUtils.h:47
TableUtils::StatTable::dumpHeader
StatTable & dumpHeader(bool value=true)
Definition: TableUtils.h:236
TableUtils::computeSum
std::size_t computeSum(const std::vector< SummandDefinition > &sum_def, std::size_t eta_offset, std::size_t row_stride, std::size_t seed_i, const std::vector< std::size_t > &stat)
Definition: TableUtils.cxx:8
TableUtils::subCategoryStride
constexpr std::size_t subCategoryStride([[maybe_unused]] const std::size_t categories, [[maybe_unused]] const std::size_t sub_categories, [[maybe_unused]] const std::size_t n_counter)
Definition: TableUtils.h:304
TableUtils::Range::m_size
std::size_t m_size
Definition: TableUtils.h:28
TableUtils::Range2D::end
const_iterator end() const
Definition: TableUtils.h:84
TableUtils::StatTable::m_label
Range< std::string > m_label
Definition: TableUtils.h:233
TableUtils::Range2D::m_columns
std::size_t m_columns
Definition: TableUtils.h:65
TableUtils::Range::equalSize
bool equalSize(const T_Other &other_range)
Definition: TableUtils.h:51
operator<<
MsgStream & operator<<(MsgStream &out, const TableUtils::StatTable< T > &stat)
Definition: TableUtils.h:652
beamspotnt.labels
list labels
Definition: bin/beamspotnt.py:1446
mergePhysValFiles.categories
categories
Definition: PhysicsAnalysis/JetTagging/JetTagValidation/JetTagDQA/scripts/mergePhysValFiles.py:17
TableUtils::MultiColumnTable::m_columnWidth
std::size_t m_columnWidth
Definition: TableUtils.h:266
TableUtils::counterStride
constexpr std::size_t counterStride([[maybe_unused]] const std::size_t categories, [[maybe_unused]] const std::size_t sub_categories, [[maybe_unused]] const std::size_t n_counter)
Definition: TableUtils.h:309
makeTable
TableUtils::StatTable< T > makeTable(const std::array< T, N > &counter, const std::array< std::string, N > &label)
Definition: TableUtils.h:523
TableUtils::Range::begin
const_iterator begin() const
Definition: TableUtils.h:38
TableUtils::maxLabelWidth
std::size_t maxLabelWidth(const T_Collection &col)
Definition: TableUtils.h:290
TableUtils::Range2D::m_firstColumnIndex
std::size_t m_firstColumnIndex
Definition: TableUtils.h:67
TableUtils::MultiColumnTable::m_separateLastRow
bool m_separateLastRow
Definition: TableUtils.h:271
TableUtils::StatTable::separateLastRow
StatTable & separateLastRow(bool value=true)
Definition: TableUtils.h:238
TableUtils::MultiColumnTable::m_labelPrefix
std::string m_labelPrefix
Definition: TableUtils.h:265
TableUtils::StatTable::m_counter
Range< T > m_counter
Definition: TableUtils.h:232
TableUtils::StatTable::m_labelPrefix
std::string m_labelPrefix
Definition: TableUtils.h:242
TableUtils::makeBinLabel
std::string makeBinLabel(const std::string &variable_name, const std::vector< float > &bins, std::size_t bin_i, bool abs_value=false, int precision=1)
Definition: TableUtils.h:485
TableUtils::MultiColumnTable::m_dumpFooter
bool m_dumpFooter
Definition: TableUtils.h:270
TableUtils::Range::operator[]
const T & operator[](std::size_t index) const
Definition: TableUtils.h:45
TableUtils::StatTable::columnWidth
StatTable & columnWidth(std::size_t value)
Definition: TableUtils.h:234
TableUtils::dumpTable
T_Stream & dumpTable(T_Stream &out, Range2D< T_Counter > counter, const Range< std::string > &row_label, const Range< std::string > &column_label, const std::string &top_left_label, const std::string &label_prefix, const std::size_t column_width, const std::size_t min_label_width, const bool dump_header, const bool dump_footer, const bool separate_last_row, const std::vector< unsigned int > &precision)
Definition: TableUtils.h:153
add-xsec-uncert-quadrature-N.label
label
Definition: add-xsec-uncert-quadrature-N.py:104
TableUtils::Range::m_ptr
const T * m_ptr
Definition: TableUtils.h:27
TableUtils::StatTable::m_separateLastRow
bool m_separateLastRow
Definition: TableUtils.h:248
TableUtils::Range
Definition: TableUtils.h:26
chainDump.column_width
column_width
Definition: chainDump.py:17
plotting.yearwise_luminosity_vs_mu.bins
bins
Definition: yearwise_luminosity_vs_mu.py:30
TableUtils::Range2D::nColumns
std::size_t nColumns() const
Definition: TableUtils.h:92
ReadTripsProbsFromCool.denominator
denominator
Definition: ReadTripsProbsFromCool.py:96
TableUtils::Range2D::const_iterator::m_columnOffset
std::size_t m_columnOffset
Definition: TableUtils.h:76
TableUtils::Range::end
const_iterator end() const
Definition: TableUtils.h:41
TableUtils::MultiColumnTable::m_topLeftLable
std::string m_topLeftLable
Definition: TableUtils.h:256
beamspotman.stat
stat
Definition: beamspotman.py:262
TableUtils::Range2D::m_rows
std::size_t m_rows
Definition: TableUtils.h:64
TableUtils::MultiColumnTable::precision
MultiColumnTable & precision(std::vector< unsigned int > &&precision)
Definition: TableUtils.h:263
TableUtils::Range2D::nRows
std::size_t nRows() const
Definition: TableUtils.h:93
TableUtils::Range::const_iterator::operator*
const T & operator*() const
Definition: TableUtils.h:33
lumiFormat.array
array
Definition: lumiFormat.py:91
TableUtils::MultiColumnTable::minLabelWidth
MultiColumnTable & minLabelWidth(std::size_t value)
Definition: TableUtils.h:258
TableUtils::Range::const_iterator::operator++
const_iterator & operator++()
Definition: TableUtils.h:32
TableUtils::StatTable::labelPrefix
StatTable & labelPrefix(const std::string &value)
Definition: TableUtils.h:239
TableUtils::MultiColumnTable::m_counter
Range2D< T > m_counter
Definition: TableUtils.h:253
TableUtils::Range2D::begin
const_iterator begin() const
Definition: TableUtils.h:81
TableUtils::Range2D::const_iterator::m_firstColumnIndex
std::size_t m_firstColumnIndex
Definition: TableUtils.h:77
TableUtils::Range2D::const_iterator::operator++
const_iterator & operator++()
Definition: TableUtils.h:71
TableUtils::makeLabelVector
std::vector< std::string > makeLabelVector(T_index n_entries, std::initializer_list< std::pair< T_index, T_string > > a_list)
Definition: TableUtils.h:275
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
TableUtils::StatTable::m_dumpFooter
bool m_dumpFooter
Definition: TableUtils.h:247
TableUtils::splitRatioDefinitionsAndLabels
std::tuple< std::vector< std::string >, std::vector< RatioDefinition > > splitRatioDefinitionsAndLabels(std::initializer_list< std::tuple< std::string, RatioDefinition > > a_ratio_list)
Definition: TableUtils.h:448
TableUtils::StatTable
Definition: TableUtils.h:231
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:16
TableUtils::categoryStride
constexpr std::size_t categoryStride([[maybe_unused]] const std::size_t categories, [[maybe_unused]] const std::size_t sub_categories, [[maybe_unused]] const std::size_t n_counter)
Definition: TableUtils.h:299
TableUtils::MultiColumnTable::labelPrefix
MultiColumnTable & labelPrefix(const std::string &value)
Definition: TableUtils.h:262
TableUtils::makeEtaBinLabel
std::string makeEtaBinLabel(const std::vector< float > &eta_bins, std::size_t eta_bin_i, bool abs_eta=false)
Definition: TableUtils.h:514
TableUtils::StatTable::dumpFooter
StatTable & dumpFooter(bool value=true)
Definition: TableUtils.h:237
DeMoScan.index
string index
Definition: DeMoScan.py:362
TableUtils::MultiColumnTable::dumpFooter
MultiColumnTable & dumpFooter(bool value=true)
Definition: TableUtils.h:260
TableUtils::Range2D::const_iterator::operator!=
bool operator!=(const const_iterator &other) const
Definition: TableUtils.h:73
a
TList * a
Definition: liststreamerinfos.cxx:10
TableUtils::Range2D::m_offset
std::size_t m_offset
Definition: TableUtils.h:68
InDetDD::other
@ other
Definition: InDetDD_Defs.h:16
TableUtils::dumpTable
T_Stream & dumpTable(T_Stream &out, Range< T_Counter > counter, const Range< std::string > &label, const std::string &label_prefix, const std::size_t column_width, const std::size_t min_label_width, const bool dump_footer, const bool separate_last_row, const unsigned int precision)
Definition: TableUtils.h:105
TableUtils::Range2D::m_columnOffset
std::size_t m_columnOffset
Definition: TableUtils.h:66
LArNewCalib_DelayDump_OFC_Cali.idx
idx
Definition: LArNewCalib_DelayDump_OFC_Cali.py:69
TableUtils::StatTable::precision
StatTable & precision(unsigned int precision)
Definition: TableUtils.h:240
TableUtils::MultiColumnTable::m_columnLabel
Range< std::string > m_columnLabel
Definition: TableUtils.h:255
TableUtils::Range::const_iterator::m_ptr
const T * m_ptr
Definition: TableUtils.h:35
TableUtils::StatTable::m_minLabelWidth
std::size_t m_minLabelWidth
Definition: TableUtils.h:244
TableUtils::makeRatioDefinition
std::tuple< std::string, RatioDefinition > makeRatioDefinition(std::string &&name, std::vector< SummandDefinition > &&numerator, std::vector< SummandDefinition > &&denominator)
Definition: TableUtils.h:438
TableUtils::ratioStride
constexpr std::size_t ratioStride([[maybe_unused]] const std::size_t categories, [[maybe_unused]] const std::size_t sub_categories, [[maybe_unused]] const std::vector< RatioDefinition > &ratio_def)
Definition: TableUtils.h:473
TableUtils::computeRatios
std::vector< float > computeRatios(const std::vector< RatioDefinition > &ratio_def, const std::size_t categories, const std::size_t sub_categories, const std::vector< std::size_t > &counter)
Definition: TableUtils.cxx:21
TableUtils::defineSummand
SummandDefinition defineSummand(T counter_idx, int multiplier)
Definition: TableUtils.h:402
TableUtils::MultiColumnTable::m_dumpHeader
bool m_dumpHeader
Definition: TableUtils.h:269
test_pyathena.counter
counter
Definition: test_pyathena.py:15
TableUtils::SummandDefinition
std::pair< std::size_t, int > SummandDefinition
Definition: TableUtils.h:376
TableUtils::Range::const_iterator
Definition: TableUtils.h:31
xAOD::bool
setBGCode setTAP setLVL2ErrorBits bool
Definition: TrigDecision_v1.cxx:60
TableUtils::Range::m_offset
std::size_t m_offset
Definition: TableUtils.h:29
TableUtils::createCounterArrayWithProjections
std::vector< T_Output > createCounterArrayWithProjections(const std::size_t categories, const std::size_t sub_categories, const std::vector< std::array< T_Input, N > > &input_counts)
Definition: TableUtils.h:322
python.AutoConfigFlags.msg
msg
Definition: AutoConfigFlags.py:7
TableUtils::Range::const_iterator::operator!=
bool operator!=(const const_iterator &other) const
Definition: TableUtils.h:34
TableUtils::Range2D::const_iterator::m_offset
std::size_t m_offset
Definition: TableUtils.h:78
TableUtils::Range2D::operator[]
Range< T > operator[](std::size_t index) const
Definition: TableUtils.h:87
TableUtils::computeRatio
float computeRatio(std::size_t numerator, std::size_t denominator)
Definition: TableUtils.h:414