Skip to content

Commit a1c112f

Browse files
enirolfdpiparo
authored andcommitted
[ntuple] Update tutorials
1 parent 197c850 commit a1c112f

File tree

2 files changed

+37
-37
lines changed

2 files changed

+37
-37
lines changed

tutorials/io/ntuple/ntpl012_processor_chain.C

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -64,28 +64,26 @@ void Read(const std::vector<RNTupleOpenSpec> &ntuples)
6464
TH1F hPx("h", "This is the px distribution", 100, -4, 4);
6565
hPx.SetFillColor(48);
6666

67-
auto model = ROOT::RNTupleModel::Create();
68-
auto ptrPx = model->MakeField<std::vector<float>>("vpx");
69-
70-
// By passing a model to the processor, we can use the pointers to field values created upon model creation during
71-
// processing. When no model is provided, a default model is created based on the first ntuple specified.
72-
// Access to the entry values in this case can be achieved through RNTupleProcessor::GetEntry() or through its
73-
// iterator.
74-
auto processor = RNTupleProcessor::CreateChain(ntuples, std::move(model));
67+
// The chain-based processor can be created by passing a list of RNTupleOpenSpecs, describing the name and location
68+
// of each ntuple in the chain.
69+
auto processor = RNTupleProcessor::CreateChain(ntuples);
7570
int prevProcessorNumber{-1};
7671

77-
for (const auto &entry : *processor) {
78-
// The RNTupleProcessor provides some additional bookkeeping information. The local entry number is reset each
79-
// a new ntuple in the chain is opened for processing.
72+
// Access to the processor's fields is done by first requesting them through RNTupleProcessor::RequestField(). The
73+
// returned value can be used to read the current entry's value for that particular field.
74+
auto px = processor->RequestField<std::vector<float>>("vpx");
75+
76+
// The iterator value is the index of the current entry being processed.
77+
for (auto idx : *processor) {
78+
// The RNTupleProcessor provides some additional bookkeeping information, such as the current processor number.
8079
if (static_cast<int>(processor->GetCurrentProcessorNumber()) > prevProcessorNumber) {
8180
prevProcessorNumber = processor->GetCurrentProcessorNumber();
82-
std::cout << "Processing `ntuple" << prevProcessorNumber + 1 << "` (" << processor->GetNEntriesProcessed()
81+
std::cout << "Processing `ntuple" << prevProcessorNumber + 1 << "` (" << idx + 1
8382
<< " total entries processed so far)" << std::endl;
8483
}
8584

86-
// We can use the pointer to the field obtained while creating our model to read the field's data for the current
87-
// entry.
88-
for (auto x : *ptrPx) {
85+
// We use the value returned from requesting the field to read its data for the current entry.
86+
for (auto x : *px) {
8987
hPx.Fill(x);
9088
}
9189
}

tutorials/io/ntuple/ntpl015_processor_join.C

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,15 @@
2424
using ROOT::Experimental::RNTupleOpenSpec;
2525
using ROOT::Experimental::RNTupleProcessor;
2626

27-
const std::string kMainNTupleName = "mainNTuple";
27+
const std::string kPrimaryNTupleName = "mainNTuple";
2828
const std::string kMainNTuplePath = "main_ntuple.root";
2929
const std::string kAuxNTupleName = "auxNTuple";
3030
const std::string kAuxNTuplePath = "aux_ntuple.root";
3131

32-
// Number of events to generate for the auxiliary ntuple. The main ntuple will have a fifth of this number.
32+
// Number of events to generate for the auxiliary ntuple. The primary ntuple will have a fifth of this number.
3333
constexpr int kNEvents = 10000;
3434

35-
void WriteMain(std::string_view ntupleName, std::string_view ntupleFileName)
35+
void WritePrimary(std::string_view ntupleName, std::string_view ntupleFileName)
3636
{
3737
auto model = ROOT::RNTupleModel::Create();
3838

@@ -41,15 +41,15 @@ void WriteMain(std::string_view ntupleName, std::string_view ntupleFileName)
4141

4242
auto writer = ROOT::RNTupleWriter::Recreate(std::move(model), ntupleName, ntupleFileName);
4343

44-
// The main ntuple only contains a subset of the entries present in the auxiliary ntuple.
44+
// The primary ntuple only contains a subset of the entries present in the auxiliary ntuple.
4545
for (int i = 0; i < kNEvents; i += 5) {
4646
*fldI = i;
4747
*fldVpx = gRandom->Gaus();
4848

4949
writer->Fill();
5050
}
5151

52-
std::cout << "Wrote " << writer->GetNEntries() << " to the main RNTuple" << std::endl;
52+
std::cout << "Wrote " << writer->GetNEntries() << " to the primary RNTuple" << std::endl;
5353
}
5454

5555
void WriteAux(std::string_view ntupleName, std::string_view ntupleFileName)
@@ -77,23 +77,25 @@ void Read()
7777
TH1F hPy("h", "This is the px + py distribution", 100, -4, 4);
7878
hPy.SetFillColor(48);
7979

80-
// The first specified ntuple is the main ntuple and will be used to drive the processor loop. The subsequent
81-
// list of ntuples (in this case, only one) are auxiliary and will be joined with the entries from the main ntuple.
82-
// We specify field "i" as the join field. This field, which should be present in all ntuples specified is used to
83-
// identify which entries belong together. Multiple join fields can be specified, in which case the combination of
84-
// field values is used. It is possible to specify up to 4 join fields. Providing an empty list of join fields
85-
// signals to the processor that all entries are aligned.
80+
// The first specified ntuple is the primary ntuple and will be used to drive the processor loop. The subsequent
81+
// list of ntuples (in this case, only one) are auxiliary and will be joined with the entries from the primary
82+
// ntuple. We specify field "i" as the join field. This field, which should be present in all ntuples specified is
83+
// used to identify which entries belong together. Multiple join fields can be specified, in which case the
84+
// combination of field values is used. It is possible to specify up to 4 join fields. Providing an empty list of
85+
// join fields signals to the processor that all entries are aligned.
8686
auto processor =
87-
RNTupleProcessor::CreateJoin({kMainNTupleName, kMainNTuplePath}, {kAuxNTupleName, kAuxNTuplePath}, {"i"});
88-
89-
float px, py;
90-
for (const auto &entry : *processor) {
91-
// Fields from the main ntuple are accessed by their original name.
92-
px = *entry.GetPtr<float>("vpx");
93-
// Fields from auxiliary ntuples are accessed by prepending the name of the auxiliary ntuple.
94-
py = *entry.GetPtr<float>(kAuxNTupleName + ".vpy");
95-
96-
hPy.Fill(px + py);
87+
RNTupleProcessor::CreateJoin({kPrimaryNTupleName, kMainNTuplePath}, {kAuxNTupleName, kAuxNTuplePath}, {"i"});
88+
89+
// Access to the processor's fields is done by first requesting them through RNTupleProcessor::RequestField(). The
90+
// returned value can be used to read the current entry's value for that particular field. Fields from the primary
91+
// ntuple are requested by their original name.
92+
auto px = processor->RequestField<float>("vpx");
93+
// Fields from auxiliary ntuples are requested by prepending the name of the auxiliary ntuple.
94+
auto py = processor->RequestField<float>(kAuxNTupleName + ".vpy");
95+
96+
// The iterator value is the index of the current entry being processed. In this example, we don't use it.
97+
for (auto _ : *processor) {
98+
hPy.Fill(*px + *py);
9799
}
98100

99101
std::cout << "Processed a total of " << processor->GetNEntriesProcessed() << " entries" << std::endl;
@@ -103,7 +105,7 @@ void Read()
103105

104106
void ntpl015_processor_join()
105107
{
106-
WriteMain(kMainNTupleName, kMainNTuplePath);
108+
WritePrimary(kPrimaryNTupleName, kMainNTuplePath);
107109
WriteAux(kAuxNTupleName, kAuxNTuplePath);
108110

109111
Read();

0 commit comments

Comments
 (0)