ファイル操作したい(TFile

 1#include <TFile.h>
 2
 3// ファイルを開く
 4TFile *fin = new TFile(
 5    "input.root",  // fname
 6    "read",        // option: read | update | recreate | create
 7    "Input ROOT file",  // ftitle (optional)
 8    505            // compress (optional)
 9);
10
11// オブジェクトを取得
12TH1D *h1 = (TH1D*)fin->Get("histogram_name");
13
14// ファイルを閉じる
15fin->Close();

TFileクラスで、ROOTファイルの読み書きができます。 ファイルを開いてオブジェクトを取得し、最後にファイルを閉じるのが基本的な流れです。

fnameはファイル名を指定します。 ファイル名は相対パスや絶対パスで指定できます。 ただし、~を使用したホームディレクトリの指定はサポートされていません。

optionはファイルアクセスモードを指定します。 読み込み専用(read / r)、 更新・追記(update / u)、 新規作成(存在する場合はエラー)(create / c) 新規作成(存在する場合は上書き)(recreate) のいずれかを指定します。 デフォルトはreadです。

ftitleはファイルのタイトル説明を設定できます。 compressは圧縮レベルを指定できます。デフォルトは505です。

 1import ROOT
 2
 3# ファイルを開く
 4fin = ROOT.TFile("input.root", "read")
 5
 6# オブジェクトを取得
 7h1 = fin.Get("histogram_name")
 8
 9# ファイルを閉じる
10fin.Close()

ファイルに保存したい(TFile

 1#include <TFile.h>
 2
 3TFile *fout = new TFile(
 4    "output.root",
 5    "recreate"
 6);
 7
 8// オブジェクトをファイルに書き込む
 9tree->Write();
10hist->Write();
11canvas->Write();
12
13fout->Close();

TFilerecreateモードで作成してから、各オブジェクトのWrite()メソッドを呼び出して保存します。 最後にClose()でファイルを閉じます。

ファイルに追記する場合はupdateモードを使用します。

オブジェクトを取得したい(TFile::Get

1#include <TFile.h>
2TFile *fin = new TFile("input.root", "read");
3TH1D *h1 = (TH1D*)fin->Get("histogram_name");
4fin->Close();

TFile::Getで、ファイルからオブジェクトを取得できます。 オブジェクトの名前を指定して、正しい型にキャストすることが重要です。

注釈

autoを使用して型推論することもできますが、明示的な型指定の方が安全です。

ディレクトリを変更したい(TFile::cd

1#include <TFile.h>
2TFile *fout = new TFile("output.root", "recreate");
3fout->cd("subdir");  // "subdir"ディレクトリに移動
4tree->Write();  // "subdir"に書き込まれる
5fout->Close();

TFile::cdで、ファイル内のディレクトリを変更できます。 ROOTファイルにはディレクトリ構造を持たせることができます。 cd()でそのディレクトリに移動してからWrite()を呼び出すことで、指定したディレクトリにオブジェクトを保存できます。

上書き確認したい(TFile

 1#include <TFile.h>
 2#include <TSystem.h>
 3#include <cstdio>
 4
 5TString ofn = "output.root";
 6FileStat_t info;
 7if (gSystem->GetPathInfo(ofn, info) == 0) {
 8    printf("File %s already exists. Do you want to overwrite it? (y/n): ", ofn.Data());
 9    char response;
10    std::cin >> response;
11    if (response != 'y' && response != 'Y') {
12        printf("Aborting file write.\n");
13        return;
14    }
15}
16
17TFile *fout = new TFile(ofn, "recreate");
18// ...オブジェクトの書き込み...
19fout->Close();

ファイルが存在する場合に、ユーザーに上書き確認を促すサンプルです。 TSystem::GetPathInfoでファイルの存在を確認しています。

イベント取得したい

 1#include <TFile.h>
 2#include <TTree.h>
 3
 4// イベント数
 5// 実際はコマンド引数などで指定できるようにする
 6Int_t n = 1000;
 7
 8// 保存するファイルを作成
 9TFile *fout = new TFile::Open(
10    "tree.root",
11    "recreate"
12);
13
14TTree *tree = new TTree("tree", "Event data");
15// TTreeをファイルに関連付ける
16tree->SetDirectory(fout);
17// 指定したイベント数ごとに自動的にフラッシュ
18ttree->SetAutoFlush(10000);
19
20// ブランチを追加
21Int_t ch1, ch2, ch3, ch4;
22Double_t temp;
23tree->Branch("ch1", &ch1, "ch1/I");
24tree->Branch("ch2", &ch2, "ch2/I");
25tree->Branch("ch3", &ch3, "ch3/I");
26tree->Branch("ch4", &ch4, "ch4/I");
27tree->Branch("temp", &temp, "temp/D");
28
29for (Int_t i = 0; i < n; i++) {
30    // データ取得
31    ch1 = ...;  // チャンネル1の値
32    ch2 = ...;  // チャンネル2の値
33    ch3 = ...;  // チャンネル3の値
34    ch4 = ...;  // チャンネル4の値
35    temp = ...; // 温度の値
36
37    // イベントをTTreeに保存
38    tree->Fill();
39
40    // 定期的に自動保存
41    if (i % 10000 == 0) {
42        tree->AutoSave("SaveSelf");        printf("Saved %d events...\n", i);
43    }
44
45}
46
47// 最終的にファイルに書き込む
48tree->Write();
49
50// ファイルを閉じる
51fout->Close();

TFileTTreeを組み合わせて、実験データをROOT形式で保存できます。 TFileでファイルを開いて、TTreeにイベントデータを保存するのが一般的な使い方です。

TTree::SetAutoFlushで、指定したイベント数ごとに自動的にファイルにフラッシュするように設定できます。 これにより、大量のイベントを保存する際のメモリ使用量を抑えることができます。

TTree::AutoSaveで、定期的にファイルに保存できます。 DAQが途中でクラッシュした場合でも、保存されたデータを復旧することができるようになります。

注意

TTree:Writeは、ファイルに書き込む際にTTreeの内容を完全に保存します。 イベントごとに呼び出してはいけません。 イベント数が多い場合は、AutoSaveAutoFlushを活用して、定期的にファイルに書き出すようにします。

リファレンス