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() - グラフの点座標を取得