測定器したい(G4VUserDetectorConstruction
)
測定器の構造はユーザーが定義する必要があります。
G4VUserDetectorConstruction
クラスを継承した自作クラスを作成し、
Construct
(必須)やConstructSDandField
(オプション)を実装します。
親クラス
1G4VUserDetectorConstruction() = default;
2virtual ~G4UserDetectorConstruction() = default;
3virtual G4VPhysicalVolume* Construct() = 0;
4virtual void ConstructSDandField();
親クラス(G4VUserDetectorConstruction
)のメンバー関数を抜粋しました。
コンストラクターとデストラクターは、このデフォルトの設定を引き継げばよさそうです。
Construct()
は測定器の構造を初期化して配置する関数です。
純粋仮想関数になっているため、自作クラスでoverrideが必要です。
必要なソリッド、論理ボリューム、物理ボリュームはすべてこの関数の中で生成します。
ConstructSDandField()
は、Construct
で生成した論理ボリュームに対して
有感検出器(SensitiveDetector)や場(Field)を設定するための関数です。
マルチスレッド環境で実行する場合は、自作クラスでoverrideが必要です。
注釈
ConstructSDandField
はGeant4.10で追加されたようです。
Geometryクラス
1// //////////////////////////////////////////////////
2// include/Geometry.hh
3// //////////////////////////////////////////////////
4
5#ifndef Geometry_h
6#define Geometry_h 1
7
8#include "G4VUserDetectorConstruction.hh"
9#include "G4LogicalVolume.hh"
10#include "G4SystemOfUnits.hh"
11
12namespace ToyMC
13{
14
15class Geometry : public G4VUserDetectorConstruction
16{
17 public:
18 // コンストラクタとデストラクタは
19 // 親クラスを引き継ぐことにする
20 Geometry() = default;
21 ~Geometry() = default;
22
23 public:
24 // これらの関数は override する
25 G4PhysicalVolume* Construct() override;
26 void ConstructSDandField() override;
27
28 // __________________________________________________
29 // これ以降は僕のベストプラクティス
30 private:
31 // ワールドを設定するための関数とパラメーター
32 G4LogicalVolume* SetupWorldVolume();
33 G4String fWorldLVName = "World";
34 G4String fWorldMaterial = "G4_AIR";
35 G4double fWorldX = 15. * cm;
36 G4double fWorldY = 15. * cm;
37 G4double fWorldZ = 15. * cm;
38
39 private:
40 // 測定器を設定するための関数とパラメーター
41 // 測定器ごとに用意する
42 G4LogicalVolume* SetupDetectorVolume();
43 G4String fDetectorLVName = "Detector";
44 G4String fDetectorMaterial = "G4_WATER";
45 G4double fDetectorX = 5. * cm;
46 G4double fDetectorY = 5. * cm;
47 G4double fDetectorZ = 5. * cm;
48
49 public:
50 // main()関数から測定器のパラメーターを確認・変更するメソッド
51 G4String GetDetectorLVName() const { return fDetectorLVName; };
52 void SetDetectorLVName(const G4String &name) { fDetectorLVName = name};
53
54 G4String GetDetectorMaterial() const { return fDetectorMaterial; };
55 void SetDetectorMaterial(const G4String &name) { fDetectorMaterial = name};
56
57 G4double GetDetectorX() const { return fDetectorX; };
58 void SetDetectorX(const G4double length) { fDetectorX = length; };
59
60 G4double GetDetectorY() const { return fDetectorY; };
61 void SetDetectorY(const G4double length) { fDetectorY = length; };
62
63 G4double GetDetectorZ() const { return fDetectorZ; };
64 void SetDetectorZ(const G4double length) { fDetectorZ = length; };
65
66};
67
68}; // namespace ToyMC
69
70#endif
自作クラス名をGeometry
として作成しています。
namespace
はToyMC
(お遊びのモンテカルロの意味)としました。
また、必要な論理物体(G4LogicalVolume)を作成する関数も用意しました。
1public:
2 Geometry() = default;
3 ~Geometry() = default;
コンストラクターとデストラクターは親クラスを引き継ぐことにしました。
Geometry::Construct
1public:
2 G4PhysicalVolume* Construct() override;
3 void ConstructSDandField() override;
override
キーワードを設定し、親クラスが持っている(純粋)仮想関数を上書きすることを明示しました。
また、overrideをつけておくと、関数名をタイポしていた場合にコンパイルエラーで指摘してくれます。
メンバー変数
1private:
2 // ワールドを設定するための関数とパラメーター
3 G4LogicalVolume* SetupWorldVolume();
4 G4String fWorldLVName = "World";
5 G4String fWorldMaterial = "G4_AIR";
6 G4double fWorldX = 15. * cm;
7 G4double fWorldY = 15. * cm;
8 G4double fWorldZ = 15. * cm;
これ以降は、僕がカスタマイズするときのベストプラクティス(と思っている)な書き方です。参考までにどうぞ。 ここでは、ワールドの大きさのパラメーターと、それをセットアップする関数を宣言しています。 具体的な中身は実験室を作りたい(SetupWorldVolume)を参照してください。
1private:
2 // 測定器を設定するための関数とパラメーター
3 // 測定器ごとに用意する
4 G4LogicalVolume* SetupDetectorVolume();
5 G4String fDetectorLVName = "Detector";
6 G4String fDetectorMaterial = "G4_WATER";
7 G4double fDetectorX = 5. * cm;
8 G4double fDetectorY = 5. * cm;
9 G4double fDetectorZ = 5. * cm;
10
11public:
12 // main()関数から測定器のパラメーターを確認・変更するメソッド
13 G4String GetDetectorLVName() const { return fDetectorLVName; };
14 void SetDetectorLVName(const G4String &name) { fDetectorLVName = name};
15
16 G4String GetDetectorMaterial() const { return fDetectorMaterial; };
17 void SetDetectorMaterial(const G4String &name) { fDetectorMaterial = name};
18
19 G4double GetDetectorX() const { return fDetectorX; };
20 void SetDetectorX(const G4double length) { fDetectorX = length; };
21
22 G4double GetDetectorY() const { return fDetectorY; };
23 void SetDetectorY(const G4double length) { fDetectorY = length; };
24
25 G4double GetDetectorZ() const { return fDetectorZ; };
26 void SetDetectorZ(const G4double length) { fDetectorZ = length; };
実験室の中に配置する物体を作成する部分です。 配置する測定器の種類の数だけ、コピペが必要です。
ここでは大きさをprivateで定義し、それにアクセスするためのセッター/ゲッターをpublicで定義しました。
これによりmain()
関数から測定器のパラメーターを変更できます。
メイン関数
1#include "Geometry.hh"
2
3int main(int argc, char** argv)
4{
5 auto rm = G4RunManagerFactory::CreateRunManager();
6
7 auto geometry = new Geometry{};
8 geometry->SetDetectorMaterial("G4_Pb"); // 測定器の素材を"G4_Pb"に変更
9 rm->SetUserInitialization(geometry);
10
11}
main()
関数の中で、
Geometry
クラスのインスタンスを作成し、
SetUserInitialization
でRunManagerに追加します。
publicなセッターを作成しておいたため、geometry->SetDetectorMaterial
のように変更できます。
ヒント
実験の最適なセットアップを検討している段階では、検出器や標的の素材を変えたり、厚みを変えたりしたいはずです。
main()
関数から変更できるようにしておくと、そのようなスタディがはかどります。