Skip to content

Commit c3cd628

Browse files
MehkaanKhanvepadulano
authored andcommitted
Address review: self-contained data, clearer naming, no leaked TCanvas
Replace the cernstaff.root/tree500_cernbuild.C dependency with a small writeData() helper that generates a synthetic categorical column via RDataFrame::Define + Snapshot, removing the need to explain classic char[] branch handling, which was out of scope for this tutorial. Rename AlphaNumHist's TH1D member and the RResultPtr variable from the terse 'h' to 'histo'/'result' for readability, and replace the raw 'new TCanvas' with a std::unique_ptr<TCanvas> to avoid showing a leak in a user-facing tutorial. Addresses review comments from vepadulano on PR #22802.
1 parent 7acc8c5 commit c3cd628

1 file changed

Lines changed: 30 additions & 40 deletions

File tree

Lines changed: 30 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,12 @@
11
/// \file
22
/// \ingroup tutorial_dataframe
33
/// \notebook
4-
/// Fill and draw a bar chart from a categorical/string column with RDataFrame.
4+
/// Fill and draw a bar chart from a categorical column with RDataFrame.
55
///
66
/// RDataFrame has no dedicated action for categorical/string columns, but the
77
/// generic RDataFrame::Fill() action can fill any user-provided object that
88
/// exposes Fill() and Merge() methods. This shows how to use it to build and
9-
/// draw a bar chart from a string column, reusing the "Nation" column of the
10-
/// classic CERN staff dataset also used in hist006_TH1_bar_charts.C.
11-
///
12-
/// Classic ROOT trees often store short strings in fixed-size char[] branches
13-
/// (leaf type "C"), which RDataFrame reads as ROOT::VecOps::RVec<char> rather
14-
/// than std::string. A one-line Define() converts such a column into a real
15-
/// std::string column before filling.
9+
/// draw a bar chart from a string column.
1610
///
1711
/// \macro_image
1812
/// \macro_code
@@ -27,55 +21,51 @@
2721
// const char*, so RDataFrame can't call it directly on a plain TH1D. Wrapping
2822
// it in a class with our own Fill(const std::string&) sidesteps both issues.
2923
struct AlphaNumHist {
30-
TH1D h;
24+
TH1D histo;
3125

32-
AlphaNumHist(const char *name, const char *title) : h(name, title, 1, 0, 1)
26+
AlphaNumHist(const char *name, const char *title) : histo(name, title, 1, 0, 1)
3327
{
34-
h.GetXaxis()->SetAlphanumeric(true);
35-
h.SetCanExtend(TH1::kAllAxes);
28+
histo.GetXaxis()->SetAlphanumeric(true);
29+
histo.SetCanExtend(TH1::kAllAxes);
3630
}
3731

38-
void Fill(const std::string &s) { h.Fill(s.c_str(), 1.); }
32+
void Fill(const std::string &s) { histo.Fill(s.c_str(), 1.); }
3933

4034
// Required so RDataFrame can merge partial per-slot results when run with
4135
// implicit multi-threading enabled.
4236
void Merge(const std::vector<AlphaNumHist *> &others)
4337
{
4438
TList l;
4539
for (auto *o : others)
46-
l.Add(&o->h);
47-
h.Merge(&l);
40+
l.Add(&o->histo);
41+
histo.Merge(&l);
4842
}
4943
};
5044

51-
void df041_alphanumericHistograms()
45+
void writeData(std::string_view datasetName, std::string_view fileName)
5246
{
53-
// Reuse the same "cernstaff.root" dataset as hist006_TH1_bar_charts.C,
54-
// generating it first if it doesn't already exist.
55-
TString filedir = gROOT->GetTutorialDir();
56-
filedir += TString("/io/tree/");
57-
TString filename = "cernstaff.root";
58-
bool fileNotFound = gSystem->AccessPathName(filename);
59-
if (fileNotFound) {
60-
TString macroName = filedir + "tree500_cernbuild.C";
61-
if (!gInterpreter->IsLoaded(macroName))
62-
gInterpreter->LoadMacro(macroName);
63-
gROOT->ProcessLineFast("tree500_cernbuild()");
64-
}
47+
std::random_device rd;
48+
std::mt19937 gen{rd()};
49+
std::uniform_int_distribution<int> distrib{0, 2};
6550

66-
ROOT::RDataFrame df0("T", filename.Data());
51+
const std::vector<std::string> colours{"RED", "GREEN", "BLUE"};
52+
53+
ROOT::RDataFrame df{100};
54+
df.Define("colour", [&]() { return colours[distrib(gen)]; }).Snapshot(datasetName, fileName);
55+
}
56+
57+
auto canvas = std::make_unique<TCanvas>("c");
58+
59+
void df041_alphanumericHistograms()
60+
{
61+
writeData("tree", "df041_alphanumericHistograms.root");
6762

68-
// "Nation" is a classic char[] branch, read by RDataFrame as
69-
// ROOT::VecOps::RVec<char>. Converting it to a real std::string column
70-
// makes it fillable through the AlphaNumHist adapter above.
71-
auto df = df0.Define("NationStr", [](const ROOT::VecOps::RVec<char> &c) { return std::string(c.begin(), c.end()); },
72-
{"Nation"});
63+
ROOT::RDataFrame df("tree", "df041_alphanumericHistograms.root");
7364

74-
AlphaNumHist model("hNation", "Staff by nation;Nation;Count");
75-
auto h = df.Fill<std::string>(model, {"NationStr"});
76-
h->h.LabelsDeflate("X");
65+
AlphaNumHist model("hColour", "Entries by colour;Colour;Count");
66+
auto result = df.Fill<std::string>(model, {"colour"});
67+
result->histo.LabelsDeflate("X");
7768

78-
auto c1 = new TCanvas("c1", "Bar chart from RDataFrame", 700, 500);
79-
h->h.SetFillColor(45);
80-
h->h.DrawCopy("bar2");
69+
result->histo.SetFillColor(45);
70+
result->histo.DrawCopy("bar2");
8171
}

0 commit comments

Comments
 (0)