Tomographer  v2.0
Tomographer C++ Framework Documentation
mhrw_valuehist_tasks.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  *
8  * Permission is hereby granted, free of charge, to any person obtaining a copy
9  * of this software and associated documentation files (the "Software"), to deal
10  * in the Software without restriction, including without limitation the rights
11  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12  * copies of the Software, and to permit persons to whom the Software is
13  * furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24  * SOFTWARE.
25  */
26 
27 #ifndef TOMOGRAPHER_MHRW_VALUEHIST_TASKS_H
28 #define TOMOGRAPHER_MHRW_VALUEHIST_TASKS_H
29 
31 #include <tomographer2/tools/cxxutil.h> // tomographer_assert()
34 #include <tomographer2/mhrwtasks.h>
35 
36 #include <boost/math/constants/constants.hpp>
37 
38 
47 namespace Tomographer {
48 namespace MHRWTasks {
49 namespace ValueHistogramTasks {
50 
51 
52 namespace tomo_internal {
53 template<typename CDataBaseType, bool UseBinningAnalysis>
54 struct histogram_types {// version WITHOUT binning analysis:
57  typedef HistogramType MHRWStatsCollectorResultType;
58  typedef typename HistogramType::Params HistogramParams;
59 };
60 template<typename CDataBaseType>
61 struct histogram_types<CDataBaseType, true> {// version WITH binning analysis:
64  typename CDataBaseType::ValueCalculator, typename CDataBaseType::CountIntType,
65  typename CDataBaseType::CountRealType, Eigen::Dynamic, Eigen::Dynamic
66  > BinningMHRWStatsCollectorParams;
67  //
68  typedef typename BinningMHRWStatsCollectorParams::Result MHRWStatsCollectorResultType;
69  typedef typename BinningMHRWStatsCollectorParams::HistogramType HistogramType;
70  typedef typename BinningMHRWStatsCollectorParams::HistogramParams HistogramParams;
71 };
72 } // namespace tomo_internal
73 
74 
75 
76 
77 // ------------------------------------------------
78 
79 
87 template<typename CDataBaseType_, typename LoggerType_>
89  : public virtual Tools::NeedOwnOperatorNew<
90  AveragedHistogram<UniformBinsHistogram<typename CDataBaseType_::HistogramType::Scalar,
91  typename CDataBaseType_::CountRealType>,
92  typename CDataBaseType_::CountRealType>
93  >::ProviderType
94 {
95  typedef CDataBaseType_ CDataBaseType;
96  typedef typename CDataBaseType::ValueCalculator ValueCalculator;
97  typedef typename CDataBaseType::CountRealType CountRealType;
98  typedef typename CDataBaseType::CountIntType CountIntType;
99  typedef typename CDataBaseType::StepRealType StepRealType;
100  typedef LoggerType_ LoggerType;
101 
102  typedef typename CDataBaseType::HistogramType HistogramType;
103  typedef typename CDataBaseType::HistogramParams HistogramParams;
106 
107  typedef HistogramType MHRWStatsCollectorResultType;
108 
109  TOMO_STATIC_ASSERT_EXPR( CDataBaseType::UseBinningAnalysis == false ) ;
110 
120  : public MHRandomWalkTaskResult<MHRWStatsCollectorResultType,CountIntType,StepRealType>,
121  public virtual Tools::NeedOwnOperatorNew<NormalizedHistogramType>::ProviderType
122  {
124 
125  RunTaskResult()
126  : Base(), histogram()
127  {
128  }
129 
130  template<typename BaseType, typename NormalizedHistogramTypeRef>
131  RunTaskResult(BaseType&& b, NormalizedHistogramTypeRef&& histogram_)
132  : Base(std::forward<BaseType>(b)), histogram(histogram_)
133  {
134  }
135 
136  const NormalizedHistogramType histogram;
137  };
138 
140 
141 
142  ResultsCollectorSimple(LoggerType & logger_)
143  : _finalized(false), _finalhistogram(HistogramParams()),
144  _collected_runtaskresults(),
145  _llogger("MHRWTasks::ValueHistogramTasks::ResultsCollectorSimple", logger_)
146  {
147  }
148 
150  {
151  for (std::size_t j = 0; j < _collected_runtaskresults.size(); ++j) {
152  if (_collected_runtaskresults[j] != NULL) {
153  delete _collected_runtaskresults[j];
154  }
155  }
156  }
157 
158  inline bool isFinalized() const { return _finalized; }
159 
160  inline FinalHistogramType finalHistogram() const {
161  tomographer_assert(isFinalized() && "You may only call finalHistogram() after the runs have been finalized.");
162  return _finalhistogram;
163  }
164 
165  inline std::size_t numTasks() const {
166  tomographer_assert(isFinalized() && "You may only call numTasks() after the runs have been finalized.");
167  return _collected_runtaskresults.size();
168  }
169 
170  inline const RunTaskResultList & collectedRunTaskResults() const {
171  tomographer_assert(isFinalized() && "You may only call collectedRunTaskResults() after the runs have been finalized.");
172  return _collected_runtaskresults;
173  }
174 
175  inline const RunTaskResult * collectedRunTaskResult(std::size_t task_no) const {
176  tomographer_assert(isFinalized() && "You may only call collectedRunTaskResult(std::size_t) after the runs have been finalized.");
177  tomographer_assert(task_no < _collected_runtaskresults.size());
178  return _collected_runtaskresults[task_no];
179  }
180 
181  template<typename RealType = double>
182  inline void printHistogramCsv(std::ostream & stream, std::string sep = "\t", std::string linesep = "\n", int precision = 10)
183  {
184  stream << "Value" << sep << "Counts" << sep << "Error" << linesep
185  << std::scientific << std::setprecision(precision);
186  for (int kk = 0; kk < _finalhistogram.bins.size(); ++kk) {
187  stream << RealType(_finalhistogram.params.binLowerValue(kk)) << sep
188  << RealType(_finalhistogram.bins(kk)) << sep
189  << RealType(_finalhistogram.delta(kk)) << linesep;
190  }
191  }
192 
193 private:
194  bool _finalized;
195  FinalHistogramType _finalhistogram;
196 
197  RunTaskResultList _collected_runtaskresults;
198 
200 
201 public:
202 
203  // these functions will be called by the task manager/dispatcher
204 
205  template<typename Cnt, typename CData>
206  inline void init(Cnt num_total_runs, Cnt /*n_chunk*/, const CData * pcdata)
207  {
208  tomographer_assert(!isFinalized() && "init() called after results have been finalized!");
209 
210  _collected_runtaskresults.resize(num_total_runs, NULL);
211  _finalhistogram.reset(pcdata->histogram_params);
212  }
213  template<typename Cnt, typename TaskResultType, typename CData>
214  inline void collectResult(Cnt task_no, TaskResultType&& taskresult, const CData * /*pcdata*/)
215  {
216  tomographer_assert(!isFinalized() && "collectResult() called after results have been finalized!");
217 
218  auto logger = _llogger.subLogger(TOMO_ORIGIN);
219  logger.debug([&](std::ostream & str) {
220  str << "Got task result. Histogram is:\n" << taskresult.stats_collector_result.prettyPrint();
221  });
222 
223  NormalizedHistogramType thishistogram = taskresult.stats_collector_result;
224  typename NormalizedHistogramType::CountType normalization =
225  thishistogram.bins.sum() + thishistogram.off_chart;
226  thishistogram.bins /= normalization;
227  thishistogram.off_chart /= normalization;
228 
229  _finalhistogram.addHistogram(thishistogram);
230  _collected_runtaskresults[task_no]
231  = new RunTaskResult(std::forward<TaskResultType>(taskresult), std::move(thishistogram));
232  }
233  template<typename Cnt, typename CData>
234  inline void runsFinished(Cnt, const CData *)
235  {
236  tomographer_assert(!isFinalized() && "runsFinished() called after results have been finalized!");
237 
238  _finalized = true;
239  _finalhistogram.finalize();
240  }
241 
242 }; // struct ResultsCollectorSimple
243 
244 
245 
246 
247 
255 template<typename CDataBaseType_, typename LoggerType_>
257  : public virtual Tools::NeedOwnOperatorNew<
258  UniformBinsHistogram<typename CDataBaseType_::HistogramType::Scalar,
259  typename CDataBaseType_::CountRealType>
260  >::ProviderType
261 {
262  typedef CDataBaseType_ CDataBaseType;
263  typedef typename CDataBaseType::ValueCalculator ValueCalculator;
264  typedef typename CDataBaseType::CountRealType CountRealType;
265  typedef typename CDataBaseType::CountIntType CountIntType;
266  typedef typename CDataBaseType::StepRealType StepRealType;
267  typedef LoggerType_ LoggerType;
268 
269  typedef typename tomo_internal::histogram_types<CDataBaseType_,true>::BinningMHRWStatsCollectorParams
270  BinningMHRWStatsCollectorParams;
271 
272  typedef typename BinningMHRWStatsCollectorParams::BinningAnalysisParamsType BinningAnalysisParamsType;
273 
274  typedef typename BinningMHRWStatsCollectorParams::Result MHRWStatsCollectorResultType;
275 
276  typedef typename CDataBaseType::HistogramType HistogramType;
277  typedef typename CDataBaseType::HistogramParams HistogramParams;
278 
281 
289 
290 
293 
294  TOMO_STATIC_ASSERT_EXPR( CDataBaseType::UseBinningAnalysis ) ;
295 
296 
297  ResultsCollectorWithBinningAnalysis(LoggerType & logger_)
298  : _finalized(false), _finalhistogram(), _simplefinalhistogram(),
299  _collected_runtaskresults(),
300  _llogger("MHRWTasks::ValueHistogramTasks::ResultsCollectorWithBinningAnalysis", logger_)
301  {
302  }
303 
305  {
306  for (std::size_t j = 0; j < _collected_runtaskresults.size(); ++j) {
307  if (_collected_runtaskresults[j] != NULL) {
308  delete _collected_runtaskresults[j];
309  }
310  }
311  }
312 
313  inline bool isFinalized() const { return _finalized; }
314 
315  inline FinalHistogramType finalHistogram() const {
316  tomographer_assert(isFinalized() && "You may only call finalHistogram() after the runs have been finalized.");
317  return _finalhistogram;
318  }
319 
320  inline SimpleFinalHistogramType simpleFinalHistogram() const {
321  tomographer_assert(isFinalized() && "You may only call simpleFinalHistogram() after the runs have been finalized.");
322  return _simplefinalhistogram;
323  }
324 
325  inline std::size_t numTasks() const {
326  tomographer_assert(isFinalized() && "You may only call numTasks() after the runs have been finalized.");
327  return _collected_runtaskresults.size();
328  }
329 
330  inline const RunTaskResultList & collectedRunTaskResults() const {
331  tomographer_assert(isFinalized() && "You may only call collectedRunTaskResults() after the runs have been finalized.");
332  return _collected_runtaskresults;
333  }
334 
335  inline const RunTaskResult * collectedRunTaskResult(std::size_t task_no) const {
336  tomographer_assert(isFinalized() && "You may only call collectedRunTaskResult(std::size_t) after the runs have been finalized.");
337  tomographer_assert(task_no < _collected_runtaskresults.size());
338  return _collected_runtaskresults[task_no];
339  }
340 
341 
342  template<typename RealType = double>
343  inline void printHistogramCsv(std::ostream & stream, std::string sep = "\t", std::string linesep = "\n", int precision = 10)
344  {
345  stream << "Value" << sep << "Counts" << sep << "Error" << sep << "SimpleError" << linesep
346  << std::scientific << std::setprecision(precision);
347  for (int kk = 0; kk < _finalhistogram.bins.size(); ++kk) {
348  stream << RealType(_finalhistogram.params.binLowerValue(kk)) << sep
349  << RealType(_finalhistogram.bins(kk)) << sep
350  << RealType(_finalhistogram.delta(kk)) << sep
351  << RealType(_simplefinalhistogram.delta(kk)) << linesep;
352  }
353  }
354 
355 private:
356  bool _finalized;
357  FinalHistogramType _finalhistogram;
358  SimpleFinalHistogramType _simplefinalhistogram;
359 
360  RunTaskResultList _collected_runtaskresults;
361 
363 
364 
365 public:
366 
367  template<typename Cnt, typename CData>
368  inline void init(Cnt num_total_runs, Cnt /*n_chunk*/, const CData * pcdata)
369  {
370  tomographer_assert(!isFinalized() && "init() called after results have been finalized!");
371 
372  _collected_runtaskresults.resize(num_total_runs, NULL);
373  _finalhistogram.reset(pcdata->histogram_params);
374  _simplefinalhistogram.reset(pcdata->histogram_params);
375  }
376 
377  template<typename Cnt, typename TaskResultType, typename CData>
378  inline void collectResult(Cnt task_no, TaskResultType && taskresult, const CData *)
379  {
380  tomographer_assert(!isFinalized() && "collectResult() called after results have been finalized!");
381 
382  auto logger = _llogger.subLogger(TOMO_ORIGIN);
383 
384  auto stats_coll_result = taskresult.stats_collector_result;
385 
386  logger.debug([&](std::ostream & str) {
387  str << "(). Got task result. Histogram (w/ error bars from binning analysis):\n"
388  << stats_coll_result.hist.prettyPrint();
389  });
390 
391  if ((stats_coll_result.converged_status !=
392  Eigen::ArrayXi::Constant(stats_coll_result.hist.numBins(), BinningAnalysisParamsType::CONVERGED)).any()) {
393  logger.debug([&,this](std::ostream & str) {
394  str << "Error bars have not converged! The error bars at different binning levels are:\n"
395  << stats_coll_result.error_levels << "\n"
396  << "\t-> convergence analysis: \n";
397  for (std::size_t k = 0; k < stats_coll_result.hist.numBins(); ++k) {
398  str << "\t val[" << std::setw(3) << k << "] = "
399  << std::setw(12) << stats_coll_result.hist.bins(k)
400  << " +- " << std::setw(12) << stats_coll_result.hist.delta(k);
401  if (stats_coll_result.converged_status(k) == BinningAnalysisParamsType::CONVERGED) {
402  str << " [CONVERGED]";
403  } else if (stats_coll_result.converged_status(k) == BinningAnalysisParamsType::NOT_CONVERGED) {
404  str << " [NOT CONVERGED]";
405  } else if (stats_coll_result.converged_status(k) == BinningAnalysisParamsType::UNKNOWN_CONVERGENCE) {
406  str << " [UNKNOWN]";
407  } else {
408  str << " [UNKNOWN CONVERGENCE STATUS: " << stats_coll_result.converged_status(k) << "]";
409  }
410  str << "\n";
411  }
412  });
413  }
414 
415  // because stats_coll_result is a histogram WITH error bars, add_histogram will do the
416  // right thing and take them into account.
417  _finalhistogram.addHistogram(stats_coll_result.hist);
418 
419  logger.debug("added histogram.");
420 
421  // this one is declared for histograms WITHOUT error bars (SimpleHistogramType is a
422  // UniformBinsHistogram), so it will just ignore the error bars.
423  logger.debug([&](std::ostream & str) {
424  str << "Simple histogram is:\n";
425  histogramPrettyPrint<SimpleNormalizedHistogramType>(str, stats_coll_result.hist);
426  });
427  _simplefinalhistogram.addHistogram(stats_coll_result.hist);
428 
429  _collected_runtaskresults[task_no] = new RunTaskResult(std::move(taskresult));
430 
431  logger.debug("done.");
432  }
433 
434  template<typename Cnt, typename CData>
435  inline void runsFinished(Cnt, const CData *)
436  {
437  tomographer_assert(!isFinalized() && "runs_finished() called after results have been finalized!");
438 
439  _finalized = true;
440  _finalhistogram.finalize();
441  _simplefinalhistogram.finalize();
442  }
443 
444 };
445 
446 
447 
448 
449 
450 
451 
452 // ------------------------------------------------
453 
454 
455 namespace tomo_internal {
456 template<typename CDataBaseType, typename LoggerType, bool UseBinningAnalysis>
457 struct ResultsCollectorTypeHelper {
459 };
460 template<typename CDataBaseType, typename LoggerType>
461 struct ResultsCollectorTypeHelper<CDataBaseType, LoggerType, true> {
463 };
464 } // namespace tomo_internal
465 
466 
467 
468 
474 template<typename ValueCalculator_, bool UseBinningAnalysis_ = true,
475  typename CountIntType_ = int, typename StepRealType_ = double,
476  typename CountRealType_ = double>
477 struct CDataBase
478  : public MHRWTasks::CDataBase<CountIntType_, StepRealType_>,
479  public virtual Tools::NeedOwnOperatorNew<ValueCalculator_>::ProviderType
480 {
482 
483  typedef typename Base::CountIntType CountIntType;
484  typedef typename Base::StepRealType StepRealType;
485 
486  typedef ValueCalculator_ ValueCalculator;
487  typedef CountRealType_ CountRealType;
488 
489  static constexpr bool UseBinningAnalysis = UseBinningAnalysis_;
490 
492  MHRWStatsCollectorResultType;
495 
497 
498 
499  TOMOGRAPHER_ENABLED_IF(!UseBinningAnalysis)
500  CDataBase(const ValueCalculator & valcalc_, HistogramParams histogram_params_,
501  MHRWParamsType p, int base_seed = 0)
502  : Base(std::move(p), base_seed), valcalc(valcalc_), histogram_params(histogram_params_),
503  binningNumLevels()
504  {
505  }
506 
507  TOMOGRAPHER_ENABLED_IF(UseBinningAnalysis)
508  CDataBase(const ValueCalculator & valcalc_, HistogramParams histogram_params_, int binning_num_levels_,
509  MHRWParamsType p, int base_seed = 0)
510  : Base(std::move(p), base_seed), valcalc(valcalc_), histogram_params(histogram_params_),
511  binningNumLevels(binning_num_levels_)
512  {
513  }
514 
515  const ValueCalculator valcalc;
516  const HistogramParams histogram_params;
517  const Tools::StoreIfEnabled<int, UseBinningAnalysis> binningNumLevels;
518 
519 
520  template<typename LoggerType, TOMOGRAPHER_ENABLED_IF_TMPL(!UseBinningAnalysis)>
522  createStatsCollector(LoggerType & logger) const
523  {
525  histogram_params,
526  valcalc,
527  logger
528  );
529  }
530 
531  template<typename LoggerType, TOMOGRAPHER_ENABLED_IF_TMPL(UseBinningAnalysis)>
533  typename tomo_internal::histogram_types<CDataBase, true>::BinningMHRWStatsCollectorParams,
534  LoggerType>
535  createStatsCollector(LoggerType & logger) const
536  {
537  typedef typename tomo_internal::histogram_types<CDataBase, true>::BinningMHRWStatsCollectorParams
538  BinningMHRWStatsCollectorParams;
539 
541  histogram_params,
542  valcalc,
543  binningNumLevels.value,
544  logger
545  );
546  }
547 
549  template<typename LoggerType>
551  typedef
552 #ifndef TOMOGRAPHER_PARSED_BY_DOXYGEN
553  typename
554  tomo_internal::ResultsCollectorTypeHelper<CDataBase<ValueCalculator,UseBinningAnalysis,CountIntType,StepRealType,CountRealType>,
555  LoggerType, UseBinningAnalysis>::type
556 #else
557  [...] // parsed by doxygen -- make this more readable
558 #endif
559  Type;
560 
561  typedef typename Type::RunTaskResult RunTaskResultType;
562  };
563 };
564 // define static members:
565 template<typename ValueCalculator_, bool UseBinningAnalysis_,
566  typename CountIntType_, typename StepRealType_,
567  typename CountRealType_>
569 
570 
571 
572 
573 
574 
575 
576 
577 
578 } // namespace ValueHistogramTasks
579 } // namespace MHRWTasks
580 } // namespace Tomographer
581 
582 
583 #endif
A StatsCollector which builds a histogram of values calculated with a ValueCalculator for each data s...
#define TOMO_STATIC_ASSERT_EXPR(...)
Tool for static assertions without message.
Definition: cxxutil.h:59
CountIntType_ CountIntType
Type used to count the number of iterations.
Definition: mhrwtasks.h:78
Eigen::Array< CountType, Eigen::Dynamic, 1 > bins
The counts for each bin.
Definition: histogram.h:194
Base namespace for the Tomographer project.
Definition: densellh.h:44
Provide appropriate operator new() definitions for a structure which has a member of the given stored...
UniformBinsHistogram< typename HistogramType::Scalar, CountRealType > SimpleNormalizedHistogramType
The "simple" histogram, as if without binning analysis.
CountType_ CountType
The type that serves to count how many hits in each bin.
Definition: histogram.h:78
StepRealType_ StepRealType
Type used to specify the step size.
Definition: mhrwtasks.h:80
Multiprocessing tasks interface (see Task Manager/Dispatcher Interfaces) for parallel Metropolis-Hast...
void finalize()
Finalize the averaging procedure.
Definition: histogram.h:636
#define TOMO_ORIGIN
Use this as argument for a Tomographer::Logger::LocalLogger constructor .
Definition: loggers.h:1658
T setw(T...args)
T resize(T...args)
STL class.
LocalLogger< LocalLogger< BaseLoggerType > > subLogger(const std::string &new_prefix)
Create a sub-logger.
Definition: loggers.h:1881
Data needed to be accessible to the working code.
Definition: mhrwtasks.h:63
The parameters of a UniformBinsHistogram.
Definition: histogram.h:87
Traits-like class for ValueHistogramWithBinningMHRWStatsCollector.
constant data for our MH random walk tasks with value histogram stats collector
Collect a histogram of values from a MH random walk, with binning analysis.
AveragedHistogram< HistogramType, CountRealType > FinalHistogramType
The final histogram, properly averaged.
Some C++ utilities, with a tad of C++11 tricks.
T move(T...args)
T scientific(T...args)
Managing the need for specific overrides to operator new() for some types (especially Eigen types) ...
CountType off_chart
The number of points that fell outside of the given range.
Definition: histogram.h:196
void addHistogram(const HistogramType &histogram)
Add a new histogram in the data series.
Definition: histogram.h:604
void reset(const Params &params_)
Resets the data and sets new params.
Definition: histogram.h:566
Results collector, if no binning analysis is being used.
Stores a histogram.
Definition: histogram.h:68
Definitions for MHRWStatsCollector Interface&#39;s.
T setprecision(T...args)
STL class.
Utilities for logging messages.