TGraphErrorsを用いてデータが書かれているテキストファイルから簡単にROOTを用いてプロット、Fitなどを行います。脱Excel,gnuplot
前提
以下のようなデータファイル(data.dat)があるとします。
1 1 0.1 1 0.2
2 2 0.2 4 0.4
3 3 0.3 9 0.9
...
全部で5列あって、x y1 dy1 y2 dy2となっているとします。
実装
ROOTを開いて次のようにファイルを読み込みます。
root [] TGraphErrors* tg1 = new TGraphErrors("data.dat","%lg %lg %lg %*lg %*lg"); // (x,y1,dy1)の組のGraphを作る
root [] TGraphErrors* tg2 = new TGraphErrors("data.dat","%lg %*lg %*lg %lg %lg"); // (x,y2,dy2)の組のGraphを作る
root [] tg1->Draw("ap"); // option a = axis, p = point
root [] tg2->Draw("p"); // 2つめ以降はaxisはDrawしない
TGraphErrorsではデータが入った配列*1やTVectorDなどを突っ込んで動くコンストラクタがありますが、いつも私はチャラくお手軽にファイルに書き出したデータをプロットするのに使っています*2。
この場合ではこのコンストラクタ
TGraphErrors TGraphErrors(const char* filename, const char* format = "%lg %lg %lg %lg", Option_t* option = "")
を使っています。データフォーマットは
- %lg %lg %lg %lg (x,y,dx,dy)
- %lg %lg %lg (x,y,dy)
- %lg %lg (x,y)
のように自動で認識します。
データファイルの中で無視する列は *%lg とすると良いです(これをいつも忘れるから書いた)。
*1: 動的配列であるstd::vectorでも出来ます。
std::vector<Double_t> x,y,dx,dy;
/*
x,y,dx,dyに詰める
*/
TGraphErrors* tg = new TGraphErrors((Int_t)x.size(),&(x.at(0)),&(y.at(0)),&(dx.at(0)),&(dy.at(0)));
*2: このやり方だと、書かれているデータに何らかの処理をしてプロットすることは出来ないのでマクロなどで以前の記事のようにデータファイルから配列を取得して処理してからTGraphErrorsのコンストラクタに突っ込む、もしくはawkなどを使って予めデータを処理しておくことが必要になるでしょう。
おまけ
TGraphErrorsはTGraphを継承しているのでFitなども当然出来ます。これが良いところ。
root [] tg1->Fit("pol1");
root [] tg2->Fit("pol2");
Fitの関数はよく使うものとしては"polN" (n次多項式), "gaus" (Gaussian)などでしょう。自分で関数をTF1で作ってFitも出来ます。
ここで
root [] tg1->Fit("pol1","rob");
とすると、ROBUST Fittingというのをやってくれます。
これは、データをある関数でFitするときに外れ値がいるとそいつに強く引っ張られてしまいますが、それをなるべく抑えてFittingしてくれるメソッドなのだそうです(参考)。
ついでに、グラフタイトル、軸ラベルの変更などしてしまいましょう。
root [] tg2->SetTitle("y = x^{2}"); // TLaTeXが使えます
root [] tg2->GetXaxis()->SetTitle("x");
root [] tg2->GetYaxis()->SetTitle("y");
#alpha
などとするとギリシャ文字も書けるし、原子核の核種などもプロット内に記述できるのでTLaTeXは度々重宝しております。