Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
ntpl015_processor_join.C
Go to the documentation of this file.
1/// \file
2/// \ingroup tutorial_ntuple
3/// \notebook
4/// Demonstrate the RNTupleProcessor for horizontal compositions (joins) of RNTuples
5///
6/// \macro_image
7/// \macro_code
8///
9/// \date November 2024
10/// \author The ROOT Team
11
12// NOTE: The RNTupleProcessor and related classes are experimental at this point.
13// Functionality and interface are still subject to changes.
14
15#include <ROOT/RNTupleModel.hxx>
18
19#include <TCanvas.h>
20#include <TH1F.h>
21#include <TRandom.h>
22
23// Import classes from the `Experimental` namespace for the time being.
25
26const std::string kPrimaryNTupleName = "mainNTuple";
27const std::string kMainNTuplePath = "main_ntuple.root";
28const std::string kAuxNTupleName = "auxNTuple";
29const std::string kAuxNTuplePath = "aux_ntuple.root";
30
31// Number of events to generate for the auxiliary ntuple. The primary ntuple will have a fifth of this number.
32constexpr int kNEvents = 10000;
33
34void WritePrimary(std::string_view ntupleName, std::string_view ntupleFileName)
35{
37
38 auto fldI = model->MakeField<std::uint32_t>("i");
39 auto fldVpx = model->MakeField<float>("vpx");
40
41 auto writer = ROOT::RNTupleWriter::Recreate(std::move(model), ntupleName, ntupleFileName);
42
43 // The primary ntuple only contains a subset of the entries present in the auxiliary ntuple.
44 for (int i = 0; i < kNEvents; i += 5) {
45 *fldI = i;
46 *fldVpx = gRandom->Gaus();
47
48 writer->Fill();
49 }
50
51 std::cout << "Wrote " << writer->GetNEntries() << " to the primary RNTuple" << std::endl;
52}
53
54void WriteAux(std::string_view ntupleName, std::string_view ntupleFileName)
55{
57
58 auto fldI = model->MakeField<std::uint32_t>("i");
59 auto fldVpy = model->MakeField<float>("vpy");
60
61 auto writer = ROOT::RNTupleWriter::Recreate(std::move(model), ntupleName, ntupleFileName);
62
63 for (int i = 0; i < kNEvents; ++i) {
64 *fldI = i;
65 *fldVpy = gRandom->Gaus();
66
67 writer->Fill();
68 }
69
70 std::cout << "Wrote " << writer->GetNEntries() << " to the auxiliary RNTuple" << std::endl;
71}
72
73void Read()
74{
75 auto c = new TCanvas("c", "RNTupleJoinProcessor Example", 200, 10, 700, 500);
76 TH1F hPy("h", "This is the px + py distribution", 100, -4, 4);
77 hPy.SetFillColor(48);
78
79 // The first specified ntuple is the primary ntuple and will be used to drive the processor loop. The subsequent
80 // list of ntuples (in this case, only one) are auxiliary and will be joined with the entries from the primary
81 // ntuple. We specify field "i" as the join field. This field, which should be present in all ntuples specified is
82 // used to identify which entries belong together. Multiple join fields can be specified, in which case the
83 // combination of field values is used. It is possible to specify up to 4 join fields. Providing an empty list of
84 // join fields signals to the processor that all entries are aligned.
85 auto processor =
86 CreateRNTupleJoinProcessor({kPrimaryNTupleName, kMainNTuplePath}, {kAuxNTupleName, kAuxNTuplePath}, {"i"});
87
88 // Access to the processor's fields is done by first requesting them through RNTupleProcessor::RequestField(). The
89 // returned value can be used to read the current entry's value for that particular field. Fields from the primary
90 // ntuple are requested by their original name.
91 auto px = processor->RequestField<float>("vpx");
92 // Fields from auxiliary ntuples are requested by prepending the name of the auxiliary ntuple.
93 auto py = processor->RequestField<float>(kAuxNTupleName + ".vpy");
94
95 // The iterator value gives access to the the current entry to process.
96 for (const auto &idx : *processor) {
97 // Load the entry.
98 processor->LoadEntry(idx);
99 hPy.Fill(*px + *py);
100 }
101
102 std::cout << "Processed a total of " << processor->GetNEntriesProcessed() << " entries" << std::endl;
103
104 hPy.DrawCopy();
105}
106
107void ntpl015_processor_join()
108{
109 WritePrimary(kPrimaryNTupleName, kMainNTuplePath);
110 WriteAux(kAuxNTupleName, kAuxNTuplePath);
111
112 Read();
113}
#define c(i)
Definition RSha256.hxx:101
R__EXTERN TRandom * gRandom
Definition TRandom.h:73
static std::unique_ptr< RNTupleModel > Create()
static std::unique_ptr< RNTupleWriter > Recreate(std::unique_ptr< ROOT::RNTupleModel > model, std::string_view ntupleName, std::string_view storage, const ROOT::RNTupleWriteOptions &options=ROOT::RNTupleWriteOptions())
Creates an RNTupleWriter backed by storage, overwriting it if one with the same URI exists.
The Canvas class.
Definition TCanvas.h:23
1-D histogram with a float per channel (see TH1 documentation)
Definition TH1.h:878
virtual Double_t Gaus(Double_t mean=0, Double_t sigma=1)
Samples a random number from the standard Normal (Gaussian) Distribution with the given mean and sigm...
Definition TRandom.cxx:274
std::unique_ptr< RNTupleProcessor > CreateRNTupleJoinProcessor(RNTupleInputSpec primaryNTuple, RNTupleInputSpec auxNTuple, const std::vector< std::string > &joinFields, const RNTupleProcessorOptions &opts=RNTupleProcessorOptions())
Create an RNTupleProcessor for a join (i.e., a horizontal combination) of RNTuples.