Logo ROOT   6.07/09
Reference Guide
THist.hxx
Go to the documentation of this file.
1 /// \file ROOT/THist.h
2 /// \ingroup Hist ROOT7
3 /// \author Axel Naumann <axel@cern.ch>
4 /// \date 2015-03-23
5 /// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback is welcome!
6 
7 /*************************************************************************
8  * Copyright (C) 1995-2015, Rene Brun and Fons Rademakers. *
9  * All rights reserved. *
10  * *
11  * For the licensing terms see $ROOTSYS/LICENSE. *
12  * For the list of contributors see $ROOTSYS/README/CREDITS. *
13  *************************************************************************/
14 
15 #ifndef ROOT7_THist
16 #define ROOT7_THist
17 
18 #include "ROOT/RArrayView.hxx"
19 #include "ROOT/TAxis.hxx"
20 #include "ROOT/TDrawable.hxx"
21 #include "ROOT/THistBinIter.hxx"
22 #include "ROOT/THistDrawable.hxx"
23 #include "ROOT/THistImpl.hxx"
24 #include "ROOT/THistData.hxx"
25 #include <initializer_list>
26 
27 namespace ROOT {
28 namespace Experimental {
29 
30 // fwd declare for fwd declare for friend declaration in THist...
31 template<int DIMENSIONS, class PRECISION,
32  template <int D_, class P_, template <class P__> class S_> class... STAT>
33 class THist;
34 
35 // fwd declare for friend declaration in THist.
36 template<int DIMENSIONS, class PRECISION,
37  template <int D_, class P_, template <class P__> class S_> class... STAT>
38 class THist<DIMENSIONS, PRECISION, STAT...>
39  HistFromImpl(std::unique_ptr<typename THist<DIMENSIONS, PRECISION, STAT...>::ImplBase_t> pHistImpl);
40 
41 /**
42  \class THist
43  Histogram class for histograms with `DIMENSIONS` dimensions, where each
44  bin count is stored by a value of type `PRECISION`. STAT stores statistical
45  data of the entries filled into the histogram (bin content, uncertainties etc).
46 
47  A histogram counts occurrences of values or n-dimensional combinations thereof.
48  Contrary to for instance a `TTree`, a histogram combines adjacent values. The
49  resolution of this combination is defined by the axis binning, see e.g.
50  http://www.wikiwand.com/en/Histogram
51  */
52 
53 template<int DIMENSIONS, class PRECISION,
54  template <int D_, class P_, template <class P__> class S_> class... STAT>
55 class THist {
56 public:
57  /// The type of the `Detail::THistImplBase` of this histogram.
58  using ImplBase_t
61  /// The coordinates type: a `DIMENSIONS`-dimensional `std::array` of `double`.
63  /// The type of weights
65  /// Pointer type to `HistImpl_t::Fill`, for faster access.
67  /// Range.
69 
71 
72  /// Number of dimensions of the coordinates
73  static constexpr int GetNDim() noexcept { return DIMENSIONS; }
74 
75  THist() = default;
76  THist(THist&&) = default;
77 
78  /// Create a histogram from an `array` of axes (`TAxisConfig`s). Example code:
79  ///
80  /// Construct a 1-dimensional histogram that can be filled with `floats`s.
81  /// The axis has 10 bins between 0. and 1. The two outermost sets of curly
82  /// braces are to reach the initialization of the `std::array` elements; the
83  /// inner one is for the initialization of a `TAxisCoordinate`.
84  ///
85  /// THist<1,float> h1f({{ {10, 0., 1.} }});
86  ///
87  /// Construct a 2-dimensional histogram, with the first axis as before, and
88  /// the second axis having non-uniform ("irregular") binning, where all bin-
89  /// edges are specified. As this is itself an array it must be enclosed by
90  /// double curlies.
91  ///
92  /// THist<2,int> h2i({{ {10, 0., 1.}, {{-1., 0., 1., 10., 100.}} }});
93  explicit THist(std::array<TAxisConfig, DIMENSIONS> axes);
94 
95  /// Constructor overload taking the histogram title
96  THist(std::string_view histTitle, std::array<TAxisConfig, DIMENSIONS> axes);
97 
98  /// Constructor overload that's only available for a 1-dimensional histogram.
99  template <int ENABLEIF_NDIM = DIMENSIONS,
101  explicit THist(const TAxisConfig &xaxis):
102  THist(std::array<TAxisConfig, 1>{{xaxis}})
103  { }
104 
105  /// Constructor overload that's only available for a 1-dimensional histogram,
106  /// also passing the histogram title.
107  template <int ENABLEIF_NDIM = DIMENSIONS,
109  THist(std::string_view histTitle, const TAxisConfig &xaxis):
110  THist(histTitle, std::array<TAxisConfig, 1>{{xaxis}})
111  { }
112 
113  /// Constructor overload that's only available for a 2-dimensional histogram.
114  template<int ENABLEIF_NDIM = DIMENSIONS,
116  THist(const TAxisConfig &xaxis, const TAxisConfig &yaxis):
117  THist(std::array<TAxisConfig, 2>{{xaxis, yaxis}})
118  { }
119 
120  /// Constructor overload that's only available for a 2-dimensional histogram,
121  /// also passing the histogram title.
122  template<int ENABLEIF_NDIM = DIMENSIONS,
124  THist(std::string_view histTitle, const TAxisConfig &xaxis, const TAxisConfig &yaxis):
125  THist(histTitle, std::array<TAxisConfig, 2>{{xaxis, yaxis}})
126  { }
127 
128  /// Constructor overload that's only available for a 3-dimensional histogram.
129  template<int ENABLEIF_NDIM = DIMENSIONS,
131  THist(const TAxisConfig &xaxis, const TAxisConfig &yaxis, const TAxisConfig &zaxis):
132  THist(std::array<TAxisConfig, 3>{{xaxis, yaxis, zaxis}})
133  { }
134 
135  /// Constructor overload that's only available for a 3-dimensional histogram,
136  /// also passing the histogram title.
137  template<int ENABLEIF_NDIM = DIMENSIONS,
140  const TAxisConfig &xaxis, const TAxisConfig &yaxis, const TAxisConfig &zaxis):
141  THist(histTitle, std::array<TAxisConfig, 3>{{xaxis, yaxis, zaxis}})
142  { }
143 
144 
145  /// Access the ImplBase_t this THist points to.
146  ImplBase_t *GetImpl() const noexcept { return fImpl.get(); }
147 
148  /// "Steal" the ImplBase_t this THist points to.
149  std::unique_ptr<ImplBase_t>&& TakeImpl() noexcept { return std::move(fImpl); }
150 
151  /// Add `weight` to the bin containing coordinate `x`.
152  void Fill(const CoordArray_t &x, Weight_t weight = (Weight_t) 1) noexcept { (fImpl.get()->*fFillFunc)(x, weight); }
153 
154  /// For each coordinate in `xN`, add `weightN[i]` to the bin at coordinate
155  /// `xN[i]`. The sizes of `xN` and `weightN` must be the same. This is more
156  /// efficient than many separate calls to `Fill()`.
157  void FillN(const std::array_view <CoordArray_t> xN,
158  const std::array_view <Weight_t> weightN) noexcept { fImpl->FillN(xN, weightN); }
159 
160  /// Convenience overload: `FillN()` with weight 1.
161  void FillN(const std::array_view <CoordArray_t> xN) noexcept { fImpl->FillN(xN); }
162 
163  /// Get the number of entries this histogram was filled with.
164  int64_t GetEntries() const noexcept { return fImpl->GetStat().GetEntries(); }
165 
166  /// Get the content of the bin at `x`.
167  Weight_t GetBinContent(const CoordArray_t &x) const { return fImpl->GetBinContent(x); }
168 
169  /// Get the uncertainty on the content of the bin at `x`.
170  double GetBinUncertainty(const CoordArray_t &x) const { return fImpl->GetBinUncertainty(x); }
171 
172  const_iterator begin() const { return const_iterator(*fImpl); }
173 
174  const_iterator end() const { return const_iterator(*fImpl, fImpl->GetNBins()); }
175 
176  /// Swap *this and other.
177  ///
178  /// Very efficient; swaps the `fImpl` pointers.
180  std::swap(fImpl, other.fImpl);
181  std::swap(fFillFunc, other.fFillFunc);
182  }
183 
184 private:
185  std::unique_ptr<ImplBase_t> fImpl; ///< The actual histogram implementation
186  FillFunc_t fFillFunc = nullptr; ///<! Pinter to THistImpl::Fill() member function
187 
188  friend THist HistFromImpl<>(std::unique_ptr<ImplBase_t>);
189 };
190 
191 /// Swap two histograms.
192 ///
193 /// Very efficient; swaps the `fImpl` pointers.
194 template<int DIMENSIONS, class PRECISION,
195  template <int D_, class P_, template <class P__> class S_> class... STAT>
198 {
199  a.swap(b);
200 };
201 
202 
203 namespace Internal {
204 /**
205  Generate THist::fImpl from THist constructor arguments.
206  */
207 template<int NDIM, int IDIM, class DATA, class... PROCESSEDAXISCONFIG>
208 struct THistImplGen {
209  /// Select the template argument for the next axis type, and "recurse" into
210  /// THistImplGen for the next axis.
211  template<TAxisConfig::EKind KIND>
212  std::unique_ptr<Detail::THistImplBase<DATA>>
213  MakeNextAxis(std::string_view title, const std::array<TAxisConfig, NDIM> &axes,
214  PROCESSEDAXISCONFIG... processedAxisArgs)
215  {
216  using NextAxis_t = typename AxisConfigToType<KIND>::Axis_t;
217  NextAxis_t nextAxis = AxisConfigToType<KIND>()(axes[IDIM]);
218  using HistImpl_t = THistImplGen<NDIM, IDIM + 1, DATA, PROCESSEDAXISCONFIG..., NextAxis_t>;
219  return HistImpl_t()(title, axes, processedAxisArgs..., nextAxis);
220  }
221 
222  /// Make a THistImpl-derived object reflecting the TAxisConfig array.
223  ///
224  /// Delegate to the appropriate MakeNextAxis instantiation, depending on the
225  /// axis type selected in the TAxisConfig.
226  /// \param axes - `TAxisConfig` objects describing the axis of the resulting
227  /// THistImpl.
228  /// \param statConfig - the statConfig parameter to be passed to the THistImpl
229  /// \param processedAxisArgs - the TAxisBase-derived axis objects describing the
230  /// axes of the resulting THistImpl. There are `IDIM` of those; in the end
231  /// (`IDIM` == `GetNDim()`), all `axes` have been converted to
232  /// `processedAxisArgs` and the THistImpl constructor can be invoked, passing
233  /// the `processedAxisArgs`.
234  std::unique_ptr<Detail::THistImplBase<DATA>>
235  operator()(std::string_view title, const std::array <TAxisConfig, NDIM> &axes,
236  PROCESSEDAXISCONFIG... processedAxisArgs)
237  {
238  switch (axes[IDIM].GetKind()) {
240  return MakeNextAxis<TAxisConfig::kEquidistant>(title, axes, processedAxisArgs...);
241  case TAxisConfig::kGrow:
242  return MakeNextAxis<TAxisConfig::kGrow>(title, axes, processedAxisArgs...);
244  return MakeNextAxis<TAxisConfig::kIrregular>(title, axes, processedAxisArgs...);
245  default:
246  R__ERROR_HERE("HIST") << "Unhandled axis kind";
247  }
248  return nullptr;
249  }
250 };
251 
252 /// Generate THist::fImpl from constructor arguments; recursion end.
253 template<int NDIM, class DATA, class... PROCESSEDAXISCONFIG>
254 /// Create the histogram, now that all axis types and initializer objects are
255 /// determined.
256 struct THistImplGen<NDIM, NDIM, DATA, PROCESSEDAXISCONFIG...> {
258  std::unique_ptr<HistImplBase_t>
259  operator()(std::string_view title, const std::array<TAxisConfig, DATA::GetNDim()> &, PROCESSEDAXISCONFIG... axisArgs)
260  {
261  using HistImplt_t = Detail::THistImpl<DATA, PROCESSEDAXISCONFIG...>;
262  return std::make_unique<HistImplt_t>(title, axisArgs...);
263  }
264 };
265 } // namespace Internal
266 
267 
268 template<int DIMENSIONS, class PRECISION,
269  template <int D_, class P_, template <class P__> class S_> class... STAT>
270 THist<DIMENSIONS, PRECISION, STAT...>::THist(std::string_view title, std::array<TAxisConfig, DIMENSIONS> axes):
273 {
274  fFillFunc = fImpl->GetFillFunc();
275 }
276 
277 
278 template<int DIMENSIONS, class PRECISION,
279  template <int D_, class P_, template <class P__> class S_> class... STAT>
280 THist<DIMENSIONS, PRECISION, STAT...>::THist(std::array<TAxisConfig, DIMENSIONS> axes):
281  THist("", axes) {}
282 
283 
284 /// Adopt an external, stand-alone THistImpl. The THist will take ownership.
285 template<int DIMENSIONS, class PRECISION,
286  template <int D_, class P_, template <class P__> class S_> class... STAT>
287 THist<DIMENSIONS, PRECISION, STAT...>
289 {
290  THist<DIMENSIONS, PRECISION, STAT...> ret;
291  ret.fFillFunc = pHistImpl->GetFillFunc();
292  std::swap(ret.fImpl, pHistImpl);
293  return ret;
294 };
295 
296 
297 /// \name THist Typedefs
298 ///\{ Convenience typedefs (ROOT6-compatible type names)
299 
300 // Keep them as typedefs, to make sure old-style documentation tools can understand them.
306 
312 
318 ///\}
319 
320 
321 /// Add two histograms. This is the generic, inefficient version for now; it
322 /// assumes no matching axes.
323 template<int DIMENSIONS,
324  class PRECISION_TO, class PRECISION_FROM,
325  template <int D_, class P_, template <class P__> class S_> class... STAT_TO,
326  template <int D_, class P_, template <class P__> class S_> class... STAT_FROM>
329 {
330  auto toImpl = to.GetImpl();
331  auto fillFuncTo = toImpl->GetFillFunc();
332  using HistFrom_t = THist<DIMENSIONS, PRECISION_FROM, STAT_FROM...>;
333  using FromCoord_t = typename HistFrom_t::CoordArray_t;
334  using FromWeight_t = typename HistFrom_t::Weight_t;
335  auto add = [fillFuncTo, toImpl](const FromCoord_t& x, FromWeight_t c)
336  {
337  (toImpl->*fillFuncTo)(x, c);
338  // TODO: something nice with the uncertainty - depending on whether `to` cares
339  };
340  from.GetImpl()->ApplyXC(add);
341 }
342 
343 
344 /// Interface to graphics taking a unique_ptr<THist>.
345 template<int DIMENSIONS, class PRECISION,
346  template <int D_, class P_, template <class P__> class S_> class... STAT>
347 std::unique_ptr <Internal::TDrawable>
350 {
351  return std::make_unique<Internal::THistDrawable<DIMENSIONS>>(hist, opts);
352 }
353 
354 /// Interface to graphics taking a shared_ptr<THist>.
355 template<int DIMENSIONS, class PRECISION,
356  template <int D_, class P_, template <class P__> class S_> class... STAT>
357 std::unique_ptr <Internal::TDrawable>
360 {
361  return std::make_unique<Internal::THistDrawable<DIMENSIONS>>(std::move(hist), opts);
362 }
363 
364 } // namespace Experimental
365 } // namespace ROOT
366 
367 #endif
int64_t GetEntries() const noexcept
Get the number of entries this histogram was filled with.
Definition: THist.hxx:164
std::vector< PRECISION > THistDataDefaultStorage
std::vector has more template arguments; for the default storage we don&#39;t care about them...
Definition: THistData.hxx:374
std::array< double, DIMENSIONS > CoordArray_t
Definition: THistUtils.hxx:22
ImplBase_t * GetImpl() const noexcept
Access the ImplBase_t this THist points to.
Definition: THist.hxx:146
static constexpr int GetNDim() noexcept
Number of dimensions of the coordinates.
Definition: THist.hxx:73
std::unique_ptr< ImplBase_t > fImpl
The actual histogram implementation.
Definition: THist.hxx:185
This namespace contains pre-defined functions to be used in conjuction with TExecutor::Map and TExecu...
Definition: StringConv.hxx:21
double GetBinUncertainty(const CoordArray_t &x) const
Get the uncertainty on the content of the bin at x.
Definition: THist.hxx:170
return c
Interface class for THistImpl.
Definition: THistImpl.hxx:140
typename ImplBase_t::FillFunc_t FillFunc_t
Pointer type to HistImpl_t::Fill, for faster access.
Definition: THist.hxx:66
Generate THist::fImpl from THist constructor arguments.
Definition: THist.hxx:208
virtual void ApplyXC(std::function< void(const CoordArray_t &, Weight_t)>) const =0
Apply a function (lambda) to all bins of the histogram.
Iterates over the bins of a THist or THistImpl.
virtual FillFunc_t GetFillFunc() const =0
Retrieve the pointer to the overridden Fill(x, w) function.
std::unique_ptr< ImplBase_t > && TakeImpl() noexcept
"Steal" the ImplBase_t this THist points to.
Definition: THist.hxx:149
TArc * a
Definition: textangle.C:12
void swap(THist< DIMENSIONS, PRECISION, STAT... > &other) noexcept
Swap *this and other.
Definition: THist.hxx:179
STL namespace.
THist(const TAxisConfig &xaxis)
Constructor overload that&#39;s only available for a 1-dimensional histogram.
Definition: THist.hxx:101
Detail::THistBinIter< ImplBase_t > const_iterator
Definition: THist.hxx:70
friend THist HistFromImpl(std::unique_ptr< ImplBase_t >)
Double_t x[n]
Definition: legend1.C:17
#define PRECISION
Definition: MnPrint.cxx:26
THist(std::string_view histTitle, const TAxisConfig &xaxis, const TAxisConfig &yaxis, const TAxisConfig &zaxis)
Constructor overload that&#39;s only available for a 3-dimensional histogram, also passing the histogram ...
Definition: THist.hxx:139
represents a TAxisEquidistant
Definition: TAxis.hxx:709
THist(std::string_view histTitle, const TAxisConfig &xaxis, const TAxisConfig &yaxis)
Constructor overload that&#39;s only available for a 2-dimensional histogram, also passing the histogram ...
Definition: THist.hxx:124
void Add(THist< DIMENSIONS, PRECISION_TO, STAT_TO... > &to, THist< DIMENSIONS, PRECISION_FROM, STAT_FROM... > &from)
Add two histograms.
Definition: THist.hxx:327
represents a TAxisGrow
Definition: TAxis.hxx:710
PRECISION Weight_t
The type of weights.
Definition: THist.hxx:64
THist(const TAxisConfig &xaxis, const TAxisConfig &yaxis)
Constructor overload that&#39;s only available for a 2-dimensional histogram.
Definition: THist.hxx:116
std::unique_ptr< Detail::THistImplBase< DATA > > operator()(std::string_view title, const std::array< TAxisConfig, NDIM > &axes, PROCESSEDAXISCONFIG...processedAxisArgs)
Make a THistImpl-derived object reflecting the TAxisConfig array.
Definition: THist.hxx:235
Objects used to configure the different axis types.
Definition: TAxis.hxx:706
THist(const TAxisConfig &xaxis, const TAxisConfig &yaxis, const TAxisConfig &zaxis)
Constructor overload that&#39;s only available for a 3-dimensional histogram.
Definition: THist.hxx:131
void FillN(const std::array_view< CoordArray_t > xN) noexcept
Convenience overload: FillN() with weight 1.
Definition: THist.hxx:161
A THistImplBase&#39;s data, provides accessors to all its statistics.
Definition: THistData.hxx:425
const_iterator end() const
Definition: THist.hxx:174
THist(std::string_view histTitle, const TAxisConfig &xaxis)
Constructor overload that&#39;s only available for a 1-dimensional histogram, also passing the histogram ...
Definition: THist.hxx:109
represents a TAxisIrregular
Definition: TAxis.hxx:711
void FillN(const std::array_view< CoordArray_t > xN, const std::array_view< Weight_t > weightN) noexcept
For each coordinate in xN, add weightN[i] to the bin at coordinate xN[i].
Definition: THist.hxx:157
Hist::CoordArray_t< DATA::GetNDim()> CoordArray_t
Type of the coordinate: a DIMENSIONS-dimensional array of doubles.
Definition: THistImpl.hxx:145
Histogram class for histograms with DIMENSIONS dimensions, where each bin count is stored by a value ...
Definition: THist.hxx:33
void swap(THist< DIMENSIONS, PRECISION, STAT... > &a, THist< DIMENSIONS, PRECISION, STAT... > &b) noexcept
Swap two histograms.
Definition: THist.hxx:196
void(THistImplBase::*)(const CoordArray_t &x, Weight_t w) FillFunc_t
Type of the Fill(x, w) function.
Definition: THistImpl.hxx:150
int type
Definition: TGX11.cxx:120
const_iterator begin() const
Definition: THist.hxx:172
Hist::AxisIterRange_t< DIMENSIONS > AxisIterRange_t
Range type.
Definition: THistImpl.hxx:72
FillFunc_t fFillFunc
! Pinter to THistImpl::Fill() member function
Definition: THist.hxx:186
Converts a TAxisConfig of whatever kind to the corresponding TAxisBase-derived object.
Definition: TAxis.hxx:848
typename ImplBase_t::CoordArray_t CoordArray_t
The coordinates type: a DIMENSIONS-dimensional std::array of double.
Definition: THist.hxx:62
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
Definition: TRolke.cxx:630
class THist< DIMENSIONS, PRECISION, STAT... > HistFromImpl(std::unique_ptr< typename THist< DIMENSIONS, PRECISION, STAT... >::ImplBase_t > pHistImpl)
Adopt an external, stand-alone THistImpl. The THist will take ownership.
Definition: THist.hxx:288
void Fill(const CoordArray_t &x, Weight_t weight=(Weight_t) 1) noexcept
Add weight to the bin containing coordinate x.
Definition: THist.hxx:152
Weight_t GetBinContent(const CoordArray_t &x) const
Get the content of the bin at x.
Definition: THist.hxx:167
std::unique_ptr< Internal::TDrawable > GetDrawable(const std::shared_ptr< THist< DIMENSIONS, PRECISION, STAT... >> &hist, THistDrawOptions< DIMENSIONS > opts={})
Interface to graphics taking a unique_ptr<THist>.
Definition: THist.hxx:348
typename ImplBase_t::AxisIterRange_t AxisRange_t
Range.
Definition: THist.hxx:68
std::unique_ptr< HistImplBase_t > operator()(std::string_view title, const std::array< TAxisConfig, DATA::GetNDim()> &, PROCESSEDAXISCONFIG...axisArgs)
Definition: THist.hxx:259
#define R__ERROR_HERE(GROUP)
Definition: TLogger.hxx:122
std::unique_ptr< Detail::THistImplBase< DATA > > MakeNextAxis(std::string_view title, const std::array< TAxisConfig, NDIM > &axes, PROCESSEDAXISCONFIG...processedAxisArgs)
Select the template argument for the next axis type, and "recurse" into THistImplGen for the next axi...
Definition: THist.hxx:213