From f692e72c53cb7ec2d8ba86bd2b8bd4f1cbb6226f Mon Sep 17 00:00:00 2001 From: Jonas Hahnfeld Date: Wed, 24 Sep 2025 13:40:05 +0200 Subject: [PATCH] [hist] Add first basic tutorial --- tutorials/CMakeLists.txt | 2 +- tutorials/hist/histv7/hist001_RHist_basics.C | 92 ++++++++++++++++++++ tutorials/hist/histv7/index.md | 8 ++ 3 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 tutorials/hist/histv7/hist001_RHist_basics.C create mode 100644 tutorials/hist/histv7/index.md diff --git a/tutorials/CMakeLists.txt b/tutorials/CMakeLists.txt index 609d740a3516b..f513769a29848 100644 --- a/tutorials/CMakeLists.txt +++ b/tutorials/CMakeLists.txt @@ -410,7 +410,7 @@ else() if(MSVC AND NOT win_broken_tests) list(APPEND root7_veto analysis/dataframe/df013_InspectAnalysis.C) endif() - file(GLOB v7_veto_files RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/ visualisation/webgui/browserv7/*.cxx visualisation/webgui/fitpanelv7/*.cxx visualisation/rcanvas/*.py visualisation/rcanvas/*.cxx) + file(GLOB v7_veto_files RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/ hist/histv7/*.C visualisation/webgui/browserv7/*.cxx visualisation/webgui/fitpanelv7/*.cxx visualisation/rcanvas/*.py visualisation/rcanvas/*.cxx) list(APPEND root7_veto ${v7_veto_files}) # This depends on RCanvas list(APPEND root7_veto io/ntuple/ntpl011_global_temperatures.C) diff --git a/tutorials/hist/histv7/hist001_RHist_basics.C b/tutorials/hist/histv7/hist001_RHist_basics.C new file mode 100644 index 0000000000000..78121cf2e93e5 --- /dev/null +++ b/tutorials/hist/histv7/hist001_RHist_basics.C @@ -0,0 +1,92 @@ +/// \file +/// \ingroup tutorial_histv7 +/// +/// Basics of RHist, including filling and adding them. +/// +/// \macro_code +/// +/// \date September 2025 +/// \author The ROOT Team + +#include +#include +#include + +#include +#include +#include +#include + +// It is currently not possible to directly draw RHist's, 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 = 10; + 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 hist001_RHist_basics() +{ + // Create an axis that can be used for multiple histograms. + ROOT::Experimental::RRegularAxis axis(40, 0, 20); + + // Create a first histograms and fill with random values. + ROOT::Experimental::RHist hist1({axis}); + + // Create a normal distribution with mean 5.0 and stddev 2.0. + std::mt19937 gen; + std::normal_distribution normal1(5.0, 2.0); + for (std::size_t i = 0; i < 1000; i++) { + hist1.Fill(normal1(gen)); + } + + // "Draw" the histogram with ASCII characters. + std::cout << "hist1 with expected mean = " << normal1.mean() << "\n"; + DrawHistogram(hist1); + std::cout << "\n"; + + // Create a second histogram and fill with random values of a different distribution. + ROOT::Experimental::RHist hist2({axis}); + std::normal_distribution normal2(13.0, 4.0); + for (std::size_t i = 0; i < 1500; i++) { + hist2.Fill(normal2(gen)); + } + std::cout << "hist2 with expected mean = " << normal2.mean() << "\n"; + DrawHistogram(hist2); + std::cout << "\n"; + + // Create a third, merged histogram from the two previous two. + ROOT::Experimental::RHist hist3({axis}); + hist3.Add(hist1); + hist3.Add(hist2); + std::cout << "hist3 with expected entries = " << (hist1.GetNEntries() + hist2.GetNEntries()) << "\n"; + DrawHistogram(hist3); +} diff --git a/tutorials/hist/histv7/index.md b/tutorials/hist/histv7/index.md new file mode 100644 index 0000000000000..bfc59abdbc0d1 --- /dev/null +++ b/tutorials/hist/histv7/index.md @@ -0,0 +1,8 @@ +\defgroup tutorial_histv7 Histogram tutorials +\ingroup tutorial_hist + +Examples demonstrating ROOT's histogram package. + +| **Tutorial** | **Description** | +|---|---| +| hist001_RHist_basics.C | Basics of RHist, including filling and adding them. |