Geant4のコーディングガイドライン

Geant4にはユーザー向けの明確なコーディングのガイドラインは存在しません。 Geant4は開発の歴史が長く、すでに広く利用されているツールキットであることから、 それぞれのアプリケーション側のコーディングスタイルを尊重し、 Geant4側から強制はしないというスタンスのようです。

とはいえ、附属サンプルコードやリファレンスガイドを読んでいると「暗黙の慣習」のようなものを感じます。 このページでは、Geant4を使っていて感じる「慣習のようなもの」を整理してみました。 (C++一般の慣習なのか、Geant4固有の慣習なのか、は区別できていません)。

注釈

20年以上にわたる開発の歴史のためか、命名規則にはばらつきがあり、 内部のソースコードや附属サンプルでもスタイルが一貫してないと感じる箇所もありました。 結局のところ、多くのサンプルを読みながら「雰囲気」に慣れていくのが一番の近道かもしれません。

ファイル名の命名規則

Geant4のファイル名はPascalCaseが使われています。 また、クラス名とファイル名は一致しており、 ヘッダーファイルはinclude/クラス名.hh、 ソースファイルはsrc/クラス名.ccが使われています。

クラス名の命名規則

Geant4のクラス名にはPascalCaseが使われています。

G4*からはじまるクラス名は、Geant4が提供する標準クラスです。 その中でも、G4V*からはじまるクラスは、純粋仮想関数をもつ抽象基底クラスであり、 ユーザーが継承して実装すること前提となっています。 とくに G4VUser*およびG4User*クラスは、ユーザーによる拡張や設定を行うためのフック用クラスです。

G4VUserクラスとG4Userクラスの違い

G4VUser*クラスは、ユーザーが必ず継承して実装すべき抽象クラスで、 G4Userクラスは、必要に応じて継承・オーバーライド可能な具象クラスです。

ユーザー定義クラスの命名規則(の慣習)

1class DetectorConstruction : public G4VUserDetectorConstruction
2{
3    // 自作クラスの実装
4}

ユーザー定義クラスについては、 上記ように継承元のクラス名を明示的にクラス名に残すことで、 クラスの役割を明確にする命名が一般的です。

関数名の命名規則

関数名はPascalCaseが使われています。 セッターにはSet*、 ゲッターにはGet*という接頭辞に使われています。

変数名の命名規則

Geant4の変数名には、基本的にcamelCaseが基本的に使われています。 また、ゆるめのシステム・ハンガリアン記法が一部で採用されており、 変数の種類や役割が名前からわかるようになっています。

ローカル変数

ローカル変数には、aSteptheTrackのように、 接頭辞として不定冠詞や定冠詞が使われることがあります。 aan)(不定冠詞)は任意のインスタンス、 the(定冠詞)は特定のインスタンスを指します。

1const G4Step* aStep = ...;
2const G4Track* theTrack = ...;

メンバー変数

クラスのメンバー変数には、接頭辞としてf*(fieldの略)が使われます。

1G4int fNumberOfChambers = 5;
2G4LogicalVolume *fLogicalChamber = nullptr;

ポインター変数

ポインター型の変数には、接頭辞として p*(pointerの略)や fp*(field pointerの略)が使われることがあります。

1G4Material *pMaterial;
2G4VPhysicalVolume *fpWorld;

引数

関数の引数には、aValueanEventのように、接頭辞として不定冠詞のaanが使われる傾向があります 参照型では&aValue、 ポインター型では&apValueのように使われます。

1// G4Trackのメソッドを抜粋
2G4Track::SetTrackID(const G4int aValue)
3G4Track::SetPosition(const G4ThreeVector &aValue)
4G4Track::SetTouchableHandle(const G4TouchableHandle &apValue)

定数

定数(constな変数)やenum定数には、接頭辞としてk*(constantの意味)使われます。

1const G4double kMaxStepLength = 10.0 * mm;
2enum State { kAlive, kDead, kStopButAlive };

注釈

定数の接頭辞をk*とする由来は諸説あるようです。 数学分野で\(k\)を定数として扱う習慣に由来するという説、 constantの頭文字を音的にもじったという説、 などがありますが、いずれも決定的な根拠があるわけではなく、 慣習的に広まったと考えられています。

型エイリアス

Geant4ではG4*型の型エイリアスを使うことが推奨されています。 これらのエイリアスは、 プラットフォームごとの型実装の違いを吸収するために設けられています。

1// #include "globals.hh" // 非推奨(古い一括ヘッダー)
2#include "G4Types.hh"    // v10.6以降の推奨ヘッダー
3
4G4String name = "Geant4";     // std::stringに相当
5G4int numberOfParticles = 1;  // int に相当
6G4double energy = 1.0 * GeV;  // double に相当
7// 他にもある

入出力ストリーム(G4cout / G4cerr / G4debug / G4endl

Geant4では、C++標準のstd:coutstd:cerrの代わりに、 専用の出力ストリームを使うことが推奨されています。

1G4cout << "標準出力" << G4endl;
2G4err << "標準エラー出力" << G4endl;
3G4debug << "デバッグ用出力" << G4endl;

これらはGeant4の出力システムと統合されており、 UIやログのふるまいと一貫性を保つことができます。 とくに、G4debugはQt上で赤色でハイライト表示されるため、デバッグ時の視認性が高く、オススメです。

シングルトン

1auto rm = G4RunManagerFactory::CreateRunManager();
2auto em = G4EventManager::GetEventManager();
3auto sm = G4SDManager::GetSDMpointer();
4auto nm = G4NistManager::Instance();
5auto am = G4AnalysisManager::Instance();

RunManagerをはじめとするマネージャークラスは、シングルトンで設計されています。 コードのどこからでも、同じ方法で同じオブジェクトを参照できるようになっています。

注釈

マネージャークラスごとにシングルトンへのアクセス方法が異なるので注意してください。 関数名がブレているのは歴史的経緯なのではと推測しています。

リファレンス