Skip to content

Commit db62b94

Browse files
amadiodpiparo
authored andcommitted
Add a tutorial for TBufferMerger
1 parent 7cae62c commit db62b94

File tree

1 file changed

+69
-0
lines changed

1 file changed

+69
-0
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/// \file
2+
/// \ingroup tutorial_multicore
3+
///
4+
/// Fill an Ntuple in distinct workers, and write the output to a file.
5+
/// This tutorial illustrates the basics of how it's possible with ROOT
6+
/// to write simultaneously to a single output file using TBufferMerger.
7+
///
8+
/// \macro_code
9+
///
10+
/// \author Guilherme Amadio
11+
/// \date May 2017
12+
13+
#include <ROOT/TBufferMerger.hxx>
14+
15+
using ROOT::Experimental::TBufferMerger;
16+
using ROOT::Experimental::TBufferMergerFile;
17+
18+
#include <random>
19+
#include <thread>
20+
21+
// A simple function to fill the ntuple with random values
22+
void fill(TNtuple &ntuple, size_t n)
23+
{
24+
std::random_device rd;
25+
std::default_random_engine rng(rd());
26+
std::normal_distribution<double> dist(0.0, 1.0);
27+
28+
auto gaussian_random = [&]() { return dist(rng); };
29+
30+
for (auto i : ROOT::TSeqI(n)) ntuple.Fill(gaussian_random());
31+
}
32+
33+
void mt103_fillNtuples()
34+
{
35+
// Avoid unnecessary output
36+
gROOT->SetBatch();
37+
38+
// Make ROOT thread-safe
39+
ROOT::EnableThreadSafety();
40+
41+
// Total number of events
42+
const size_t nEvents = 65535;
43+
44+
// Match number of threads to what the hardware can do
45+
const size_t nWorkers = std::thread::hardware_concurrency();
46+
47+
// Split work in equal parts
48+
const size_t nEventsPerWorker = nEvents / nWorkers;
49+
50+
// Create the TBufferMerger
51+
TBufferMerger merger("mp103_fillNtuple.root");
52+
53+
// Define what each worker will do
54+
auto work_function = [&]() {
55+
auto f = merger.GetFile();
56+
TNtuple ntrand("ntrand", "Random Numbers", "r");
57+
fill(ntrand, nEventsPerWorker);
58+
ntrand.Write();
59+
f->Write();
60+
};
61+
62+
// Create worker threads
63+
std::vector<std::thread> workers;
64+
65+
for (auto i : ROOT::TSeqI(nWorkers)) workers.emplace_back(work_function);
66+
67+
// Make sure workers are done
68+
for (auto &&worker : workers) worker.join();
69+
}

0 commit comments

Comments
 (0)