50 operator bool()
const {
return m_ptr !=
nullptr &&
m_size>0; }
51 template <
typename T_Other>
53 return m_size == other_range.m_size;
97 template <
typename T_Other>
99 return m_rows == other_range.m_size;
105 template <
class T_Stream,
typename T_Counter>
109 const std::string &label_prefix,
110 const std::size_t column_width,
111 const std::size_t min_label_width,
112 const bool dump_footer,
113 const bool separate_last_row,
114 const unsigned int precision) {
115 if (counter &&
label && counter.equalSize(
label)) {
116 std::size_t max_size =min_label_width;
117 for (
const std::string &name :
label ) {
118 max_size = std::max(max_size, name.size());
120 const std::size_t total_size =max_size+3+2*2+column_width;
121 std::string line(total_size,
'-');
122 std::array<std::size_t,3> vertical_line_pos{0u, max_size+3, line.size()-1};
123 for (std::size_t pos : vertical_line_pos) {
126 out << line << std::endl;
129 auto default_precision = out.precision();
130 for (
const T_Counter &
a : counter) {
131 if (separate_last_row && idx+1 ==
label.size()) {
132 out << line << std::endl;
134 assert( idx <
label.size());
135 out <<
"| " << (label_prefix.empty() ? std::left : std::right)
136 << std::setw(label_prefix.size()) << ( idx==0 ? label_prefix :
empty)
137 << std::setw(max_size-label_prefix.size()) <<
label[idx] << std::right
138 << std::setprecision( precision != std::numeric_limits<unsigned int>::max() ? precision : default_precision)
139 <<
" | " << std::setw(column_width) <<
a <<
" |" << std::endl;
142 out << std::setprecision(default_precision);
144 out << line << std::endl;
153 template <
class T_Stream,
typename T_Counter>
158 std::string_view top_left_label,
159 const std::string &label_prefix,
160 const std::size_t column_width,
161 const std::size_t min_label_width,
162 const bool dump_header,
163 const bool dump_footer,
164 const bool separate_last_row,
165 const std::vector<unsigned int> &precision) {
166 if (counter && row_label && column_label
167 && counter.equalSize(row_label)
168 && counter.nColumns() == column_label.
size()) {
169 std::size_t max_size =std::max(top_left_label.size(),
static_cast<std::size_t
>(min_label_width));
170 for (
const std::string &name : row_label ) {
171 max_size = std::max(max_size, name.size() + label_prefix.size());
173 std::size_t the_width = column_width;
174 for (
const std::string &name : column_label ) {
175 the_width = std::max(the_width, name.size());
177 std::size_t total_size =max_size+2*2;
178 for (std::size_t column_i=0; column_i<column_label.size(); ++column_i) {
179 total_size += the_width + 3;
181 std::string line(total_size,
'-');
185 for (std::size_t column_i=0; column_i<column_label.size(); ++column_i) {
187 pos += the_width + 3;
189 line[line.size()-1]=
'|';
191 out << line << std::endl <<
"| " << std::setw(max_size) << top_left_label <<
" |" << std::left;
192 for (
const std::string &
header : column_label ) {
193 out <<
" " << std::setw(the_width) <<
header <<
" |";
195 out << std::right << std::endl;
197 out << line << std::endl;
200 auto default_precision = out.precision();
202 if (separate_last_row && idx+1 == row_label.size()) {
203 out << line << std::endl;
205 assert( idx < row_label.size());
206 out <<
"| " << (label_prefix.empty() ? std::left : std::right)
207 << std::setw(label_prefix.size()) << ( idx==0 ? label_prefix :
empty)
208 << std::setw(max_size-label_prefix.size()) << row_label[idx] << std::right <<
" |";
209 unsigned int col_i=0;
210 for (
const T_Counter &
a : a_row) {
212 << std::setprecision( (col_i < precision.size()
213 && precision[col_i] != std::numeric_limits<unsigned int>::max())
216 << std::setw(the_width) <<
a <<
" |";
222 out << std::setprecision(default_precision);
231 template <
typename T>
246 unsigned int m_precision = std::numeric_limits<unsigned int>::max();
252 template <
typename T>
286 stat.m_minLabelWidth,
289 stat.m_separateLastRow,
295 template <
typename T_index,
class T_
string>
297 std::initializer_list<std::pair<T_index, T_string> > a_list)
299 std::vector<std::string> labels;
300 labels.resize( n_entries );
301 if (a_list.size() != n_entries) {
302 throw std::logic_error(
"Expected number of entries and elements in the initializer lists do not match.");
304 for (
auto elm : a_list) {
305 labels.at(elm.first) = std::move(elm.second);
310 template<
class T_Collection>
312 std::size_t max_width=0u;
313 for (
const auto &elm : col ) {
314 max_width = std::max( max_width, elm.size());
320 constexpr inline std::size_t
categoryStride([[maybe_unused]]
const std::size_t categories,
321 [[maybe_unused]]
const std::size_t sub_categories,
322 [[maybe_unused]]
const std::size_t n_counter) {
326 [[maybe_unused]]
const std::size_t sub_categories,
327 [[maybe_unused]]
const std::size_t n_counter) {
328 return (categories+1) * n_counter;
330 constexpr inline std::size_t
counterStride([[maybe_unused]]
const std::size_t categories,
331 [[maybe_unused]]
const std::size_t sub_categories,
332 [[maybe_unused]]
const std::size_t n_counter) {
333 return (categories+1);
342 template<
typename T_Output,
typename T_Input, const std::
size_t N>
344 const std::size_t sub_categories,
345 const std::vector< std::array<T_Input, N> > &input_counts) {
346 if (categories*sub_categories!= input_counts.size()) {
347 std::stringstream
msg;
348 msg <<
"Category dimensions (" << categories <<
" * " << sub_categories <<
"="
349 << (categories * sub_categories) <<
") and input counter container size "
350 << input_counts.size() <<
" do not match.";
351 throw std::logic_error(
msg.str());
353 std::vector<T_Output> output_counts;
354 output_counts.resize((categories+1) * (sub_categories+1) * N);
355 const std::size_t sub_category_stride =
subCategoryStride(categories, sub_categories, N);
356 const std::size_t counter_stride =
counterStride(categories, sub_categories, N);
357 const std::size_t category_stride =
categoryStride(categories, sub_categories, N);
359 for (std::size_t sub_category_i=0;
360 sub_category_i < sub_categories;
362 for (std::size_t category_i=0; category_i<categories; ++category_i) {
363 std::size_t src_idx = category_i * sub_categories + sub_category_i;
364 std::size_t dest_idx_base = sub_category_i * sub_category_stride + 0 * counter_stride;
365 std::size_t dest_idx_project_categories_base = dest_idx_base;
366 dest_idx_base += category_i * category_stride;
367 dest_idx_project_categories_base += categories * category_stride;
369 for (std::size_t counter_i=0; counter_i<N; ++counter_i) {
370 std::size_t dest_idx=dest_idx_base + counter_i * counter_stride;
371 assert( src_idx < input_counts.size() && counter_i < input_counts[src_idx].size());
372 assert( dest_idx < output_counts.size());
373 output_counts[dest_idx] = input_counts[src_idx][counter_i];
374 assert( dest_idx_project_categories_base + counter_i * counter_stride < output_counts.size());
375 output_counts[dest_idx_project_categories_base + counter_i * counter_stride] += output_counts[dest_idx];
380 for (std::size_t category_i=0; category_i<=categories; ++category_i) {
381 for (std::size_t counter_i=0; counter_i<N; ++counter_i) {
382 std::size_t dest_idx_base = 0 * sub_category_stride + counter_i * counter_stride + category_i;
383 std::size_t dest_idx_project_sub_categories = sub_categories * sub_category_stride + dest_idx_base;
384 assert( dest_idx_project_sub_categories < output_counts.size() );
385 for (std::size_t sub_category_i=0;
386 sub_category_i<sub_categories;
388 std::size_t sub_category_idx = dest_idx_base + sub_category_i * sub_category_stride;
389 assert( sub_category_idx < output_counts.size() );
390 output_counts[dest_idx_project_sub_categories] += output_counts[sub_category_idx];
394 return output_counts;
399 std::vector< SummandDefinition > >;
403 template <
typename T>
406 return std::make_pair( std::vector< SummandDefinition > { std::make_pair(
static_cast<std::size_t
>(numerator),1)},
407 std::vector< SummandDefinition > { std::make_pair(
static_cast<std::size_t
>(denominator),1)});
411 template <
typename T>
412 inline std::tuple< std::string, RatioDefinition >
414 return std::make_pair( std::move(name),
defineSimpleRatio(numerator, denominator) );
422 template <
typename T>
424 return std::make_pair(
static_cast<std::size_t
>(counter_idx), multiplier) ;
429 std::size_t
computeSum(
const std::vector< SummandDefinition > &sum_def,
430 std::size_t eta_offset,
431 std::size_t row_stride,
433 const std::vector<std::size_t> &stat);
435 inline float computeRatio(std::size_t numerator, std::size_t denominator) {
436 return denominator!=0 ?
static_cast<float>(numerator/
static_cast<double>(denominator)) : 0.f;
446 std::size_t eta_offset,
447 std::size_t row_stride,
449 const std::vector<std::size_t> &stat) {
450 std::size_t numerator=
computeSum(ratio_def.first, eta_offset, row_stride, seed_i, stat);
451 std::size_t denominator=!ratio_def.second.empty()
452 ?
computeSum(ratio_def.second, eta_offset, row_stride, seed_i, stat)
460 std::vector< SummandDefinition >&&numerator,
461 std::vector< SummandDefinition >&&denominator) {
462 return std::make_tuple(std::move(name),
463 std::make_pair(std::move(numerator),
464 std::move(denominator)));
468 inline std::tuple<std::vector<std::string>, std::vector<RatioDefinition> >
471 std::tuple< std::vector<std::string>, std::vector<RatioDefinition> > splitted;
472 std::get<0>(splitted).reserve( a_ratio_list.size() );
473 for (
auto a_ratio : a_ratio_list) {
474 std::get<0>(splitted).emplace_back( std::move(std::get<0>(a_ratio)) );
476 std::get<1>(splitted).reserve( a_ratio_list.size() );
477 for (
auto a_ratio : a_ratio_list) {
478 std::get<1>(splitted).emplace_back( std::move(std::get<1>(a_ratio)) );
484 constexpr inline std::size_t
categoryStride([[maybe_unused]]
const std::size_t categories,
485 [[maybe_unused]]
const std::size_t sub_categories,
486 [[maybe_unused]]
const std::vector<RatioDefinition> &ratio_def) {
490 [[maybe_unused]]
const std::size_t sub_categories,
491 [[maybe_unused]]
const std::vector<RatioDefinition> &ratio_def) {
492 return (categories) * ratio_def.size();
494 constexpr inline std::size_t
ratioStride([[maybe_unused]]
const std::size_t categories,
495 [[maybe_unused]]
const std::size_t sub_categories,
496 [[maybe_unused]]
const std::vector<RatioDefinition> &ratio_def) {
501 std::vector<float>
computeRatios(
const std::vector<RatioDefinition> &ratio_def,
502 const std::size_t categories,
503 const std::size_t sub_categories,
504 const std::vector< std::size_t> &counter);
507 const std::vector<float> &
bins,
509 bool abs_value=
false,
511 std::stringstream range_label;
512 range_label << std::fixed << std::setprecision(precision);
513 if (bin_i==
bins.size()+1) {
514 range_label <<
" All " << variable_name;
518 std::stringstream value_str;
519 value_str << std::fixed << std::setprecision(precision) << 0.;
520 range_label << std::setw(4) << (abs_value ? value_str.str().c_str() :
"-inf") <<
"-";
523 range_label << std::setw(4) <<
bins.at(bin_i-1) <<
"-";
525 if (bin_i>=
bins.size()) {
526 range_label << std::setw(4) <<
"+inf";
529 range_label << std::setw(4) <<
bins.at(bin_i);
532 return range_label.str();
536 std::size_t eta_bin_i,
537 bool abs_eta=
false) {
543template <
typename T, std::
size_t N>
545 const std::array<std::string, N> &
label) {
553template <
typename T, std::
size_t Nrows, std::
size_t Ncolumns>
555 const std::array<std::string, Nrows> &row_label,
556 const std::array<std::string, Ncolumns> &column_label,
557 std::string_view top_left_label=
"") {
560 counter.size(), column_label.size(),
561 !counter.empty() ?
static_cast<std::size_t
>(&counter[1][0] - &counter[0][0]) : 0u,
566 std::string{top_left_label}
573 std::size_t start_idx,
574 std::size_t row_stride,
575 const std::vector<std::string> &row_label,
576 const std::vector<std::string> &column_label,
577 std::string_view top_left_label=
"") {
578 if (start_idx + (row_label.size()-1) * row_stride >= counter.size() || row_stride < column_label.size()) {
579 std::stringstream
msg;
580 msg <<
"Counter dimension and label dimensions (" << row_label.size() <<
" * " << column_label.size()
581 <<
") do not match: [" << start_idx <<
", "
582 << start_idx <<
" + " << (row_label.size()-1) <<
" * " << row_stride <<
" = "
583 << (start_idx + (row_label.size()-1) * row_stride)
584 <<
" !< " << counter.size();
585 msg <<
" [row_labels:";
586 for (
const std::string &
label : row_label) {
589 msg <<
"; column_labels:";
590 for (
const std::string &
label : column_label) {
594 throw std::logic_error(
msg.str());
605 std::string{top_left_label}
609template <
typename T, std::
size_t N>
611 std::size_t start_row_idx,
612 std::size_t row_stride,
613 std::size_t start_column_idx,
614 std::size_t column_stride,
615 const std::vector<std::string> &row_label,
616 const std::vector<std::string> &column_label,
617 std::string_view top_left_label=
"") {
618 if (start_row_idx + (row_label.size()-1) * row_stride >= counter.size()*N
619 || start_column_idx + (column_label.size()-1) * column_stride >= counter.size()*N
620 || (row_stride*row_label.size()>column_stride && column_stride*column_label.size()>row_stride) ) {
621 std::stringstream
msg;
622 msg <<
"Counter dimension and label dimensions (" << row_label.size() <<
" * " << column_label.size()
623 <<
") do not match: [" << start_row_idx <<
", "
624 << start_row_idx <<
" + " << (row_label.size()-1) <<
" * " << row_stride <<
" = "
625 << (start_row_idx + (row_label.size()-1) * row_stride)
627 << start_column_idx <<
" + " << (column_label.size()-1) <<
" * " << column_stride <<
" = "
628 << (start_column_idx + (column_label.size()-1) * column_stride)
629 <<
" !< " << counter.size()
631 << (start_row_idx + (row_label.size()-1) * row_stride) <<
" >= " << (counter.size()*N)
632 <<
" || " << (start_column_idx + (column_label.size()-1) * column_stride) <<
" >= " << (counter.size()*N)
633 <<
" || ( " << (row_stride*row_label.size()) <<
" > " << column_stride <<
" && " << (column_stride*column_label.size()) <<
" > " << (row_stride)
635 msg <<
" [row_labels:";
636 for (
const std::string &
label : row_label) {
639 msg <<
"; column_labels:";
640 for (
const std::string &
label : column_label) {
644 throw std::logic_error(
msg.str());
655 std::string{top_left_label}};
662 const std::vector<std::string> &row_label,
663 const std::vector<std::string> &column_label,
664 std::string_view top_left_label=
"") {
665 return makeTable(counter, 0u, column_label.size(), row_label, column_label, top_left_label);
676 return dumpTable(out,
681 stat.m_minLabelWidth,
683 stat.m_separateLastRow,
694 return dumpTable(out,
701 stat.m_minLabelWidth,
704 stat.m_separateLastRow,
715 return dumpTable(out,
720 stat.m_minLabelWidth,
722 stat.m_separateLastRow,
static const std::vector< std::string > bins
MsgStream & operator<<(MsgStream &out, const TableUtils::StatTable< T > &stat)
TableUtils::StatTable< T > makeTable(const std::array< T, N > &counter, const std::array< std::string, N > &label)
static const Attributes_t empty
std::string label(const std::string &format, int i)
std::tuple< std::vector< std::string >, std::vector< RatioDefinition > > splitRatioDefinitionsAndLabels(std::initializer_list< std::tuple< std::string, RatioDefinition > > a_ratio_list)
SummandDefinition defineSummand(T counter_idx, int multiplier)
constexpr std::size_t categoryStride(const std::size_t categories, const std::size_t sub_categories, const std::size_t n_counter)
float computeRatio(std::size_t numerator, std::size_t denominator)
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)
std::size_t maxLabelWidth(const T_Collection &col)
RatioDefinition defineSimpleRatio(T numerator, T denominator)
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)
std::vector< std::string > makeLabelVector(T_index n_entries, std::initializer_list< std::pair< T_index, T_string > > a_list)
constexpr std::size_t subCategoryStride(const std::size_t categories, const std::size_t sub_categories, const std::size_t n_counter)
constexpr std::size_t counterStride(const std::size_t categories, const std::size_t sub_categories, const std::size_t n_counter)
std::string makeEtaBinLabel(const std::vector< float > &eta_bins, std::size_t eta_bin_i, bool abs_eta=false)
std::tuple< std::string, RatioDefinition > makeRatioDefinition(std::string &&name, std::vector< SummandDefinition > &&numerator, std::vector< SummandDefinition > &&denominator)
std::pair< std::vector< SummandDefinition >, std::vector< SummandDefinition > > RatioDefinition
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)
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)
constexpr std::size_t ratioStride(const std::size_t categories, const std::size_t sub_categories, const std::vector< RatioDefinition > &ratio_def)
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)
std::pair< std::size_t, int > SummandDefinition
std::string m_labelPrefix
MultiColumnTable & dumpFooter(bool value=true)
Range< std::string > m_columnLabel
friend std::ostream & operator<<(std::ostream &out, const MultiColumnTable &stat)
MultiColumnTable & separateLastRow(bool value=true)
std::size_t m_columnWidth
MultiColumnTable & columnWidth(std::size_t value)
MultiColumnTable & minLabelWidth(std::size_t value)
Range< std::string > m_rowLabel
std::string m_topLeftLable
std::size_t m_minLabelWidth
std::vector< unsigned int > m_precision
MultiColumnTable & precision(std::vector< unsigned int > &&precision)
MultiColumnTable & dumpHeader(bool value=true)
MultiColumnTable & labelPrefix(const std::string &value)
std::size_t m_columnOffset
Range< T > operator*() const
std::size_t m_firstColumnIndex
const_iterator & operator++()
bool operator!=(const const_iterator &other) const
const_iterator begin() const
const_iterator end() const
bool equalSize(const T_Other &other_range)
std::size_t nRows() const
std::size_t m_columnOffset
std::size_t nColumns() const
std::size_t m_firstColumnIndex
Range< T > operator[](std::size_t index) const
const_iterator & operator++()
bool operator!=(const const_iterator &other) const
const T & operator*() const
bool equalSize(const T_Other &other_range)
const_iterator begin() const
const T & operator[](std::size_t index) const
const_iterator end() const
StatTable & precision(unsigned int precision)
Range< std::string > m_label
StatTable & minLabelWidth(std::size_t value)
StatTable & separateLastRow(bool value=true)
StatTable & dumpFooter(bool value=true)
StatTable & columnWidth(std::size_t value)
StatTable & labelPrefix(const std::string &value)
std::size_t m_columnWidth
StatTable & dumpHeader(bool value=true)
std::size_t m_minLabelWidth
std::string m_labelPrefix