RNTupleしたい

 1#include <ROOT/RNTuple.hxx>
 2#include <memory>
 3
 4using RNTupleWriter = ROOT::Experimental::RNTupleWriter;
 5using RNTupleReader = ROOT::Experimental::RNTupleReader;
 6
 7// データを書き込む
 8auto writer = RNTupleWriter::Recreate("ntuple", "output.root");
 9auto pt = writer->MakeField<float>("pt");
10auto eta = writer->MakeField<float>("eta");
11
12for (int i = 0; i < 100; i++) {
13    *pt = 10.0 + i * 0.1;
14    *eta = -2.5 + i * 0.05;
15    writer->Fill();
16}
17writer->Commit();

RNTupleTTreeの後継となるクラスです。ただし、互換性はありません。

TTreeは1995年にROOTがリリースされたときから、フレームワークの主要クラスでした。しかし、30年前と比べて、データ解析周辺の環境は様変わりしています。それに対応するために、これまでの高エネルギー物理学での知見を活かしつつ、新しいクラスの開発が行われています。

 1import ROOT
 2from ROOT.Experimental import RNTupleWriter, RNTupleReader
 3
 4# データを書き込む
 5writer = RNTupleWriter.Recreate("ntuple", "output.root")
 6pt = writer.MakeField("pt", "float")
 7eta = writer.MakeField("eta", "float")
 8
 9for i in range(100):
10    pt[0] = 10.0 + i * 0.1
11    eta[0] = -2.5 + i * 0.05
12    writer.Fill()
13writer.Commit()

RNTupleについて

TTreeとの比較

項目

TTree

RNTuple

リリース年

1995年

2018年(実験的)

バージョン

安定

実験的

パフォーマンス

良好

最適化済み

互換性

あり

なし

圧縮

オプション

デフォルト

並列読み書き

限定的

高速

データを書き込みたい(RNTupleWriter::Recreate

 1#include <ROOT/RNTuple.hxx>
 2
 3using RNTupleWriter = ROOT::Experimental::RNTupleWriter;
 4
 5auto writer = RNTupleWriter::Recreate("ntuple", "data.root");
 6auto event_id = writer->MakeField<int>("event_id");
 7auto pt = writer->MakeField<float>("pt");
 8auto eta = writer->MakeField<float>("eta");
 9
10for (int i = 0; i < 1000; i++) {
11    *event_id = i;
12    *pt = 10.0 + i * 0.01;
13    *eta = -2.5 + i * 0.005;
14    writer->Fill();
15}
16
17writer->Commit();

RNTupleWriter::Recreate()でNTupleを新規作成します。フィールドを定義してからFill()でデータを記録します。

データを読み込みたい(RNTupleReader::Open

 1#include <ROOT/RNTuple.hxx>
 2
 3using RNTupleReader = ROOT::Experimental::RNTupleReader;
 4
 5auto reader = RNTupleReader::Open("ntuple", "data.root");
 6auto view = reader->GetView<int, float, float>({"event_id", "pt", "eta"});
 7
 8for (auto entry : view) {
 9    int event_id = std::get<0>(entry);
10    float pt = std::get<1>(entry);
11    float eta = std::get<2>(entry);
12    std::cout << "Event: " << event_id << ", pt: " << pt << ", eta: " << eta << std::endl;
13}

RNTupleReader::Open()でNTupleから読み込みます。GetView()でフィールドを指定してアクセスできます。

複数のフィールドを定義したい(MakeField

 1#include <ROOT/RNTuple.hxx>
 2
 3using RNTupleWriter = ROOT::Experimental::RNTupleWriter;
 4
 5auto writer = RNTupleWriter::Recreate("events", "output.root");
 6
 7auto run_number = writer->MakeField<int>("run");
 8auto event_number = writer->MakeField<int>("event");
 9auto energy = writer->MakeField<double>("energy");
10auto charge = writer->MakeField<int>("charge");
11
12for (int i = 0; i < 100; i++) {
13    *run_number = 2025;
14    *event_number = i;
15    *energy = 100.0 + i;
16    *charge = (i % 2 == 0) ? 1 : -1;
17    writer->Fill();
18}
19
20writer->Commit();

各データ型に応じてMakeField<T>()でフィールドを定義します。複数のフィールドを定義して、Fill()で全フィールドを同時に記録します。

参考情報

RNTupleの特徴

  • 高速な読み書き: 最適化されたバイナリ形式

  • デフォルト圧縮: ディスク容量を効率的に利用

  • スケーラビリティ: 大規模データセットに対応

  • モダン設計: 並列処理に最適化

実験的ステータス

RNTupleはまだ実験的なクラスです。本番環境での使用は、ROOT開発チームの最新情報を確認してから判断してください。

関連メソッド

参考リンク