diff --git a/tutorials/hist/histv7/hist001_RHist_basics.C b/tutorials/hist/histv7/hist001_RHist_basics.C index f6636871c47b1..254d201354b2e 100644 --- a/tutorials/hist/histv7/hist001_RHist_basics.C +++ b/tutorials/hist/histv7/hist001_RHist_basics.C @@ -4,6 +4,7 @@ /// Basics of RHist, including filling and adding them. /// /// \macro_code +/// \macro_output /// /// \date September 2025 /// \author The ROOT Team @@ -17,7 +18,7 @@ #include #include -// It is currently not possible to directly draw RHist's, so this function implements an output with ASCII characters. +// It is currently not possible to directly draw an RHist, so this function implements an output with ASCII characters. static void DrawHistogram(const ROOT::Experimental::RHist &hist) { // Get the axis object from the histogram. @@ -56,9 +57,9 @@ static void DrawHistogram(const ROOT::Experimental::RHist &hist) void hist001_RHist_basics() { // Create an axis that can be used for multiple histograms. - ROOT::Experimental::RRegularAxis axis(40, {0, 20}); + ROOT::Experimental::RRegularAxis axis(40, {0.0, 20.0}); - // Create a first histograms and fill with random values. + // Create a first histogram and fill with random values. ROOT::Experimental::RHist hist1({axis}); // Create a normal distribution with mean 5.0 and stddev 2.0. diff --git a/tutorials/hist/histv7/hist002_RHist_weighted.C b/tutorials/hist/histv7/hist002_RHist_weighted.C new file mode 100644 index 0000000000000..2128e82429aa2 --- /dev/null +++ b/tutorials/hist/histv7/hist002_RHist_weighted.C @@ -0,0 +1,119 @@ +/// \file +/// \ingroup tutorial_histv7 +/// +/// Weighted filling of RHist and RBinWithError bin content type. +/// +/// \macro_code +/// \macro_output +/// +/// \date October 2025 +/// \author The ROOT Team + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +// It is currently not possible to directly draw an RHist, so this function implements an output with ASCII characters. +static void DrawHistogram(const ROOT::Experimental::RHist &hist) +{ + // Get the axis object from the histogram. + auto &axis = std::get(hist.GetAxes()[0]); + + // Print (some of) the global statistics. + std::cout << "entries = " << hist.GetNEntries(); + std::cout << ", mean = " << hist.ComputeMean(); + std::cout << ", stddev = " << hist.ComputeStdDev(); + std::cout << "\n"; + + // "Draw" the histogram with ASCII characters. The height is hard-coded to work for this tutorial. + for (int row = 15; row > 0; row--) { + auto print = [&](ROOT::Experimental::RBinIndex bin) { + auto value = hist.GetBinContent(bin); + static constexpr int Scale = 100; + std::cout << (value >= (row * Scale) ? '*' : ' '); + }; + + // First the underflow bin, separated by a vertical bar. + print(ROOT::Experimental::RBinIndex::Underflow()); + std::cout << '|'; + + // Now iterate the normal bins and print a '*' if the value is sufficiently large. + for (auto bin : axis.GetNormalRange()) { + print(bin); + } + + // Finally the overflow bin after a separating vertical bar. + std::cout << '|'; + print(ROOT::Experimental::RBinIndex::Overflow()); + std::cout << "\n"; + } +} + +void hist002_RHist_weighted() +{ + // Create an axis that can be used for multiple histograms. + ROOT::Experimental::RRegularAxis axis(40, {0.0, 20.0}); + + // Create two histograms, one of which will be filled with weighted entries. + ROOT::Experimental::RHist hist1({axis}); + ROOT::Experimental::RHist hist2({axis}); + + // Create a normal distribution with mean 10.0 and stddev 5.0. + std::mt19937 gen; + std::normal_distribution normal(10.0, 5.0); + for (std::size_t i = 0; i < 25000; i++) { + hist1.Fill(normal(gen)); + double value = normal(gen); + double weight = 0.2 + 0.008 * value * value; + hist2.Fill(value, ROOT::Experimental::RWeight(weight)); + } + + // "Draw" the histograms with ASCII characters. + std::cout << "hist1 with expected mean = " << normal.mean() << "\n"; + DrawHistogram(hist1); + std::cout << "\n"; + + std::cout << "hist2 with distorted normal distribution\n"; + DrawHistogram(hist2); + std::cout << "\n"; + + // Create and fill a third histogram with the special RBinWithError bin content type. + // In addition to the sum of weights, it tracks the sum of weights squared to compute the bin errors. + ROOT::Experimental::RHist hist3({axis}); + for (std::size_t i = 0; i < 25000; i++) { + double value = normal(gen); + double weight = 0.2 + 0.008 * value * value; + hist3.Fill(value, ROOT::Experimental::RWeight(weight)); + } + + // Visualize the computed bin errors with ASCII characters. + std::cout << "bin errors of hist3 (not to scale)\n"; + for (int row = 15; row > 0; row--) { + auto print = [&](ROOT::Experimental::RBinIndex bin) { + auto error = std::sqrt(hist3.GetBinContent(bin).fSum2); + static constexpr int Scale = 5; + std::cout << (error >= (row * Scale) ? '*' : ' '); + }; + + // First the underflow bin, separated by a vertical bar. + print(ROOT::Experimental::RBinIndex::Underflow()); + std::cout << '|'; + + // Now iterate the normal bins and print a '*' if the value is sufficiently large. + for (auto bin : axis.GetNormalRange()) { + print(bin); + } + + // Finally the overflow bin after a separating vertical bar. + std::cout << '|'; + print(ROOT::Experimental::RBinIndex::Overflow()); + std::cout << "\n"; + } +} diff --git a/tutorials/hist/histv7/index.md b/tutorials/hist/histv7/index.md index bfc59abdbc0d1..41c0ff469d9ea 100644 --- a/tutorials/hist/histv7/index.md +++ b/tutorials/hist/histv7/index.md @@ -1,4 +1,4 @@ -\defgroup tutorial_histv7 Histogram tutorials +\defgroup tutorial_histv7 RHist tutorials \ingroup tutorial_hist Examples demonstrating ROOT's histogram package. @@ -6,3 +6,4 @@ Examples demonstrating ROOT's histogram package. | **Tutorial** | **Description** | |---|---| | hist001_RHist_basics.C | Basics of RHist, including filling and adding them. | +| hist002_RHist_weighted.C | Weighted filling of RHist and RBinWithError bin content type. |