ヒストグラムをフィットしたい(TH1::Fit

 1#include <TH1D.h>
 2#include <TF1.h>
 3#include <TRandom3.h>
 4
 5TH1D *h = new TH1D("h", "data", 100, -5, 5);
 6
 7TRandom3 random;
 8for (int i = 0; i < 5000; i++) {
 9    h->Fill(random.Gaus(0, 1));
10}
11
12TF1 *f = new TF1("f", "gaus", -5, 5);
13h->Fit(f);

TH1::Fitメソッドで、ヒストグラムを数学関数でフィットできます。 フィット関数はTF1で作成し、ヒストグラムのデータに対して最小二乗法による最適化を行います。

 1from ROOT import TH1D, TF1, TRandom3
 2
 3h = TH1D("h", "data", 100, -5, 5)
 4
 5random = TRandom3()
 6for i in range(5000):
 7    h.Fill(random.Gaus(0, 1))
 8
 9f = TF1("f", "gaus", -5, 5)
10h.Fit(f)

メソッドシグネチャ

1TFitResultPtr Fit(TF1 *f1,
2                  Option_t *option = "",
3                  Option_t *goption = "",
4                  Axis_t xmin = 0,
5                  Axis_t xmax = 0)

引数と戻り値

引数:

  • f1 - フィット関数(TF1オブジェクト)

  • option - フィットオプション(文字列)

    • "Q" - 静粛モード(出力なし)

    • "S" - 統計情報を出力

    • "V" - 冗長モード(詳細情報を出力)

    • "+" - 前のフィット結果に追加

    • "N" - パラメーターの制約を無視

    • "R" - 指定範囲でのみフィット

  • goption - グラフィック描画オプション(Drawに渡される)

  • xmin, xmax - フィット範囲(指定しない場合はヒストグラム全体)

戻り値:

  • TFitResultPtr - フィット結果オブジェクト(パラメーター値、誤差、カイ二乗値などを含む)

基本的なフィット

 1#include <TH1D.h>
 2#include <TF1.h>
 3#include <TRandom3.h>
 4#include <iostream>
 5
 6TH1D *h = new TH1D("h", "Histogram", 100, -5, 5);
 7
 8TRandom3 random;
 9for (int i = 0; i < 5000; i++) {
10    h->Fill(random.Gaus(0, 1));
11}
12
13// ガウス関数でフィット
14TF1 *f = new TF1("f", "gaus", -5, 5);
15h->Fit(f);
16
17// フィット結果を表示
18std::cout << "フィット完了" << std::endl;

基本的な用法で、ヒストグラムをガウス関数でフィットできます。 Fit()メソッドはパラメーターを自動的に初期化してフィットを実行します。

ガウス関数でフィットしたい

 1#include <TH1D.h>
 2#include <TF1.h>
 3#include <TRandom3.h>
 4#include <iostream>
 5
 6TH1D *h = new TH1D("h", "data", 100, -5, 5);
 7
 8TRandom3 random;
 9for (int i = 0; i < 5000; i++) {
10    h->Fill(random.Gaus(0, 1));
11}
12
13// ガウス関数でフィット
14TF1 *f = new TF1("f", "gaus", -5, 5);
15h->Fit(f);
16
17// フィット結果を取得
18Double_t mean = f->GetParameter(1);
19Double_t sigma = f->GetParameter(2);
20
21std::cout << "Mean: " << mean << std::endl;
22std::cout << "Sigma: " << sigma << std::endl;

"gaus"は組み込み関数で、3つのパラメーター(正規化、平均値、標準偏差)を持ちます。 フィット後、GetParameter()でパラメーター値を取得できます。

Python での実装

 1from ROOT import TH1D, TF1, TRandom3
 2
 3h = TH1D("h", "data", 100, -5, 5)
 4
 5random = TRandom3()
 6for i in range(5000):
 7    h.Fill(random.Gaus(0, 1))
 8
 9f = TF1("f", "gaus", -5, 5)
10h.Fit(f)
11
12mean = f.GetParameter(1)
13sigma = f.GetParameter(2)
14
15print(f"Mean: {mean}")
16print(f"Sigma: {sigma}")

カスタム関数でフィットしたい

 1#include <TH1D.h>
 2#include <TF1.h>
 3#include <TRandom3.h>
 4#include <iostream>
 5#include <cmath>
 6
 7// カスタム関数
 8Double_t myFunc(Double_t *x, Double_t *par) {
 9    return par[0] * exp(-0.5 * pow((x[0] - par[1]) / par[2], 2));
10}
11
12TH1D *h = new TH1D("h", "data", 100, -5, 5);
13
14TRandom3 random;
15for (int i = 0; i < 5000; i++) {
16    h->Fill(random.Gaus(0, 1));
17}
18
19// カスタム関数でフィット
20TF1 *f = new TF1("f", myFunc, -5, 5, 3);
21h->Fit(f);

関数ポインターまたはラムダ式でカスタム関数を定義し、フィットに使用できます。

パラメーター初期化によるフィット最適化

 1#include <TH1D.h>
 2#include <TF1.h>
 3#include <TRandom3.h>
 4
 5TH1D *h = new TH1D("h", "data", 100, -10, 10);
 6
 7TRandom3 random;
 8for (int i = 0; i < 5000; i++) {
 9    h->Fill(random.Gaus(2, 1.5));
10}
11
12// ガウス関数を作成
13TF1 *f = new TF1("f", "gaus", -10, 10);
14
15// パラメーターを手動で初期化
16f->SetParameter(0, 200);   // 正規化(ヒストグラムの最大値程度)
17f->SetParameter(1, 2.0);   // 平均値
18f->SetParameter(2, 1.0);   // 標準偏差
19
20// フィット実行
21h->Fit(f);

初期パラメーター値がデータに近い場合、フィットが高速かつ正確になる傾向があります。 ヒストグラムのピーク位置や幅から推定して初期値を設定することが重要です。

パラメーター制約によるフィット

 1#include <TH1D.h>
 2#include <TF1.h>
 3#include <TRandom3.h>
 4
 5TH1D *h = new TH1D("h", "data", 100, -5, 5);
 6
 7TRandom3 random;
 8for (int i = 0; i < 5000; i++) {
 9    h->Fill(random.Gaus(0, 1));
10}
11
12// ガウス関数を作成
13TF1 *f = new TF1("f", "gaus", -5, 5);
14
15// 平均値を0に固定し、他のパラメーターのみフィット
16f->FixParameter(1, 0.0);
17
18// フィット実行
19h->Fit(f);

FixParameter()で特定のパラメーターを固定することで、他のパラメーターのみをフィットできます。 物理知識から特定のパラメーター値がわかっている場合に有効です。

フィット結果の解析

 1#include <TH1D.h>
 2#include <TF1.h>
 3#include <TRandom3.h>
 4#include <iostream>
 5
 6TH1D *h = new TH1D("h", "data", 100, -5, 5);
 7
 8TRandom3 random;
 9for (int i = 0; i < 5000; i++) {
10    h->Fill(random.Gaus(0, 1));
11}
12
13TF1 *f = new TF1("f", "gaus", -5, 5);
14TFitResultPtr res = h->Fit(f);
15
16// フィット結果から値を取得
17if (res) {
18    // パラメーター値と誤差
19    Double_t norm = f->GetParameter(0);
20    Double_t mean = f->GetParameter(1);
21    Double_t sigma = f->GetParameter(2);
22
23    Double_t mean_err = f->GetParError(1);
24    Double_t sigma_err = f->GetParError(2);
25
26    // 統計情報
27    Double_t chi2 = f->GetChisquare();
28    Int_t ndf = f->GetNDF();
29    Double_t prob = f->GetProb();
30
31    std::cout << "Mean: " << mean << " +/- " << mean_err << std::endl;
32    std::cout << "Sigma: " << sigma << " +/- " << sigma_err << std::endl;
33    std::cout << "Chi2/NDF: " << chi2 / ndf << std::endl;
34    std::cout << "Probability: " << prob << std::endl;
35}

フィット後、パラメーター値、誤差、カイ二乗値などの統計情報を取得できます。 これらの値は結果の品質を判定するために重要です。

指定範囲でのフィット

 1#include <TH1D.h>
 2#include <TF1.h>
 3#include <TRandom3.h>
 4
 5TH1D *h = new TH1D("h", "data", 100, -5, 5);
 6
 7TRandom3 random;
 8for (int i = 0; i < 5000; i++) {
 9    h->Fill(random.Gaus(0, 1));
10}
11
12TF1 *f = new TF1("f", "gaus", -5, 5);
13
14// 特定の範囲でのみフィット
15h->Fit(f, "", "", -2, 2);

Fit()の最後の2つの引数で、フィット範囲を指定できます。 ヒストグラムの一部のみをフィットしたい場合に有効です。

複数のガウス関数でフィットしたい

 1#include <TH1D.h>
 2#include <TF1.h>
 3#include <TRandom3.h>
 4
 5TH1D *h = new TH1D("h", "bimodal data", 100, -10, 10);
 6
 7TRandom3 random;
 8for (int i = 0; i < 5000; i++) {
 9    if (random.Uniform() < 0.5) {
10        h->Fill(random.Gaus(-3, 1));
11    } else {
12        h->Fill(random.Gaus(3, 1));
13    }
14}
15
16// 2つのガウス関数の和
17TF1 *f = new TF1("f",
18    "gaus(0) + gaus(3)",
19    -10, 10);
20
21// パラメーターを初期化
22f->SetParameter(0, 250);   // 第1ガウスの正規化
23f->SetParameter(1, -3);    // 第1ガウスの平均値
24f->SetParameter(2, 1);     // 第1ガウスの標準偏差
25
26f->SetParameter(3, 250);   // 第2ガウスの正規化
27f->SetParameter(4, 3);     // 第2ガウスの平均値
28f->SetParameter(5, 1);     // 第2ガウスの標準偏差
29
30h->Fit(f);

複数のガウス関数を組み合わせることで、複雑な分布(双峰分布など)をフィットできます。 各ガウス関数は3つのパラメーターを持つため、パラメーターのインデックスに注意が必要です。

フィット結果の可視化

 1#include <TH1D.h>
 2#include <TF1.h>
 3#include <TRandom3.h>
 4#include <TCanvas.h>
 5
 6TH1D *h = new TH1D("h", "Gaussian Fit", 100, -5, 5);
 7
 8TRandom3 random;
 9for (int i = 0; i < 5000; i++) {
10    h->Fill(random.Gaus(0, 1));
11}
12
13TF1 *f = new TF1("f", "gaus", -5, 5);
14h->Fit(f);
15
16TCanvas *c = new TCanvas("c", "Fit Result", 600, 400);
17h->Draw();
18f->SetLineColor(2);
19f->SetLineWidth(2);
20f->Draw("same");
21
22c->BuildLegend();

ヒストグラムとフィット曲線を重ねて描画することで、フィットの品質を視覚的に確認できます。

フィットオプションの活用

 1#include <TH1D.h>
 2#include <TF1.h>
 3#include <TRandom3.h>
 4
 5TH1D *h = new TH1D("h", "data", 100, -5, 5);
 6
 7TRandom3 random;
 8for (int i = 0; i < 5000; i++) {
 9    h->Fill(random.Gaus(0, 1));
10}
11
12TF1 *f = new TF1("f", "gaus", -5, 5);
13
14// 詳細情報を出力
15h->Fit(f, "V");
16
17// 静粛モード
18// h->Fit(f, "Q");
19
20// 指定範囲でフィット
21// h->Fit(f, "R", "", -2, 2);

Fit()メソッドのオプション引数を活用することで、フィットの動作や出力をカスタマイズできます。

関連メソッド

参考リンク