ヒット配列したい(G4VHitsCollection
/ G4THitsCollection
)
1G4THitsCollection<SensorHit> hit_collection;
2
3// テンプレートクラスを使うことで、任意の型を持った変数を定義できます。
4// ここでは
5// hit_collection = [SensorHit1, SensorHit2, SensorHit3, ...]
6// のようなSensorHitオブジェクトが詰まったコンテナー配列を定義しています。
ひとつイベントで発生した複数のヒットは、SensorHit
型を持つヒット配列として保存します。
ヒット配列はG4THitsCollection
テンプレートクラスを使って定義します。
G4THitsCollection
はG4VHitsCollection
を継承したテンプレートクラスですが、そのさらに親をたどるとstd:vector
をベースにしているようです。
親クラス
1G4VHitsCollection() = default;
2G4VHitsCollection(G4String detector_name, G4String collection_name);
3virtual ~G4HitsCollection() = default;
4virtual void DrawAllHits(){};
5virtual void PrintAllHits(){};
6virtual G4VHit* GetHit(size_t) const {return nullptr;};
7virtual size_t GetSize() const {return 0;};
G4THitsCollection
クラスは、G4VHitsCollection
クラスを継承したテンプレートクラスです。
コンストラクターとデストラクターは、親クラスのものをそのまま使っているようです。
GetHit
とGetSize
は、テンプレートクラスでoverrideして再定義しています。
テンプレートクラス
1G4THitsCollection();
2G4THitsCollection(G4String detector_name, G4String collection_name);
3~G4THitsCollection() override;
4inline void* operator new(size_t);
5inline void operator delete(void* aHC)
6void DrawAllHits() override;
7void PrintAllHits() override;
8inline size_t insert(T* aHit);
9inline size_t entries() const;
10G4VHit* GetHit(size_t i) const override { return ((std::vector<T*>*)theCollection)[i]; };
11size_t GetSize() const override { return ((std::vector<T*>*)theCollection)->size(); };
G4THitsCollection
クラスのメンバー関数を抜粋しました。
コンストラクターとデストラクターの引数は、親クラスを引き継いで定義されています。
GetHit
とGetSize
は、内部変数theCollection
に対する処理として再定義されています。
またその内部変数にヒットを追加するためのinsert
が追加されています。
型エイリアスしたい(using
/ typedef
)
1// C++11で導入された文法
2// using コレクション名 = G4THitsCollection<ヒットクラス名>;
3using SensorHitsCollection = G4THitsCollection<SensorHit>;
4SensorHitsCollection hit_collection{};
5SensorHitsCollection hit_collection{"DetectorName", "CollectionName"};
G4THitsCollection<SensorHit>
型は名前が長いため、型エイリアスを定義して
SensorHitsCollection
型という名前で使えるようにします。
注釈
using
はC++11以降で使える型エイリアスの宣言です。
以前はtypedef
が使われていました。
基本的には同じことができるそうなのですが、高機能なusing
を使えばよいようです。
1// C言語から使われている文法
2// typedef G4THitsCollection<ヒットクラス名> コレクション名;
3typedef G4THitsCollection<SensorHit> SensorHitsCollection;
4SensorHitsCollection hit_collection();
5SensorHitsCollection hit_collection("DetectorName", "CollectionName");
SensorHitクラス
SensorHitsCollection
型はSensorHit
クラスのファイルの中で定義し、Sensor
クラスの中で使います。
1// 0. SensorHit.hh で型エイリアスを定義する
2using SensorHitsCollection = G4THitsCollection<SensorHit>;
SensorHitsCollectionを初期化したい
1void Sensor::Initialize(G4HCofThisEvent* /*aHCE*/)
2{
3 // Sensor::Initializeで初期化
4 // 1. ヒット配列を初期化
5 // fSensorHitsCollection はprivate変数で定義
6 auto fSensorHitsCollection = new SensorHitsCollection{"DetectorName", "CollectionName"};
7}
SensorHitsCollectionにSensorHitを追加したい
1G4bool Sensor::ProcessHits(G4Step *aStep)
2{
3 // Sensor::ProcessHitsの処理
4 // 2. ヒット(SensorHit)を新しく作成
5 SensorHit *hit = new SensorHit{};
6 hit->Fill(aStep); // G4Step *aStep とする
7
8 // 3. ヒット配列にヒットを追加
9 // ここでは同じヒットを複数回追加しているが、
10 // 実際には別のステップで取得したヒットを追加する
11 hitCollection->insert(hit);
12 hitCollection->insert(hit);
13 hitCollection->insert(hit);
14 hitCollection->insert(hit);
G4EventにSensorHitsCollectionを渡したい
1void Sensor::EndOfEvent(G4HCofThisEvent *aHCE)
2{
3 // EndOfEventの処理
4 // 4. データを確認
5 G4int entries = hitCollection->entries();
6 for (G4int i = 0; i < entries; i++)
7 {
8 //SensorHit * h = (*hitCollection)[i]
9 SensorHit *h = hitCollection->GetHit(i);
10 h->Print();
11 }
12
13 // 5. HCEにSensorHitsCollectionを追加
14 aHCE->AddHitsCollection(0, fSensorHitsCollection);
15}
G4EventでSensorHitsCollectionを取得したい
1void EventAction::EndOfEventAction(const G4Event *aEvent)
2{
3 // このイベントのヒット配列を取得する
4 G4HCofThisEvent *hce = aEvent->GetHCofThisEvent();
5 // ヒット配列の数を確認する
6 G4int n_collections = hce->GetNumberOfCollections();
7 for (G4int i = 0; i < n_collections; i++)
8 {
9 // ヒット配列の配列からヒット配列を取得する
10 auto hc = hce->GetHC(i);
11
12 // ヒット配列の中のヒット数を確認する
13 G4int n_hits = hc->entries();
14 for (G4int j = 0; j < n_hits; j++)
15 {
16 // ヒット配列からヒットを取得する
17 auto h = hc->GetHit(j);
18
19 // ヒットの中身を表示する
20 h->Print();
21
22 // ファイルに保存する処理はここに書くとよい
23 h->ToCsvString();
24 }
25 }
26}
有感検出器でヒットがあった場合のヒット配列の処理の流れを、 ユーザー定義が必要な関数と対応させてみました。