ステッピングアクションしたい(G4UserSteppingAction
)
ステップごとのデータを収集したい場合は、
G4UserSteppingAction
クラスを継承したクラスを作成します。
ヒント
測定器のヒット情報を取得するときにステップ情報へのアクセスが必要になります。 その場合は、迷わずG4VSensitiveDetectorクラスを使いましょう。
親クラス
1G4UserSteppingAction();
2virtual ~G4UserSteppingAction() = default;
3virtual void UserSteppingAction(const G4Step*){};
親クラスのメンバー関数を抜粋しました。
コンストラクターとデストラクターは、この設定を引き継げばよさそうです。
UserSteppingAction()
は、ステッピング処理で実行される関数です。
仮想関数になっているため、設定は必須ではありません。
必要に応じて自作クラスでoverrideします。
SteppingActionクラス
1// include/SteppingAction.hh
2
3#ifndef SteppingAction_h
4#define SteppingAction_h 1
5
6#include "G4UserSteppingAction.hh"
7
8namespace ToyMC
9{
10
11class SteppingAction : public G4UserSteppingAction
12{
13 public:
14 SteppingAction() = default;
15 ~SteppingAction() = default;
16
17 void UserSteppingAction(const G4Step* aStep) override;
18}
19
20} // namespace ToyMC
21
22#endif
ステッピングアクションはG4UserSteppingAction
を継承したクラスを自作します。
仮想関数として定義されているUserSteppingAction
を実装します。
UserSteppingAction
1void SteppingAction::UserSteppingAction(const G4Step *aStep)
2{
3 G4coud << "UserSteppingAction" << G4endl;
4
5 G4int parent_id = aStep->GetTrack()->GetParentID();
6
7 // 入射粒子の位置を表示
8 if (parent_id == 0) {
9 G4int track_id = aStep->GetTrack()->GetTrackID();
10 G4int step_id = aStep->GetTrack()->GetCurrentStepNumber();
11 auto p = aStep->GetPreStepPoint()->GetPosition() / mm;
12 auto q = aStep->GetPostStepPoint()->GetPosition() / mm;
13 G4cout << "TrackID: " << track_id << G4endl;
14 G4cout << "StepID: " << step_id << G4endl;
15 G4cout
16 << "Pre : (" << p.getX()
17 << ", " << p.getY()
18 << ", " << p.getZ()
19 << ") [mm]"
20 << G4endl;
21 G4cout
22 << "Post: (" << q.getX()
23 << ", " << q.getY()
24 << ", " << q.getZ()
25 << ") [mm]"
26 << G4endl;
27 }
28}
入射した粒子のステッピング処理を確認するため、ステップ番号とその両端の座標を表示してみました。
このようにデバッグ的にUserSteppingAction
をしてみるのはよいと思いますが、測定器のヒット情報はG4VSensitiveDetector::ProcessHits
に定義したほうがよいと思います。
境界判断したい
1void SteppingAction::UserSteppingAction(const G4Step *aStep)
2{
3 auto pre_step = aStep->GetPreStepPoint();
4 auto status = pre_step->GetStepStatus();
5
6 if (status == fWorldBoundary) { G4cout << "ワールド境界の外に到達" << G4endl; };
7 if (status == fGeomBoundary) { G4cout << "ジオメトリ境界に到達 = いまのボリュームに入射した" << G4endl; };
8 if (status == fUserDefinedLimit) { G4cout << "ユーザー設定のリミットに到達" << G4endl; };
9 if (status == fUndefined) { G4coud << "ステップが未定義" << G4endl; };
10};