ファイル出力したい(G4VAnalysisManager

1auto am = G4AnalysisManager::Instance();

G4AnalysisManagerは、シミュレーションで得られた結果を管理するインスタンスです。 シングルトンとして設計されており、 G4AnalysisManager::Instanceで取得できます。

初期設定したい

 1void MyRunAction::BeginOfRunAction(const G4Run* aRun) {
 2    auto am = G4AnalysisManager::Instance();
 3
 4    am->SetVerboseLevel(1);  // ログ詳細レベル
 5    am->SetFileName("my_output");  // 出力ファイル名
 6    am->SetHistDirectoryName("hist");  // ヒストグラム用ディレクトリ
 7    am->SetNtupleDirectoryName("ntuple");  // Ntuple用ディレクトリ
 8    am->SetFirstHistoId(0);  // ヒストグラムの開始番号
 9    am->SetFirstNtupleId(0);  // Ntupleの開始番号
10    am->SetNtupleMerging(true);  // マルチスレッド対応
11
12    am->OpenFile();  // 出力ファイルを開く
13}

G4AnalysisManagerG4UserRunAction::BeginOfRunAction()の中で設定します。

ファイルを開きたい(OpenFile

1auto am = G4AnalysisManager::Instance();
2am->SetDefaultFileType("csv");
3am->SetFileName("ファイル名")
4am->OpenFile();
5
6G4debug << "File opened: " << am->GetFileName() << G4endl;
7// File opened: ファイル名.csv

ファイルを閉じたい(CloseFile

1auto am = G4AnalysisManager::Instance();
2am->CloseFile()
3
4G4debug << "File closed: " << am->GetFileName() << G4endl;
5// File closed: ファイル名.csv

ファイル名を変更したい(SetFileName

1auto am = G4AnalysisManager::Instance()
2am->SetFileName("ファイル名.root");  // ROOT形式
3am->SetFileName("ファイル名.csv");   // CSV形式
4am->SetFileName("ファイル名");

ファイル名は拡張子をつけて設定できます。 拡張子がない場合は、SetDefaultFileTypeで指定した形式の拡張子が追加されます。

ファイル形式を変更したい(SetDefaultFileType

1auto am = G4AnalysisManager::Instance()
2am->SetDefaultFileType("csv");  // CSV形式
3am->SetDefaultFileType("root");  // ROOT形式

一般的なユーザーであればCSV形式で出力するとよいと思います。 CSV形式であれば、ユーザーが使い慣れているツールで解析できます。

HEP業界のユーザーであればROOT形式のほうが使いやすいと思います。 AnalysisManagerを使った付属サンプルのほとんどがROOTファイルで出力されるようになっています。

参考

同様の設定はマクロコマンドでもできます。

/analysis/setDefaultFileType csv
/analysis/setDefaultFileType root

サブディレクトリを作成したい(SetHistoDirectoryName / SetNtupleDirectoryName

1am->SetHistoDirectoryName("histo");
2am->SetNtupleDirectoryName("ntuple");

CSV形式のファイルを保存するディレクトリを設定できます。 ディレクトリはあらかじめ作成しておく必要があります。

ヒストグラムを作成したい(CreateH1 / CreateH2 / CreateH3

 1auto am = G4AnalysisManager::Instance()
 2// 1Dヒストグラム
 3am->CreateH1(
 4    "name1",  // オブジェクト名
 5    "title",  // ヒストグラムのタイトル
 6    xbins,    // ビンの数
 7    xmin,     // ビンの最小値
 8    xmax      // ビンの最大値
 9);  // h1 Id = 0
10
11am->CreateH1("name2", "title", xbins, xmin, xmax);  // h1 Id = 1
12
13// 2Dヒストグラム
14am->CreateH2("name3", "title", xbins, xmin, xmax, ybins, ymin, ymax);  // h2 Id = 0
15am->CreateH2("name4", "title", xbins, xmin, xmax, ybins, ymin, ymax);  // h2 Id = 1

CreateH1CreateH2CreateH3でヒストグラムを準備できます。

ヒストグラムのIDを取得したい(GetH1Id / GetH2Id / GetH3Id

1// ヒストグラムのIDを取得
2G4int id1 = am->GetH1Id("name1");
3G4int id2 = am->GetH1Id("name2");
4G4int id3 = am->GetH2Id("name3");
5G4int id4 = am->GetH2Id("name4");

ヒストグラムを作成したときの名前を使って、ヒストグラムのIDを取得できます。 EventActionクラスで、ヒストグラムに値をフィルするときに利用できます。

ヒストグラムにフィルしたい(FillH1 / FillH2 / FillH3

1am->FillH1(id, value, weight);
2am->FillH2(id, xvalue, yvalue, weight);
3am->FillH3(id, xvalue, yvalue, zvalue, weight);

ヒストグラムIDを指定して値をフィルできます。

ヒストグラムを確認したい(GetH1 / GetH2 / GetH3

1auto h1 = am->GetH1(id);
2G4String name = am->GetH1Name(id);
3
4G4double mean = h1->mean();
5G4double rms = h1->rms();

ヒストグラムIDを指定して、ヒストグラムを取得できます。 取得したヒストグラムを使って、平均値などを取得できます。

1G4int nH1s = am->GetNofH1s;
2for ( G4int i=0; i<nH1s; ++i) {
3    auto h1 = am->GetH1(i);
4    if (h1 == nullptr) continue;
5    G4String name = am->GetH1Name(i);
6    G4cout << "Name: " << name << G4endl;
7    G4cout << "Mean: " << h1->mean() << G4endl;
8    G4cout << "Rms: " << h1->rms() << G4endl;
9}

GetNofH1でヒストグラムの数が取得できます。 その数だけループして確認できます。

Ntupleを作成したい(CreateNtuple / CreateNtupleDColumn / FinishNtuple

1am->CreateNtuple("Ntuple1", "title1");  // ntuple Id = 0
2am->CreateNtupleIColumn("name1");  // column Id = 0
3am->CreateNtupleDColumn("name2");  // column Id = 1
4am->FinishNtuple();
5
6am->CreateNtuple("Ntuple2", "title2");  // ntuple Id = 1
7am->CreateNtupleIColumn("name3");  // column Id = 0
8am->CreateNtupleDColumn("name4");  // column Id = 1
9am->FinishNtuple();

CreateNtupleでNtupleを作成します。 CreateNtupleDColumnCreateNtupleIColumnでカラムを定義します。 FinishNtupleでNtupleを閉じます。

これを繰り返すことで複数のNtupleを作成できます。

AnalysisManagerを使いたくない

G4AnalysisManagerを使わなくてもファイルに出力できます。 その場合、C++の標準ライブラリを使い、 ユーザーのお好みで std::tuplestd::mapstd::vectorなどを使います。

G4VAnalysisManagerを使って、ファイルに出力できます。 Geant4は独自のデータベース形式を持たない代わりに、 ユーザー自身がいろいろなフォーマットに出力できるようになっています。

ファイル操作(設定/開く/閉じる)はランごとに実行すればよいため、RunActionの中で動作を定義します。 ユーザーが編集する必要があるユーザーフック関数は以下の3箇所です。

  1. RunAction::RunAction: RunActionクラスのコンストラクターで、ファイル名や出力形式を設定します。 また、データを保存する「箱の形」を用意します。

  2. RunAction::BeginOfRunAction: ラン開始時にファイルを開きます。

  3. RunAction::BeginOfRunAction: ラン終了時にデータを保存し、ファイルを閉じます。

以下は、付属サンプルB4dとB5から該当箇所を抜粋して、説明を追加してみました。

 1// //////////////////////////////////////////////////
 2// include/RunAction.hh
 3// //////////////////////////////////////////////////
 4
 5#include "G4UserRunAction.hh"
 6#include "G4Run.hh"
 7
 8class RunAction : public G4UserRunAction
 9{
10    public:
11      RunAction();
12      ~RunAction() override = default;
13
14      void BeginOfRunAction(const G4Run* aRun) override;
15      void EndOfRunAction(const G4Run* aRun) override;
16
17    private:
18      // (オプション)
19      // EventAction* fEventAction = nullptr;
20}
 1// //////////////////////////////////////////////////
 2// src/RunAction.cc
 3// //////////////////////////////////////////////////
 4
 5// RunActionのコンストラクタ(初期化)
 6RunAction::RunAction()
 7{
 8    // G4AnalysisManagerのインスタンスを作成する
 9    // このインスタンスはシングルトンになっている
10    auto am = G4AnalysisManager::Instance();
11
12    // 表示レベルを設定する(オプション)
13    am->SetVerboseLevel(1);
14
15    // ファイル名を設定する(オプション)
16    // マクロファイルで変更可能
17    am->SetFileName("ファイル名");
18
19    // ファイル形式を指定する(オプション)
20    // ファイル名に拡張子がない場合はROOT形式になる
21    am->SetDefaultFileType("csv");
22    // am->SetDefaultFileType("root");
23
24    // /////////////////////////
25    // ユーザー独自の設定
26    // 目的に合わせて自分で考える部分
27    ///////////////////////////
28
29    // 1Dヒストグラムを作成する
30    // am->CreateH1("name", "title", nbins, xmin, xmax);
31    am->CreateH1("Chamber1", "Drift Chamber 1 # Hits", 50, 0., 50); // h1 Id = 0
32    am->CreateH1("Chamber2", "Drift Chamber 2 # Hits", 50, 0., 50); // h1 Id = 2
33
34    // 2Dヒストグラムを作成する
35    // am->CreateH2("name", "title", nxbins, xmin, xmax, nybins, ymin, ymax);
36    am->CreateH2("Chamber1 XY", "Drift Chamber 1 X vx Y", 50, -1000., 1000., 50, -300., 300.);  // h2 Id = 0
37    am->CreateH2("Chamber2 XY", "Drift Chamber 2 X vx Y", 50, -1000., 1000., 50, -300., 300.);  // h2 Id = 1
38
39    // Ntupleを作成する
40    // am->CreateNtuple("name", "title);
41    am->CreateNtuple("B5", "Hits");
42    // am->CreateNtupleIColumn("name");
43    am->CreateNtupleIColumn("Dc1Hits");  // column Id = 0
44    am->CreateNtupleIColumn("Dc2Hits");  // column Id = 1
45    // am->CreateNtupleDColumn("name");
46    am->CreateNtupleDColumn("ECEnergy");  // column Id = 2
47    am->CreateNtupleDColumn("HCEnergy");  // column Id = 3
48    am->CreateNtupleDColumn("Time1");     // column Id = 4
49    am->CreateNtupleDColumn("Time2");     // column Id = 5
50    // am->CreateNtupleDColumn("name", vector);
51    am->CreateNtupleDcolumn("ECEnergyVector", fEventAction->GetEmCalEdep());  // column Id = 6
52    am->CreateNtupleDcolumn("HCEnergyVector", fEventAction->GetHadCalEdep());  // column Id = 7
53    am->FinishNtuple();
54
55    // Ntupleのファイル名を設定する
56    // am->SetNtupleFileName(id, "fileName");
57    am->SetNtupleFileName(0, "B5ntuple");
58}
 1// //////////////////////////////////////////////////
 2// src/RunAction.cc
 3// //////////////////////////////////////////////////
 4
 5// ラン開始時の処理
 6void RunAction::BeginOfRunAction(const G4Run* aRun)
 7{
 8    // ラン番号を表示する
 9    G4cout << "Run started: " << run->GetRunID() << G4endl;
10
11    // AnalysisManagerのインスタンスを取得する
12    // AMがシングルトンなので、作成済みのインスタンスが取得できる
13    auto am = G4AnalysisManager::Instance()
14
15    // 前のランの結果をリセットする
16    // 付属サンプルB5は、ラン終了時に自動リセットせず、
17    // ラン開始時にリセットしている
18    am->Reset();
19
20    // ファイルを開く
21    // ファイル名はコンストラクタで設定済み
22    am->OpenFile();
23    G4cout << "File opened: " << am->GetFileName() << G4endl;
24}
 1// //////////////////////////////////////////////////
 2// src/RunAction.cc
 3// //////////////////////////////////////////////////
 4
 5// ラン終了時の処理
 6void RunAction::EndOfRunAction(const G4Run* aRun)
 7{
 8    // AnalysisManagerのインスタンスを取得する
 9    // AMがシングルトンなので、作成済みのインスタンスが取得できる
10    auto am = G4AnalysisManager::Instance()
11
12    // 取得したデータをファイルに出力する
13    am->Write();
14
15    // ファイルを閉じる
16    am->CloseFile(false);
17    // サンプルB5では、ラン終了時にデータ(ヒストグラム)を
18    // 保持したままにしている
19    // デフォルトは自動リセットされる
20    // am->CloseFile(reset=true);
21    G4cout << "File closed: " << am->GetFileName() << G4endl;
22}

ヒント

データ取得はイベントごとやステップごとに値を取得するため、 EventActionクラスやSteppingActionクラスで定義します。

リファレンス