Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/root/ROOT/RHist.hxx was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /// \file
0002 /// \warning This is part of the %ROOT 7 prototype! It will change without notice. It might trigger earthquakes.
0003 /// Feedback is welcome!
0004 
0005 #ifndef ROOT_RHist
0006 #define ROOT_RHist
0007 
0008 #include "RBinIndex.hxx"
0009 #include "RHistEngine.hxx"
0010 #include "RHistStats.hxx"
0011 #include "RWeight.hxx"
0012 
0013 #include <array>
0014 #include <cassert>
0015 #include <stdexcept>
0016 #include <tuple>
0017 #include <utility>
0018 #include <vector>
0019 
0020 class TBuffer;
0021 
0022 namespace ROOT {
0023 namespace Experimental {
0024 
0025 /**
0026 A histogram for aggregation of data along multiple dimensions.
0027 
0028 Every call to \ref Fill(const A &... args) "Fill" increments the bin content and is reflected in global statistics:
0029 \code
0030 ROOT::Experimental::RHist<int> hist(10, {5, 15});
0031 hist.Fill(8.5);
0032 // hist.GetBinContent(ROOT::Experimental::RBinIndex(3)) will return 1
0033 \endcode
0034 
0035 The class is templated on the bin content type. For counting, as in the example above, it may be an integral type such
0036 as `int` or `long`. Narrower types such as `unsigned char` or `short` are supported, but may overflow due to their
0037 limited range and must be used with care. For weighted filling, the bin content type must not be an integral type, but
0038 a floating-point type such as `float` or `double`, or the special type RBinWithError. Note that `float` has a limited
0039 significand precision of 24 bits.
0040 
0041 An object can have arbitrary dimensionality determined at run-time. The axis configuration is passed as a vector of
0042 RAxisVariant:
0043 \code
0044 std::vector<ROOT::Experimental::RAxisVariant> axes;
0045 axes.push_back(ROOT::Experimental::RRegularAxis(10, 5, 15));
0046 axes.push_back(ROOT::Experimental::RVariableBinAxis({1, 10, 100, 1000}));
0047 ROOT::Experimental::RHist<int> hist(axes);
0048 // hist.GetNDimensions() will return 2
0049 \endcode
0050 
0051 \warning This is part of the %ROOT 7 prototype! It will change without notice. It might trigger earthquakes.
0052 Feedback is welcome!
0053 */
0054 template <typename BinContentType>
0055 class RHist final {
0056    /// The histogram engine including the bin contents.
0057    RHistEngine<BinContentType> fEngine;
0058    /// The global histogram statistics.
0059    RHistStats fStats;
0060 
0061    /// Private constructor based off an engine.
0062    RHist(RHistEngine<BinContentType> engine) : fEngine(std::move(engine)), fStats(fEngine.GetNDimensions()) {}
0063 
0064 public:
0065    /// Construct a histogram.
0066    ///
0067    /// \param[in] axes the axis objects, must have size > 0
0068    explicit RHist(std::vector<RAxisVariant> axes) : fEngine(std::move(axes)), fStats(fEngine.GetNDimensions()) {}
0069 
0070    /// Construct a one-dimensional histogram engine with a regular axis.
0071    ///
0072    /// \param[in] nNormalBins the number of normal bins, must be > 0
0073    /// \param[in] interval the axis interval (lower end inclusive, upper end exclusive)
0074    /// \par See also
0075    /// the
0076    /// \ref RRegularAxis::RRegularAxis(std::size_t nNormalBins, std::pair<double, double> interval, bool enableFlowBins)
0077    /// "constructor of RRegularAxis"
0078    RHist(std::size_t nNormalBins, std::pair<double, double> interval) : RHist({RRegularAxis(nNormalBins, interval)}) {}
0079 
0080    /// The copy constructor is deleted.
0081    ///
0082    /// Copying all bin contents can be an expensive operation, depending on the number of bins. If required, users can
0083    /// explicitly call Clone().
0084    RHist(const RHist<BinContentType> &) = delete;
0085    /// Efficiently move construct a histogram.
0086    ///
0087    /// After this operation, the moved-from object is invalid.
0088    RHist(RHist<BinContentType> &&) = default;
0089 
0090    /// The copy assignment operator is deleted.
0091    ///
0092    /// Copying all bin contents can be an expensive operation, depending on the number of bins. If required, users can
0093    /// explicitly call Clone().
0094    RHist<BinContentType> &operator=(const RHist<BinContentType> &) = delete;
0095    /// Efficiently move a histogram.
0096    ///
0097    /// After this operation, the moved-from object is invalid.
0098    RHist<BinContentType> &operator=(RHist<BinContentType> &&) = default;
0099 
0100    ~RHist() = default;
0101 
0102    const RHistEngine<BinContentType> &GetEngine() const { return fEngine; }
0103    const RHistStats &GetStats() const { return fStats; }
0104 
0105    const std::vector<RAxisVariant> &GetAxes() const { return fEngine.GetAxes(); }
0106    std::size_t GetNDimensions() const { return fEngine.GetNDimensions(); }
0107    std::size_t GetTotalNBins() const { return fEngine.GetTotalNBins(); }
0108 
0109    std::uint64_t GetNEntries() const { return fStats.GetNEntries(); }
0110    /// \copydoc RHistStats::ComputeNEffectiveEntries()
0111    double ComputeNEffectiveEntries() const { return fStats.ComputeNEffectiveEntries(); }
0112    /// \copydoc RHistStats::ComputeMean()
0113    double ComputeMean(std::size_t dim = 0) const { return fStats.ComputeMean(dim); }
0114    /// \copydoc RHistStats::ComputeStdDev()
0115    double ComputeStdDev(std::size_t dim = 0) const { return fStats.ComputeStdDev(dim); }
0116 
0117    /// Get the content of a single bin.
0118    ///
0119    /// \code
0120    /// ROOT::Experimental::RHist<int> hist({/* two dimensions */});
0121    /// std::array<ROOT::Experimental::RBinIndex, 2> indices = {3, 5};
0122    /// int content = hist.GetBinContent(indices);
0123    /// \endcode
0124    ///
0125    /// \note Compared to TH1 conventions, the first normal bin has index 0 and underflow and overflow bins are special
0126    /// values. See also the class documentation of RBinIndex.
0127    ///
0128    /// Throws an exception if the number of indices does not match the axis configuration or the bin is not found.
0129    ///
0130    /// \param[in] indices the array of indices for each axis
0131    /// \return the bin content
0132    /// \par See also
0133    /// the \ref GetBinContent(const A &... args) const "variadic function template overload" accepting arguments
0134    /// directly
0135    template <std::size_t N>
0136    const BinContentType &GetBinContent(const std::array<RBinIndex, N> &indices) const
0137    {
0138       return fEngine.GetBinContent(indices);
0139    }
0140 
0141    /// Get the content of a single bin.
0142    ///
0143    /// \code
0144    /// ROOT::Experimental::RHist<int> hist({/* two dimensions */});
0145    /// int content = hist.GetBinContent(ROOT::Experimental::RBinIndex(3), ROOT::Experimental::RBinIndex(5));
0146    /// // ... or construct the RBinIndex arguments implicitly from integers:
0147    /// content = hist.GetBinContent(3, 5);
0148    /// \endcode
0149    ///
0150    /// \note Compared to TH1 conventions, the first normal bin has index 0 and underflow and overflow bins are special
0151    /// values. See also the class documentation of RBinIndex.
0152    ///
0153    /// Throws an exception if the number of arguments does not match the axis configuration or the bin is not found.
0154    ///
0155    /// \param[in] args the arguments for each axis
0156    /// \return the bin content
0157    /// \par See also
0158    /// the \ref GetBinContent(const std::array<RBinIndex, N> &indices) const "function overload" accepting
0159    /// `std::array`
0160    template <typename... A>
0161    const BinContentType &GetBinContent(const A &...args) const
0162    {
0163       return fEngine.GetBinContent(args...);
0164    }
0165 
0166    /// Add all bin contents and statistics of another histogram.
0167    ///
0168    /// Throws an exception if the axes configurations are not identical.
0169    ///
0170    /// \param[in] other another histogram
0171    void Add(const RHist<BinContentType> &other)
0172    {
0173       fEngine.Add(other.fEngine);
0174       fStats.Add(other.fStats);
0175    }
0176 
0177    /// Clear all bin contents and statistics.
0178    void Clear()
0179    {
0180       fEngine.Clear();
0181       fStats.Clear();
0182    }
0183 
0184    /// Clone this histogram.
0185    ///
0186    /// Copying all bin contents can be an expensive operation, depending on the number of bins.
0187    ///
0188    /// \return the cloned object
0189    RHist<BinContentType> Clone() const
0190    {
0191       RHist<BinContentType> h(fEngine.Clone());
0192       h.fStats = fStats;
0193       return h;
0194    }
0195 
0196    /// Fill an entry into the histogram.
0197    ///
0198    /// \code
0199    /// ROOT::Experimental::RHist<int> hist({/* two dimensions */});
0200    /// auto args = std::make_tuple(8.5, 10.5);
0201    /// hist.Fill(args);
0202    /// \endcode
0203    ///
0204    /// If one of the arguments is outside the corresponding axis and flow bins are disabled, the entry will be silently
0205    /// discarded.
0206    ///
0207    /// Throws an exception if the number of arguments does not match the axis configuration, or if an argument cannot be
0208    /// converted for the axis type at run-time.
0209    ///
0210    /// \param[in] args the arguments for each axis
0211    /// \par See also
0212    /// the \ref Fill(const A &... args) "variadic function template overload" accepting arguments directly and the
0213    /// \ref Fill(const std::tuple<A...> &args, RWeight weight) "overload for weighted filling"
0214    template <typename... A>
0215    void Fill(const std::tuple<A...> &args)
0216    {
0217       fEngine.Fill(args);
0218       fStats.Fill(args);
0219    }
0220 
0221    /// Fill an entry into the histogram with a weight.
0222    ///
0223    /// This overload is not available for integral bin content types (see \ref RHistEngine::SupportsWeightedFilling).
0224    ///
0225    /// \code
0226    /// ROOT::Experimental::RHist<float> hist({/* two dimensions */});
0227    /// auto args = std::make_tuple(8.5, 10.5);
0228    /// hist.Fill(args, ROOT::Experimental::RWeight(0.8));
0229    /// \endcode
0230    ///
0231    /// If one of the arguments is outside the corresponding axis and flow bins are disabled, the entry will be silently
0232    /// discarded.
0233    ///
0234    /// Throws an exception if the number of arguments does not match the axis configuration, or if an argument cannot be
0235    /// converted for the axis type at run-time.
0236    ///
0237    /// \param[in] args the arguments for each axis
0238    /// \param[in] weight the weight for this entry
0239    /// \par See also
0240    /// the \ref Fill(const A &... args) "variadic function template overload" accepting arguments directly and the
0241    /// \ref Fill(const std::tuple<A...> &args) "overload for unweighted filling"
0242    template <typename... A>
0243    void Fill(const std::tuple<A...> &args, RWeight weight)
0244    {
0245       fEngine.Fill(args, weight);
0246       fStats.Fill(args, weight);
0247    }
0248 
0249    /// Fill an entry into the histogram.
0250    ///
0251    /// \code
0252    /// ROOT::Experimental::RHist<int> hist({/* two dimensions */});
0253    /// hist.Fill(8.5, 10.5);
0254    /// \endcode
0255    ///
0256    /// For weighted filling, pass an RWeight as the last argument:
0257    /// \code
0258    /// ROOT::Experimental::RHist<float> hist({/* two dimensions */});
0259    /// hist.Fill(8.5, 10.5, ROOT::Experimental::RWeight(0.8));
0260    /// \endcode
0261    /// This is not available for integral bin content types (see \ref RHistEngine::SupportsWeightedFilling).
0262    ///
0263    /// If one of the arguments is outside the corresponding axis and flow bins are disabled, the entry will be silently
0264    /// discarded.
0265    ///
0266    /// Throws an exception if the number of arguments does not match the axis configuration, or if an argument cannot be
0267    /// converted for the axis type at run-time.
0268    ///
0269    /// \param[in] args the arguments for each axis
0270    /// \par See also
0271    /// the function overloads accepting `std::tuple` \ref Fill(const std::tuple<A...> &args) "for unweighted filling"
0272    /// and \ref Fill(const std::tuple<A...> &args, RWeight) "for weighted filling"
0273    template <typename... A>
0274    void Fill(const A &...args)
0275    {
0276       fEngine.Fill(args...);
0277       fStats.Fill(args...);
0278    }
0279 
0280    /// %ROOT Streamer function to throw when trying to store an object of this class.
0281    void Streamer(TBuffer &) { throw std::runtime_error("unable to store RHist"); }
0282 };
0283 
0284 } // namespace Experimental
0285 } // namespace ROOT
0286 
0287 #endif