Tomographer  v5.2
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 
44 #include <Eigen/Core>
45 
46 #include <tomographer/tools/fmt.h>
48 #include <tomographer/tools/cxxutil.h> // TOMOGRAPHER_ENABLED_IF, tomographer_assert(), getWidthForTerminalOutput
50 
51 
58 namespace Tomographer {
59 
60 
61 
66 template<typename Scalar_ = double>
67 struct TOMOGRAPHER_EXPORT HistogramParams
68 {
70  typedef Scalar_ Scalar;
71 
73  inline HistogramParams(Scalar min_ = 0.0, Scalar max_ = 1.0, Eigen::Index num_bins_ = 50)
74  : min(min_), max(max_), num_bins(num_bins_)
75  {
76  }
78  template<typename Params2
79 #ifndef TOMOGRAPHER_PARSED_BY_DOXYGEN
80  // enforce Params-like type by checking that properties 'min','max','num_bins' exist:
81  , decltype((int)std::declval<const Params2>().min + (int)std::declval<const Params2>().max
82  + std::declval<Params2>().num_bins) dummyval = 0
83 #endif
84  >
85  inline HistogramParams(const Params2& other)
86  : min(other.min), max(other.max), num_bins(other.num_bins)
87  {
88  }
89 
91  Scalar min;
93  Scalar max;
95  Eigen::Index num_bins;
96 
102  inline bool isWithinBounds(Scalar value) const
103  {
104  return Tools::isFinite(value) && value >= min && value < max;
105  }
112  inline Eigen::Index binIndex(Scalar value) const
113  {
114  if ( !isWithinBounds(value) ) {
115  throw std::out_of_range(streamstr("HistogramParams: Value "<<value
116  <<" out of range ["<<min<<","<<max<<"["));
117  }
118  return binIndexUnsafe(value);
119  }
128  inline Eigen::Index binIndexUnsafe(Scalar value) const
129  {
130  return (Eigen::Index)((value-min) / (max-min) * num_bins);
131  }
140  inline Scalar binLowerValue(Eigen::Index index) const
141  {
142  tomographer_assert(Tools::isPositive(index) && index < num_bins);
143  return min + index * (max-min) / num_bins;
144  }
152  inline Scalar binCenterValue(Eigen::Index index) const
153  {
154  tomographer_assert(Tools::isPositive(index) && index < num_bins);
155  return min + (index+boost::math::constants::half<Scalar>()) * (max-min) / num_bins;
156  }
165  inline Scalar binUpperValue(Eigen::Index index) const
166  {
167  tomographer_assert(Tools::isPositive(index) && index < num_bins);
168  return min + (index+1) * (max-min) / num_bins;
169  }
174  inline Scalar binResolution() const
175  {
176  return (max - min) / num_bins;
177  }
178 
182  {
183  const auto halfbinres = boost::math::constants::half<Scalar>() * binResolution();
184  return Eigen::Array<Scalar, Eigen::Dynamic, 1>::LinSpaced(num_bins, min+halfbinres, max-halfbinres);
185  }
186 
190  {
191  return Eigen::Array<Scalar, Eigen::Dynamic, 1>::LinSpaced(num_bins, min, max-binResolution());
192  }
193 
197  {
198  return Eigen::Array<Scalar, Eigen::Dynamic, 1>::LinSpaced(num_bins, min+binResolution(), max);
199  }
200 };
201 
202 
203 
204 
212 template<typename Scalar_, typename CountType_ = int>
213 class TOMOGRAPHER_EXPORT Histogram
214  // inheriting from this has some advantages over EIGEN_MAKE_ALIGNED_OPERATOR_NEW, such
215  // as not needing to explicitly declare the specialization
216  // NeedOwnOperatorNew<Histogram>:
217  //
218  // -- really not needed because the matrices are dynamically sized
219  //
220  // : public virtual Tools::NeedOwnOperatorNew<Eigen::Array<CountType,Eigen::Dynamic,1> >::ProviderType
221 {
222 public:
224  typedef Scalar_ Scalar;
225 
227  typedef CountType_ CountType;
228 
230  static constexpr bool HasErrorBars = false;
231 
234 
236  Params params;
240  CountType off_chart;
241 
243  template<typename Params2 = Params
244 #ifndef TOMOGRAPHER_PARSED_BY_DOXYGEN
245  // enforce Params-like type by checking that properties 'min','max','num_bins' exist:
246  , decltype((int)std::declval<const Params2>().min + (int)std::declval<const Params2>().max
247  + std::declval<Params2>().num_bins) dummyval = 0
248 #endif
249  >
250  Histogram(Params2 p = Params2())
251  : params(p), bins(Eigen::Array<CountType,Eigen::Dynamic,1>::Zero(p.num_bins)),
252  off_chart(0)
253  {
254  }
255 
257  Histogram(Scalar min_, Scalar max_, Eigen::Index num_bins)
258  : params(min_, max_, num_bins), bins(Eigen::Array<CountType,Eigen::Dynamic,1>::Zero(num_bins)),
259  off_chart(0)
260  {
261  }
262 
265  : params(std::move(x.params)),
266  bins(std::move(x.bins)),
267  off_chart(x.off_chart)
268  {
269  }
270 
272  Histogram(const Histogram & x)
273  : params(x.params),
274  bins(x.bins),
275  off_chart(x.off_chart)
276  {
277  }
278 
280  template<typename HistogramType,// and enforce it's indeed a histogram type by testing
281  // its 'HasErrorBars' property:
282  TOMOGRAPHER_ENABLED_IF_TMPL(HistogramType::HasErrorBars == 0 ||
283  HistogramType::HasErrorBars == 1)>
284  static Histogram copy(const HistogramType & other)
285  {
286  Histogram h(other.params);
287  h.bins = other.bins.template cast<CountType>();
288  h.off_chart = other.off_chart;
289  return h;
290  }
291 
293  inline void reset()
294  {
295  bins.resize(params.num_bins);
296  bins.setZero();
297  off_chart = 0;
298  }
299 
309  template<typename EigenType>
310  inline void load(const Eigen::DenseBase<EigenType> & x, CountType off_chart_ = 0)
311  {
312  tomographer_assert(x.cols() == 1);
313  tomographer_assert(x.rows() == params.num_bins);
314  bins = x.derived().template cast<CountType>();
315  off_chart = off_chart_;
316  }
317 
326  template<typename EigenType>
327  inline void add(const Eigen::ArrayBase<EigenType> & x, CountType off_chart_ = 0)
328  {
329  // the argument must be of ArrayBase type (as opposed to load() where we can
330  // also accept MatrixBase types) because Eigen doesn't allow operator+=
331  // between Arrays and Matrices, but has an operator= .
332  tomographer_assert(x.cols() == 1);
333  tomographer_assert(x.rows() == params.num_bins);
334  bins += x.derived().template cast<CountType>();
335  off_chart += off_chart_;
336  }
337 
346  template<typename OtherScalar, typename OtherCountType>
348  {
349  tomographer_assert(x.bins.cols() == 1);
350  tomographer_assert(x.bins.rows() == params.num_bins);
351  tomographer_assert(std::fabs(x.params.min - params.min) < 1e-8);
352  tomographer_assert(std::fabs(x.params.max - params.max) < 1e-8);
353  bins += x.bins.template cast<CountType>();
354  off_chart += x.off_chart;
355  }
356 
358  inline Eigen::Index numBins() const
359  {
360  return params.num_bins;
361  }
362 
364  inline CountType count(Eigen::Index i) const
365  {
366  return bins(i);
367  }
368 
370  inline bool isWithinBounds(Scalar value) const
371  {
372  return params.isWithinBounds(value);
373  }
375  inline Eigen::Index binIndex(Scalar value) const
376  {
377  return params.binIndex(value);
378  }
380  inline Scalar binLowerValue(Eigen::Index index) const
381  {
382  return params.binLowerValue(index);
383  }
385  inline Scalar binCenterValue(Eigen::Index index) const
386  {
387  return params.binCenterValue(index);
388  }
390  inline Scalar binUpperValue(Eigen::Index index) const
391  {
392  return params.binUpperValue(index);
393  }
394 
396  inline Scalar binResolution() const
397  {
398  return params.binResolution();
399  }
400 
409  inline Eigen::Index record(Scalar value)
410  {
411  if ( !isWithinBounds(value) ) {
412  ++off_chart;
413  return -1;
414  }
415  // calling bin_index_unsafe because we have already checked that value is in range.
416  const Eigen::Index index = params.binIndexUnsafe(value);
417  ++bins( index );
418  return index;
419  }
420 
430  inline Eigen::Index record(Scalar value, CountType weight)
431  {
432  if ( !isWithinBounds(value) ) {
433  off_chart += weight;
434  return -1;
435  }
436  // calling bin_index_unsafe is safe here because we have already checked that value is
437  // in range.
438  const Eigen::Index index = params.binIndexUnsafe(value);
439  bins(index) += weight;
440  return index;
441  }
442 
443 
457  template<typename NewCountType = decltype(Scalar(1) + CountType(1))>
458  inline NewCountType normalization() const
459  {
460  // DON'T DO NewCountType(binResolution())*NewCountType(bins.sum()) as we may loose
461  // precision (if NewCountType=int, for example)
462  return NewCountType(off_chart) + NewCountType(binResolution() * bins.sum());
463  }
464 
472  template<typename NewCountType = Scalar>
474  {
476  const NewCountType f = normalization<NewCountType>();
477  h.load(bins.template cast<NewCountType>() / f, NewCountType(off_chart) / f);
478  return h;
479  }
480 
481 
489  inline CountType totalCounts() const
490  {
491  return bins.sum() + off_chart;
492  }
493 
494 
505  template<typename NewCountType = Scalar>
507  {
509  const NewCountType f = totalCounts();
510  h.load(bins.template cast<NewCountType>() / f, NewCountType(off_chart) / f);
511  return h;
512  }
513 
518  inline std::string prettyPrint(int max_width = 0) const
519  {
520  return histogramPrettyPrint(*this, max_width);
521  }
522 
523 };
524 // static members:
525 template<typename Scalar_, typename CountType_>
527 
528 
529 
530 
536 template<typename Scalar_, typename CountType_ = double>
537 class TOMOGRAPHER_EXPORT HistogramWithErrorBars
538  : public Histogram<Scalar_, CountType_>
539  // public virtual Tools::EigenAlignedOperatorNewProvider -- no need for dynamically-sized matrices
540 {
541 public:
543  typedef Scalar_ Scalar;
545  typedef CountType_ CountType;
546 
552  typedef typename Base_::Params Params;
553 
555  static constexpr bool HasErrorBars = true;
556 
559 
560  // make these accessible without having to use the "Base_::member" syntax all the time
561  using Base_::params;
562  using Base_::bins;
563  using Base_::off_chart;
564 
565 
571  HistogramWithErrorBars(Params params = Params())
572  : Base_(params), delta(Eigen::Array<CountType, Eigen::Dynamic, 1>::Zero(params.num_bins))
573  {
574  }
575 
581  HistogramWithErrorBars(Scalar min, Scalar max, Eigen::Index num_bins)
582  : Base_(min, max, num_bins), delta(Eigen::Array<CountType, Eigen::Dynamic, 1>::Zero(num_bins))
583  {
584  }
585 
588  : Base_(std::move(x)),
589  delta(std::move(x.delta))
590  {
591  }
592 
595  : Base_(x),
596  delta(x.delta)
597  {
598  }
599 
600 
602  template<typename HistogramType,
603  TOMOGRAPHER_ENABLED_IF_TMPL(HistogramType::HasErrorBars == 1)>
604  static HistogramWithErrorBars copy(const HistogramType & other)
605  {
606  HistogramWithErrorBars h(other.params);
607  h.bins = other.bins.template cast<CountType>();
608  h.delta = other.delta.template cast<CountType>();
609  h.off_chart = other.off_chart;
610  return h;
611  }
612 
619  inline void reset()
620  {
621  Base_::reset();
622  delta.resize(Base_::numBins());
623  delta.setZero();
624  }
625 
630  inline CountType errorBar(Eigen::Index i) const
631  {
632  return delta(i);
633  }
634 
635 
648  template<typename EigenType, typename EigenType2 = EigenType>
649  inline void load(const Eigen::DenseBase<EigenType> & d,
650  const Eigen::DenseBase<EigenType2> & derr,
651  CountType off_chart_ = 0)
652  {
653  Base_::load(d, off_chart_);
654  tomographer_assert(derr.cols() == 1);
655  tomographer_assert(derr.rows() == params.num_bins);
656  delta = derr.derived().template cast<CountType>();
657  }
658 
659 
667  template<typename NewCountType = Scalar>
669  {
671  const NewCountType f = Base_::template normalization<NewCountType>();
672  h.load(bins.template cast<NewCountType>() / f,
673  delta.template cast<NewCountType>() / f,
674  NewCountType(off_chart) / f);
675  return h;
676  }
677 
688  template<typename NewCountType = Scalar>
690  {
692  const NewCountType f = Base_::totalCounts();
693  h.load(bins.template cast<NewCountType>() / f,
694  delta.template cast<NewCountType>() / f,
695  NewCountType(off_chart) / f);
696  return h;
697  }
698 
699 
700 private:
704  template<typename... Args>
705  inline void add(Args && ... )
706  {
707  }
711  template<typename... Args>
712  inline void record(Args && ... )
713  {
714  }
715 public:
716 
717 
725  std::string prettyPrint(int max_width = 0) const
726  {
727  return histogramPrettyPrint(*this, max_width);
728  }
729 
730 };
731 // static members:
732 template<typename Scalar_, typename CountType_>
734 
735 
736 
737 
738 
739 
770 template<typename HistogramType_, typename RealAvgType = double>
771 class TOMOGRAPHER_EXPORT AveragedHistogram
772  : public HistogramWithErrorBars<typename HistogramType_::Scalar, RealAvgType>
773 {
774 public:
779  typedef HistogramType_ HistogramType;
782 
784  typedef typename Base_::Params Params;
786  typedef typename Base_::Scalar Scalar;
788  typedef typename Base_::CountType CountType;
789 
791  static constexpr bool HasErrorBars = true;
792 
799 
800 
807  AveragedHistogram(const Params& params = Params())
808  : Base_(params), num_histograms(0)
809  {
810  }
811 
817  AveragedHistogram(Scalar min, Scalar max, Eigen::Index num_bins)
818  : Base_(min, max, num_bins), num_histograms(0)
819  {
820  }
821 
822 
824  : Base_(copy), num_histograms(copy.num_histograms)
825  {
826  }
828  : Base_(std::move(x)),
829  num_histograms(x.num_histograms)
830  {
831  }
832 
833 
840  inline void reset(const Params& params_)
841  {
842  Base_::params = params_;
843  Base_::reset();
844  num_histograms = 0;
845  }
846 
853  inline void reset()
854  {
855  Base_::reset();
856  num_histograms = 0;
857  }
858 
859  // ---------------------------------------------------------------------------
860  // Implementation in case the added histograms don't have their own error bars
861  // ---------------------------------------------------------------------------
862 
877  TOMOGRAPHER_ENABLED_IF(!HistogramType::HasErrorBars)
878  inline void addHistogram(const HistogramType& histogram)
879  {
880  // bins collects the sum of the histograms
881  // delta for now collects the sum of squares. delta will be normalized in finalize().
882 
883  tomographer_assert((typename HistogramType::CountType)histogram.numBins() ==
884  (typename HistogramType::CountType)Base_::numBins());
885 
886  for (Eigen::Index k = 0; k < histogram.numBins(); ++k) {
887  RealAvgType binvalue = histogram.count(k);
888  Base_::bins(k) += binvalue;
889  Base_::delta(k) += binvalue * binvalue;
890  }
891 
892  Base_::off_chart += histogram.off_chart;
893  ++num_histograms;
894  }
895 
910  TOMOGRAPHER_ENABLED_IF(!HistogramType::HasErrorBars)
911  inline void finalize()
912  {
913  Base_::bins /= num_histograms;
914  Base_::delta /= num_histograms;
915  Base_::off_chart /= num_histograms;
916 
917  // delta = sqrt(< X^2 > - < X >^2) / sqrt(Nrepeats-1)
918  auto finhist2 = Base_::bins*Base_::bins; // for array, this is c-wise product
919  Base_::delta = ( (Base_::delta - finhist2) / (num_histograms-1) ).sqrt();
920  }
921 
922  // ---------------------------------------------------------------------------
923  // Implementation in case the added histograms do have their own error bars
924  // ---------------------------------------------------------------------------
925 
940  TOMOGRAPHER_ENABLED_IF(HistogramType::HasErrorBars)
941  inline void addHistogram(const HistogramType& histogram)
942  {
943  // bins collects the sum of the histograms
944  // delta for now collects the sum of squares. delta will be normalized in finished().
945 
946  tomographer_assert((typename HistogramType::CountType)histogram.numBins() == Base_::numBins());
947 
948  for (Eigen::Index k = 0; k < histogram.numBins(); ++k) {
949  RealAvgType binvalue = histogram.count(k);
950  Base_::bins(k) += binvalue;
951  RealAvgType bindelta = histogram.errorBar(k);
952  Base_::delta(k) += bindelta*bindelta;
953  }
954 
955  Base_::off_chart += histogram.off_chart;
956  ++num_histograms;
957  }
972  TOMOGRAPHER_ENABLED_IF(HistogramType::HasErrorBars)
973  inline void finalize()
974  {
975  Base_::bins /= num_histograms;
976  Base_::off_chart /= num_histograms;
977 
978  Base_::delta = Base_::delta.sqrt();
979  Base_::delta /= num_histograms;
980  }
981 
982 };
983 
984 
985 
986 
1011 template<typename HistogramType_, typename CountRealType_>
1012 class TOMOGRAPHER_EXPORT AggregatedHistogramSimple
1013  : public virtual Tools::NeedOwnOperatorNew<
1014  AveragedHistogram<HistogramType_,CountRealType_>
1015  >::ProviderType
1016 {
1017 public:
1022  typedef HistogramType_ HistogramType;
1023 
1024  TOMO_STATIC_ASSERT_EXPR( ! HistogramType::HasErrorBars ) ;
1025 
1027  typedef typename HistogramType::Params HistogramParams;
1028 
1030  typedef typename HistogramType::Scalar HistogramScalarType;
1031 
1033  typedef CountRealType_ CountRealType;
1034 
1039 
1040 
1041 
1043  : final_histogram(std::move(x.final_histogram))
1044  {
1045  }
1046 
1047  AggregatedHistogramSimple(FinalHistogramType && x)
1048  : final_histogram(std::move(x))
1049  {
1050  }
1051 
1053  FinalHistogramType final_histogram;
1054 
1055 
1080  template<typename ContainerType, typename ExtractHistogramFn>
1081  static inline AggregatedHistogramSimple aggregate(const HistogramParams & params,
1082  const ContainerType & list,
1083  ExtractHistogramFn extract_histogram_fn)
1084  {
1085  FinalHistogramType h(params); // initializes with zeros
1086 
1087  // iterate over all task histograms, add them to the averaged histogram
1088  for (const auto item : list) {
1089  h.addHistogram(extract_histogram_fn(item));
1090  }
1091 
1092  h.finalize();
1093 
1095  }
1096 
1097 
1098 
1112  inline void printHistogramCsv(std::ostream & stream,
1113  const std::string sep = "\t",
1114  const std::string linesep = "\n",
1115  const int precision = 10)
1116  {
1117  stream << "Value" << sep << "Counts" << sep << "Error" << linesep
1118  << std::scientific << std::setprecision(precision);
1119  for (Eigen::Index kk = 0; kk < final_histogram.bins.size(); ++kk) {
1120  stream << final_histogram.params.binLowerValue(kk) << sep
1121  << final_histogram.bins(kk) << sep
1122  << final_histogram.delta(kk) << linesep;
1123  }
1124  }
1125 
1126 
1127 }; // class AggregatedHistogramSimple
1128 
1129 
1130 
1158 template<typename HistogramType_, typename CountRealType_>
1159 class TOMOGRAPHER_EXPORT AggregatedHistogramWithErrorBars
1160  : public virtual Tools::NeedOwnOperatorNew<
1161  AveragedHistogram<HistogramType_, CountRealType_> ,
1162  AveragedHistogram<Histogram<typename HistogramType_::Scalar,
1163  typename HistogramType_::CountType>,
1164  CountRealType_>
1165  >::ProviderType
1166 {
1167 public:
1172  typedef HistogramType_ HistogramType;
1173 
1174  TOMO_STATIC_ASSERT_EXPR( HistogramType::HasErrorBars ) ;
1175 
1177  typedef typename HistogramType::Params HistogramParams;
1178 
1180  typedef typename HistogramType::Scalar HistogramScalarType;
1181 
1183  typedef CountRealType_ CountRealType;
1184 
1188 
1197 
1198 
1199 
1201  : final_histogram(std::move(x.final_histogram)),
1202  simple_final_histogram(std::move(x.simple_final_histogram))
1203  {
1204  }
1205 
1206  AggregatedHistogramWithErrorBars(FinalHistogramType && x, SimpleFinalHistogramType && y)
1207  : final_histogram(std::move(x)),
1208  simple_final_histogram(std::move(y))
1209  {
1210  }
1211 
1213  FinalHistogramType final_histogram;
1214 
1216  SimpleFinalHistogramType simple_final_histogram;
1217 
1218 
1243  template<typename ContainerType, typename ExtractHistogramFn>
1244  static inline AggregatedHistogramWithErrorBars aggregate(const HistogramParams & params,
1245  const ContainerType & list,
1246  ExtractHistogramFn extract_histogram_fn)
1247  {
1248  // initializes with zeros
1249  FinalHistogramType hist(params);
1250  SimpleFinalHistogramType histsimple(params);
1251 
1252  // iterate over all task histograms, add them to the averaged histogram
1253  for (const auto& item : list) {
1254  const auto& h = extract_histogram_fn(item);
1255  // hist's type is based on individual histograms WITH error bars, so this will take
1256  // into account h's error bars.
1257  hist.addHistogram(h);
1258  // histsimple's type is based on non-error bar individual histograms, so this will
1259  // ignore h's error bars.
1260  histsimple.addHistogram(h);
1261  }
1262 
1263  hist.finalize();
1264  histsimple.finalize();
1265 
1266  return AggregatedHistogramWithErrorBars(std::move(hist), std::move(histsimple));
1267  }
1268 
1269 
1270 
1286  inline void printHistogramCsv(std::ostream & stream,
1287  const std::string sep = "\t",
1288  const std::string linesep = "\n",
1289  const int precision = 10)
1290  {
1291  stream << "Value" << sep << "Counts" << sep << "Error" << sep << "SimpleError" << linesep
1292  << std::scientific << std::setprecision(precision);
1293  for (Eigen::Index kk = 0; kk < final_histogram.bins.size(); ++kk) {
1294  stream << final_histogram.params.binLowerValue(kk) << sep
1295  << final_histogram.bins(kk) << sep
1296  << final_histogram.delta(kk) << sep
1297  << simple_final_histogram.delta(kk) << linesep;
1298  }
1299  }
1300 
1301 
1302 }; // class AggregatedHistogramWithErrorBars
1303 
1304 
1305 
1306 
1307 
1308 
1309 
1310 // -----------------------------------------------------------------------------
1311 // Pretty Print Histogram Utilities
1312 // -----------------------------------------------------------------------------
1313 
1314 
1315 
1316 namespace tomo_internal {
1317 // internal helpers
1318 //
1319 // find maximum value in the list only among those values which are finite (not inf or nan)
1320 //
1321 template<typename Scalar, typename Fn>
1322 inline Scalar max_finite_value(const Eigen::Index num_items, Fn val_generator,
1323  const Scalar default_val = Scalar(1.0))
1324 {
1325  bool has_first_val = false;
1326  Scalar max_val = default_val;
1327  for (Eigen::Index k = 0; k < num_items; ++k) {
1328  const Scalar this_val = val_generator(k);
1329  if (Tools::isFinite(this_val) && (!has_first_val || this_val > max_val)) {
1330  max_val = this_val;
1331  has_first_val = true;
1332  }
1333  }
1334  return max_val;
1335 }
1336 
1337 //
1338 // get labels left of histogram (generic HistogramType interface: no information, just bin #)
1339 //
1340 template<typename HistogramType>
1341 struct histogram_pretty_print_label
1342 {
1343  static inline void getLabels(std::vector<std::string> & labels, const HistogramType & hist)
1344  {
1345  labels.resize(hist.numBins());
1346  for (std::size_t k = 0; k < hist.numBins(); ++k) {
1347  labels[k] = std::to_string(k);
1348  }
1349  }
1350 };
1351 // get labels left of histogram (for the family of histograms with 'Params':
1352 // Histogram, HistogramWithErrorBars etc.)
1353 //
1354 // common code for several specializations of histogram_pretty_print_label
1355 template<typename HistogramType>
1356 inline void histogram_get_labels_for_hist_params(std::vector<std::string> & labels, const HistogramType& hist)
1357 {
1358  labels.resize((std::size_t)hist.numBins());
1359 
1360  const typename HistogramType::Scalar max_label_val
1361  = std::max(hist.binCenterValue(0), hist.binCenterValue(hist.numBins()-1));
1362  const int powten = (int)std::floor(std::log10(max_label_val));
1363  const int relprecision = 4;
1364  const int precision = (powten > relprecision) ? 0 : (relprecision - powten - 1);
1365 
1366  for (Eigen::Index k = 0; k < hist.numBins(); ++k) {
1367  std::ostringstream ss;
1368  ss << std::fixed << std::setprecision(precision) << std::right << hist.binCenterValue(k);
1369  labels[(std::size_t)k] = ss.str();
1370  }
1371 }
1372 // specialize histogram pretty-print labels using the code above
1373 template<typename Scalar_, typename CountType_>
1374 struct histogram_pretty_print_label<Histogram<Scalar_, CountType_> >
1375 {
1377  static inline void getLabels(std::vector<std::string> & labels, const HistogramType & hist)
1378  {
1379  histogram_get_labels_for_hist_params<HistogramType>(labels, hist);
1380  }
1381 };
1382 // specialize histogram pretty-print labels using the code above
1383 template<typename Scalar_, typename CountType_>
1384 struct histogram_pretty_print_label<HistogramWithErrorBars<Scalar_, CountType_> >
1385 {
1387  static inline void getLabels(std::vector<std::string> & labels, const HistogramType & hist)
1388  {
1389  histogram_get_labels_for_hist_params<HistogramType>(labels, hist);
1390  }
1391 };
1392 // specialize histogram pretty-print labels using the code above
1393 template<typename BaseHistogramType_, typename RealAvgType_>
1394 struct histogram_pretty_print_label<AveragedHistogram<BaseHistogramType_, RealAvgType_> >
1395 {
1397  static inline void getLabels(std::vector<std::string> & labels, const HistogramType & hist)
1398  {
1399  histogram_get_labels_for_hist_params<HistogramType>(labels, hist);
1400  }
1401 };
1402 
1403 // format bin counts nicely
1404 template<typename HistogramType>
1405 struct histogram_pretty_print_value
1406 {
1407  const HistogramType & hist;
1408  histogram_pretty_print_value(const HistogramType & hist_) : hist(hist_) { }
1409 
1410  TOMOGRAPHER_ENABLED_IF(!HistogramType::HasErrorBars)
1411  static inline void getStrValues(std::vector<std::string> & svalues, const HistogramType & hist)
1412  {
1413  svalues.resize((std::size_t)hist.numBins());
1414 
1415  typename HistogramType::CountType max_val =
1416  max_finite_value<typename HistogramType::CountType>(hist.numBins(),
1417  [&](Eigen::Index k) { return hist.count(k); },
1418  typename HistogramType::CountType(1));
1419 
1420  const int powten = (int)std::floor(std::log10(max_val));
1421  const int relprecision = 3;
1422  const int precision = abs_precision_for(powten, relprecision);
1423  const int w = (precision > 0) ? (precision+powten+1) : (relprecision+2);
1424 
1425  for (Eigen::Index k = 0; k < hist.numBins(); ++k) {
1426  std::ostringstream ss;
1427  ss << std::setprecision(precision) << std::fixed << std::right << std::setw(w)
1428  << hist.count(k);
1429  svalues[(std::size_t)k] = ss.str();
1430  }
1431  }
1432 
1433  TOMOGRAPHER_ENABLED_IF(HistogramType::HasErrorBars)
1434  static inline void getStrValues(std::vector<std::string> & svalues, const HistogramType & hist)
1435  {
1436  svalues.resize((std::size_t)hist.numBins());
1437 
1438  typename HistogramType::CountType max_val =
1439  max_finite_value<typename HistogramType::CountType>(hist.numBins(),
1440  [&](Eigen::Index k) { return hist.count(k); },
1441  typename HistogramType::CountType(1));
1442 
1443  const int powten = (int)std::floor(std::log10(max_val)); // floor of log_{10}(...)
1444  const int relprecision = 3;
1445  const int precision = abs_precision_for(powten, relprecision);
1446  const int w = (precision > 0) ? (precision+powten+2) : (relprecision+2);
1447 
1448  for (Eigen::Index k = 0; k < hist.numBins(); ++k) {
1449  std::ostringstream ss;
1450  ss << std::setprecision(precision) << std::fixed << std::right << std::setw(w)
1451  << hist.count(k) << " +- "
1452  << std::setprecision(abs_precision_for(powten-1, relprecision-1)) << std::setw(w)
1453  << hist.errorBar(k);
1454  svalues[(std::size_t)k] = ss.str();
1455  }
1456  }
1457 private:
1458  static inline int abs_precision_for(const int powten, const int relprecision)
1459  {
1460  return (powten >= relprecision) ? 0 : (relprecision - powten - 1);
1461  }
1462 };
1463 
1465 //
1466 // access this with public API using histogram_pretty_print().
1467 //
1468 template<typename HistogramType>
1469 struct histogram_pretty_printer
1470 {
1471  const HistogramType & hist;
1472  const int max_width;
1473 
1474  // the histogram count type, but at least precision double
1475  typedef decltype(typename HistogramType::CountType(1) + double(1)) CountType;
1476 
1477  const std::string lsep;
1478  const std::string rsep;
1479 
1480  std::vector<std::string> labels;
1481  int maxlabelwidth;
1482 
1483  std::vector<std::string> svalues;
1484  int maxsvaluewidth;
1485 
1486  CountType max_value;
1487 
1488  int max_bar_width;
1489  CountType barscale;
1490 
1491  histogram_pretty_printer(const HistogramType & hist_, const int max_width_)
1492  : hist(hist_), max_width(max_width_), lsep(" |"), rsep(" ")
1493  {
1494  // first pass:
1495  // - determine the maximum value attained in the histogram
1496  // - determine maximum width of formatted label & value fields.
1497 
1498  labels.resize((std::size_t)hist.numBins());
1499  svalues.resize((std::size_t)hist.numBins());
1500 
1501  histogram_pretty_print_label<HistogramType>::getLabels(labels, hist);
1502  histogram_pretty_print_value<HistogramType>::getStrValues(svalues, hist);
1503 
1504  bool has_maxval = false;
1505  for (std::size_t k = 0; k < (std::size_t)hist.numBins(); ++k) {
1506  const CountType val = maxval(k);
1507 
1508  if (Tools::isFinite(val) && (!has_maxval || val > max_value)) {
1509  max_value = val;
1510  has_maxval = true;
1511  }
1512  if (k == 0 || (int)labels[k].size() > maxlabelwidth) {
1513  maxlabelwidth = (int)labels[k].size();
1514  }
1515  if (k == 0 || (int)svalues[k].size() > maxsvaluewidth) {
1516  maxsvaluewidth = (int)svalues[k].size();
1517  }
1518  }
1519  if (!has_maxval) {
1520  max_value = 1.0;
1521  }
1522 
1523  max_bar_width = max_width - maxlabelwidth - maxsvaluewidth - (int)lsep.size() - (int)rsep.size();
1524  if (max_bar_width < 2) {
1525  max_bar_width = 2;
1526  }
1527  barscale = ((max_value > 0) ? (max_value / max_bar_width) : 1.0);
1528  }
1529 
1530  inline std::size_t value_to_bar_length(CountType val) const
1531  {
1532  if (val < 0 || !Tools::isFinite(val)) {
1533  val = 0;
1534  }
1535  std::size_t l = (std::size_t)(val/barscale+0.5);
1536  if (l >= (std::size_t)max_bar_width) {
1537  return (std::size_t)max_bar_width-1;
1538  }
1539  return l;
1540  }
1541 
1542  inline void fill_str_len(std::string & s, CountType valstart, CountType valend,
1543  char c, char clside, char crside) const
1544  {
1545  std::size_t vs = value_to_bar_length(valstart);
1546  std::size_t ve = value_to_bar_length(valend);
1547  //tomographer_assert(vs >= 0);
1548  tomographer_assert(vs < s.size());
1549  //tomographer_assert(ve >= 0);
1550  tomographer_assert(ve < s.size());
1551  for (std::size_t j = vs; j < ve; ++j) {
1552  s[j] = c;
1553  }
1554  if (clside && crside && clside != crside && vs == ve) {
1555  if (ve < s.size()-1) {
1556  ++ve;
1557  } else if (vs > 1) {
1558  --vs;
1559  }
1560  }
1561  if (clside) {
1562  s[vs] = clside;
1563  }
1564  if (crside) {
1565  s[ve] = crside;
1566  }
1567  }
1568 
1569  inline void pretty_print(std::ostream & str) const
1570  {
1571  // perform now second pass:
1572  // - display the histogram line by line, with the calculated widths.
1573 
1574  for (std::size_t k = 0; k < (std::size_t)hist.numBins(); ++k) {
1575  str << std::setw(maxlabelwidth) << labels[k] << lsep
1576  << make_bar(k) << rsep << std::setw(maxsvaluewidth) << svalues[k] << "\n";
1577  }
1578  }
1579 
1580 private:
1581  // maxval(k): how much this bar may extend in length
1582  TOMOGRAPHER_ENABLED_IF(!HistogramType::HasErrorBars)
1583  inline CountType maxval(const std::size_t k) const
1584  {
1585  return hist.count((Eigen::Index)k);
1586  }
1587  TOMOGRAPHER_ENABLED_IF(HistogramType::HasErrorBars)
1588  inline CountType maxval(const std::size_t k) const
1589  {
1590  return (hist.count((Eigen::Index)k) + hist.errorBar((Eigen::Index)k));
1591  }
1592  // make_bar(k): produce the histogram bar in characters...
1593  TOMOGRAPHER_ENABLED_IF(!HistogramType::HasErrorBars)
1594  inline std::string make_bar(std::size_t k) const
1595  {
1596  std::string sbar((std::size_t)max_bar_width, ' ');
1597  fill_str_len(sbar, 0.0, hist.count((Eigen::Index)k), '*', 0, 0);
1598  return sbar;
1599  }
1600  TOMOGRAPHER_ENABLED_IF(HistogramType::HasErrorBars)
1601  inline std::string make_bar(std::size_t k) const
1602  {
1603  std::string sbar((std::size_t)max_bar_width, ' ');
1604  const typename HistogramType::CountType binval = hist.count((Eigen::Index)k);
1605  const typename HistogramType::CountType binerr = hist.errorBar((Eigen::Index)k);
1606  fill_str_len(sbar, 0.0, binval - binerr, '*', '*', '*');
1607  fill_str_len(sbar, binval - binerr, binval + binerr, '-', '|', '|');
1608  return sbar;
1609  }
1610 };
1611 
1612 template<typename HistogramType>
1613 inline std::string histogram_short_bar_fmt(const HistogramType & histogram, const bool log_scale,
1614  const int max_width)
1615 {
1616  std::string s = Tools::fmts("%.2g|", (double)histogram.binLowerValue(0));
1617  std::string send = Tools::fmts("|%.2g", (double)histogram.binUpperValue(histogram.numBins()-1));
1618  if (histogram.off_chart > 0) {
1619  send += Tools::fmts(" [+%.1g off]", (double)histogram.off_chart);
1620  }
1621 
1622  const int maxbarwidth = max_width - (int)s.size() - (int)send.size();
1623  const int numdiv = (int)(std::ceil((float)histogram.numBins() / maxbarwidth) + 0.5f);
1624  const int barwidth = (int)(std::ceil((float)histogram.numBins() / numdiv) + 0.5f);
1625 
1627  Eigen::ArrayXf veclog(barwidth);
1628 
1629  int k;
1630  float minlogval = 0;
1631  float maxlogval = 0;
1632  for (k = 0; k < barwidth; ++k) {
1633  vec(k) = histogram.bins.segment((Eigen::Index)(numdiv*k),
1634  std::min((Eigen::Index)numdiv,
1635  (Eigen::Index)(histogram.bins.size()-numdiv*k))).sum();
1636  if (vec(k) > 0) {
1637  if (log_scale) {
1638  veclog(k) = std::log((float)vec(k));
1639  } else {
1640  veclog(k) = (float)vec(k);
1641  }
1642  if (k == 0 || minlogval > veclog(k)) {
1643  minlogval = veclog(k);
1644  }
1645  if (k == 0 || maxlogval < veclog(k)) {
1646  maxlogval = veclog(k) + 1e-6f;
1647  }
1648  } else {
1649  veclog(k) = 0.f;
1650  }
1651  }
1652 
1653  // now, prepare string
1654  const std::string chars = ".-+ox%#";
1655  for (k = 0; k < barwidth; ++k) {
1656  if (vec(k) <= 0) {
1657  s += ' ';
1658  } else {
1659  int i = (int)(chars.size() * (veclog(k) - minlogval) / (maxlogval - minlogval));
1660  if (i < 0) { i = 0; }
1661  if (i >= (int)chars.size()) { i = (int)chars.size()-1; }
1662  s += chars[(std::size_t)i];
1663  }
1664  }
1665 
1666  s += send;
1667 
1668  return s;
1669 }
1670 
1671 } // namespace tomo_internal
1672 
1673 
1682 template<typename HistogramType>
1683 inline void histogramPrettyPrint(std::ostream & str, const HistogramType & histogram, int max_width = 0)
1684 {
1685  tomographer_assert(Tools::isPositive(histogram.params.num_bins));
1686 
1687  if (histogram.params.num_bins == 0) {
1688  str << "<empty histogram: no bins>\n";
1689  return;
1690  }
1691 
1692  max_width = Tools::getWidthForTerminalOutput(max_width);
1693  tomo_internal::histogram_pretty_printer<HistogramType>(histogram, max_width).pretty_print(str);
1694 }
1695 
1704 template<typename HistogramType>
1705 inline std::string histogramPrettyPrint(const HistogramType & histogram, int max_width = 0)
1706 {
1707  std::ostringstream ss;
1708  histogramPrettyPrint<HistogramType>(ss, histogram, max_width);
1709  return ss.str();
1710 }
1711 
1729 template<typename HistogramType>
1730 inline int histogramShortBar(std::ostream & str, const HistogramType & histogram,
1731  bool log_scale = true, int max_width = 0)
1732 {
1733  tomographer_assert(Tools::isPositive(histogram.params.num_bins));
1734 
1735  max_width = Tools::getWidthForTerminalOutput(max_width);
1736 
1737  std::string s;
1738  if (histogram.params.num_bins == 0) {
1739  s = "<empty histogram: no bins>";
1740  } else {
1741  s = tomo_internal::histogram_short_bar_fmt<HistogramType>(histogram, log_scale, max_width);
1742  }
1743 
1744  str << s;
1745  return max_width - (int)s.size();
1746 }
1757 template<typename HistogramType>
1758 inline std::string histogramShortBar(const HistogramType & histogram, bool log_scale = true, int max_width = 0)
1759 {
1760  tomographer_assert(Tools::isPositive(histogram.params.num_bins));
1761 
1762  if (histogram.params.num_bins == 0) {
1763  return "<empty histogram: no bins>";
1764  }
1765 
1766  max_width = Tools::getWidthForTerminalOutput(max_width);
1767  return tomo_internal::histogram_short_bar_fmt<HistogramType>(histogram, log_scale, max_width);
1768 }
1769 
1770 
1785 template<typename HistogramType>
1787  std::string head,
1788  const HistogramType& hist,
1789  std::string tail,
1790  bool log_scale = true,
1791  int full_max_width = 0)
1792 {
1793  full_max_width = Tools::getWidthForTerminalOutput(full_max_width);
1794 
1795  str << head;
1796  const int w = histogramShortBar(str, hist, log_scale, full_max_width - (int)head.size() - (int)tail.size());
1797  str << std::setw(w + (int)tail.size()) << std::right << tail << "\n";
1798 }
1799 
1814 template<typename HistogramType>
1816  const HistogramType& hist,
1817  std::string tail,
1818  bool log_scale = true,
1819  int full_max_width = 0)
1820 {
1821  std::ostringstream ss;
1822  histogramShortBarWithInfo(ss, head, hist, tail, log_scale, full_max_width);
1823  return ss.str();
1824 }
1825 
1826 
1827 
1828 
1829 
1830 // compatibility with Tomographer <= 4
1831 template<typename Scalar_ = double>
1833 template<typename Scalar_, typename CountType_ = int>
1835 template<typename Scalar_, typename CountType_ = double>
1837 
1838 
1839 
1840 } // namespace Tomographer
1841 
1842 
1843 
1844 
1845 #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:152
bool isWithinBounds(Scalar value) const
Shorthand for Params::isWithinBounds()
Definition: histogram.h:370
HistogramType::Params HistogramParams
The parameters type used to describe our histogram range and number of bins.
Definition: histogram.h:1024
FinalHistogramType final_histogram
The final histogram, with error bars.
Definition: histogram.h:1053
Histogram(Params2 p=Params2())
Constructor: stores the parameters and initializes the histogram to zero counts everywhere.
Definition: histogram.h:250
Eigen::Array< CountType, Eigen::Dynamic, 1 > delta
The error bars associated with each histogram bin.
Definition: histogram.h:558
void reset()
Resets the histogram to zero counts everywhere (including the off-chart counts)
Definition: histogram.h:293
CountRealType_ CountRealType
Type used for averaged histogram counts (e.g. double)
Definition: histogram.h:1033
Eigen::Index record(Scalar value)
Record a new value in the histogram.
Definition: histogram.h:409
Scalar max
Upper range value.
Definition: histogram.h:93
void addHistogram(const HistogramType &histogram)
Add a new histogram in the data series.
Definition: histogram.h:878
bool isFinite(const X val)
Test whether floating-point value is finite.
Definition: cxxutil.h:379
The parameters of a Histogram.
Definition: histogram.h:67
void reset()
Resets the histogram to zero counts everywhere, and zero error bars.
Definition: histogram.h:619
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:1786
T ceil(T... args)
Scalar binResolution() const
Returns the width of a bin.
Definition: histogram.h:174
HistogramParams< Scalar_ > Params
The type for specifying parameters of this histogram (limits, number of bins)
Definition: histogram.h:233
Scalar binCenterValue(Eigen::Index index) const
Shorthand for Params::binCenterValue()
Definition: histogram.h:385
Eigen::Index binIndexUnsafe(Scalar value) const
Returns which bin this value should be counted in.
Definition: histogram.h:128
HistogramParams(const Params2 &other)
Copy constructor, from any other Histogram::Params type.
Definition: histogram.h:85
T log(T... args)
static HistogramWithErrorBars copy(const HistogramType &other)
explicitly copy another histogram type
Definition: histogram.h:604
Stores a histogram along with error bars.
Definition: histogram.h:537
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:364
Base_::Scalar Scalar
The histogram&#39;s X-axis scalar type. See HistogramWithErrorBars::Scalar.
Definition: histogram.h:786
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:257
void add(const Histogram< OtherScalar, OtherCountType > &x)
Add data to the histogram.
Definition: histogram.h:347
HistogramWithErrorBars(Params params=Params())
Constructor, with given histogram parameters.
Definition: histogram.h:571
Base_::Params Params
The histogram parameters&#39; type. See HistogramWithErrorBars::Params.
Definition: histogram.h:784
bool isWithinBounds(Scalar value) const
Tests whether the given value is in the range of the histogram.
Definition: histogram.h:102
HistogramWithErrorBars(HistogramWithErrorBars &&x)
Constructor: move another histogram type.
Definition: histogram.h:587
std::string prettyPrint(int max_width=0) const
Pretty-print the histogram and return it as a string with horizontal bars.
Definition: histogram.h:518
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:112
Params params
Parameters of this histogram (range and # of bins)
Definition: histogram.h:236
T floor(T... args)
HistogramType::Scalar HistogramScalarType
The scalar type of the histogram (i.e., x-axis labels)
Definition: histogram.h:1180
Histogram< Scalar_, CountType_ > Base_
Shortcut for our base class type.
Definition: histogram.h:548
HistogramParams(Scalar min_=0.0, Scalar max_=1.0, Eigen::Index num_bins_=50)
The obvious constructor.
Definition: histogram.h:73
Histogram< typename HistogramType::Scalar, typename HistogramType::CountType > SimpleHistogramType
The "simple" histogram, as if without binning analysis.
Definition: histogram.h:1192
void add(const Eigen::ArrayBase< EigenType > &x, CountType off_chart_=0)
Add data to the histogram.
Definition: histogram.h:327
T log10(T... args)
CountType_ CountType
The Type used to keep track of counts. See Histogram::CountType.
Definition: histogram.h:545
HistogramType::Scalar HistogramScalarType
The scalar type of the histogram (i.e., x-axis labels)
Definition: histogram.h:1030
int num_histograms
The number of histograms averaged.
Definition: histogram.h:798
SegmentReturnType segment(Index start, Index n)
void reset()
Resets the data keeping the exisiting params.
Definition: histogram.h:853
Scalar_ Scalar
The scalar type of the "X"-axis of the histogram (usually double)
Definition: histogram.h:224
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:1038
T min(T... args)
NewCountType normalization() const
Calculate the total weight stored in this histogram.
Definition: histogram.h:458
AveragedHistogram(const Params &params=Params())
Constructs an AveragedHistogram with the given histogram parameters.
Definition: histogram.h:807
Histogram< Scalar, NewCountType > normalized() const
Get a normalized version of this histogram.
Definition: histogram.h:473
HistogramWithErrorBars(Scalar min, Scalar max, Eigen::Index num_bins)
Constructor, with given histogram parameters.
Definition: histogram.h:581
Combines several histograms (with same parameters) into an averaged histogram.
Definition: histogram.h:771
void histogramPrettyPrint(std::ostream &str, const HistogramType &histogram, int max_width=0)
pretty-print the given histogram.
Definition: histogram.h:1683
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:310
AveragedHistogram< HistogramType, CountRealType > FinalHistogramType
The type of the final resulting, averaged histogram.
Definition: histogram.h:1187
static Histogram copy(const HistogramType &other)
explicitly copy another histogram type
Definition: histogram.h:284
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:1172
#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:552
Eigen::Index numBins() const
Shorthand for params.num_bins
Definition: histogram.h:358
AveragedHistogram< SimpleHistogramType, CountRealType > SimpleFinalHistogramType
Properly averaged "simple" histogram, with naive statistical standard deviation error bars from the s...
Definition: histogram.h:1196
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:238
CountType off_chart
The number of points that fell outside of the given range.
Definition: histogram.h:240
CountRealType_ CountRealType
Type used for averaged histogram counts (e.g. double)
Definition: histogram.h:1183
Base_::CountType CountType
The histogram&#39; count type. This is exactly the same as RealAvgType.
Definition: histogram.h:788
Stores a histogram.
Definition: histogram.h:213
Eigen::Array< Scalar, Eigen::Dynamic, 1 > valuesCenter() const
Return an array of values corresponding to the center of each bin.
Definition: histogram.h:181
Histogram(const Histogram &x)
Constructor: copy another histogram type.
Definition: histogram.h:272
Eigen::Index binIndex(Scalar value) const
Shorthand for Params::binIndex()
Definition: histogram.h:375
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:140
CountType totalCounts() const
Return the total number of histogram counts (no normalization)
Definition: histogram.h:489
HistogramWithErrorBars< Scalar, NewCountType > normalized() const
Get a normalized version of this histogram.
Definition: histogram.h:668
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:1216
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:1022
void reset(const Params &params_)
Resets the data and sets new params.
Definition: histogram.h:840
Scalar_ Scalar
The scalar type used to specify the "value" (horizongal axis) of the histogram.
Definition: histogram.h:70
std::string prettyPrint(int max_width=0) const
Print the histogram in human readable form.
Definition: histogram.h:725
T scientific(T... args)
AveragedHistogram(Scalar min, Scalar max, Eigen::Index num_bins)
Constructs an AveragedHistogram with the given histogram parameters.
Definition: histogram.h:817
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:396
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:189
Histogram< Scalar, NewCountType > normalizedCounts() const
Get a version of this histogram, normalized by total counts.
Definition: histogram.h:506
static AggregatedHistogramSimple aggregate(const HistogramParams &params, const ContainerType &list, ExtractHistogramFn extract_histogram_fn)
Aggregate a list of histograms.
Definition: histogram.h:1081
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:1244
HistogramWithErrorBars< typename HistogramType_::Scalar, RealAvgType > Base_
Shortcut for our base class&#39; type.
Definition: histogram.h:781
Scalar binUpperValue(Eigen::Index index) const
Returns the value which a given bin index represents (upper bin value limit)
Definition: histogram.h:165
CountType errorBar(Eigen::Index i) const
Get error bar for bin number i.
Definition: histogram.h:630
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:543
HistogramType_ HistogramType
Type of the individual histograms we are averaging.
Definition: histogram.h:779
Scalar binUpperValue(Eigen::Index index) const
Shorthand for Params::binUpperValue()
Definition: histogram.h:390
Eigen::Array< Scalar, Eigen::Dynamic, 1 > valuesUpper() const
Return an array of values corresponding to the upper value of each bin.
Definition: histogram.h:196
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:1286
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:1730
Eigen::Index record(Scalar value, CountType weight)
Record a new value in the histogram, with a certain weight.
Definition: histogram.h:430
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:649
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:1112
HistogramWithErrorBars(const HistogramWithErrorBars &x)
Constructor: copy another histogram type.
Definition: histogram.h:594
Histogram(Histogram &&x)
Constructor: move another histogram type.
Definition: histogram.h:264
T setprecision(T... args)
HistogramWithErrorBars< Scalar, NewCountType > normalizedCounts() const
Get a version of this histogram, normalized by total counts.
Definition: histogram.h:689
Eigen::Index num_bins
Number of bins to split the range into.
Definition: histogram.h:95
STL class.
Histogram aggregator, if each individual histogram already has error bars.
Definition: histogram.h:1159
Histogram aggregator, if each histogram doesn&#39;t have error bars.
Definition: histogram.h:1012
HistogramType::Params HistogramParams
The parameters type used to describe our histogram range and number of bins.
Definition: histogram.h:1174
CountType_ CountType
The type that serves to count how many hits in each bin.
Definition: histogram.h:227
#define tomographer_assert(...)
Assertion test macro.
Definition: cxxdefs.h:84
Scalar binLowerValue(Eigen::Index index) const
Shorthand for Params::binLowerValue()
Definition: histogram.h:380
Scalar min
Lower range value.
Definition: histogram.h:91
void finalize()
Finalize the averaging procedure.
Definition: histogram.h:911
Derived & setZero(Index size)
FinalHistogramType final_histogram
The final histogram, properly combining the error bars of each histogram.
Definition: histogram.h:1213