@@ -451,6 +451,115 @@ public:
451451 fStats .Scale (factor);
452452 }
453453
454+ // / Slice this histogram with an RSliceSpec per dimension.
455+ // /
456+ // / With a range, only the specified bins are retained. All other bin contents are transferred to the underflow and
457+ // / overflow bins:
458+ // / \code
459+ // / ROOT::Experimental::RHist<int> hist(/* one dimension */);
460+ // / // Fill the histogram with a number of entries...
461+ // / auto sliced = hist.Slice({hist.GetAxes()[0].GetNormalRange(1, 5)});
462+ // / // The returned histogram will have 4 normal bins, an underflow and an overflow bin.
463+ // / \endcode
464+ // /
465+ // / Slicing can also perform operations per dimension, see RSliceSpec. RSliceSpec::ROperationRebin allows to rebin
466+ // / the histogram axis, grouping a number of normal bins into a new one:
467+ // / \code
468+ // / ROOT::Experimental::RHist<int> hist(/* one dimension */);
469+ // / // Fill the histogram with a number of entries...
470+ // / auto rebinned = hist.Slice(ROOT::Experimental::RSliceSpec::ROperationRebin(2));
471+ // / // The returned histogram has groups of two normal bins merged.
472+ // / \endcode
473+ // /
474+ // / RSliceSpec::ROperationSum sums the bin contents along that axis, which allows to project to a lower-dimensional
475+ // / histogram:
476+ // / \code
477+ // / ROOT::Experimental::RHist<int> hist({/* two dimensions */});
478+ // / // Fill the histogram with a number of entries...
479+ // / auto projected = hist.Slice(ROOT::Experimental::RSliceSpec{}, ROOT::Experimental::RSliceSpec::ROperationSum{});
480+ // / // The returned histogram has one dimension, with bin contents summed along the second axis.
481+ // / \endcode
482+ // / Note that it is not allowed to sum along all histogram axes because the return value would be a scalar.
483+ // /
484+ // / Ranges and operations can be combined. In that case, the range is applied before the operation.
485+ // /
486+ // / \warning Combining a range and the sum operation drops bin contents, which will taint the global histogram
487+ // / statistics. Attempting to access its values, for example calling GetNEntries(), will throw exceptions.
488+ // /
489+ // / \param[in] sliceSpecs the slice specifications for each axis
490+ // / \return the sliced histogram
491+ // / \par See also
492+ // / the \ref Slice(const A &... args) const "variadic function template overload" accepting arguments directly
493+ RHist Slice (const std::vector<RSliceSpec> &sliceSpecs) const
494+ {
495+ bool dropped = false ;
496+ RHist sliced (fEngine .SliceImpl (sliceSpecs, dropped));
497+ assert (sliced.fStats .GetNDimensions () == sliced.GetNDimensions ());
498+ if (dropped || fStats .IsTainted ()) {
499+ sliced.fStats .Taint ();
500+ } else {
501+ sliced.fStats .fNEntries = fStats .fNEntries ;
502+ sliced.fStats .fSumW = fStats .fSumW ;
503+ sliced.fStats .fSumW2 = fStats .fSumW2 ;
504+ std::size_t slicedDim = 0 ;
505+ for (std::size_t i = 0 ; i < sliceSpecs.size (); i++) {
506+ // A sum operation makes the dimension disappear.
507+ if (sliceSpecs[i].GetOperationSum () == nullptr ) {
508+ sliced.fStats .fDimensionStats [slicedDim] = fStats .fDimensionStats [i];
509+ slicedDim++;
510+ }
511+ }
512+ assert (slicedDim == sliced.GetNDimensions ());
513+ }
514+ return sliced;
515+ }
516+
517+ // / Slice this histogram with an RSliceSpec per dimension.
518+ // /
519+ // / With a range, only the specified bins are retained. All other bin contents are transferred to the underflow and
520+ // / overflow bins:
521+ // / \code
522+ // / ROOT::Experimental::RHist<int> hist(/* one dimension */);
523+ // / // Fill the histogram with a number of entries...
524+ // / auto sliced = hist.Slice(hist.GetAxes()[0].GetNormalRange(1, 5));
525+ // / // The returned histogram will have 4 normal bins, an underflow and an overflow bin.
526+ // / \endcode
527+ // /
528+ // / Slicing can also perform operations per dimension, see RSliceSpec. RSliceSpec::ROperationRebin allows to rebin
529+ // / the histogram axis, grouping a number of normal bins into a new one:
530+ // / \code
531+ // / ROOT::Experimental::RHist<int> hist(/* one dimension */);
532+ // / // Fill the histogram with a number of entries...
533+ // / auto rebinned = hist.Slice(ROOT::Experimental::RSliceSpec::ROperationRebin(2));
534+ // / // The returned histogram has groups of two normal bins merged.
535+ // / \endcode
536+ // /
537+ // / RSliceSpec::ROperationSum sums the bin contents along that axis, which allows to project to a lower-dimensional
538+ // / histogram:
539+ // / \code
540+ // / ROOT::Experimental::RHist<int> hist({/* two dimensions */});
541+ // / // Fill the histogram with a number of entries...
542+ // / auto projected = hist.Slice(ROOT::Experimental::RSliceSpec{}, ROOT::Experimental::RSliceSpec::ROperationSum{});
543+ // / // The returned histogram has one dimension, with bin contents summed along the second axis.
544+ // / \endcode
545+ // / Note that it is not allowed to sum along all histogram axes because the return value would be a scalar.
546+ // /
547+ // / Ranges and operations can be combined. In that case, the range is applied before the operation.
548+ // /
549+ // / \warning Combining a range and the sum operation drops bin contents, which will taint the global histogram
550+ // / statistics. Attempting to access its values, for example calling GetNEntries(), will throw exceptions.
551+ // /
552+ // / \param[in] args the arguments for each axis
553+ // / \return the sliced histogram
554+ // / \par See also
555+ // / the \ref Slice(const std::vector<RSliceSpec> &sliceSpecs) const "function overload" accepting `std::vector`
556+ template <typename ... A>
557+ RHist Slice (const A &...args) const
558+ {
559+ std::vector<RSliceSpec> sliceSpecs{args...};
560+ return Slice (sliceSpecs);
561+ }
562+
454563 // / %ROOT Streamer function to throw when trying to store an object of this class.
455564 void Streamer (TBuffer &) { throw std::runtime_error (" unable to store RHist" ); }
456565};
0 commit comments