Tomographer  v5.3
Tomographer C++ Framework Documentation
histogram.h
Go to the documentation of this file.
1 /* This file is part of the Tomographer project, which is distributed under the
2  * terms of the MIT license.
3  *
4  * The MIT License (MIT)
5  *
6  * Copyright (c) 2016 ETH Zurich, Institute for Theoretical Physics, Philippe Faist
7  * Copyright (c) 2017 Caltech, Institute for Quantum Information and Matter, Philippe Faist
8  *
9  * Permission is hereby granted, free of charge, to any person obtaining a copy
10  * of this software and associated documentation files (the "Software"), to deal
11  * in the Software without restriction, including without limitation the rights
12  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13  * copies of the Software, and to permit persons to whom the Software is
14  * furnished to do so, subject to the following conditions:
15  *
16  * The above copyright notice and this permission notice shall be included in
17  * all copies or substantial portions of the Software.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25  * SOFTWARE.
26  */
27 
28 #ifndef HISTOGRAM_H
29 #define HISTOGRAM_H
30 
31 #include <cmath>
32 #include <cstdlib>
33 
34 #include <utility> // std::declval
35 #include <iostream>
36 #include <iomanip> // std::setprecision
37 #include <sstream> // std::stringstream
38 #include <stdexcept> // std::out_of_range
39 #include <type_traits> // std::enable_if
40 #include <algorithm> // std::max
41 
42 #include <boost/math/constants/constants.hpp>
43 // histogram types can be serialized with boost::serialization
44 #include <boost/serialization/serialization.hpp>
45 #include <boost/serialization/base_object.hpp>
46 
47 #include <Eigen/Core>
48 
49 #include <tomographer/tools/fmt.h>
51 #include <tomographer/tools/cxxutil.h> // TOMOGRAPHER_ENABLED_IF, tomographer_assert(), getWidthForTerminalOutput
53 
54 
61 namespace Tomographer {
62 
63 
64 
71 template<typename Scalar_ = double>
72 struct TOMOGRAPHER_EXPORT HistogramParams
73 {
75  typedef Scalar_ Scalar;
76 
78  inline HistogramParams(Scalar min_ = 0.0, Scalar max_ = 1.0, Eigen::Index num_bins_ = 50)
79  : min(min_), max(max_), num_bins(num_bins_)
80  {
81  }
83  template<typename Params2
84 #ifndef TOMOGRAPHER_PARSED_BY_DOXYGEN
85  // enforce Params-like type by checking that properties 'min','max','num_bins' exist:
86  , decltype((int)std::declval<const Params2>().min + (int)std::declval<const Params2>().max
87  + std::declval<Params2>().num_bins) dummyval = 0
88 #endif
89  >
90  inline HistogramParams(const Params2& other)
91  : min(other.min), max(other.max), num_bins(other.num_bins)
92  {
93  }
94 
96  Scalar min;
98  Scalar max;
100  Eigen::Index num_bins;
101 
107  inline bool isWithinBounds(Scalar value) const
108  {
109  return Tools::isFinite(value) && value >= min && value < max;
110  }
117  inline Eigen::Index binIndex(Scalar value) const
118  {
119  if ( !isWithinBounds(value) ) {
120  throw std::out_of_range(streamstr("HistogramParams: Value "<<value
121  <<" out of range ["<<min<<","<<max<<"["));
122  }
123  return binIndexUnsafe(value);
124  }
133  inline Eigen::Index binIndexUnsafe(Scalar value) const
134  {
135  return (Eigen::Index)((value-min) / (max-min) * num_bins);
136  }
145  inline Scalar binLowerValue(Eigen::Index index) const
146  {
147  tomographer_assert(Tools::isPositive(index) && index < num_bins);
148  return min + index * (max-min) / num_bins;
149  }
157  inline Scalar binCenterValue(Eigen::Index index) const
158  {
159  tomographer_assert(Tools::isPositive(index) && index < num_bins);
160  return min + (index+boost::math::constants::half<Scalar>()) * (max-min) / num_bins;
161  }
170  inline Scalar binUpperValue(Eigen::Index index) const
171  {
172  tomographer_assert(Tools::isPositive(index) && index < num_bins);
173  return min + (index+1) * (max-min) / num_bins;
174  }
179  inline Scalar binResolution() const
180  {
181  return (max - min) / num_bins;
182  }
183 
187  {
188  const auto halfbinres = boost::math::constants::half<Scalar>() * binResolution();
189  return Eigen::Array<Scalar, Eigen::Dynamic, 1>::LinSpaced(num_bins, min+halfbinres, max-halfbinres);
190  }
191 
195  {
196  return Eigen::Array<Scalar, Eigen::Dynamic, 1>::LinSpaced(num_bins, min, max-binResolution());
197  }
198 
202  {
203  return Eigen::Array<Scalar, Eigen::Dynamic, 1>::LinSpaced(num_bins, min+binResolution(), max);
204  }
205 
206 private:
207  friend boost::serialization::access;
208  template<typename Archive>
209  void serialize(Archive & a, unsigned int /* version */)
210  {
211  a & min;
212  a & max;
213  a & num_bins;
214  }
215 };
216 
217 
218 
219 
229 template<typename Scalar_, typename CountType_ = int>
230 class TOMOGRAPHER_EXPORT Histogram
231  // inheriting from this has some advantages over EIGEN_MAKE_ALIGNED_OPERATOR_NEW, such
232  // as not needing to explicitly declare the specialization
233  // NeedOwnOperatorNew<Histogram>:
234  //
235  // -- really not needed because the matrices are dynamically sized
236  //
237  // : public virtual Tools::NeedOwnOperatorNew<Eigen::Array<CountType,Eigen::Dynamic,1> >::ProviderType
238 {
239 public:
241  typedef Scalar_ Scalar;
242 
244  typedef CountType_ CountType;
245 
247  static constexpr bool HasErrorBars = false;
248 
251 
253  Params params;
257  CountType off_chart;
258 
260  template<typename Params2 = Params
261 #ifndef TOMOGRAPHER_PARSED_BY_DOXYGEN
262  // enforce Params-like type by checking that properties 'min','max','num_bins' exist:
263  , decltype((int)std::declval<const Params2>().min + (int)std::declval<const Params2>().max
264  + std::declval<Params2>().num_bins) dummyval = 0
265 #endif
266  >
267  Histogram(Params2 p = Params2())
268  : params(p), bins(Eigen::Array<CountType,Eigen::Dynamic,1>::Zero(p.num_bins)),
269  off_chart(0)
270  {
271  }
272 
274  Histogram(Scalar min_, Scalar max_, Eigen::Index num_bins)
275  : params(min_, max_, num_bins), bins(Eigen::Array<CountType,Eigen::Dynamic,1>::Zero(num_bins)),
276  off_chart(0)
277  {
278  }
279 
282  : params(std::move(x.params)),
283  bins(std::move(x.bins)),
284  off_chart(x.off_chart)
285  {
286  }
287 
289  Histogram(const Histogram & x)
290  : params(x.params),
291  bins(x.bins),
292  off_chart(x.off_chart)
293  {
294  }
295 
297  template<typename HistogramType,// and enforce it's indeed a histogram type by testing
298  // its 'HasErrorBars' property:
299  TOMOGRAPHER_ENABLED_IF_TMPL(HistogramType::HasErrorBars == 0 ||
300  HistogramType::HasErrorBars == 1)>
301  static Histogram copy(const HistogramType & other)
302  {
303  Histogram h(other.params);
304  h.bins = other.bins.template cast<CountType>();
305  h.off_chart = other.off_chart;
306  return h;
307  }
308 
310  inline void reset()
311  {
312  bins.resize(params.num_bins);
313  bins.setZero();
314  off_chart = 0;
315  }
316 
326  template<typename EigenType>
327  inline void load(const Eigen::DenseBase<EigenType> & x, CountType off_chart_ = 0)
328  {
329  tomographer_assert(x.cols() == 1);
330  tomographer_assert(x.rows() == params.num_bins);
331  bins = x.derived().template cast<CountType>();
332  off_chart = off_chart_;
333  }
334 
343  template<typename EigenType>
344  inline void add(const Eigen::ArrayBase<EigenType> & x, CountType off_chart_ = 0)
345  {
346  // the argument must be of ArrayBase type (as opposed to load() where we can
347  // also accept MatrixBase types) because Eigen doesn't allow operator+=
348  // between Arrays and Matrices, but has an operator= .
349  tomographer_assert(x.cols() == 1);
350  tomographer_assert(x.rows() == params.num_bins);
351  bins += x.derived().template cast<CountType>();
352  off_chart += off_chart_;
353  }
354 
363  template<typename OtherScalar, typename OtherCountType>
365  {
366  tomographer_assert(x.bins.cols() == 1);
367  tomographer_assert(x.bins.rows() == params.num_bins);
368  tomographer_assert(std::fabs(x.params.min - params.min) < 1e-8);
369  tomographer_assert(std::fabs(x.params.max - params.max) < 1e-8);
370  bins += x.bins.template cast<CountType>();
371  off_chart += x.off_chart;
372  }
373 
375  inline Eigen::Index numBins() const
376  {
377  return params.num_bins;
378  }
379 
381  inline CountType count(Eigen::Index i) const
382  {
383  return bins(i);
384  }
385 
387  inline bool isWithinBounds(Scalar value) const
388  {
389  return params.isWithinBounds(value);
390  }
392  inline Eigen::Index binIndex(Scalar value) const
393  {
394  return params.binIndex(value);
395  }
397  inline Scalar binLowerValue(Eigen::Index index) const
398  {
399  return params.binLowerValue(index);
400  }
402  inline Scalar binCenterValue(Eigen::Index index) const
403  {
404  return params.binCenterValue(index);
405  }
407  inline Scalar binUpperValue(Eigen::Index index) const
408  {
409  return params.binUpperValue(index);
410  }
411 
413  inline Scalar binResolution() const
414  {
415  return params.binResolution();
416  }
417 
426  inline Eigen::Index record(Scalar value)
427  {
428  if ( !isWithinBounds(value) ) {
429  ++off_chart;
430  return -1;
431  }
432  // calling bin_index_unsafe because we have already checked that value is in range.
433  const Eigen::Index index = params.binIndexUnsafe(value);
434  ++bins( index );
435  return index;
436  }
437 
447  inline Eigen::Index record(Scalar value, CountType weight)
448  {
449  if ( !isWithinBounds(value) ) {
450  off_chart += weight;
451  return -1;
452  }
453  // calling bin_index_unsafe is safe here because we have already checked that value is
454  // in range.
455  const Eigen::Index index = params.binIndexUnsafe(value);
456  bins(index) += weight;
457  return index;
458  }
459 
460 
474  template<typename NewCountType = decltype(Scalar(1) + CountType(1))>
475  inline NewCountType normalization() const
476  {
477  // DON'T DO NewCountType(binResolution())*NewCountType(bins.sum()) as we may loose
478  // precision (if NewCountType=int, for example)
479  return NewCountType(off_chart) + NewCountType(binResolution() * bins.sum());
480  }
481 
489  template<typename NewCountType = Scalar>
491  {
493  const NewCountType f = normalization<NewCountType>();
494  h.load(bins.template cast<NewCountType>() / f, NewCountType(off_chart) / f);
495  return h;
496  }
497 
498 
506  inline CountType totalCounts() const
507  {
508  return bins.sum() + off_chart;
509  }
510 
511 
522  template<typename NewCountType = Scalar>
524  {
526  const NewCountType f = totalCounts();
527  h.load(bins.template cast<NewCountType>() / f, NewCountType(off_chart) / f);
528  return h;
529  }
530 
535  inline std::string prettyPrint(int max_width = 0) const
536  {
537  return histogramPrettyPrint(*this, max_width);
538  }
539 
540 private:
541  friend boost::serialization::access;
542  template<typename Archive>
543  void serialize(Archive & a, unsigned int /* version */)
544  {
545  a & params;
546  a & bins;
547  a & off_chart;
548  }
549 
550 };
551 // static members:
552 template<typename Scalar_, typename CountType_>
554 
555 
556 
557 
565 template<typename Scalar_, typename CountType_ = double>
566 class TOMOGRAPHER_EXPORT HistogramWithErrorBars
567  : public Histogram<Scalar_, CountType_>
568  // public virtual Tools::EigenAlignedOperatorNewProvider -- no need for dynamically-sized matrices
569 {
570 public:
572  typedef Scalar_ Scalar;
574  typedef CountType_ CountType;
575 
581  typedef typename Base_::Params Params;
582 
584  static constexpr bool HasErrorBars = true;
585 
588 
589  // make these accessible without having to use the "Base_::member" syntax all the time
590  using Base_::params;
591  using Base_::bins;
592  using Base_::off_chart;
593 
594 
600  HistogramWithErrorBars(Params params = Params())
601  : Base_(params), delta(Eigen::Array<CountType, Eigen::Dynamic, 1>::Zero(params.num_bins))
602  {
603  }
604 
610  HistogramWithErrorBars(Scalar min, Scalar max, Eigen::Index num_bins)
611  : Base_(min, max, num_bins), delta(Eigen::Array<CountType, Eigen::Dynamic, 1>::Zero(num_bins))
612  {
613  }
614 
617  : Base_(std::move(x)),
618  delta(std::move(x.delta))
619  {
620  }
621 
624  : Base_(x),
625  delta(x.delta)
626  {
627  }
628 
629 
631  template<typename HistogramType,
632  TOMOGRAPHER_ENABLED_IF_TMPL(HistogramType::HasErrorBars == 1)>
633  static HistogramWithErrorBars copy(const HistogramType & other)
634  {
635  HistogramWithErrorBars h(other.params);
636  h.bins = other.bins.template cast<CountType>();
637  h.delta = other.delta.template cast<CountType>();
638  h.off_chart = other.off_chart;
639  return h;
640  }
641 
648  inline void reset()
649  {
650  Base_::reset();
651  delta.resize(Base_::numBins());
652  delta.setZero();
653  }
654 
659  inline CountType errorBar(Eigen::Index i) const
660  {
661  return delta(i);
662  }
663 
664 
677  template<typename EigenType, typename EigenType2 = EigenType>
678  inline void load(const Eigen::DenseBase<EigenType> & d,
679  const Eigen::DenseBase<EigenType2> & derr,
680  CountType off_chart_ = 0)
681  {
682  Base_::load(d, off_chart_);
683  tomographer_assert(derr.cols() == 1);
684  tomographer_assert(derr.rows() == params.num_bins);
685  delta = derr.derived().template cast<CountType>();
686  }
687 
688 
696  template<typename NewCountType = Scalar>
698  {
700  const NewCountType f = Base_::template normalization<NewCountType>();
701  h.load(bins.template cast<NewCountType>() / f,
702  delta.template cast<NewCountType>() / f,
703  NewCountType(off_chart) / f);
704  return h;
705  }
706 
717  template<typename NewCountType = Scalar>
719  {
721  const NewCountType f = Base_::totalCounts();
722  h.load(bins.template cast<NewCountType>() / f,
723  delta.template cast<NewCountType>() / f,
724  NewCountType(off_chart) / f);
725  return h;
726  }
727 
728 
729 private:
733  template<typename... Args>
734  inline void add(Args && ... )
735  {
736  }
740  template<typename... Args>
741  inline void record(Args && ... )
742  {
743  }
744 public:
745 
746 
754  std::string prettyPrint(int max_width = 0) const
755  {
756  return histogramPrettyPrint(*this, max_width);
757  }
758 
759 private:
760  friend boost::serialization::access;
761  template<typename Archive>
762  void serialize(Archive & a, unsigned int /* version */)
763  {
764  a & boost::serialization::base_object<Base_>(*this);
765  a & delta;
766  }
767 
768 };
769 // static members:
770 template<typename Scalar_, typename CountType_>
772 
773 
774 
775 
776 
777 
810 template<typename HistogramType_, typename RealAvgType = double>
811 class TOMOGRAPHER_EXPORT AveragedHistogram
812  : public HistogramWithErrorBars<typename HistogramType_::Scalar, RealAvgType>
813 {
814 public:
819  typedef HistogramType_ HistogramType;
822 
824  typedef typename Base_::Params Params;
826  typedef typename Base_::Scalar Scalar;
828  typedef typename Base_::CountType CountType;
829 
831  static constexpr bool HasErrorBars = true;
832 
839 
840 
847  AveragedHistogram(const Params& params = Params())
848  : Base_(params), num_histograms(0)
849  {
850  }
851 
857  AveragedHistogram(Scalar min, Scalar max, Eigen::Index num_bins)
858  : Base_(min, max, num_bins), num_histograms(0)
859  {
860  }
861 
862 
864  : Base_(copy), num_histograms(copy.num_histograms)
865  {
866  }
868  : Base_(std::move(x)),
869  num_histograms(x.num_histograms)
870  {
871  }
872 
873 
880  inline void reset(const Params& params_)
881  {
882  Base_::params = params_;
883  Base_::reset();
884  num_histograms = 0;
885  }
886 
893  inline void reset()
894  {
895  Base_::reset();
896  num_histograms = 0;
897  }
898 
899  // ---------------------------------------------------------------------------
900  // Implementation in case the added histograms don't have their own error bars
901  // ---------------------------------------------------------------------------
902 
917  TOMOGRAPHER_ENABLED_IF(!HistogramType::HasErrorBars)
918  inline void addHistogram(const HistogramType& histogram)
919  {
920  // bins collects the sum of the histograms
921  // delta for now collects the sum of squares. delta will be normalized in finalize().
922 
923  tomographer_assert((typename HistogramType::CountType)histogram.numBins() ==
924  (typename HistogramType::CountType)Base_::numBins());
925 
926  for (Eigen::Index k = 0; k < histogram.numBins(); ++k) {
927  RealAvgType binvalue = histogram.count(k);
928  Base_::bins(k) += binvalue;
929  Base_::delta(k) += binvalue * binvalue;
930  }
931 
932  Base_::off_chart += histogram.off_chart;
933  ++num_histograms;
934  }
935 
950  TOMOGRAPHER_ENABLED_IF(!HistogramType::HasErrorBars)
951  inline void finalize()
952  {
953  Base_::bins /= num_histograms;
954  Base_::delta /= num_histograms;
955  Base_::off_chart /= num_histograms;
956 
957  // delta = sqrt(< X^2 > - < X >^2) / sqrt(Nrepeats-1)
958  auto finhist2 = Base_::bins*Base_::bins; // for array, this is c-wise product
959  Base_::delta = ( (Base_::delta - finhist2) / (num_histograms-1) ).sqrt();
960  }
961 
962  // ---------------------------------------------------------------------------
963  // Implementation in case the added histograms do have their own error bars
964  // ---------------------------------------------------------------------------
965 
980  TOMOGRAPHER_ENABLED_IF(HistogramType::HasErrorBars)
981  inline void addHistogram(const HistogramType& histogram)
982  {
983  // bins collects the sum of the histograms
984  // delta for now collects the sum of squares. delta will be normalized in finished().
985 
986  tomographer_assert((typename HistogramType::CountType)histogram.numBins() == Base_::numBins());
987 
988  for (Eigen::Index k = 0; k < histogram.numBins(); ++k) {
989  RealAvgType binvalue = histogram.count(k);
990  Base_::bins(k) += binvalue;
991  RealAvgType bindelta = histogram.errorBar(k);
992  Base_::delta(k) += bindelta*bindelta;
993  }
994 
995  Base_::off_chart += histogram.off_chart;
996  ++num_histograms;
997  }
1012  TOMOGRAPHER_ENABLED_IF(HistogramType::HasErrorBars)
1013  inline void finalize()
1014  {
1015  Base_::bins /= num_histograms;
1016  Base_::off_chart /= num_histograms;
1017 
1018  Base_::delta = Base_::delta.sqrt();
1019  Base_::delta /= num_histograms;
1020  }
1021 
1022 private:
1023  friend boost::serialization::access;
1024  template<typename Archive>
1025  void serialize(Archive & a, unsigned int /* version */)
1026  {
1027  a & boost::serialization::base_object<Base_>(*this);
1028  a & num_histograms;
1029  }
1030 
1031 };
1032 
1033 
1034 
1035 
1062 template<typename HistogramType_, typename CountRealType_>
1063 class TOMOGRAPHER_EXPORT AggregatedHistogramSimple
1064  : public virtual Tools::NeedOwnOperatorNew<
1065  AveragedHistogram<HistogramType_,CountRealType_>
1066  >::ProviderType
1067 {
1068 public:
1073  typedef HistogramType_ HistogramType;
1074 
1075  TOMO_STATIC_ASSERT_EXPR( ! HistogramType::HasErrorBars ) ;
1076 
1078  typedef typename HistogramType::Params HistogramParams;
1079 
1081  typedef typename HistogramType::Scalar HistogramScalarType;
1082 
1084  typedef CountRealType_ CountRealType;
1085 
1090 
1091 
1092 
1094  : final_histogram(std::move(x.final_histogram))
1095  {
1096  }
1097 
1098  AggregatedHistogramSimple(FinalHistogramType && x)
1099  : final_histogram(std::move(x))
1100  {
1101  }
1102 
1104  FinalHistogramType final_histogram;
1105 
1106 
1131  template<typename ContainerType, typename ExtractHistogramFn>
1132  static inline AggregatedHistogramSimple aggregate(const HistogramParams & params,
1133  const ContainerType & list,
1134  ExtractHistogramFn extract_histogram_fn)
1135  {
1136  FinalHistogramType h(params); // initializes with zeros
1137 
1138  // iterate over all task histograms, add them to the averaged histogram
1139  for (const auto item : list) {
1140  h.addHistogram(extract_histogram_fn(item));
1141  }
1142 
1143  h.finalize();
1144 
1146  }
1147 
1148 
1149 
1163  inline void printHistogramCsv(std::ostream & stream,
1164  const std::string sep = "\t",
1165  const std::string linesep = "\n",
1166  const int precision = 10)
1167  {
1168  stream << "Value" << sep << "Counts" << sep << "Error" << linesep
1169  << std::scientific << std::setprecision(precision);
1170  for (Eigen::Index kk = 0; kk < final_histogram.bins.size(); ++kk) {
1171  stream << final_histogram.params.binLowerValue(kk) << sep
1172  << final_histogram.bins(kk) << sep
1173  << final_histogram.delta(kk) << linesep;
1174  }
1175  }
1176 
1177 
1178 private:
1179  friend boost::serialization::access;
1180  template<typename Archive>
1181  void serialize(Archive & a, unsigned int /* version */)
1182  {
1183  a & final_histogram;
1184  }
1185 
1186 }; // class AggregatedHistogramSimple
1187 
1188 
1189 
1217 template<typename HistogramType_, typename CountRealType_>
1218 class TOMOGRAPHER_EXPORT AggregatedHistogramWithErrorBars
1219  : public virtual Tools::NeedOwnOperatorNew<
1220  AveragedHistogram<HistogramType_, CountRealType_> ,
1221  AveragedHistogram<Histogram<typename HistogramType_::Scalar,
1222  typename HistogramType_::CountType>,
1223  CountRealType_>
1224  >::ProviderType
1225 {
1226 public:
1231  typedef HistogramType_ HistogramType;
1232 
1233  TOMO_STATIC_ASSERT_EXPR( HistogramType::HasErrorBars ) ;
1234 
1236  typedef typename HistogramType::Params HistogramParams;
1237 
1239  typedef typename HistogramType::Scalar HistogramScalarType;
1240 
1242  typedef CountRealType_ CountRealType;
1243 
1247 
1256 
1257 
1258 
1260  : final_histogram(std::move(x.final_histogram)),
1261  simple_final_histogram(std::move(x.simple_final_histogram))
1262  {
1263  }
1264 
1265  AggregatedHistogramWithErrorBars(FinalHistogramType && x, SimpleFinalHistogramType && y)
1266  : final_histogram(std::move(x)),
1267  simple_final_histogram(std::move(y))
1268  {
1269  }
1270 
1272  FinalHistogramType final_histogram;
1273 
1275  SimpleFinalHistogramType simple_final_histogram;
1276 
1277 
1302  template<typename ContainerType, typename ExtractHistogramFn>
1303  static inline AggregatedHistogramWithErrorBars aggregate(const HistogramParams & params,
1304  const ContainerType & list,
1305  ExtractHistogramFn extract_histogram_fn)
1306  {
1307  // initializes with zeros
1308  FinalHistogramType hist(params);
1309  SimpleFinalHistogramType histsimple(params);
1310 
1311  // iterate over all task histograms, add them to the averaged histogram
1312  for (const auto& item : list) {
1313  const auto& h = extract_histogram_fn(item);
1314  // hist's type is based on individual histograms WITH error bars, so this will take
1315  // into account h's error bars.
1316  hist.addHistogram(h);
1317  // histsimple's type is based on non-error bar individual histograms, so this will
1318  // ignore h's error bars.
1319  histsimple.addHistogram(h);
1320  }
1321 
1322  hist.finalize();
1323  histsimple.finalize();
1324 
1325  return AggregatedHistogramWithErrorBars(std::move(hist), std::move(histsimple));
1326  }
1327 
1328 
1329 
1345  inline void printHistogramCsv(std::ostream & stream,
1346  const std::string sep = "\t",
1347  const std::string linesep = "\n",
1348  const int precision = 10)
1349  {
1350  stream << "Value" << sep << "Counts" << sep << "Error" << sep << "SimpleError" << linesep
1351  << std::scientific << std::setprecision(precision);
1352  for (Eigen::Index kk = 0; kk < final_histogram.bins.size(); ++kk) {
1353  stream << final_histogram.params.binLowerValue(kk) << sep
1354  << final_histogram.bins(kk) << sep
1355  << final_histogram.delta(kk) << sep
1356  << simple_final_histogram.delta(kk) << linesep;
1357  }
1358  }
1359 
1360 private:
1361  friend boost::serialization::access;
1362  template<typename Archive>
1363  void serialize(Archive & a, unsigned int /* version */)
1364  {
1365  a & final_histogram;
1366  a & simple_final_histogram;
1367  }
1368 
1369 
1370 }; // class AggregatedHistogramWithErrorBars
1371 
1372 
1373 
1374 
1375 
1376 
1377 
1378 // -----------------------------------------------------------------------------
1379 // Pretty Print Histogram Utilities
1380 // -----------------------------------------------------------------------------
1381 
1382 
1383 
1384 namespace tomo_internal {
1385 // internal helpers
1386 //
1387 // find maximum value in the list only among those values which are finite (not inf or nan)
1388 //
1389 template<typename Scalar, typename Fn>
1390 inline Scalar max_finite_value(const Eigen::Index num_items, Fn val_generator,
1391  const Scalar default_val = Scalar(1.0))
1392 {
1393  bool has_first_val = false;
1394  Scalar max_val = default_val;
1395  for (Eigen::Index k = 0; k < num_items; ++k) {
1396  const Scalar this_val = val_generator(k);
1397  if (Tools::isFinite(this_val) && (!has_first_val || this_val > max_val)) {
1398  max_val = this_val;
1399  has_first_val = true;
1400  }
1401  }
1402  return max_val;
1403 }
1404 
1405 //
1406 // get labels left of histogram (generic HistogramType interface: no information, just bin #)
1407 //
1408 template<typename HistogramType>
1409 struct histogram_pretty_print_label
1410 {
1411  static inline void getLabels(std::vector<std::string> & labels, const HistogramType & hist)
1412  {
1413  labels.resize(hist.numBins());
1414  for (std::size_t k = 0; k < hist.numBins(); ++k) {
1415  labels[k] = std::to_string(k);
1416  }
1417  }
1418 };
1419 // get labels left of histogram (for the family of histograms with 'Params':
1420 // Histogram, HistogramWithErrorBars etc.)
1421 //
1422 // common code for several specializations of histogram_pretty_print_label
1423 template<typename HistogramType>
1424 inline void histogram_get_labels_for_hist_params(std::vector<std::string> & labels, const HistogramType& hist)
1425 {
1426  labels.resize((std::size_t)hist.numBins());
1427 
1428  const typename HistogramType::Scalar max_label_val
1429  = std::max(hist.binCenterValue(0), hist.binCenterValue(hist.numBins()-1));
1430  const int powten = (int)std::floor(std::log10(max_label_val));
1431  const int relprecision = 4;
1432  const int precision = (powten > relprecision) ? 0 : (relprecision - powten - 1);
1433 
1434  for (Eigen::Index k = 0; k < hist.numBins(); ++k) {
1435  std::ostringstream ss;
1436  ss << std::fixed << std::setprecision(precision) << std::right << hist.binCenterValue(k);
1437  labels[(std::size_t)k] = ss.str();
1438  }
1439 }
1440 // specialize histogram pretty-print labels using the code above
1441 template<typename Scalar_, typename CountType_>
1442 struct histogram_pretty_print_label<Histogram<Scalar_, CountType_> >
1443 {
1445  static inline void getLabels(std::vector<std::string> & labels, const HistogramType & hist)
1446  {
1447  histogram_get_labels_for_hist_params<HistogramType>(labels, hist);
1448  }
1449 };
1450 // specialize histogram pretty-print labels using the code above
1451 template<typename Scalar_, typename CountType_>
1452 struct histogram_pretty_print_label<HistogramWithErrorBars<Scalar_, CountType_> >
1453 {
1455  static inline void getLabels(std::vector<std::string> & labels, const HistogramType & hist)
1456  {
1457  histogram_get_labels_for_hist_params<HistogramType>(labels, hist);
1458  }
1459 };
1460 // specialize histogram pretty-print labels using the code above
1461 template<typename BaseHistogramType_, typename RealAvgType_>
1462 struct histogram_pretty_print_label<AveragedHistogram<BaseHistogramType_, RealAvgType_> >
1463 {
1465  static inline void getLabels(std::vector<std::string> & labels, const HistogramType & hist)
1466  {
1467  histogram_get_labels_for_hist_params<HistogramType>(labels, hist);
1468  }
1469 };
1470 
1471 // format bin counts nicely
1472 template<typename HistogramType>
1473 struct histogram_pretty_print_value
1474 {
1475  const HistogramType & hist;
1476  histogram_pretty_print_value(const HistogramType & hist_) : hist(hist_) { }
1477 
1478  TOMOGRAPHER_ENABLED_IF(!HistogramType::HasErrorBars)
1479  static inline void getStrValues(std::vector<std::string> & svalues, const HistogramType & hist)
1480  {
1481  svalues.resize((std::size_t)hist.numBins());
1482 
1483  typename HistogramType::CountType max_val =
1484  max_finite_value<typename HistogramType::CountType>(hist.numBins(),
1485  [&](Eigen::Index k) { return hist.count(k); },
1486  typename HistogramType::CountType(1));
1487 
1488  const int powten = (int)std::floor(std::log10(max_val));
1489  const int relprecision = 3;
1490  const int precision = abs_precision_for(powten, relprecision);
1491  const int w = (precision > 0) ? (precision+powten+1) : (relprecision+2);
1492 
1493  for (Eigen::Index k = 0; k < hist.numBins(); ++k) {
1494  std::ostringstream ss;
1495  ss << std::setprecision(precision) << std::fixed << std::right << std::setw(w)
1496  << hist.count(k);
1497  svalues[(std::size_t)k] = ss.str();
1498  }
1499  }
1500 
1501  TOMOGRAPHER_ENABLED_IF(HistogramType::HasErrorBars)
1502  static inline void getStrValues(std::vector<std::string> & svalues, const HistogramType & hist)
1503  {
1504  svalues.resize((std::size_t)hist.numBins());
1505 
1506  typename HistogramType::CountType max_val =
1507  max_finite_value<typename HistogramType::CountType>(hist.numBins(),
1508  [&](Eigen::Index k) { return hist.count(k); },
1509  typename HistogramType::CountType(1));
1510 
1511  const int powten = (int)std::floor(std::log10(max_val)); // floor of log_{10}(...)
1512  const int relprecision = 3;
1513  const int precision = abs_precision_for(powten, relprecision);
1514  const int w = (precision > 0) ? (precision+powten+2) : (relprecision+2);
1515 
1516  for (Eigen::Index k = 0; k < hist.numBins(); ++k) {
1517  std::ostringstream ss;
1518  ss << std::setprecision(precision) << std::fixed << std::right << std::setw(w)
1519  << hist.count(k) << " +- "
1520  << std::setprecision(abs_precision_for(powten-1, relprecision-1)) << std::setw(w)
1521  << hist.errorBar(k);
1522  svalues[(std::size_t)k] = ss.str();
1523  }
1524  }
1525 private:
1526  static inline int abs_precision_for(const int powten, const int relprecision)
1527  {
1528  return (powten >= relprecision) ? 0 : (relprecision - powten - 1);
1529  }
1530 };
1531 
1533 //
1534 // access this with public API using histogram_pretty_print().
1535 //
1536 template<typename HistogramType>
1537 struct histogram_pretty_printer
1538 {
1539  const HistogramType & hist;
1540  const int max_width;
1541 
1542  // the histogram count type, but at least precision double
1543  typedef decltype(typename HistogramType::CountType(1) + double(1)) CountType;
1544 
1545  const std::string lsep;
1546  const std::string rsep;
1547 
1548  std::vector<std::string> labels;
1549  int maxlabelwidth;
1550 
1551  std::vector<std::string> svalues;
1552  int maxsvaluewidth;
1553 
1554  CountType max_value;
1555 
1556  int max_bar_width;
1557  CountType barscale;
1558 
1559  histogram_pretty_printer(const HistogramType & hist_, const int max_width_)
1560  : hist(hist_), max_width(max_width_), lsep(" |"), rsep(" ")
1561  {
1562  // first pass:
1563  // - determine the maximum value attained in the histogram
1564  // - determine maximum width of formatted label & value fields.
1565 
1566  labels.resize((std::size_t)hist.numBins());
1567  svalues.resize((std::size_t)hist.numBins());
1568 
1569  histogram_pretty_print_label<HistogramType>::getLabels(labels, hist);
1570  histogram_pretty_print_value<HistogramType>::getStrValues(svalues, hist);
1571 
1572  bool has_maxval = false;
1573  for (std::size_t k = 0; k < (std::size_t)hist.numBins(); ++k) {
1574  const CountType val = maxval(k);
1575 
1576  if (Tools::isFinite(val) && (!has_maxval || val > max_value)) {
1577  max_value = val;
1578  has_maxval = true;
1579  }
1580  if (k == 0 || (int)labels[k].size() > maxlabelwidth) {
1581  maxlabelwidth = (int)labels[k].size();
1582  }
1583  if (k == 0 || (int)svalues[k].size() > maxsvaluewidth) {
1584  maxsvaluewidth = (int)svalues[k].size();
1585  }
1586  }
1587  if (!has_maxval) {
1588  max_value = 1.0;
1589  }
1590 
1591  max_bar_width = max_width - maxlabelwidth - maxsvaluewidth - (int)lsep.size() - (int)rsep.size();
1592  if (max_bar_width < 2) {
1593  max_bar_width = 2;
1594  }
1595  barscale = ((max_value > 0) ? (max_value / max_bar_width) : 1.0);
1596  }
1597 
1598  inline std::size_t value_to_bar_length(CountType val) const
1599  {
1600  if (val < 0 || !Tools::isFinite(val)) {
1601  val = 0;
1602  }
1603  std::size_t l = (std::size_t)(val/barscale+0.5);
1604  if (l >= (std::size_t)max_bar_width) {
1605  return (std::size_t)max_bar_width-1;
1606  }
1607  return l;
1608  }
1609 
1610  inline void fill_str_len(std::string & s, CountType valstart, CountType valend,
1611  char c, char clside, char crside) const
1612  {
1613  std::size_t vs = value_to_bar_length(valstart);
1614  std::size_t ve = value_to_bar_length(valend);
1615  //tomographer_assert(vs >= 0);
1616  tomographer_assert(vs < s.size());
1617  //tomographer_assert(ve >= 0);
1618  tomographer_assert(ve < s.size());
1619  for (std::size_t j = vs; j < ve; ++j) {
1620  s[j] = c;
1621  }
1622  if (clside && crside && clside != crside && vs == ve) {
1623  if (ve < s.size()-1) {
1624  ++ve;
1625  } else if (vs > 1) {
1626  --vs;
1627  }
1628  }
1629  if (clside) {
1630  s[vs] = clside;
1631  }
1632  if (crside) {
1633  s[ve] = crside;
1634  }
1635  }
1636 
1637  inline void pretty_print(std::ostream & str) const
1638  {
1639  // perform now second pass:
1640  // - display the histogram line by line, with the calculated widths.
1641 
1642  for (std::size_t k = 0; k < (std::size_t)hist.numBins(); ++k) {
1643  str << std::setw(maxlabelwidth) << labels[k] << lsep
1644  << make_bar(k) << rsep << std::setw(maxsvaluewidth) << svalues[k] << "\n";
1645  }
1646  }
1647 
1648 private:
1649  // maxval(k): how much this bar may extend in length
1650  TOMOGRAPHER_ENABLED_IF(!HistogramType::HasErrorBars)
1651  inline CountType maxval(const std::size_t k) const
1652  {
1653  return hist.count((Eigen::Index)k);
1654  }
1655  TOMOGRAPHER_ENABLED_IF(HistogramType::HasErrorBars)
1656  inline CountType maxval(const std::size_t k) const
1657  {
1658  return (hist.count((Eigen::Index)k) + hist.errorBar((Eigen::Index)k));
1659  }
1660  // make_bar(k): produce the histogram bar in characters...
1661  TOMOGRAPHER_ENABLED_IF(!HistogramType::HasErrorBars)
1662  inline std::string make_bar(std::size_t k) const
1663  {
1664  std::string sbar((std::size_t)max_bar_width, ' ');
1665  fill_str_len(sbar, 0.0, hist.count((Eigen::Index)k), '*', 0, 0);
1666  return sbar;
1667  }
1668  TOMOGRAPHER_ENABLED_IF(HistogramType::HasErrorBars)
1669  inline std::string make_bar(std::size_t k) const
1670  {
1671  std::string sbar((std::size_t)max_bar_width, ' ');
1672  const typename HistogramType::CountType binval = hist.count((Eigen::Index)k);
1673  const typename HistogramType::CountType binerr = hist.errorBar((Eigen::Index)k);
1674  fill_str_len(sbar, 0.0, binval - binerr, '*', '*', '*');
1675  fill_str_len(sbar, binval - binerr, binval + binerr, '-', '|', '|');
1676  return sbar;
1677  }
1678 };
1679 
1680 template<typename HistogramType>
1681 inline std::string histogram_short_bar_fmt(const HistogramType & histogram, const bool log_scale,
1682  const int max_width)
1683 {
1684  std::string s = Tools::fmts("%.2g|", (double)histogram.binLowerValue(0));
1685  std::string send = Tools::fmts("|%.2g", (double)histogram.binUpperValue(histogram.numBins()-1));
1686  if (histogram.off_chart > 0) {
1687  send += Tools::fmts(" [+%.1g off]", (double)histogram.off_chart);
1688  }
1689 
1690  const int maxbarwidth = max_width - (int)s.size() - (int)send.size();
1691  const int numdiv = (int)(std::ceil((float)histogram.numBins() / maxbarwidth) + 0.5f);
1692  const int barwidth = (int)(std::ceil((float)histogram.numBins() / numdiv) + 0.5f);
1693 
1695  Eigen::ArrayXf veclog(barwidth);
1696 
1697  int k;
1698  float minlogval = 0;
1699  float maxlogval = 0;
1700  for (k = 0; k < barwidth; ++k) {
1701  vec(k) = histogram.bins.segment((Eigen::Index)(numdiv*k),
1702  std::min((Eigen::Index)numdiv,
1703  (Eigen::Index)(histogram.bins.size()-numdiv*k))).sum();
1704  if (vec(k) > 0) {
1705  if (log_scale) {
1706  veclog(k) = std::log((float)vec(k));
1707  } else {
1708  veclog(k) = (float)vec(k);
1709  }
1710  if (k == 0 || minlogval > veclog(k)) {
1711  minlogval = veclog(k);
1712  }
1713  if (k == 0 || maxlogval < veclog(k)) {
1714  maxlogval = veclog(k) + 1e-6f;
1715  }
1716  } else {
1717  veclog(k) = 0.f;
1718  }
1719  }
1720 
1721  // now, prepare string
1722  const std::string chars = ".-+ox%#";
1723  for (k = 0; k < barwidth; ++k) {
1724  if (vec(k) <= 0) {
1725  s += ' ';
1726  } else {
1727  int i = (int)(chars.size() * (veclog(k) - minlogval) / (maxlogval - minlogval));
1728  if (i < 0) { i = 0; }
1729  if (i >= (int)chars.size()) { i = (int)chars.size()-1; }
1730  s += chars[(std::size_t)i];
1731  }
1732  }
1733 
1734  s += send;
1735 
1736  return s;
1737 }
1738 
1739 } // namespace tomo_internal
1740 
1741 
1750 template<typename HistogramType>
1751 inline void histogramPrettyPrint(std::ostream & str, const HistogramType & histogram, int max_width = 0)
1752 {
1753  tomographer_assert(Tools::isPositive(histogram.params.num_bins));
1754 
1755  if (histogram.params.num_bins == 0) {
1756  str << "<empty histogram: no bins>\n";
1757  return;
1758  }
1759 
1760  max_width = Tools::getWidthForTerminalOutput(max_width);
1761  tomo_internal::histogram_pretty_printer<HistogramType>(histogram, max_width).pretty_print(str);
1762 }
1763 
1772 template<typename HistogramType>
1773 inline std::string histogramPrettyPrint(const HistogramType & histogram, int max_width = 0)
1774 {
1775  std::ostringstream ss;
1776  histogramPrettyPrint<HistogramType>(ss, histogram, max_width);
1777  return ss.str();
1778 }
1779 
1797 template<typename HistogramType>
1798 inline int histogramShortBar(std::ostream & str, const HistogramType & histogram,
1799  bool log_scale = true, int max_width = 0)
1800 {
1801  tomographer_assert(Tools::isPositive(histogram.params.num_bins));
1802 
1803  max_width = Tools::getWidthForTerminalOutput(max_width);
1804 
1805  std::string s;
1806  if (histogram.params.num_bins == 0) {
1807  s = "<empty histogram: no bins>";
1808  } else {
1809  s = tomo_internal::histogram_short_bar_fmt<HistogramType>(histogram, log_scale, max_width);
1810  }
1811 
1812  str << s;
1813  return max_width - (int)s.size();
1814 }
1825 template<typename HistogramType>
1826 inline std::string histogramShortBar(const HistogramType & histogram, bool log_scale = true, int max_width = 0)
1827 {
1828  tomographer_assert(Tools::isPositive(histogram.params.num_bins));
1829 
1830  if (histogram.params.num_bins == 0) {
1831  return "<empty histogram: no bins>";
1832  }
1833 
1834  max_width = Tools::getWidthForTerminalOutput(max_width);
1835  return tomo_internal::histogram_short_bar_fmt<HistogramType>(histogram, log_scale, max_width);
1836 }
1837 
1838 
1853 template<typename HistogramType>
1855  std::string head,
1856  const HistogramType& hist,
1857  std::string tail,
1858  bool log_scale = true,
1859  int full_max_width = 0)
1860 {
1861  full_max_width = Tools::getWidthForTerminalOutput(full_max_width);
1862 
1863  str << head;
1864  const int w = histogramShortBar(str, hist, log_scale, full_max_width - (int)head.size() - (int)tail.size());
1865  str << std::setw(w + (int)tail.size()) << std::right << tail << "\n";
1866 }
1867 
1882 template<typename HistogramType>
1884  const HistogramType& hist,
1885  std::string tail,
1886  bool log_scale = true,
1887  int full_max_width = 0)
1888 {
1889  std::ostringstream ss;
1890  histogramShortBarWithInfo(ss, head, hist, tail, log_scale, full_max_width);
1891  return ss.str();
1892 }
1893 
1894 
1895 
1896 
1897 
1898 // compatibility with Tomographer <= 4
1899 template<typename Scalar_ = double>
1901 template<typename Scalar_, typename CountType_ = int>
1903 template<typename Scalar_, typename CountType_ = double>
1905 
1906 
1907 
1908 } // namespace Tomographer
1909 
1910 
1911 
1912 
1913 #endif
Utilities for formatting strings.
Scalar binCenterValue(Eigen::Index index) const
Returns the value which a given bin index represents (center bin value)
Definition: histogram.h:157
bool isWithinBounds(Scalar value) const
Shorthand for Params::isWithinBounds()
Definition: histogram.h:387
HistogramType::Params HistogramParams
The parameters type used to describe our histogram range and number of bins.
Definition: histogram.h:1075
FinalHistogramType final_histogram
The final histogram, with error bars.
Definition: histogram.h:1104
Histogram(Params2 p=Params2())
Constructor: stores the parameters and initializes the histogram to zero counts everywhere.
Definition: histogram.h:267
Eigen::Array< CountType, Eigen::Dynamic, 1 > delta
The error bars associated with each histogram bin.
Definition: histogram.h:587
void reset()
Resets the histogram to zero counts everywhere (including the off-chart counts)
Definition: histogram.h:310
CountRealType_ CountRealType
Type used for averaged histogram counts (e.g. double)
Definition: histogram.h:1084
Eigen::Index record(Scalar value)
Record a new value in the histogram.
Definition: histogram.h:426
Scalar max
Upper range value.
Definition: histogram.h:98
void addHistogram(const HistogramType &histogram)
Add a new histogram in the data series.
Definition: histogram.h:918
bool isFinite(const X val)
Test whether floating-point value is finite.
Definition: cxxutil.h:379
The parameters of a Histogram.
Definition: histogram.h:72
void reset()
Resets the histogram to zero counts everywhere, and zero error bars.
Definition: histogram.h:648
Base namespace for the Tomographer project.
Definition: densellh.h:45
void histogramShortBarWithInfo(std::ostream &str, std::string head, const HistogramType &hist, std::string tail, bool log_scale=true, int full_max_width=0)
Format the histogram as a one-line bar, with some surrounding info.
Definition: histogram.h:1854
T ceil(T... args)
Scalar binResolution() const
Returns the width of a bin.
Definition: histogram.h:179
HistogramParams< Scalar_ > Params
The type for specifying parameters of this histogram (limits, number of bins)
Definition: histogram.h:250
Scalar binCenterValue(Eigen::Index index) const
Shorthand for Params::binCenterValue()
Definition: histogram.h:402
Eigen::Index binIndexUnsafe(Scalar value) const
Returns which bin this value should be counted in.
Definition: histogram.h:133
HistogramParams(const Params2 &other)
Copy constructor, from any other Histogram::Params type.
Definition: histogram.h:90
T log(T... args)
static HistogramWithErrorBars copy(const HistogramType &other)
explicitly copy another histogram type
Definition: histogram.h:633
Stores a histogram along with error bars.
Definition: histogram.h:566
T to_string(T... args)
Provide appropriate operator new() definitions for a structure which has a member of the given stored...
T right(T... args)
CountType count(Eigen::Index i) const
Shorthand for bins(i)
Definition: histogram.h:381
Base_::Scalar Scalar
The histogram&#39;s X-axis scalar type. See HistogramWithErrorBars::Scalar.
Definition: histogram.h:826
STL namespace.
Histogram(Scalar min_, Scalar max_, Eigen::Index num_bins)
Constructor: stores the parameters and initializes the histogram to zero counts everywhere.
Definition: histogram.h:274
void add(const Histogram< OtherScalar, OtherCountType > &x)
Add data to the histogram.
Definition: histogram.h:364
HistogramWithErrorBars(Params params=Params())
Constructor, with given histogram parameters.
Definition: histogram.h:600
Base_::Params Params
The histogram parameters&#39; type. See HistogramWithErrorBars::Params.
Definition: histogram.h:824
bool isWithinBounds(Scalar value) const
Tests whether the given value is in the range of the histogram.
Definition: histogram.h:107
HistogramWithErrorBars(HistogramWithErrorBars &&x)
Constructor: move another histogram type.
Definition: histogram.h:616
std::string prettyPrint(int max_width=0) const
Pretty-print the histogram and return it as a string with horizontal bars.
Definition: histogram.h:535
Eigen::Index binIndex(Scalar value) const
Returns which bin this value should be counted in (index in the histogram&#39;s bins array) ...
Definition: histogram.h:117
Params params
Parameters of this histogram (range and # of bins)
Definition: histogram.h:253
T floor(T... args)
HistogramType::Scalar HistogramScalarType
The scalar type of the histogram (i.e., x-axis labels)
Definition: histogram.h:1239
Histogram< Scalar_, CountType_ > Base_
Shortcut for our base class type.
Definition: histogram.h:577
HistogramParams(Scalar min_=0.0, Scalar max_=1.0, Eigen::Index num_bins_=50)
The obvious constructor.
Definition: histogram.h:78
Histogram< typename HistogramType::Scalar, typename HistogramType::CountType > SimpleHistogramType
The "simple" histogram, as if without binning analysis.
Definition: histogram.h:1251
void add(const Eigen::ArrayBase< EigenType > &x, CountType off_chart_=0)
Add data to the histogram.
Definition: histogram.h:344
T log10(T... args)
CountType_ CountType
The Type used to keep track of counts. See Histogram::CountType.
Definition: histogram.h:574
HistogramType::Scalar HistogramScalarType
The scalar type of the histogram (i.e., x-axis labels)
Definition: histogram.h:1081
int num_histograms
The number of histograms averaged.
Definition: histogram.h:838
SegmentReturnType segment(Index start, Index n)
void reset()
Resets the data keeping the exisiting params.
Definition: histogram.h:893
Scalar_ Scalar
The scalar type of the "X"-axis of the histogram (usually double)
Definition: histogram.h:241
T setw(T... args)
T resize(T... args)
STL class.
AveragedHistogram< HistogramType, CountRealType > FinalHistogramType
The type of the final resulting, averaged histogram.
Definition: histogram.h:1089
T min(T... args)
NewCountType normalization() const
Calculate the total weight stored in this histogram.
Definition: histogram.h:475
AveragedHistogram(const Params &params=Params())
Constructs an AveragedHistogram with the given histogram parameters.
Definition: histogram.h:847
Histogram< Scalar, NewCountType > normalized() const
Get a normalized version of this histogram.
Definition: histogram.h:490
HistogramWithErrorBars(Scalar min, Scalar max, Eigen::Index num_bins)
Constructor, with given histogram parameters.
Definition: histogram.h:610
Combines several histograms (with same parameters) into an averaged histogram.
Definition: histogram.h:811
void histogramPrettyPrint(std::ostream &str, const HistogramType &histogram, int max_width=0)
pretty-print the given histogram.
Definition: histogram.h:1751
void load(const Eigen::DenseBase< EigenType > &x, CountType off_chart_=0)
Load data for the histogram. Uses current histogram parameters, just sets the bin counts...
Definition: histogram.h:327
AveragedHistogram< HistogramType, CountRealType > FinalHistogramType
The type of the final resulting, averaged histogram.
Definition: histogram.h:1246
static Histogram copy(const HistogramType &other)
explicitly copy another histogram type
Definition: histogram.h:301
Basic utilities for dealing with Eigen matrices and other types.
HistogramType_ HistogramType
The histogram type corresponding to the result of a task.
Definition: histogram.h:1231
#define TOMO_STATIC_ASSERT_EXPR(...)
Tool for static assertions without message.
Definition: cxxdefs.h:77
Base_::Params Params
Shortcut for our base class&#39; histogram parameters. See Histogram::Params.
Definition: histogram.h:581
Eigen::Index numBins() const
Shorthand for params.num_bins
Definition: histogram.h:375
AveragedHistogram< SimpleHistogramType, CountRealType > SimpleFinalHistogramType
Properly averaged "simple" histogram, with naive statistical standard deviation error bars from the s...
Definition: histogram.h:1255
std::enable_if< std::is_unsigned< X >::value, bool >::type isPositive(const X)
Test whether the given value is positive or zero.
Definition: cxxutil.h:360
Eigen::Array< CountType, Eigen::Dynamic, 1 > bins
The counts for each bin.
Definition: histogram.h:255
CountType off_chart
The number of points that fell outside of the given range.
Definition: histogram.h:257
CountRealType_ CountRealType
Type used for averaged histogram counts (e.g. double)
Definition: histogram.h:1242
Base_::CountType CountType
The histogram&#39; count type. This is exactly the same as RealAvgType.
Definition: histogram.h:828
Stores a histogram.
Definition: histogram.h:230
Eigen::Array< Scalar, Eigen::Dynamic, 1 > valuesCenter() const
Return an array of values corresponding to the center of each bin.
Definition: histogram.h:186
Histogram(const Histogram &x)
Constructor: copy another histogram type.
Definition: histogram.h:289
Eigen::Index binIndex(Scalar value) const
Shorthand for Params::binIndex()
Definition: histogram.h:392
T str(T... args)
Scalar binLowerValue(Eigen::Index index) const
Returns the value which a given bin index represents (lower bin value limit)
Definition: histogram.h:145
CountType totalCounts() const
Return the total number of histogram counts (no normalization)
Definition: histogram.h:506
HistogramWithErrorBars< Scalar, NewCountType > normalized() const
Get a normalized version of this histogram.
Definition: histogram.h:697
Some C++ utilities, with a tad of C++11 tricks.
SimpleFinalHistogramType simple_final_histogram
The "naive" final histogram, ignoring the error bars of each histogram (see class doc) ...
Definition: histogram.h:1275
T fabs(T... args)
T max(T... args)
T move(T... args)
HistogramType_ HistogramType
The histogram type corresponding to the result of a task.
Definition: histogram.h:1073
void reset(const Params &params_)
Resets the data and sets new params.
Definition: histogram.h:880
Scalar_ Scalar
The scalar type used to specify the "value" (horizongal axis) of the histogram.
Definition: histogram.h:75
std::string prettyPrint(int max_width=0) const
Print the histogram in human readable form.
Definition: histogram.h:754
T scientific(T... args)
AveragedHistogram(Scalar min, Scalar max, Eigen::Index num_bins)
Constructs an AveragedHistogram with the given histogram parameters.
Definition: histogram.h:857
Managing the need for specific overrides to operator new() for some types (especially Eigen types) ...
T size(T... args)
Scalar binResolution() const
Shorthand for Params::binResolution()
Definition: histogram.h:413
std::string fmts(const char *fmt,...)
printf- format to a std::string
Definition: fmt.h:128
Eigen::Array< Scalar, Eigen::Dynamic, 1 > valuesLower() const
Return an array of values corresponding to the lower value of each bin.
Definition: histogram.h:194
Histogram< Scalar, NewCountType > normalizedCounts() const
Get a version of this histogram, normalized by total counts.
Definition: histogram.h:523
static AggregatedHistogramSimple aggregate(const HistogramParams &params, const ContainerType &list, ExtractHistogramFn extract_histogram_fn)
Aggregate a list of histograms.
Definition: histogram.h:1132
VarValueDecoder< T >::RetType value(const Var &var)
Access the value of the given variable, as a C++ type.
Definition: ezmatio.h:878
static AggregatedHistogramWithErrorBars aggregate(const HistogramParams &params, const ContainerType &list, ExtractHistogramFn extract_histogram_fn)
Aggregate a list of histograms.
Definition: histogram.h:1303
HistogramWithErrorBars< typename HistogramType_::Scalar, RealAvgType > Base_
Shortcut for our base class&#39; type.
Definition: histogram.h:821
Scalar binUpperValue(Eigen::Index index) const
Returns the value which a given bin index represents (upper bin value limit)
Definition: histogram.h:170
CountType errorBar(Eigen::Index i) const
Get error bar for bin number i.
Definition: histogram.h:659
int getWidthForTerminalOutput(int max_width=0)
Return a suitable width for displaying stuff on the standard output.
Definition: cxxutil.h:569
Scalar_ Scalar
The Scalar (X-axis) Type. See Histogram::Scalar.
Definition: histogram.h:572
HistogramType_ HistogramType
Type of the individual histograms we are averaging.
Definition: histogram.h:819
Scalar binUpperValue(Eigen::Index index) const
Shorthand for Params::binUpperValue()
Definition: histogram.h:407
Eigen::Array< Scalar, Eigen::Dynamic, 1 > valuesUpper() const
Return an array of values corresponding to the upper value of each bin.
Definition: histogram.h:201
void printHistogramCsv(std::ostream &stream, const std::string sep="\, const std::string linesep="\", const int precision=10)
Produce a comma-separated-value (CSV) representation of the final aggregated histogram data...
Definition: histogram.h:1345
void resize(Index nbRows, Index nbCols)
#define streamstr(tokens)
Utility macro to format stream tokens to a std::string.
Definition: fmt.h:149
int histogramShortBar(std::ostream &str, const HistogramType &histogram, bool log_scale=true, int max_width=0)
Format the histogram as a one-line bar.
Definition: histogram.h:1798
Eigen::Index record(Scalar value, CountType weight)
Record a new value in the histogram, with a certain weight.
Definition: histogram.h:447
void load(const Eigen::DenseBase< EigenType > &d, const Eigen::DenseBase< EigenType2 > &derr, CountType off_chart_=0)
Load data for the histogram. Uses current histogram parameters, just sets the bin counts and the erro...
Definition: histogram.h:678
void printHistogramCsv(std::ostream &stream, const std::string sep="\, const std::string linesep="\", const int precision=10)
Produce a comma-separated-value (CSV) representation of the final aggregated histogram data...
Definition: histogram.h:1163
HistogramWithErrorBars(const HistogramWithErrorBars &x)
Constructor: copy another histogram type.
Definition: histogram.h:623
Histogram(Histogram &&x)
Constructor: move another histogram type.
Definition: histogram.h:281
T setprecision(T... args)
HistogramWithErrorBars< Scalar, NewCountType > normalizedCounts() const
Get a version of this histogram, normalized by total counts.
Definition: histogram.h:718
Eigen::Index num_bins
Number of bins to split the range into.
Definition: histogram.h:100
STL class.
Histogram aggregator, if each individual histogram already has error bars.
Definition: histogram.h:1218
Histogram aggregator, if each histogram doesn&#39;t have error bars.
Definition: histogram.h:1063
HistogramType::Params HistogramParams
The parameters type used to describe our histogram range and number of bins.
Definition: histogram.h:1233
CountType_ CountType
The type that serves to count how many hits in each bin.
Definition: histogram.h:244
#define tomographer_assert(...)
Assertion test macro.
Definition: cxxdefs.h:84
Scalar binLowerValue(Eigen::Index index) const
Shorthand for Params::binLowerValue()
Definition: histogram.h:397
Scalar min
Lower range value.
Definition: histogram.h:96
void finalize()
Finalize the averaging procedure.
Definition: histogram.h:951
Derived & setZero(Index size)
FinalHistogramType final_histogram
The final histogram, properly combining the error bars of each histogram.
Definition: histogram.h:1272