Skip to content

Commit 89d3471

Browse files
committed
[tutorials][hist] Refactor histogram tutorials to return void instead of TCanvas*
1 parent c4b3303 commit 89d3471

File tree

14 files changed

+204
-24
lines changed

14 files changed

+204
-24
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#pragma once
2+
3+
#include <string>
4+
5+
namespace CPyCppyy {
6+
namespace MyWrapper {
7+
std::string CreateCallbackWrapper(std::string);
8+
}
9+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import cppyy
2+
3+
cppyy.cppdef(
4+
r"""
5+
#include <utility>
6+
#include <iostream>
7+
#include <string>
8+
9+
void foo() { std::cout << "foo!\n";}
10+
11+
void bar(int a, float b) { std::cout << "bar(" << a << "," << b << ")\n"; }
12+
13+
template <typename T, typename U>
14+
void baz(T a, U b, std::string c) { std::cout << "baz(" << a << "," << b << ",\"" << c << "\")\n"; }
15+
16+
template<typename F, typename... Args>
17+
void dataframe_define_mock(F callable, Args&&... args) {
18+
callable(std::forward<Args>(args)...);
19+
}
20+
"""
21+
)
22+
23+
cppyy.gbl.dataframe_define_mock(cppyy.gbl.foo)
24+
cppyy.gbl.dataframe_define_mock(cppyy.gbl.bar, 42, 11.11)
25+
cppyy.gbl.dataframe_define_mock(cppyy.gbl.baz[int, float], 33, 101.101, "hello")
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import ROOT
2+
3+
a = ROOT.TH1D("", "", 5, 0., 1.)
4+
b = ROOT.TH1D("", "", 5, 0., 1.)
5+
ab = a + b
6+
print(ab)
7+
8+
c = ROOT.TH2D("", "", 5, 0., 1., 5, 0., 1.)
9+
d = ROOT.TH2D("", "", 5, 0., 1., 5, 0., 1.)
10+
cd = c + d
11+
print(cd)
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import ROOT
2+
import numpy as np
3+
4+
5+
def make_write_hist(entry: int) -> ROOT.TH1D:
6+
hname = f"h_{entry}"
7+
h = ROOT.TH1D(hname, hname, entry, 0, entry)
8+
h[...] = np.random.uniform(0, entry, entry)
9+
with ROOT.TFile.Open("bench_out/histos.root", "update") as f:
10+
f.WriteObject(h, hname)
11+
return h
12+
13+
rdf = ROOT.RDataFrame(10) \
14+
.Define("x", "(int)rdfentry_ + 1") \
15+
.Define("hist", make_write_hist, ["x"])
16+
17+
rdf.Display().Print()

tutorials/CMakeLists.txt

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -550,13 +550,6 @@ set(returncode_1 math/fit/fit2a.C
550550
visualisation/graphics/tmathtext.C visualisation/graphics/tmathtext2.C
551551
visualisation/graphs/gr106_exclusiongraph.C
552552
visualisation/graphs/gr016_struct.C
553-
hist/hist102_TH2_contour_list.C
554-
hist/hist006_TH1_bar_charts.C
555-
hist/hist037_TH2Poly_boxes.C
556-
hist/hist060_TH1_stats.C
557-
hist/hist014_TH1_cumulative.C
558-
hist/hist004_TH1_labels.C
559-
hist/hist036_TH2_labels.C
560553
analysis/tree/h1analysis.C
561554
math/chi2test.C
562555
math/r/SimpleFitting.C)
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import time
2+
3+
import matplotlib.pyplot as plt
4+
import numpy as np
5+
import ROOT
6+
7+
# ROOT.EnableImplicitMT()
8+
9+
@ROOT.Numba.Declare(['double', 'int'], 'double')
10+
def pypow_numba(x, y):
11+
return x**y
12+
13+
def pypow_cppyy(x: float, y: int) -> float:
14+
return x**y
15+
16+
def benchmark(N):
17+
rdf = ROOT.RDataFrame(N).Define("x", "(double)rdfentry_").Define("y", "2")
18+
19+
# cppyy version
20+
start_cppyy = time.perf_counter()
21+
rdf_cppyy = rdf.Define("pow_cppyy", pypow_cppyy, ["x", "y"])
22+
mean_cppyy = rdf_cppyy.Mean("pow_cppyy").GetValue()
23+
end_cppyy = time.perf_counter()
24+
25+
# Numba version
26+
start_numba = time.perf_counter()
27+
rdf_numba = rdf.Define("pow_numba", "Numba::pypow_numba(x, y)")
28+
mean_numba = rdf_numba.Mean("pow_numba").GetValue()
29+
end_numba = time.perf_counter()
30+
31+
return {
32+
"N": N,
33+
"mean_numba": mean_numba,
34+
"mean_cppyy": mean_cppyy,
35+
"time_numba": end_numba - start_numba,
36+
"time_cppyy": end_cppyy - start_cppyy,
37+
}
38+
39+
N_values = [10_000, 100_000, 1_000_000, 5_000_000, 10_000_000, 50_000_000, 100_000_000]
40+
results = [benchmark(N) for N in N_values]
41+
42+
print("Résultats :)")
43+
print(f"{'N':>10} | {'Numba time (s)':>15} | {'cppyy time (s)':>15} | {'cppyy speedup':>15} | {'Δ Mean':>10}")
44+
print("-" * 75)
45+
for r in results[1:]:
46+
mean_diff = abs(r["mean_numba"] - r["mean_cppyy"])
47+
cppyy_speedup = r["time_numba"] / r["time_cppyy"] if r["time_cppyy"] > 0 else float('inf')
48+
print(f"{r['N']:>10} | {r['time_numba']:>15.3f} | {r['time_cppyy']:>15.3f} | {cppyy_speedup:>15.2f} | {mean_diff:>10.5f}")
49+
50+
51+
plt.figure(figsize=(7,5))
52+
plt.plot(N_values, [r["time_numba"] for r in results], "-o", label="Numba")
53+
plt.plot(N_values, [r["time_cppyy"] for r in results], "-o", label="cppyy")
54+
55+
plt.xlabel("Number of entries")
56+
plt.ylabel("Execution time (s)")
57+
plt.title("RDataFrame Define(): Numba vs cppyy")
58+
plt.legend()
59+
plt.grid(True)
60+
plt.savefig("/home/siliataider/Documents/root/bench_out/benchmark_numba_vs_cppyy.png")
61+
plt.show()
62+
63+
# N = 5_000_000
64+
# rdf = ROOT.RDataFrame(N).Define("x", "(double)rdfentry_").Define("y", "2.0")
65+
66+
# # --- Numba version --------------------------------------------------------
67+
# @ROOT.Numba.Declare(['double', 'int'], 'double')
68+
# def pypow_numba(x, y):
69+
# return x**y
70+
71+
# start_numba = time.perf_counter()
72+
73+
# rdf_numba = rdf.Define("pow_numba", "Numba::pypow_numba(x, y)")
74+
# mean_numba = rdf_numba.Mean("pow_numba").GetValue()
75+
76+
# end_numba = time.perf_counter()
77+
78+
# print(f"[Numba] Mean: {mean_numba:.5f}, time: {end_numba - start_numba:.3f} s")
79+
80+
# # --- cppyy version --------------------------------------------------------
81+
# def pypow_cppyy(x: float, y: int) -> float:
82+
# return x**y
83+
84+
# start_cppyy = time.perf_counter()
85+
86+
# rdf_cppyy = rdf.Define("pow_cppyy", pypow_cppyy, ["x", "y"])
87+
# mean_cppyy = rdf_cppyy.Mean("pow_cppyy").GetValue()
88+
89+
# end_cppyy = time.perf_counter()
90+
91+
# print(f"[cppyy] Mean: {mean_cppyy:.5f}, time: {end_cppyy - start_cppyy:.3f} s")
92+
93+
94+
95+
import ROOT
96+
97+
ROOT.gInterpreter.Declare("""
98+
#include <ROOT/RVec.hxx>
99+
using namespace ROOT::VecOps;
100+
101+
template <typename T>
102+
struct SquareVecT {
103+
RVec<T> operator()(const RVec<T>& xvec) const {
104+
return xvec * xvec;
105+
}
106+
};
107+
""")
108+
109+
square_vec_int = ROOT.SquareVecT[int]()
110+
rdf = ROOT.RDataFrame(3) \
111+
.Define("xvec", "ROOT::VecOps::RVec{(int)rdfentry_, (int)rdfentry_ + 1, (int)rdfentry_ + 2}") \
112+
.Define("squared_xvec", square_vec_int, ["xvec"])

tutorials/hist/hist004_TH1_labels.C

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
/// \date November 2024
1212
/// \author Rene Brun
1313

14-
TCanvas *hist004_TH1_labels()
14+
void hist004_TH1_labels()
1515
{
1616
// Create the histogram
1717
const std::array people{"Jean", "Pierre", "Marie", "Odile", "Sebastien", "Fons", "Rene",
@@ -56,6 +56,4 @@ TCanvas *hist004_TH1_labels()
5656
pt->AddText(" \">\" to sort by decreasing values");
5757
pt->AddText(" \"<\" to sort by increasing values");
5858
pt->Draw();
59-
60-
return c1;
6159
}

tutorials/hist/hist006_TH1_bar_charts.C

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
/// \date November 2024
1010
/// \author Rene Brun
1111

12-
TCanvas *hist006_TH1_bar_charts()
12+
void hist006_TH1_bar_charts()
1313
{
1414
// Try to open first the file cernstaff.root in tutorials/io/tree directory
1515
TString filedir = gROOT->GetTutorialDir();
@@ -88,6 +88,4 @@ TCanvas *hist006_TH1_bar_charts()
8888
legend->Draw();
8989

9090
c1->cd();
91-
92-
return c1;
9391
}

tutorials/hist/hist014_TH1_cumulative.C

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
#include "TCanvas.h"
1818
#include "TRandom.h"
1919

20-
TCanvas *hist014_TH1_cumulative()
20+
void hist014_TH1_cumulative()
2121
{
2222
TH1 *h = new TH1D("h", "h", 100, -5., 5.);
2323
gRandom->SetSeed();
@@ -37,6 +37,4 @@ TCanvas *hist014_TH1_cumulative()
3737
c->cd(2);
3838
hc->Draw();
3939
c->Update();
40-
41-
return c;
4240
}

tutorials/hist/hist036_TH2_labels.C

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
/// \date July 2016
1010
/// \author Rene Brun
1111

12-
TCanvas *hist036_TH2_labels()
12+
void hist036_TH2_labels()
1313
{
1414
const Int_t nx = 12;
1515
const Int_t ny = 20;
@@ -44,5 +44,4 @@ TCanvas *hist036_TH2_labels()
4444
pt->AddText(" \">\" to sort by decreasing values");
4545
pt->AddText(" \"<\" to sort by increasing values");
4646
pt->Draw();
47-
return c1;
4847
}

0 commit comments

Comments
 (0)