15 #ifndef ROOT7_THistImpl
16 #define ROOT7_THistImpl
20 #include "ROOT/RArrayView.hxx"
30 namespace Experimental {
33 template <
int D_,
class P_,
template <
class P__>
class STORAGE>
class... STAT>
39 template<
int NDIM>
using AxisIter_t = std::array<TAxisBase::const_iterator, NDIM>;
52 return static_cast<int>(
a) & static_cast<int>(b);
67 template <
int DIMENSIONS>
68 class THistImplPrecisionAgnosticBase {
82 static constexpr
int GetNDim() {
return DIMENSIONS; }
85 virtual int GetNBins() const noexcept = 0;
125 GetRange(
const std::array<Hist::EOverflow, DIMENSIONS>& withOverUnder)
const = 0;
168 virtual void FillN(
const std::array_view<CoordArray_t> xN,
169 const std::array_view<Weight_t> weightN) = 0;
172 virtual void FillN(
const std::array_view<CoordArray_t> xN) = 0;
238 return std::get<0>(axes).GetNBins();
243 template <
int I,
class AXES>
244 struct TGetBinCount {
246 return std::get<I>(axes).GetNBins() *
TGetBinCount<
I - 1, AXES>()(axes);
251 template<
class... AXISCONFIG>
253 using axesTuple = std::tuple<AXISCONFIG...>;
254 return TGetBinCount<
sizeof...(AXISCONFIG) - 1, axesTuple>()(axesTuple{axisArgs...});
258 template <
int IDX,
class HISTIMPL,
class AXES,
bool GROW>
262 template <
class HISTIMPL,
class AXES,
bool GROW>
271 template <
int I,
class HISTIMPL,
class AXES,
bool GROW>
272 struct TGetBinIndex {
275 constexpr
const int thisAxis = HISTIMPL::GetNDim() -
I - 1;
276 int bin = std::get<thisAxis>(axes).FindBin(x[thisAxis]);
277 if (GROW && std::get<thisAxis>(axes).CanGrow()
278 && (bin < 0 || bin > std::get<thisAxis>(axes).GetNBinsNoOver())) {
279 hist->GrowAxis(
I, x[thisAxis]);
285 return bin +
TGetBinIndex<
I - 1, HISTIMPL, AXES, GROW>()(hist, axes, x, status)
286 * std::get<thisAxis>(axes).GetNBins();
297 const std::array<
Hist::EOverflow, std::tuple_size<AXES>::value>& )
const {}
303 template<
int I,
class AXES>
304 struct TFillIterRange {
307 const std::array<
Hist::EOverflow, std::tuple_size<AXES>::value> &over)
const {
309 range[0][
I] = std::get<I>(axes).begin_with_underflow();
311 range[0][
I] = std::get<I>(axes).begin();
313 range[1][
I] = std::get<I>(axes).end_with_overflow();
315 range[1][
I] = std::get<I>(axes).end();
337 template<
int I,
class COORD,
class AXES>
338 struct TFillBinCoord {
340 int axisbin = binidx % std::get<I>(axes).GetNBins();
341 size_t coordidx = std::tuple_size<AXES>::value -
I - 1;
344 coord[coordidx] = std::get<I>(axes).GetBinFrom(axisbin);
347 coord[coordidx] = std::get<I>(axes).GetBinCenter(axisbin);
350 coord[coordidx] = std::get<I>(axes).GetBinTo(axisbin);
354 binidx / std::get<I>(axes).GetNBins());
360 template <
class... AXISCONFIG>
361 static std::array<
TAxisView,
sizeof...(AXISCONFIG)>
363 std::array<
TAxisView,
sizeof...(AXISCONFIG)> axisViews = {
375 template <
class DATA,
class... AXISCONFIG>
377 static_assert(
sizeof...(AXISCONFIG) == DATA::GetNDim(),
378 "Number of axes must equal histogram dimension");
380 friend typename DATA::Hist_t;
396 THistImpl(std::string_view title, AXISCONFIG... axisArgs);
412 for (
auto&& binref: *
this)
413 op(binref.GetCenter(), binref.GetContent());
419 for (
auto&& binref: *
this)
420 op(binref.GetCenter(), binref.GetContent(), binref.GetUncertainty());
438 decltype(
fAxes),
false>()(
nullptr,
fAxes,
x, status);
486 void FillN(
const std::array_view<CoordArray_t> xN,
487 const std::array_view<Weight_t> weightN)
final {
489 if (xN.size() != weightN.size()) {
490 R__ERROR_HERE(
"HIST") <<
"Not the same number of points and weights!";
495 for (
size_t i = 0; i < xN.size(); ++i) {
496 Fill(xN[i], weightN[i]);
503 void FillN(
const std::array_view<CoordArray_t> xN)
final {
512 this->
GetStat().Fill(x, bin, w);
525 return this->
GetStat().GetBinUncertainty(binidx);
537 return this->
GetStat().HasBinUncertainty();
544 AxisIterRange_t<DATA::GetNDim()>
546 std::array<std::array<TAxisBase::const_iterator, DATA::GetNDim()>, 2> ret;
571 template <
class DATA,
class... AXISCONFIG>
576 template <
class DATA,
class... AXISCONFIG>
583 template <
class DATA,
class... AXISCONFIG>
585 THistImpl(std::string_view title, AXISCONFIG... axisArgs):
593 template <
class DATA>
594 class THistImplRuntime:
public THistImplBase<DATA> {
596 THistImplRuntime(std::array<
TAxisConfig, DATA::GetNDim()>&& axisCfg);
Exclude under- and overflows.
virtual void ApplyXC(std::function< void(const CoordArray_t &, Weight_t)>) const =0
Apply a function (lambda) to all bins of the histogram.
DATA Stat_t
Type of the statistics (bin content, uncertainties etc).
virtual int GetNBins() const noexcept=0
Number of bins of this histogram, including all overflow and underflow bins.
void AddBinContent(int binidx, Weight_t w)
Add w to the bin at index bin.
std::array< double, DIMENSIONS > CoordArray_t
CoordArray_t GetBinFrom(int binidx) const final
Get the coordinate of the low limit of the bin.
virtual void Apply(std::function< void(THistBinRef< const THistImplBase >)>) const =0
Apply a function (lambda) to all bins of the histogram.
typename ImplBase_t::CoordArray_t CoordArray_t
Weight_t GetBinContent(const CoordArray_t &x) const final
Get the content of the bin at position x.
virtual double GetBinUncertainty(const CoordArray_t &x) const =0
Get the bin uncertainty for the bin at coordinate x.
Weight_t GetBinContent(int binidx) const
Get the bin content (sum of weights) for bin index binidx.
double GetBinContentAsDouble(int binidx) const final
Get the bin content (sum of weights) for bin index binidx, cast to double.
Interface class for THistImpl.
int GetBinIndexAndGrow(const CoordArray_t &x) final
Gets the bin index for coordinate x, growing the axes as needed and possible.
typename Hist::AxisIterRange_t< NDIM > AxisIterRange_t
void operator()(COORD &, const AXES &, EBinCoord, int) const
int operator()(HISTIMPL *, const AXES &, const typename HISTIMPL::CoordArray_t &, TAxisBase::EFindStatus &status) const
virtual Weight_t GetBinContent(const CoordArray_t &x) const =0
Get the bin content (sum of weights) for the bin at coordinate x.
bool operator&(EOverflow a, EOverflow b)
Weight_t & GetBinContent(int binidx)
Get the bin content (sum of weights) for bin index binidx (non-const).
Iterates over the bins of a THist or THistImpl.
std::tuple< AXISCONFIG...> fAxes
The histogram's axes.
void GrowAxis(int, double)
Grow the axis number iAxis to fit the coordinate x.
int GetBinIndex(const CoordArray_t &x) const final
Gets the bin index for coordinate x; returns -1 if there is no such bin, e.g.
virtual CoordArray_t GetBinFrom(int binidx) const =0
Get the lower edge in all dimensions of the bin with index binidx.
Common view on a TAxis, no matter what its kind.
const_iterator begin() const noexcept
virtual CoordArray_t GetBinCenter(int binidx) const =0
Get the center in all dimensions of the bin with index binidx.
virtual int GetBinIndex(const CoordArray_t &x) const =0
Given the coordinate x, determine the index of the bin.
virtual int GetBinIndexAndGrow(const CoordArray_t &x)=0
Given the coordinate x, determine the index of the bin, possibly growing axes for which x is out of r...
void operator()(Hist::AxisIterRange_t< std::tuple_size< AXES >::value > &, const AXES &, const std::array< Hist::EOverflow, std::tuple_size< AXES >::value > &) const
const std::tuple< AXISCONFIG...> & GetAxes() const
Get the axes of this histogram.
EFindStatus
Status of FindBin(x)
const std::string & GetTitle() const
Get the histogram title.
Stat_t & GetStat() noexcept
Non-const access to statistics.
Hist::CoordArray_t< DIMENSIONS > CoordArray_t
Type of the coordinate: a DIMENSIONS-dimensional array of doubles.
int GetNBinsFromAxes(AXISCONFIG...axisArgs)
std::string fTitle
Histogram title.
int operator()(HISTIMPL *hist, const AXES &axes, const typename HISTIMPL::CoordArray_t &x, TAxisBase::EFindStatus &status) const
void function(const Char_t *name_, T fun, const Char_t *docstring=0)
int operator()(const AXES &axes) const
void FillN(const std::array_view< CoordArray_t > xN) final
Fill an array of weightN to the bins specified by coordinates xN.
virtual void ApplyXCE(std::function< void(const CoordArray_t &, Weight_t, double)>) const =0
Apply a function (lambda) to all bins of the histogram.
FillFunc_t GetFillFunc() const final
Retrieve the fill function for this histogram implementation, to prevent the virtual function call fo...
static std::array< TAxisView, sizeof...(AXISCONFIG)> GetAxisView(const AXISCONFIG &...axes) noexcept
iterator begin() noexcept
THistImplPrecisionAgnosticBase(std::string_view title)
AxisIterRange_t< DATA::GetNDim()> GetRange(const std::array< Hist::EOverflow, DATA::GetNDim()> &withOverUnder) const final
Get the begin() and end() for each axis.
const_iterator end() const noexcept
bool HasBinUncertainty() const final
Whether this histogram's statistics provide storage for uncertainties, or whether uncertainties are d...
Include both under- and overflows.
void Fill(const CoordArray_t &x, Weight_t w=1.)
Add a single weight w to the bin at coordinate x.
Objects used to configure the different axis types.
const Stat_t & GetStat() const noexcept
Const access to statistics.
typename DATA::Weight_t Weight_t
Type of the bin content (and thus weights).
Represents a bin reference.
CoordArray_t GetBinTo(int binidx) const final
Get the coordinate of the high limit of the bin.
int GetNBins() const noexceptfinal
Get the number of bins in this histogram, including possible under- and overflow bins.
virtual bool HasBinUncertainty() const =0
Whether this histogram's statistics provide storage for uncertainties, or whether uncertainties are d...
Hist::CoordArray_t< DATA::GetNDim()> CoordArray_t
Type of the coordinate: a DIMENSIONS-dimensional array of doubles.
void Apply(std::function< void(THistBinRef< const ImplBase_t >)> op) const final
Apply a function (lambda) to all bins of the histogram.
virtual CoordArray_t GetBinTo(int binidx) const =0
Get the upper edge in all dimensions of the bin with index binidx.
void ApplyXC(std::function< void(const CoordArray_t &, Weight_t)> op) const final
Apply a function (lambda) to all bins of the histogram.
static constexpr int GetNDim()
Number of dimensions of the coordinates.
THistImplBase(std::string_view title, size_t numBins)
virtual void FillN(const std::array_view< CoordArray_t > xN, const std::array_view< Weight_t > weightN)=0
Interface function to fill a vector or array of coordinates with corresponding weights.
virtual AxisIterRange_t GetRange(const std::array< Hist::EOverflow, DIMENSIONS > &withOverUnder) const =0
Get a AxisIterRange_t for the whole histogram, possibly restricting the range to non-overflow bins...
double GetBinUncertainty(int binidx) const final
Return the uncertainties for the given bin.
void(THistImplBase::*)(const CoordArray_t &x, Weight_t w) FillFunc_t
Type of the Fill(x, w) function.
virtual TAxisView GetAxis(int iAxis) const =0
Get a TAxisView on axis with index iAxis.
THistBinIter< const ImplBase_t > const_iterator
The returned bin index is valid.
virtual ~THistImplPrecisionAgnosticBase()
TAxisView GetAxis(int iAxis) const final
Normalized axes access, converting the actual axis to TAxisConfig.
THistImplPrecisionAgnosticBase()=default
Base class for THistImplBase that abstracts out the histogram's PRECISION.
virtual FillFunc_t GetFillFunc() const =0
Retrieve the pointer to the overridden Fill(x, w) function.
Hist::AxisIterRange_t< DIMENSIONS > AxisIterRange_t
Range type.
Stat_t fStatistics
The histogram's bin content, uncertainties etc.
void operator()(Hist::AxisIterRange_t< std::tuple_size< AXES >::value > &range, const AXES &axes, const std::array< Hist::EOverflow, std::tuple_size< AXES >::value > &over) const
void FillN(const std::array_view< CoordArray_t > xN, const std::array_view< Weight_t > weightN) final
Fill an array of weightN to the bins specified by coordinates xN.
int operator()(const AXES &axes) const
typedef void((*Func_t)())
double GetBinUncertainty(const CoordArray_t &x) const final
Get the bin uncertainty for the bin at coordinate x.
Fill range with begin() and end() of all axes, including under/overflow as specified by over...
void operator()(COORD &coord, const AXES &axes, EBinCoord kind, int binidx) const
virtual double GetBinContentAsDouble(int binidx) const =0
The bin content, cast to double.
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
virtual void ApplyXCE(std::function< void(const CoordArray_t &, Weight_t, double)> op) const final
Apply a function (lambda) to all bins of the histogram.
Fill coord with low bin edge or center or high bin edge of all axes.
Coordinate could fit after growing the axis.
std::array< AxisIter_t< NDIM >, 2 > AxisIterRange_t
Range over n dimensional axes - a pair of arrays of n axis iterators.
virtual double GetBinUncertainty(int binidx) const =0
The bin's uncertainty.
THistBinIter< ImplBase_t > iterator
CoordArray_t GetBinCenter(int binidx) const final
Get the center coordinate of the bin.
EOverflow
Kinds of under- and overflow handling.
decltype(auto) constexpr apply(F &&f, Tuple &&t)
#define R__ERROR_HERE(GROUP)
THistImplBase(size_t numBins)
std::array< TAxisBase::const_iterator, NDIM > AxisIter_t
Iterator over n dimensional axes - an array of n axis iterators.