テキストファイルをTTreeに変換したい(TTree::ReadFile

 1#include <TTree.h>
 2#include <TFile.h>
 3#include <TString.h>
 4
 5// TTreeオブジェクトを作成
 6TTree *tree = new TTree("tree", "tree from text file");
 7
 8// テキストファイルを読み込み
 9tree->ReadFile("input.csv", "col1/I:col2/I:col3/D", ",");
10
11// ヒストグラムを作成
12tree->Draw("col1");

TTree::ReadFileメソッドで、テキスト形式のファイル(CSV、タブ区切り等)を直接TTreeオブジェクトに読み込むことができます。

 1from ROOT import TTree, TFile
 2
 3# TTreeオブジェクトを作成
 4tree = TTree("tree", "tree from text file")
 5
 6# テキストファイルを読み込み
 7tree.ReadFile("input.csv", "col1/I:col2/I:col3/D", ",")
 8
 9# ヒストグラムを作成
10tree.Draw("col1")

メソッドのシグネチャ

1Long64_t ReadFile(
2    const char *filename,
3    const char *branchDescriptor,
4    char delimiter = ' '
5)

TTree::ReadFileは、テキスト形式のデータファイルをROOTのTTreeオブジェクトに直接読み込む便利なメソッドです。

引数の説明

filename - 読み込むファイルパス

  • テキスト形式のデータファイルを指定します

  • 絶対パスまたは相対パスで指定可能です

  • 複数ファイルを読み込む場合はTStringを使って動的に指定することも可能です

branchDescriptor - ブランチ構造定義

  • ブランチ名と型を指定します

  • 複数のブランチは:(コロン)で区切ります

  • 型は以下の形式で指定します:branchname/type

delimiter - 区切り文字

  • データの区切り文字を指定します

  • デフォルトは" "(スペース)です

  • CSVファイルの場合は","を指定します

  • タブ区切りの場合は"\t"を指定します

データ型一覧

型コード

C++型

説明

I

Int_t

32ビット整数

L

Long64_t

64ビット整数

F

Float_t

単精度浮動小数点数(デフォルト)

D

Double_t

倍精度浮動小数点数

C

Char_t

文字

S

Short_t

16ビット短整数

戻り値

  • 成功時: 読み込んだデータ行数(Long64_t)

  • 失敗時: -1

ファイル形式の要件

TTree::ReadFileで読み込むテキストファイルは以下の形式である必要があります。

  • 1行目以降がデータ: 各行が1つのイベントに対応

  • 列の順序: branchDescriptorで指定した順序と一致する必要があります

  • 区切り文字: 指定した区切り文字で各列が分離されている

サンプルファイル形式

CSV形式(カンマ区切り):

# コメント行はスキップされます
100,105,104,103,20.5
101,106,103,100,20.7
102,107,105,102,20.9

スペース区切り形式:

100 105 104 103 20.5
101 106 103 100 20.7
102 107 105 102 20.9

タブ区切り形式:

100 105 104 103 20.5
101 106 103 100 20.7
102 107 105 102 20.9

異なるファイル形式を読み込みたい

CSV形式(カンマ区切り)

 1#include <TTree.h>
 2#include <TFile.h>
 3
 4TTree *tree = new TTree("tree", "CSV data");
 5
 6// CSVファイルを読み込み(4つのInt型列と1つのDouble型列)
 7Long64_t nentries = tree->ReadFile("data.csv", "ch1/I:ch2/I:ch3/I:ch4/I:temp/D", ",");
 8
 9std::cout << "読み込んだデータ行数: " << nentries << std::endl;
10
11// データを確認
12tree->Draw("ch1");

CSVファイルはスプレッドシートソフトで作成・編集しやすいため、実験データの保存に適しています。

スペース区切り形式

1#include <TTree.h>
2
3TTree *tree = new TTree("tree", "Space-separated data");
4
5// スペース区切りファイルを読み込み(デフォルト)
6Long64_t nentries = tree->ReadFile("data.txt", "x/D:y/D:z/D");
7
8// データの統計情報を表示
9tree->Print();

スペース区切りはテキストエディターで手動編集しやすく、シンプルなデータ形式です。

タブ区切り形式

1#include <TTree.h>
2
3TTree *tree = new TTree("tree", "Tab-separated data");
4
5// タブ区切りファイルを読み込み
6Long64_t nentries = tree->ReadFile("data.tsv", "time/D:value/D:error/D", "\t");
7
8tree->Print();

タブ区切りはスペースを含むテキストを扱う場合に有効です。

ROOTファイルに保存したい

 1#include <TTree.h>
 2#include <TFile.h>
 3#include <TString.h>
 4
 5// ファイル名を設定
 6TString input_filename = "data.csv";
 7TString output_filename = "output.root";
 8
 9// TTreeを作成
10TTree *tree = new TTree("data", "Data from CSV");
11
12// CSVファイルを読み込み
13Long64_t nentries = tree->ReadFile(
14    input_filename.Data(),
15    "ch1/I:ch2/I:ch3/I:ch4/I:temp/D",
16    ","
17);
18
19std::cout << "読み込んだイベント数: " << nentries << std::endl;
20
21// ROOTファイルを作成
22TFile *outfile = new TFile(
23    output_filename.Data(),
24    "recreate"
25);
26
27// TTreeをファイルに書き込み
28tree->Write();
29
30// ファイルを閉じる
31outfile->Close();
32
33std::cout << "保存完了: " << output_filename << std::endl;

読み込んだTTreeをROOTファイルに保存することで、後の解析を高速化できます。

 1from ROOT import TTree, TFile
 2
 3# ファイル名を設定
 4input_filename = "data.csv"
 5output_filename = "output.root"
 6
 7# TTreeを作成
 8tree = TTree("data", "Data from CSV")
 9
10# CSVファイルを読み込み
11nentries = tree.ReadFile(
12    input_filename,
13    "ch1/I:ch2/I:ch3/I:ch4/I:temp/D",
14    ","
15)
16
17print(f"読み込んだイベント数: {nentries}")
18
19# ROOTファイルを作成
20outfile = TFile(output_filename, "recreate")
21
22# TTreeをファイルに書き込み
23tree.Write()
24
25# ファイルを閉じる
26outfile.Close()
27
28print(f"保存完了: {output_filename}")

実用例

シンプルな測定データの変換(C++マクロ)

 1// convert_data.C
 2#include <TTree.h>
 3#include <TFile.h>
 4#include <TString.h>
 5#include <iostream>
 6
 7void convert_data() {
 8    // ステップ1: ファイル名を設定
 9    TString input_file = "measurement.csv";
10    TString output_file = "measurement.root";
11
12    // ステップ2: TTreeを作成
13    TTree *tree = new TTree("measurements", "Laboratory measurement data");
14
15    // ステップ3: CSVファイルを読み込み
16    // 4つのセンサーからの値と温度を読み込み
17    Long64_t nentries = tree->ReadFile(
18        input_file.Data(),
19        "sensor1/I:sensor2/I:sensor3/I:sensor4/I:temperature/D",
20        ","
21    );
22
23    if (nentries < 0) {
24        std::cout << "ファイルの読み込みに失敗しました" << std::endl;
25        return;
26    }
27
28    std::cout << "読み込んだデータ: " << nentries << " イベント" << std::endl;
29
30    // ステップ4: データの確認
31    tree->Print();
32
33    // ステップ5: ROOTファイルに保存
34    TFile *outfile = new TFile(output_file.Data(), "recreate");
35    tree->Write();
36
37    // ステップ6: ファイルを閉じる
38    outfile->Close();
39
40    std::cout << "完了: " << output_file << std::endl;
41}

マクロとして実行します。

$ root -l -b -q convert_data.C

複数ファイルを順次読み込む

 1#include <TTree.h>
 2#include <TFile.h>
 3#include <TString.h>
 4#include <iostream>
 5
 6void convert_multiple_files() {
 7    // 読み込むファイルの個数
 8    const int nfiles = 10;
 9
10    // TTreeを作成(複数ファイルのデータを統合)
11    TTree *tree = new TTree("data", "Combined data from multiple files");
12
13    Long64_t total_entries = 0;
14
15    // 各ファイルを順次読み込み
16    for (int i = 1; i <= nfiles; i++) {
17        // ファイル名を動的に生成
18        TString filename;
19        filename.Form("data_%03d.csv", i);
20
21        std::cout << "読み込み中: " << filename << std::endl;
22
23        // ファイルを読み込み
24        Long64_t nentries = tree->ReadFile(
25            filename.Data(),
26            "time/D:value/D:error/D",
27            ","
28        );
29
30        if (nentries < 0) {
31            std::cout << "  警告: ファイル読み込み失敗" << std::endl;
32            continue;
33        }
34
35        total_entries += nentries;
36        std::cout << "  " << nentries << " イベント読み込み済み" << std::endl;
37    }
38
39    std::cout << "合計: " << total_entries << " イベント" << std::endl;
40
41    // ROOTファイルに保存
42    TFile *outfile = new TFile("combined_data.root", "recreate");
43    tree->Write();
44    outfile->Close();
45}

データの検証と解析

 1#include <TTree.h>
 2#include <TFile.h>
 3#include <TString.h>
 4#include <iostream>
 5
 6void analyze_data() {
 7    // TTreeを作成
 8    TTree *tree = new TTree("data", "Data analysis");
 9
10    // データを読み込み
11    Long64_t nentries = tree->ReadFile("sensor_data.csv",
12                                       "sensor1/F:sensor2/F:sensor3/F",
13                                       ",");
14
15    std::cout << "読み込んだイベント数: " << nentries << std::endl;
16
17    // ブランチの情報を表示
18    std::cout << "\nブランチ情報:" << std::endl;
19    tree->Print();
20
21    // 統計情報を計算
22    std::cout << "\n統計情報:" << std::endl;
23    tree->Draw("sensor1");  // ヒストグラムを表示
24    tree->Draw("sensor1 >> h1(100, 0, 1000)", "", "HIST");  // カスタムヒストグラム
25
26    // クエリ結果を取得
27    tree->Draw("sensor1:sensor2", "sensor3>500", "COLZ");  // 2次元プロット
28}

注意事項

  • コメント行: #で始まる行はスキップされます

  • 空行: 空行はスキップされます

  • 型の指定: 型を指定しない場合はデフォルトのFloat_t(/F)になります

  • 戻り値の確認: ReadFileの戻り値が−1の場合は読み込み失敗を示すため、エラーチェックが推奨されます

  • 大規模ファイル: 非常に大きなテキストファイルの場合、ROOTファイル形式での保存が推奨されます。テキスト解析より高速にアクセスできます

  • 文字エンコーディング: UTF-8等のマルチバイト文字を含むファイルは読み込みに失敗する可能性があります

  • データ型の一致: ファイル内のデータ型がbranchDescriptorで指定した型と一致していることを確認してください

  • 学生実験での活用: 実験機器がテキスト形式でデータを出力する場合、このメソッドで素早くROOT解析フォーマットに変換できます

ワークフロー

  1. データ取得: 実験機器などからテキスト形式でデータを取得

  2. ファイル保存: テキストファイルとして保存(CSV推奨)

  3. TTree読み込み: ReadFileでテキストをTTreeに変換

  4. ROOT形式保存: TFileに書き込んで保存

  5. 解析: 保存したROOTファイルを後の解析で高速にアクセス

リファレンス