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