SetPointとSetPointErrorの実装例(TGraph/TGraphErrors

 1#include <TGraph.h>
 2#include <TGraphErrors.h>
 3#include <TTree.h>
 4#include <vector>
 5
 6// 波形データを複数グラフに追加する実装例
 7void plotWaveformData() {
 8    // TreeからFADCデータを取得する場合の例
 9    TTree *t = new TTree("events", "Event data");
10    std::vector<int> adc;
11    t->Branch("adc", &adc);
12
13    // イベント数分のグラフを作成
14    const Int_t N = t->GetEntries();
15    TGraph *gr[N];
16
17    for (Int_t ientry = 0; ientry < N; ientry++) {
18        t->GetEntry(ientry);
19
20        // 各イベントについてグラフを初期化
21        gr[ientry] = new TGraph();
22
23        // SetPoint()でデータを追加
24        Int_t Nsamp = (Int_t)adc.size();
25        for (Int_t isamp = 0; isamp < Nsamp; isamp++) {
26            gr[ientry]->SetPoint(isamp, isamp, adc[isamp]);
27        }
28    }
29}

このドキュメントでは、SetPoint()SetPointError()の実装パターンと、実際のデータ処理での応用例を示します。

SetPoint()の基本パターン

 1#include <TGraph.h>
 2
 3TGraph *g = new TGraph();
 4
 5// パターン1:インデックスを直接指定
 6g->SetPoint(0, 1.0, 2.0);
 7g->SetPoint(1, 2.0, 4.0);
 8g->SetPoint(2, 3.0, 6.0);
 9
10// パターン2:GetN()で現在の点数を取得(ループで便利)
11for (Int_t i = 0; i < 10; i++) {
12    Double_t x = i * 0.5;
13    Double_t y = x * x;
14    g->SetPoint(g->GetN(), x, y);
15}
16
17g->Draw("AP");

SetPoint()の第1引数はインデックス番号で、0から始まります。 ループで点を追加する場合、GetN()を使うと効率的です。

SetPointError()の実装パターン

 1#include <TGraphErrors.h>
 2#include <TMath.h>
 3
 4TGraphErrors *g = new TGraphErrors();
 5
 6// パターン1:SetPoint()の直後に同じインデックスで設定
 7g->SetPoint(0, 1.0, 2.0);
 8g->SetPointError(0, 0.1, 0.2);
 9
10g->SetPoint(1, 2.0, 4.0);
11g->SetPointError(1, 0.15, 0.3);
12
13// パターン2:インデックスを変数に保存(重要!)
14Int_t npt = g->GetN();
15g->SetPoint(npt, 3.0, 6.0);
16g->SetPointError(npt, 0.2, 0.4);
17
18// パターン3:ループでの追加
19for (Int_t i = 0; i < 5; i++) {
20    Double_t x = i + 1.0;
21    Double_t y = x * 2.0;
22    Double_t ex = TMath::Sqrt(x) * 0.1;
23    Double_t ey = y * 0.05;
24
25    Int_t n = g->GetN();
26    g->SetPoint(n, x, y);
27    g->SetPointError(n, ex, ey);
28}
29
30g->Draw("APE");

重要なポイント:

  • SetPoint()SetPointError()インデックスを一致させる

  • ループで追加する場合は、GetN()の結果を変数に保存してから使用

波形データをプロットする実装例

 1#include <TGraph.h>
 2#include <TFile.h>
 3#include <TTree.h>
 4#include <vector>
 5
 6void plotFADCWaveforms(const char *filename) {
 7    // ROOTファイルを開く
 8    TFile *f = new TFile(filename);
 9    TTree *t = (TTree*)f->Get("events");
10
11    // FADCデータを読み込むためのブランチを設定
12    std::vector<int> *adc = nullptr;
13    t->SetBranchAddress("adc", &adc);
14
15    const Int_t N = t->GetEntries();
16    TGraph *gr[N];
17
18    // 各イベントについて波形を処理
19    for (Int_t ientry = 0; ientry < N; ientry++) {
20        t->GetEntry(ientry);
21
22        // 空のグラフを作成
23        gr[ientry] = new TGraph();
24
25        // 波形データを追加
26        Int_t Nsamp = (Int_t)adc->size();
27        for (Int_t isamp = 0; isamp < Nsamp; isamp++) {
28            // SetPoint(index, x, y)
29            // - index:点のインデックス
30            // - x:サンプリング番号
31            // - y:ADC値
32            gr[ientry]->SetPoint(isamp, isamp, adc->at(isamp));
33        }
34
35        // グラフを描画(オプション)
36        // gr[ientry]->Draw("AL");
37    }
38
39    f->Close();
40}

FADCの波形データをプロットする場合、ループの中でGetN()を使わずにインデックスを直接指定するのが効率的です。

エラーバー付きデータの追加パターン

 1#include <TGraphErrors.h>
 2#include <TMath.h>
 3#include <vector>
 4
 5void addMeasurementData(TGraphErrors *g,
 6                        const std::vector<Double_t> &x_values,
 7                        const std::vector<Double_t> &y_values,
 8                        const std::vector<Double_t> &y_errors) {
 9    // 既存のグラフに新しいデータを追加
10    for (size_t i = 0; i < x_values.size(); i++) {
11        // 現在の点数を取得してインデックスとする
12        Int_t n = g->GetN();
13
14        g->SetPoint(n, x_values[i], y_values[i]);
15        g->SetPointError(n, 0.0, y_errors[i]);  // X誤差は0
16    }
17}
18
19// 使用例
20void example() {
21    TGraphErrors *g = new TGraphErrors();
22
23    // 測定データセット1
24    std::vector<Double_t> x1 = {1.0, 2.0, 3.0};
25    std::vector<Double_t> y1 = {1.5, 3.0, 4.5};
26    std::vector<Double_t> ey1 = {0.1, 0.15, 0.2};
27    addMeasurementData(g, x1, y1, ey1);
28
29    // 測定データセット2を追加
30    std::vector<Double_t> x2 = {4.0, 5.0, 6.0};
31    std::vector<Double_t> y2 = {6.0, 7.5, 9.0};
32    std::vector<Double_t> ey2 = {0.15, 0.2, 0.25};
33    addMeasurementData(g, x2, y2, ey2);
34
35    g->Draw("APE");
36}

複数のデータセットを追加する場合、GetN()を使ってインデックスを動的に取得することで、データの順序を自動的に管理できます。

よくある間違い

 1#include <TGraphErrors.h>
 2
 3TGraphErrors *g = new TGraphErrors();
 4
 5// ❌ 間違い:SetPointの直後にGetN()を呼び出すと、値が増加してしまう
 6g->SetPoint(g->GetN(), 1.0, 2.0);
 7g->SetPointError(g->GetN(), 0.1, 0.2);
 8// 結果:SetPointは0を、SetPointErrorは1を参照
 9// エラーが異なる点に付加される
10
11// ✅ 正しい:インデックスを保存してから使用
12Int_t n = g->GetN();
13g->SetPoint(n, 1.0, 2.0);
14g->SetPointError(n, 0.1, 0.2);
15// 結果:両方とも同じインデックスを参照

パフォーマンスに関する注意

 1#include <TGraph.h>
 2
 3TGraph *g = new TGraph();
 4
 5// パターン1:遅い(SetPoint()呼び出しが多い)
 6for (Int_t i = 0; i < 10000; i++) {
 7    g->SetPoint(g->GetN(), x[i], y[i]);
 8}
 9
10// パターン2:速い(配列をコンストラクタで渡す)
11TGraph *g = new TGraph(10000, x, y);

大量のデータを追加する場合は、配列からグラフを作成する方が効率的です。

関連メソッド

  • TGraph - 基本的な散布図

  • TGraphErrors - エラーバー付きグラフ

  • TGraph::GetN() - グラフの点数を取得

  • TGraph::GetPoint() - グラフの点座標を取得

参考資料