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;
88 const std::string&
GetTitle()
const {
return fTitle; }
94 virtual int GetBinIndexAndGrow(
const CoordArray_t& x) = 0;
105 virtual double GetBinUncertainty(
int binidx)
const = 0;
109 virtual bool HasBinUncertainty()
const = 0;
112 virtual double GetBinContentAsDouble(
int binidx)
const = 0;
117 virtual TAxisView GetAxis(
int iAxis)
const = 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;
195 virtual double GetBinUncertainty(
const CoordArray_t& x)
const = 0;
199 int GetNBins() const noexcept final {
return fStatistics.size(); }
216 return (
double) GetBinContent(binidx);
238 return std::get<0>(axes).GetNBins();
243 template <
int I,
class AXES>
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>
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>
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>
340 int axisbin = binidx % std::get<I>(axes).GetNBins();
341 size_t coordidx = std::tuple_size<AXES>::value -
I - 1;
343 case EBinCoord::kBinFrom:
344 coord[coordidx] = std::get<I>(axes).GetBinFrom(axisbin);
346 case EBinCoord::kBinCenter:
347 coord[coordidx] = std::get<I>(axes).GetBinCenter(axisbin);
349 case EBinCoord::kBinTo:
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());
425 const std::tuple<AXISCONFIG...>&
GetAxes()
const {
return fAxes; }
429 return std::apply(Internal::GetAxisView<AXISCONFIG...>, fAxes)[iAxis];
438 decltype(fAxes),
false>()(
nullptr, fAxes,
x, status);
452 (
this, 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 {
511 int bin = GetBinIndexAndGrow(x);
512 this->GetStat().Fill(x, bin, w);
517 int bin = GetBinIndex(
x);
519 return ImplBase_t::GetBinContent(bin);
525 return this->GetStat().GetBinUncertainty(binidx);
530 const int bin = GetBinIndex(
x);
531 return this->GetBinUncertainty(bin);
537 return this->GetStat().HasBinUncertainty();
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>
596 THistImplRuntime(std::array<
TAxisConfig, DATA::GetNDim()>&& axisCfg);
int GetNBins() const noexcept final
Get the number of bins in this histogram, including possible under- and overflow bins.
Exclude under- and overflows.
DATA Stat_t
Type of the statistics (bin content, uncertainties etc).
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.
Namespace for new ROOT classes and functions.
Weight_t GetBinContent(const CoordArray_t &x) const final
Get the content of the bin at position x.
void operator()(COORD &coord, const AXES &axes, EBinCoord kind, int binidx) const
double GetBinContentAsDouble(int binidx) const final
Get the bin content (sum of weights) for bin index binidx, cast to double.
bool operator &(EOverflow a, EOverflow b)
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.
int operator()(HISTIMPL *, const AXES &, const typename HISTIMPL::CoordArray_t &, TAxisBase::EFindStatus &status) const
typename Hist::AxisIterRange_t< NDIM > AxisIterRange_t
Weight_t GetBinContent(int binidx) const
Get the bin content (sum of weights) for bin index binidx.
Weight_t & GetBinContent(int binidx)
Get the bin content (sum of weights) for bin index binidx (non-const).
void operator()(COORD &, const AXES &, EBinCoord, int) 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.
Common view on a TAxis, no matter what its kind.
const_iterator begin() const noexcept
int operator()(const AXES &axes) const
const std::tuple< AXISCONFIG... > & GetAxes() const
Get the axes of this histogram.
EFindStatus
Status of FindBin(x)
int GetNBinsFromAxes(AXISCONFIG... axisArgs)
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.
std::string fTitle
Histogram title.
void function(const Char_t *name_, T fun, const Char_t *docstring=0)
void FillN(const std::array_view< CoordArray_t > xN) final
Fill an array of weightN to the bins specified by coordinates xN.
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
static void GetRange(const char *comments, Double_t &xmin, Double_t &xmax, Double_t &factor)
Parse comments to search for a range specifier of the style: [xmin,xmax] or [xmin,xmax,nbits] [0,1] [-10,100]; [-pi,pi], [-pi/2,pi/4],[-2pi,2*pi] [-10,100,16] [0,0,8] if nbits is not specified, or nbits <2 or nbits>32 it is set to 32 if (xmin==0 and xmax==0 and nbits <=16) the double word will be converted to a float and its mantissa truncated to nbits significative bits.
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.
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.
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)
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.
The returned bin index is valid.
virtual ~THistImplPrecisionAgnosticBase()
TAxisView GetAxis(int iAxis) const final
Normalized axes access, converting the actual axis to TAxisConfig.
Base class for THistImplBase that abstracts out the histogram's PRECISION.
Hist::AxisIterRange_t< DIMENSIONS > AxisIterRange_t
Range type.
Stat_t fStatistics
The histogram's bin content, uncertainties etc.
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.
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...
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
int operator()(const AXES &axes) const
void operator()(Hist::AxisIterRange_t< std::tuple_size< AXES >::value > &, const AXES &, const std::array< Hist::EOverflow, std::tuple_size< AXES >::value > &) const
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.
int operator()(HISTIMPL *hist, const AXES &axes, const typename HISTIMPL::CoordArray_t &x, TAxisBase::EFindStatus &status) const
CoordArray_t GetBinCenter(int binidx) const final
Get the center coordinate of the bin.
EOverflow
Kinds of under- and overflow handling.
static void Fill(TTree *tree, int init, int count)
decltype(auto) constexpr apply(F &&f, Tuple &&t)
const std::string & GetTitle() const
Get the histogram title.
#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.
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