21#include <ROOT/RNTuple.hxx>
46constexpr char const *kNTupleFileName =
"ntpl007_mtFill.root";
49constexpr int kNWriterThreads = 4;
52constexpr int kNEventsPerThread = 25000;
55void FillData(std::unique_ptr<REntry> entry, RNTupleWriter *ntuple) {
57 static std::mutex gLock;
59 static std::atomic<std::uint32_t> gThreadId;
60 const auto threadId = ++gThreadId;
62 auto prng = std::make_unique<TRandom3>();
65 auto id = entry->Get<std::uint32_t>(
"id");
66 auto vpx = entry->Get<std::vector<float>>(
"vpx");
67 auto vpy = entry->Get<std::vector<float>>(
"vpy");
68 auto vpz = entry->Get<std::vector<float>>(
"vpz");
70 for (
int i = 0; i < kNEventsPerThread; i++) {
76 int npx =
static_cast<int>(prng->Rndm(1) * 15);
78 for (
int j = 0; j < npx; ++j) {
83 vpx->emplace_back(px);
84 vpy->emplace_back(py);
85 vpz->emplace_back(pz);
88 std::lock_guard<std::mutex> guard(gLock);
97 auto model = RNTupleModel::Create();
98 model->MakeField<std::uint32_t>(
"id");
99 model->MakeField<std::vector<float>>(
"vpx");
100 model->MakeField<std::vector<float>>(
"vpy");
101 model->MakeField<std::vector<float>>(
"vpz");
104 auto ntuple = RNTupleWriter::Recreate(std::move(model),
"NTuple", kNTupleFileName);
106 std::vector<std::unique_ptr<REntry>> entries;
107 std::vector<std::thread> threads;
108 for (
int i = 0; i < kNWriterThreads; ++i)
109 entries.emplace_back(ntuple->CreateEntry());
110 for (
int i = 0; i < kNWriterThreads; ++i)
111 threads.emplace_back(FillData, std::move(entries[i]), ntuple.get());
112 for (
int i = 0; i < kNWriterThreads; ++i)
123 auto ntuple = RNTupleReader::Open(
"NTuple", kNTupleFileName);
125 auto viewVpx = ntuple->GetView<
float>(
"vpx._0");
129 TCanvas *
c1 =
new TCanvas(
"c2",
"Multi-Threaded Filling Example", 200, 10, 1500, 500);
133 TH1F h(
"h",
"This is the px distribution", 100, -4, 4);
136 for (
auto i : viewVpx.GetFieldRange())
142 auto nEvents = ntuple->GetNEntries();
143 auto viewId = ntuple->GetView<std::uint32_t>(
"id");
144 TH2F hFillSequence(
"",
"Entry Id vs Thread Id;Entry Sequence Number;Filling Thread",
145 100, 0, nEvents, 100, 0, kNWriterThreads);
146 for (
auto i : ntuple->GetEntryRange())
147 hFillSequence.Fill(i, viewId(i));
148 hFillSequence.DrawCopy();
#define R__LOAD_LIBRARY(LIBRARY)
R__EXTERN TStyle * gStyle
The REntry is a collection of values in an ntuple corresponding to a complete row in the data set.
The RNTupleModel encapulates the schema of an ntuple.
An RNTuple that is used to read data from storage.
An RNTuple that gets filled with entries (data) and writes them to storage.
1-D histogram with a float per channel (see TH1 documentation)}
2-D histogram with a float per channel (see TH1 documentation)}
void SetOptStat(Int_t stat=1)
The type of information printed in the histogram statistics box can be selected via the parameter mod...
void FillData(BinData &dv, const TH1 *hist, TF1 *func=nullptr)
fill the data vector from a TH1.