Tomographer  v5.2
Tomographer C++ Framework Documentation
pyhistogram.h
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 PY_HISTOGRAM_H
29 #define PY_HISTOGRAM_H
30 
31 
32 #include <tomographerpy/common.h>
33 
34 #include <tomographer/histogram.h>
36 
37 
38 // namespace Tomographer { namespace Tools {
39 // template<>
40 // inline bool isFinite<py::float_>(py::object o)
41 // {
42 // auto numpy = py::module::import("numpy");
43 // return numpy.attr("isfinite")(o).cast<bool>();
44 // }
45 // } } // Tomographer::Tools
46 
47 
48 namespace tpy {
49 
52 
53 
54 
56 class Histogram
57 {
58 public:
59  Histogram(HistogramParams params_)
60  : params(params_),
61  bins(py::cast(Eigen::VectorXd::Zero(params_.num_bins))),
62  off_chart(py::cast(0.0))
63  {
64  }
65 
66  Histogram(tpy::RealType min, tpy::RealType max, Eigen::Index num_bins)
67  : params(min, max, num_bins),
68  bins(py::cast(Eigen::VectorXd::Zero(num_bins))),
69  off_chart(py::cast(0.0))
70  {
71  }
72 
73  template<typename Scalar, typename CountType>
75  : params(h.params),
76  bins(py::cast(h.bins)),
77  off_chart(py::cast(h.off_chart))
78  {
79  }
80 
81  // ### Apparently doesn't work, need to be more brutal:
82  // template<typename Scalar, typename CountType>
83  // inline operator Tomographer::Histogram<Scalar,CountType> ()
84  template<typename X>
85  inline operator X () const
86  {
87  typedef typename X::Scalar Scalar;
88  typedef typename X::CountType CountType;
89  return toCxxHistogram<Scalar,CountType>();
90  }
91 
92  template<typename Scalar, typename CountType>
93  inline Tomographer::Histogram<Scalar,CountType> toCxxHistogram() const
94  {
97  h.off_chart = off_chart.cast<CountType>();
98  return h;
99  }
100 
101  inline void set_bins(py::object newbins)
102  {
103  if (py::len(newbins.attr("shape")) != 1) {
104  throw py::type_error("Expected 1-D NumPy array for assignment to Histogram.bins");
105  }
106  if ((Eigen::Index)py::len(newbins) != params.num_bins) {
107  throw py::type_error(streamstr("Expected "<<params.num_bins<<" elements for assignment to Histogram.bins,"
108  " got "<<py::len(newbins)));
109  }
110  bins = newbins;
111  }
112  inline void set_off_chart(py::object o)
113  {
114  auto np = py::module::import("numpy");
115  if ( ! np.attr("isscalar")(o).cast<bool>() ) {
116  throw py::type_error("Expected scalar for assignment to Histogram.off_chart");
117  }
118  off_chart = o;
119  }
120 
121  inline void load(py::object x, py::object o)
122  {
123  set_bins(x);
124  set_off_chart(o);
125  }
126 
127  inline py::object normalization() const {
128  auto np = py::module::import("numpy");
129  // off_chart + binResolution() * sum(bins)
130  return np.attr("add")(off_chart, np.attr("multiply")(py::cast(params.binResolution()), bins.attr("sum")()));
131  }
132 
133  inline py::object totalCounts() const {
134  auto np = py::module::import("numpy");
135  // off_chart + sum(bins)
136  return np.attr("add")(off_chart, bins.attr("sum")());
137  }
138 
139  HistogramParams params;
140  py::object bins;
141  py::object off_chart;
142 
143  enum { HasErrorBars = 0 };
144 };
145 
146 
149 {
150 public:
151  HistogramWithErrorBars(HistogramParams params_)
152  : Histogram(params_),
153  delta(py::cast(Eigen::VectorXd::Zero(params_.num_bins)))
154  {
155  }
156 
157  HistogramWithErrorBars(tpy::RealType min, tpy::RealType max, Eigen::Index num_bins)
158  : Histogram(min, max, num_bins),
159  delta(py::cast(Eigen::VectorXd::Zero(num_bins)))
160  {
161  }
162 
163  template<typename Scalar, typename CountType>
165  : Histogram(h),
166  delta(py::cast(h.delta))
167  {
168  }
169 
170  // ### Apparently doesn't work, need to be more brutal:
171  // template<typename Scalar, typename CountType>
172  // inline operator Tomographer::HistogramWithErrorBars<Scalar,CountType> ()
173  template<typename X>
174  inline operator X () const
175  {
176  typedef typename X::Scalar Scalar;
177  typedef typename X::CountType CountType;
178  return toCxxHistogram<Scalar,CountType>();
179  }
180 
181  template<typename Scalar, typename CountType>
182  inline Tomographer::HistogramWithErrorBars<Scalar,CountType> toCxxHistogram() const
183  {
187  h.off_chart = off_chart.cast<CountType>();
188  return h;
189  }
190 
191  inline void set_delta(py::object newdelta)
192  {
193  if (py::len(newdelta.attr("shape")) != 1) {
194  throw py::type_error("Expected 1-D NumPy array for assignment to HistogramWithErrorBars.delta");
195  }
196  if ((Eigen::Index)py::len(newdelta) != params.num_bins) {
197  throw py::type_error(streamstr("Expected "<<params.num_bins<<" elements for assignment to HistogramWithErrorBars.delta,"
198  " got "<<py::len(newdelta)));
199  }
200  delta = newdelta;
201  }
202 
203  inline void load(py::object x, py::object err, py::object o)
204  {
205  set_bins(x);
206  set_delta(err);
207  set_off_chart(o);
208  }
209 
210  py::object delta;
211 
212  enum { HasErrorBars = 1 };
213 };
214 
215 
216 
217 
218 } // namespace Py
219 
220 
221 #endif
Eigen::Array< CountType, Eigen::Dynamic, 1 > delta
The error bars associated with each histogram bin.
Definition: histogram.h:558
Tomographer::HistogramParams< RealType > HistogramParams
Histogram Params. See Tomographer::HistogramParams.
Definition: pyhistogram.h:51
Scalar binResolution() const
Returns the width of a bin.
Definition: histogram.h:174
Stores a histogram along with error bars.
Definition: histogram.h:537
Params params
Parameters of this histogram (range and # of bins)
Definition: histogram.h:236
double RealType
Real type for template arguments (double)
Definition: common.h:90
Histogram class like Tomographer::Histogram, but with NumPy arrays storage.
Definition: pyhistogram.h:56
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
Stores a histogram.
Definition: histogram.h:213
Some C++ utilities, with a tad of C++11 tricks.
Definitions for Histogram Types.
#define streamstr(tokens)
Utility macro to format stream tokens to a std::string.
Definition: fmt.h:149
C++ Classes and Utilities for Python Modules.
Definition: common.h:87
A Histogram with real counts and error bars. See Tomographer::HistogramWithErrorBars.
Definition: pyhistogram.h:148
Eigen::Index num_bins
Number of bins to split the range into.
Definition: histogram.h:95
internal::cast_return_type< Array< _Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols >, const CwiseUnaryOp< internal::scalar_cast_op< typename internal::traits< Array< _Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols > >::Scalar, NewType >, const Array< _Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols > > >::type cast() const