24 #include <initializer_list>
27 namespace Experimental {
30 template <
int DIMENSIONS,
class PRECISION,
template <
int D_,
class P_>
class... STAT>
34 template <
int DIMENSIONS,
class PRECISION,
template <
int D_,
class P_>
class... STAT>
35 class RHist<DIMENSIONS, PRECISION, STAT...>
36 HistFromImpl(std::unique_ptr<typename RHist<DIMENSIONS, PRECISION, STAT...>::ImplBase_t> pHistImpl);
50 template <int DIMENSIONS, class PRECISION, template <int D_, class P_> class... STAT>
55 Detail::RHistImplBase<Detail::RHistData<DIMENSIONS, PRECISION, std::vector<PRECISION>, STAT...>>;
57 using CoordArray_t =
typename ImplBase_t::CoordArray_t;
59 using Weight_t = PRECISION;
61 using FillFunc_t =
typename ImplBase_t::FillFunc_t;
63 using AxisRange_t =
typename ImplBase_t::AxisIterRange_t;
65 using const_iterator = Detail::RHistBinIter<ImplBase_t>;
68 static constexpr
int GetNDim() noexcept {
return DIMENSIONS; }
71 RHist(RHist &&) =
default;
72 RHist(
const RHist &other): fImpl(other.fImpl->Clone()), fFillFunc(other.fFillFunc)
90 explicit RHist(std::array<RAxisConfig, DIMENSIONS> axes);
93 RHist(std::string_view histTitle, std::array<RAxisConfig, DIMENSIONS> axes);
96 template <int ENABLEIF_NDIM = DIMENSIONS, class = typename std::enable_if<ENABLEIF_NDIM == 1>::type>
97 explicit RHist(
const RAxisConfig &xaxis): RHist(std::array<RAxisConfig, 1>{{xaxis}})
102 template <int ENABLEIF_NDIM = DIMENSIONS, class = typename std::enable_if<ENABLEIF_NDIM == 1>::type>
103 RHist(std::string_view histTitle,
const RAxisConfig &xaxis): RHist(histTitle, std::array<RAxisConfig, 1>{{xaxis}})
107 template <int ENABLEIF_NDIM = DIMENSIONS, class = typename std::enable_if<ENABLEIF_NDIM == 2>::type>
108 RHist(
const RAxisConfig &xaxis,
const RAxisConfig &yaxis): RHist(std::array<RAxisConfig, 2>{{xaxis, yaxis}})
113 template <int ENABLEIF_NDIM = DIMENSIONS, class = typename std::enable_if<ENABLEIF_NDIM == 2>::type>
114 RHist(std::string_view histTitle,
const RAxisConfig &xaxis,
const RAxisConfig &yaxis)
115 : RHist(histTitle, std::array<RAxisConfig, 2>{{xaxis, yaxis}})
119 template <int ENABLEIF_NDIM = DIMENSIONS, class = typename std::enable_if<ENABLEIF_NDIM == 3>::type>
120 RHist(
const RAxisConfig &xaxis,
const RAxisConfig &yaxis,
const RAxisConfig &zaxis)
121 : RHist(std::array<RAxisConfig, 3>{{xaxis, yaxis, zaxis}})
126 template <int ENABLEIF_NDIM = DIMENSIONS, class = typename std::enable_if<ENABLEIF_NDIM == 3>::type>
127 RHist(std::string_view histTitle,
const RAxisConfig &xaxis,
const RAxisConfig &yaxis,
const RAxisConfig &zaxis)
128 : RHist(histTitle, std::array<RAxisConfig, 3>{{xaxis, yaxis, zaxis}})
132 ImplBase_t *GetImpl() const noexcept {
return fImpl.get(); }
135 std::unique_ptr<ImplBase_t> TakeImpl() && noexcept {
return std::move(fImpl); }
138 void Fill(
const CoordArray_t &x, Weight_t weight = (Weight_t)1) noexcept { (fImpl.get()->*fFillFunc)(x, weight); }
143 void FillN(
const std::span<const CoordArray_t> xN,
const std::span<const Weight_t> weightN) noexcept
145 fImpl->FillN(xN, weightN);
149 void FillN(
const std::span<const CoordArray_t> xN) noexcept { fImpl->FillN(xN); }
152 int64_t GetEntries() const noexcept {
return fImpl->GetStat().GetEntries(); }
155 Weight_t GetBinContent(
const CoordArray_t &x)
const {
return fImpl->GetBinContent(x); }
158 double GetBinUncertainty(
const CoordArray_t &x)
const {
return fImpl->GetBinUncertainty(x); }
160 const_iterator begin()
const {
return const_iterator(*fImpl); }
162 const_iterator end()
const {
return const_iterator(*fImpl, fImpl->GetNBins()); }
167 void swap(RHist<DIMENSIONS, PRECISION, STAT...> &other) noexcept
169 std::swap(fImpl, other.fImpl);
170 std::swap(fFillFunc, other.fFillFunc);
174 std::unique_ptr<ImplBase_t> fImpl;
175 FillFunc_t fFillFunc =
nullptr;
177 friend RHist HistFromImpl<>(std::unique_ptr<ImplBase_t>);
181 template <
int DIMENSIONS,
class PRECISION>
182 class RHist<DIMENSIONS, PRECISION>:
public RHist<DIMENSIONS, PRECISION, RHistStatContent> {
183 using RHist<DIMENSIONS, PRECISION, RHistStatContent>::RHist;
189 template <
int DIMENSIONS,
class PRECISION,
template <
int D_,
class P_>
class... STAT>
190 void swap(RHist<DIMENSIONS, PRECISION, STAT...> &a, RHist<DIMENSIONS, PRECISION, STAT...> &b) noexcept
199 template <
int NDIM,
int IDIM,
class DATA,
class... PROCESSEDAXISCONFIG>
200 struct RHistImplGen {
203 template <RAxisConfig::EKind KIND>
204 std::unique_ptr<Detail::RHistImplBase<DATA>>
205 MakeNextAxis(std::string_view title,
const std::array<RAxisConfig, NDIM> &axes,
206 PROCESSEDAXISCONFIG... processedAxisArgs)
208 using NextAxis_t =
typename AxisConfigToType<KIND>::Axis_t;
209 NextAxis_t nextAxis = AxisConfigToType<KIND>()(axes[IDIM]);
210 using HistImpl_t = RHistImplGen<NDIM, IDIM + 1, DATA, PROCESSEDAXISCONFIG..., NextAxis_t>;
211 return HistImpl_t()(title, axes, processedAxisArgs..., nextAxis);
226 std::unique_ptr<Detail::RHistImplBase<DATA>> operator()(std::string_view title,
227 const std::array<RAxisConfig, NDIM> &axes,
228 PROCESSEDAXISCONFIG... processedAxisArgs)
230 switch (axes[IDIM].GetKind()) {
231 case RAxisConfig::kEquidistant:
return MakeNextAxis<RAxisConfig::kEquidistant>(title, axes, processedAxisArgs...);
232 case RAxisConfig::kGrow:
return MakeNextAxis<RAxisConfig::kGrow>(title, axes, processedAxisArgs...);
233 case RAxisConfig::kIrregular:
return MakeNextAxis<RAxisConfig::kIrregular>(title, axes, processedAxisArgs...);
234 default: R__ERROR_HERE(
"HIST") <<
"Unhandled axis kind";
241 template <
int NDIM,
class DATA,
class... PROCESSEDAXISCONFIG>
244 struct RHistImplGen<NDIM, NDIM, DATA, PROCESSEDAXISCONFIG...> {
245 using HistImplBase_t = ROOT::Experimental::Detail::RHistImplBase<DATA>;
246 std::unique_ptr<HistImplBase_t>
247 operator()(std::string_view title,
const std::array<RAxisConfig, DATA::GetNDim()> &, PROCESSEDAXISCONFIG... axisArgs)
249 using HistImplt_t = Detail::RHistImpl<DATA, PROCESSEDAXISCONFIG...>;
250 return std::make_unique<HistImplt_t>(title, axisArgs...);
255 template <
int DIMENSIONS,
class PRECISION,
template <
int D_,
class P_>
class... STAT>
256 RHist<DIMENSIONS, PRECISION, STAT...>::RHist(std::string_view title, std::array<RAxisConfig, DIMENSIONS> axes)
258 Internal::RHistImplGen<RHist::GetNDim(), 0,
259 Detail::RHistData<DIMENSIONS, PRECISION, std::vector<PRECISION>, STAT...>>()(
262 fFillFunc = fImpl->GetFillFunc();
265 template <
int DIMENSIONS,
class PRECISION,
template <
int D_,
class P_>
class... STAT>
266 RHist<DIMENSIONS, PRECISION, STAT...>::RHist(std::array<RAxisConfig, DIMENSIONS> axes): RHist(
"", axes)
270 template <
int DIMENSIONS,
class PRECISION,
template <
int D_,
class P_>
class... STAT>
271 RHist<DIMENSIONS, PRECISION, STAT...>
272 HistFromImpl(std::unique_ptr<
typename RHist<DIMENSIONS, PRECISION, STAT...>::ImplBase_t> pHistImpl)
274 RHist<DIMENSIONS, PRECISION, STAT...> ret;
275 ret.fFillFunc = pHistImpl->GetFillFunc();
276 std::swap(ret.fImpl, pHistImpl);
284 using RH1D = RHist<1, double, RHistStatContent, RHistStatUncertainty>;
285 using RH1F = RHist<1, float, RHistStatContent, RHistStatUncertainty>;
286 using RH1C = RHist<1, char, RHistStatContent>;
287 using RH1I = RHist<1, int, RHistStatContent>;
288 using RH1LL = RHist<1, int64_t, RHistStatContent>;
290 using RH2D = RHist<2, double, RHistStatContent, RHistStatUncertainty>;
291 using RH2F = RHist<2, float, RHistStatContent, RHistStatUncertainty>;
292 using RH2C = RHist<2, char, RHistStatContent>;
293 using RH2I = RHist<2, int, RHistStatContent>;
294 using RH2LL = RHist<2, int64_t, RHistStatContent>;
296 using RH3D = RHist<3, double, RHistStatContent, RHistStatUncertainty>;
297 using RH3F = RHist<3, float, RHistStatContent, RHistStatUncertainty>;
298 using RH3C = RHist<3, char, RHistStatContent>;
299 using RH3I = RHist<3, int, RHistStatContent>;
300 using RH3LL = RHist<3, int64_t, RHistStatContent>;
305 template <
int DIMENSIONS,
class PRECISION_TO,
class PRECISION_FROM,
306 template <
int D_,
class P_>
class... STAT_TO,
307 template <
int D_,
class P_>
class... STAT_FROM>
308 void Add(RHist<DIMENSIONS, PRECISION_TO, STAT_TO...> &to,
const RHist<DIMENSIONS, PRECISION_FROM, STAT_FROM...> &from)
310 auto toImpl = to.GetImpl();
311 auto fillFuncTo = toImpl->GetFillFunc();
312 using HistFrom_t = RHist<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);
319 from.GetImpl()->ApplyXC(add);