Logo ROOT   6.18/05
Reference Guide
imt101_parTreeProcessing.C
Go to the documentation of this file.
1/// \file
2/// \ingroup tutorial_multicore
3/// \notebook
4/// Illustrate the usage of the TTreeProcessorMT::Process method.
5/// Such method provides an implicit parallelisation of the reading and processing of a TTree.
6/// In particular, when invoking Process, the user provides a function that iterates on a subrange
7/// of the tree via a TTreeReader. Multiple tasks will be spawned, one for each sub-range, so that
8/// the processing of the tree is parallelised. Since two invocations of the user function can
9/// potentially run in parallel, the function code must be thread safe.
10/// The example also introduces a new class, ROOT::TThreadedObject, which makes objects
11/// thread private. With the help of this class, histograms can be filled safely inside the
12/// user function and then merged at the end to get the final result.
13///
14/// \macro_code
15///
16/// \date 26/09/2016
17/// \author Enric Tejedor
18
19int imt101_parTreeProcessing()
20{
21 // First enable implicit multi-threading globally, so that the implicit parallelisation is on.
22 // The parameter of the call specifies the number of threads to use.
23 int nthreads = 4;
24 ROOT::EnableImplicitMT(nthreads);
25
26 // Create one TThreadedObject per histogram to fill during the processing of the tree
27 ROOT::TThreadedObject<TH1F> ptHist("pt_dist", "p_{T} Distribution;p_{T};dN/p_{T}dp_{T}", 100, 0, 5);
28 ROOT::TThreadedObject<TH1F> pzHist("pz_dist", "p_{Z} Distribution;p_{Z};dN/dp_{Z}", 100, 0, 5);
29 ROOT::TThreadedObject<TH2F> pxpyHist("px_py", "p_{X} vs p_{Y} Distribution;p_{X};p_{Y}", 100, -5., 5., 100, -5., 5.);
30
31 // Create a TTreeProcessorMT: specify the file and the tree in it
32 ROOT::TTreeProcessorMT tp("http://root.cern.ch/files/tp_process_imt.root", "events");
33
34 // Define the function that will process a subrange of the tree.
35 // The function must receive only one parameter, a TTreeReader,
36 // and it must be thread safe. To enforce the latter requirement,
37 // TThreadedObject histograms will be used.
38 auto myFunction = [&](TTreeReader &myReader) {
40
41 // For performance reasons, a copy of the pointer associated to this thread on the
42 // stack is used
43 auto myPtHist = ptHist.Get();
44 auto myPzHist = pzHist.Get();
45 auto myPxPyHist = pxpyHist.Get();
46
47 while (myReader.Next()) {
48 auto tracks = *tracksRV;
49 for (auto &&track : tracks) {
50 myPtHist->Fill(track.Pt(), 1. / track.Pt());
51 myPxPyHist->Fill(track.Px(), track.Py());
52
53 myPzHist->Fill(track.Pz());
54 }
55 }
56 };
57
58 // Launch the parallel processing of the tree
59 tp.Process(myFunction);
60
61 // Use the TThreadedObject::Merge method to merge the thread private histograms
62 // into the final result
63 auto ptHistMerged = ptHist.Merge();
64 auto pzHistMerged = pzHist.Merge();
65 auto pxpyHistMerged = pxpyHist.Merge();
66
67 return 0;
68}
A wrapper to make object instances thread private, lazily.
A class to process the entries of a TTree in parallel.
An interface for reading values stored in ROOT columnar datasets.
A simple, robust and fast interface to read values from ROOT columnar datasets such as TTree,...
Definition: TTreeReader.h:44
void EnableImplicitMT(UInt_t numthreads=0)
Enable ROOT's implicit multi-threading for all objects and methods that provide an internal paralleli...
Definition: TROOT.cxx:579
void tracks()
Definition: tracks.C:47