37 #include <type_traits>
39 #include <boost/math/constants/constants.hpp>
64 template<
typename Scalar_,
typename CountType_ =
unsigned int>
87 template<
typename OtherParams
120 <<
" out of range ["<<min<<
","<<max<<
"["));
147 return min + index * (max-
min) / num_bins;
159 return min + (index+boost::math::constants::half<Scalar>()) * (max-
min) / num_bins;
172 return min + (index+1) * (max-min) /
num_bins;
200 : params(min_, max_, num_bins), bins(
Eigen::Array<CountType,
Eigen::Dynamic,1>::Zero(num_bins)),
206 template<
typename HistogramType>
208 : params(other.params), bins(other.params.
num_bins), off_chart(other.off_chart)
210 bins = other.bins.template cast<CountType>();
216 bins.
resize(params.num_bins);
230 template<
typename EigenType>
233 eigen_assert(x.cols() == 1);
234 eigen_assert((
std::size_t)x.rows() == params.num_bins);
235 bins = x.derived().template cast<CountType>();
236 off_chart = off_chart_;
247 template<
typename EigenType>
253 eigen_assert(x.cols() == 1);
254 eigen_assert((
std::size_t)x.rows() == params.num_bins);
255 bins += x.derived().template cast<CountType>();
256 off_chart += off_chart_;
267 template<
typename OtherScalar,
typename OtherCountType>
270 eigen_assert(x.
bins.cols() == 1);
274 bins += x.
bins.template cast<CountType>();
281 return params.num_bins;
293 return params.is_within_bounds(value);
298 return params.bin_index(value);
303 return params.bin_lower_value(index);
308 return params.bin_center_value(index);
313 return params.bin_upper_value(index);
319 return params.bin_resolution();
338 const std::size_t index = params.bin_index_unsafe(value);
361 const std::size_t index = params.bin_index_unsafe(value);
362 bins(index) += weight;
384 template<
typename Scalar_,
typename CountType_ =
double>
399 static constexpr
bool HasErrorBars =
true;
416 : Base_(params), delta(
Eigen::Array<CountType,
Eigen::Dynamic, 1>::Zero(params.
num_bins))
426 : Base_(min, max, num_bins), delta(
Eigen::Array<CountType,
Eigen::Dynamic, 1>::Zero(num_bins))
505 template<
typename HistogramType_,
typename RealAvgType =
double>
526 static constexpr
bool HasErrorBars =
true;
543 : Base_(params), num_histograms(0)
553 inline void reset(
const Params& params_)
576 template<
bool dummy =
true,
578 inline void add_histogram(
const HistogramType& histogram)
583 eigen_assert((
typename HistogramType::CountType)histogram.num_bins() ==
586 for (
std::size_t k = 0; k < histogram.num_bins(); ++k) {
587 RealAvgType binvalue = histogram.count(k);
595 template<
bool dummy =
true,
597 inline void finalize()
612 template<
bool dummy =
true,
614 inline void add_histogram(
const HistogramType& histogram)
619 eigen_assert((
typename HistogramType::CountType)histogram.num_bins() ==
Base_::num_bins());
621 for (
std::size_t k = 0; k < histogram.num_bins(); ++k) {
622 RealAvgType binvalue = histogram.count(k);
624 RealAvgType bindelta = histogram.errorbar(k);
631 template<
bool dummy =
true,
633 inline void finalize()
648 namespace tomo_internal {
652 template<
typename HistogramType>
653 struct histogram_pretty_print_label
657 labels.
resize(hist.num_bins());
658 for (
std::size_t k = 0; k < hist.num_bins(); ++k) {
667 template<
typename HistogramType>
670 labels.
resize(hist.num_bins());
672 const double max_label_val =
std::max(hist.bin_center_value(0), hist.bin_center_value(hist.num_bins()-1));
674 const int relprecision = 4;
675 const int precision = (powten > relprecision) ? 0 : (relprecision - powten - 1);
677 for (
std::size_t k = 0; k < hist.num_bins(); ++k) {
680 labels[k] = ss.
str();
684 template<
typename Scalar_,
typename CountType_>
685 struct histogram_pretty_print_label<UniformBinsHistogram<Scalar_, CountType_> >
687 typedef UniformBinsHistogram<Scalar_, CountType_> HistogramType;
690 histogram_get_labels_for_hist_params<HistogramType>(labels, hist);
694 template<
typename Scalar_,
typename CountType_>
695 struct histogram_pretty_print_label<UniformBinsHistogramWithErrorBars<Scalar_, CountType_> >
697 typedef UniformBinsHistogramWithErrorBars<Scalar_, CountType_> HistogramType;
700 histogram_get_labels_for_hist_params<HistogramType>(labels, hist);
704 template<
typename BaseHistogramType_,
typename RealAvgType_>
705 struct histogram_pretty_print_label<AveragedHistogram<BaseHistogramType_, RealAvgType_> >
707 typedef AveragedHistogram<BaseHistogramType_, RealAvgType_> HistogramType;
710 histogram_get_labels_for_hist_params<HistogramType>(labels, hist);
715 template<
typename HistogramType>
716 struct histogram_pretty_print_value
718 const HistogramType & hist;
719 histogram_pretty_print_value(
const HistogramType & hist_) : hist(hist_) { }
721 template<
bool dummy =
true,
725 svalues.
resize(hist.num_bins());
728 double max_val = 1.0;
729 for (k = 0; k < hist.num_bins(); ++k) {
730 if (k == 0 || hist.count(k) > max_val) {
731 max_val = hist.count(k);
736 const int relprecision = 3;
737 const int precision = abs_precision_for(powten, relprecision);
738 const int w = (precision > 0) ? (precision+powten+1) : (relprecision+2);
740 for (
std::size_t k = 0; k < hist.num_bins(); ++k) {
744 svalues[k] = ss.
str();
747 template<
bool dummy =
true,
751 svalues.
resize(hist.num_bins());
754 double max_val = 1.0;
755 for (k = 0; k < hist.num_bins(); ++k) {
756 if (k == 0 || hist.count(k) > max_val) {
757 max_val = hist.count(k);
762 const int relprecision = 3;
763 const int precision = abs_precision_for(powten, relprecision);
764 const int w = (precision > 0) ? (precision+powten+1) : (relprecision+2);
766 for (k = 0; k < hist.num_bins(); ++k) {
773 svalues[k] = ss.
str();
777 static inline int abs_precision_for(
const int powten,
const int relprecision)
779 return (powten > relprecision) ? 0 : (relprecision - powten - 1);
787 template<
typename HistogramType>
788 struct histogram_pretty_printer
790 const HistogramType & hist;
807 histogram_pretty_printer(
const HistogramType & hist_,
const int max_width_)
808 : hist(hist_), max_width(max_width_), lsep(
" |"), rsep(
" ")
814 labels.
resize(hist.num_bins());
815 svalues.
resize(hist.num_bins());
817 histogram_pretty_print_label<HistogramType>::getLabels(labels, hist);
818 histogram_pretty_print_value<HistogramType>::getStrValues(svalues, hist);
821 for (k = 0; k < hist.num_bins(); ++k) {
822 double val = maxval(k);
824 if (k == 0 || val > max_value) {
827 if (k == 0 || (
int)labels[k].size() > maxlabelwidth) {
828 maxlabelwidth = labels[k].
size();
830 if (k == 0 || (
int)svalues[k].size() > maxsvaluewidth) {
831 maxsvaluewidth = svalues[k].
size();
835 max_bar_width = max_width - maxlabelwidth - maxsvaluewidth - lsep.
size() - rsep.
size();
836 if (max_bar_width < 2) {
839 barscale = ((max_value > 0) ? (max_value / max_bar_width) : 1.0);
842 inline int value_to_bar_length(
double val)
const
847 int l = (int)(val/barscale+0.5);
848 if (l >= max_bar_width) {
849 return max_bar_width-1;
854 inline void fill_str_len(
std::string & s,
double valstart,
double valend,
855 char c,
char clside,
char crside)
const
857 int vs = value_to_bar_length(valstart);
858 int ve = value_to_bar_length(valend);
859 eigen_assert(vs >= 0);
860 eigen_assert(vs < (
int)s.
size());
861 eigen_assert(ve >= 0);
862 eigen_assert(ve < (
int)s.
size());
863 for (
int j = vs; j < ve; ++j) {
866 if (clside && crside && clside != crside && vs == ve) {
867 if (ve < (
int)s.
size()-1) {
888 for (k = 0; k < hist.num_bins(); ++k) {
889 str <<
std::setw(maxlabelwidth) << labels[k] << lsep
890 << make_bar(k) << rsep <<
std::setw(maxsvaluewidth) << svalues[k] <<
"\n";
896 template<
bool dummy =
true,
900 return (
double)hist.count(k);
902 template<
bool dummy =
true,
906 return (
double)(hist.count(k) + hist.errorbar(k));
909 template<
bool dummy =
true,
914 fill_str_len(sbar, 0.0, hist.count(k),
'*', 0, 0);
917 template<
bool dummy =
true,
922 const double binval = hist.count(k);
923 const double binerr = hist.errorbar(k);
924 fill_str_len(sbar, 0.0, binval - binerr,
'*',
'*',
'*');
925 fill_str_len(sbar, binval - binerr, binval + binerr,
'-',
'|',
'|');
930 template<
typename HistogramType>
931 inline std::string histogram_short_bar_fmt(
const HistogramType & histogram,
const bool log_scale,
936 if (histogram.off_chart > 0) {
937 send +=
Tools::fmts(
" [+%.1g off]", (
double)histogram.off_chart);
940 const int maxbarwidth = max_width - s.
size() - send.size();
941 const int numdiv = (int)(
std::ceil((
float)histogram.num_bins() / maxbarwidth) + 0.5f);
942 const int barwidth = (int)(
std::ceil((
float)histogram.num_bins() / numdiv) + 0.5f);
945 Eigen::ArrayXf veclog(barwidth);
950 for (k = 0; k < barwidth; ++k) {
952 (
std::size_t)(histogram.bins.size()-numdiv*k))).sum();
955 veclog(k) =
std::log((
float)vec(k));
957 veclog(k) = (float)vec(k);
959 if (k == 0 || minlogval > veclog(k)) {
960 minlogval = veclog(k);
962 if (k == 0 || maxlogval < veclog(k)) {
963 maxlogval = veclog(k) + 1e-6f;
972 for (k = 0; k < barwidth; ++k) {
976 int i = (int)(chars.
size() * (veclog(k) - minlogval) / (maxlogval - minlogval));
977 if (i < 0) { i = 0; }
978 if (i >= (
int)chars.
size()) { i = chars.
size()-1; }
996 int maybe_default_col_width(
int max_width = 0)
998 if (max_width <= 0) {
999 const int offset = max_width;
1006 if (cols_s != NULL) {
1009 max_width += offset;
1025 template<
typename HistogramType>
1030 if (histogram.params.num_bins == 0) {
1031 str <<
"<empty histogram: no bins>\n";
1035 max_width = tomo_internal::maybe_default_col_width(max_width);
1036 tomo_internal::histogram_pretty_printer<HistogramType>(histogram, max_width).pretty_print(str);
1047 template<
typename HistogramType>
1051 histogram_pretty_print<HistogramType>(ss, histogram, max_width);
1072 template<
typename HistogramType>
1074 bool log_scale =
true,
int max_width = 0)
1078 max_width = tomo_internal::maybe_default_col_width(max_width);
1081 if (histogram.params.num_bins == 0) {
1082 s =
"<empty histogram: no bins>";
1084 s = tomo_internal::histogram_short_bar_fmt<HistogramType>(histogram, log_scale, max_width);
1088 return max_width - s.
size();
1100 template<
typename HistogramType>
1105 if (histogram.params.num_bins == 0) {
1106 return "<empty histogram: no bins>";
1109 max_width = tomo_internal::maybe_default_col_width(max_width);
1110 return tomo_internal::histogram_short_bar_fmt<HistogramType>(histogram, log_scale, max_width);
Utilities for formatting strings.
Combines several histograms (with same parameters) into an averaged histogram.
Base_::Params Params
The histogram parameters' type. See UniformBinsHistogramWithErrorBars::Params.
Base namespace for the Tomographer project.
int num_histograms
The number of histograms averaged.
Base_::CountType CountType
The histogram' count type. This is exactly the same as RealAvgType.
void reset()
Resets the data keeping the exisiting params.
UniformBinsHistogramWithErrorBars< typename HistogramType_::Scalar, RealAvgType > Base_
Shortcut for our base class' type.
int histogram_short_bar(std::ostream &str, const HistogramType &histogram, bool log_scale=true, int max_width=0)
Format the histogram as a one-line bar.
Base_::Scalar Scalar
The histogram's X-axis scalar type. See UniformBinsHistogramWithErrorBars::Scalar.
void histogram_pretty_print(std::ostream &str, const HistogramType &histogram, int max_width=0)
pretty-print the given histogram.
HistogramType_ HistogramType
Type of the individual histograms we are averaging.