ROOTで複数のファイルを読む&オブジェクトを取得するなど

ROOTの内部には、OSとは切り離された独自のDirectory構造を持っています。基本的にはユーザーはあまりこれを意識せずに使えるような思想で作られている(のかな?)とは思うのですが、これが結構複雑だと私は感じておりました。それがちょっとスッキリしてきたのでまとめます。

具体的にこれを理解しようと思ったきっかけは複数のROOTファイルを読み込んで、それをマージしたいと思ったところです。

前提

ROOTファイルが1.root, 2.rootとあり、それぞれには同じ名前のObject(のKEY), TH1D* histが入っているとします。

実装

ROOTファイルを読み込むにはTFile::Openを使います。複数のファイルを読む場合はTFileオブジェクトのポインタをユニークに作ればよろしいです。

root [] TFile *f1 = TFile::Open("1.root");
root [] TFile *f2 = TFile::Open("2.root");

これらのファイルからそれぞれのヒストグラムのオブジェクトを取得するには

root [] TH1D* h1 = (TH1D*)f1->Get("hist");
root [] TH1D* h2 = (TH1D*)f2->Get("hist");

とユニークなオブジェクト名をつけて、TFile::Get関数を用いてオブジェクトを取得します。こうすればあとは煮るなり焼くなりできますね。

解説

このPostを書こうと思ったきっかけは、このファイルの情報はどのように確認できるのか、そのファイルにはどのようなオブジェクトキーが入っているのかを見ながらじゃないと出来ないじゃないかー!となったので、その出力方法などを探りました。

まず、複数のファイルのどのROOTファイルを読んでいるかのListは

root [] gROOT->GetListOfFiles()->Print();
Collection name='Files', class='TList', size=2
 TFile: name=1.root, title=, option=READ
 TFile: name=2.root  title=, option=READ

で確認出来ます。で、もしどのTFileのオブジェクトがどのファイルを指しているか分からなくなったら

root [] f1->GetName();

で見れます。このf1が参照しているROOTファイルに何が入っているかは

root [] f1->ls();
TFile**     1.root
TFile*      1.root
 KEY: TH1D  hist;1

と、結構簡単に見れることがわかりました。

artemisではこの複数ファイルの操作に関するコマンドfls, fcdが実装されています。

artemis [] fls
 files
    0  TFile 1.root (READ)
    1  TFile 2.root (READ)
artemis [] fcd 1
artemis [] ls

 1.root
>   0 TH1D hist hist

artemis []

このコマンド便利ですが、複数ファイルのオブジェクトをマージしたいときにどのディレクトリ(ROOTファイル)にいるかが気になってしまいます。そして、他のROOTファイルのオブジェクトキーを取ってくるのにどうすれば良いかなと思って調べてみました。

こちらのページ、とても参考になります。 KamonoWiki I/O

Shoichiro Masuoka

CNS, the Univ. of Tokyo. Dcotoral student

関連項目