KAHIBARO
Discord Login Register

31.6. Naming Conventions

Why Naming Conventions Matter

Consistent names make a Geant4 application readable, maintainable, and easier to debug. In a typical detector simulation you will handle many related concepts, such as geometry, materials, hits, and analysis objects. If every developer invents their own naming style, it becomes hard to see how pieces fit together.

Geant4 itself follows a relatively clear convention based on prefixes such as G4, suffixes such as *Action, and mixed case identifiers. Adopting a compatible style for your own code helps new users recognize class roles quickly and reduces the mental effort of moving between Geant4 code and your application.

In this chapter the focus is on practical, concrete naming rules for a beginner level project, and on being consistent rather than on enforcing one rigid standard.

Important rule: Choose one clear naming style early, write it down, and use it everywhere. Inconsistent names are worse than a style that is merely imperfect.

General Naming Style

At a minimum you should decide:

  1. How to name classes, methods, variables, constants, and files.
  2. How to indicate roles, such as user actions or geometry classes.
  3. How to indicate units and coordinate systems in variable names.

A simple and Geant4 friendly set of rules looks like this:

Use UpperCamelCase for class names, for example MyDetectorConstruction.
Use lowerCamelCase for variables and methods, for example worldLogical, ConstructGeometry().
Use UPPER_SNAKE_CASE for compile time constants, for example const G4double PI = 3.14159;.
Use clear, descriptive names rather than abbreviations such as x1 or val.

Geant4 prefixes its own classes with G4. You should usually avoid this prefix in your application classes to keep a clear separation between framework code and user code.

Important rule: Never use single letter or cryptic names for anything that lives longer than a few lines. Variable names should communicate meaning, not just type.

Class Names and File Names

In Geant4, most user code is organized into C++ classes that customize the toolkit behavior. Naming these classes well makes it immediately obvious which part of the simulation they control.

A good general rule is that each public class lives in its own pair of files:

Class roleClass name exampleHeader fileSource file
Detector constructionMyDetectorConstructionMyDetectorConstruction.hhMyDetectorConstruction.cc
Physics listMyPhysicsListMyPhysicsList.hhMyPhysicsList.cc
Primary generatorMyPrimaryGeneratorActionMyPrimaryGeneratorAction.hhMyPrimaryGeneratorAction.cc
Run actionMyRunActionMyRunAction.hhMyRunAction.cc
Event actionMyEventActionMyEventAction.hhMyEventAction.cc
Stepping actionMySteppingActionMySteppingAction.hhMySteppingAction.cc
Sensitive detectorMyCalorimeterSDMyCalorimeterSD.hhMyCalorimeterSD.cc

Use the same base name for the class and its files, with .hh for the header and .cc for the implementation. This aligns with conventions already discussed in the C++ chapters, but here you apply them consistently throughout a full application.

It is useful to include the detector or project name in the class name. For instance, if you build a gamma detector called "GammaDet", you might use GammaDetDetectorConstruction, GammaDetRunAction, and so on. This helps when you later work with more than one detector in the same repository.

Important rule: Ensure that the header file name exactly matches the class name. This makes include statements predictable and avoids duplicate or confusing files.

Geant4 User Class Naming Patterns

Geant4 expects you to provide specific "user" classes that inherit from toolkit base classes. While Geant4 does not enforce names, following clear patterns makes code much easier to scan.

A common and practical set of naming patterns is:

Use *DetectorConstruction for a class inheriting from G4VUserDetectorConstruction.
Use PhysicsList or Physics for a class inheriting from G4VModularPhysicsList or similar.
Use *ActionInitialization for a class inheriting from G4VUserActionInitialization.
Use RunAction, EventAction, SteppingAction, TrackingAction, *StackingAction for action classes that inherit from G4UserRunAction, G4UserEventAction, and others.
Use *PrimaryGeneratorAction for a class inheriting from G4VUserPrimaryGeneratorAction.

You can include a detector or experiment name as a prefix to differentiate between different configurations. For example:

CalorimeterDetectorConstruction, CalorimeterRunAction, CalorimeterSteppingAction.

For sensitive detectors and hits, it is helpful to reflect the detector component in the name:

Use *SD for sensitive detector classes inheriting from G4VSensitiveDetector, such as TrackerSD, CalorimeterSD.
Use *Hit for hit classes inheriting from G4VHit, such as TrackerHit, PMTHit.

For analysis classes using G4AnalysisManager, you can choose names such as AnalysisManager or MyAnalysis. Keeping the word "Analysis" present prevents confusion with geometry or physics classes.

Important rule: Include the Geant4 role in the class name, such as RunAction or DetectorConstruction. Do not name a class simply Manager or Main without context.

Geometry, Material, and Volume Naming

Detector geometry is often the most complex part of a Geant4 application. You will create many solids, logical volumes, and physical volumes. Names that consistently indicate type and level of abstraction make this manageable.

A simple and effective pattern for geometry objects is shown in the following table:

ConceptSuggested naming patternExample
SolidsomethingSolidworldSolid, crystalSolid
Logical volumesomethingLogical or logicSomethingworldLogical, logicCrystal
Physical volumesomethingPhysical or physSomethingworldPhysical, physCrystal

Use the same "something" part across the three associated objects to make their relationship visible. For example, the world volume can be:

worldSolid of type G4Box
worldLogical of type G4LogicalVolume
worldPhysical of type G4PVPlacement

Materials should be named according to their physical substance and, if useful, their role:

worldMaterial, airMaterial, waterMaterial, scintillatorMaterial, leadShieldMaterial.

For elements and isotopes, you can mirror common chemical notation with readable names, such as elH, elO, elPb. For composite materials, descriptive names are more helpful, such as plasticScintMaterial or boneMaterial.

Use internal Geant4 names from G4NistManager when you build from the NIST database, but wrap them in clearly named variables. For example:

G4Material* airMaterial = nist->FindOrBuildMaterial("G4_AIR");

In macros, use consistent volume and region names. If the logical volume is called worldLogical, you might give the physical volume or region a similar name, such as /world or WorldRegion, to avoid confusion when you use commands such as /vis/scene/add/volume.

Important rule: Keep the same base name for related solid, logical, and physical volumes. Changing crystalSolid to detectorLogical breaks the mental link between them.

Units, Coordinates, and Physical Quantities

Geant4 has its own unit system and encourages explicit units such as 10.0cm or 1.0MeV. You can reinforce this clarity with naming conventions for variables that represent physical quantities.

It is useful to embed the quantity and sometimes the unit or coordinate system in the variable name:

For positions, include something like Pos or Position, and if relevant, Global or Local, such as sourcePosition, hitGlobalPos, hitLocalPos.
For energies, use energy, energyMeV, or eDep, for example beamEnergy, beamEnergyMeV, energyDeposit, eventEDep.
For lengths or dimensions, include Length, Size, Radius, or explicit unit hints, for example worldSizeXY, worldSizeZ, crystalLength, shieldThickness.
For times, use time, timeOfFlight, hitTime.

In C++, the type already carries the unit information, in the sense that a G4double might be in centimeters or meters, but the name clarifies how the variable is supposed to be interpreted. This matters especially when you perform unit conversions or export data to external tools such as ROOT.

Consider the following examples, which mix named variables and explicit Geant4 units:

G4double crystalLength = 5.0*cm;
G4double beamEnergy = 662.0*keV;
G4ThreeVector sourcePosition = G4ThreeVector(0., 0., -10.*cm);

Coordinate systems can also be a source of confusion. When you store positions, it can be worth including Global or Local in the variable name if both appear in the same context, such as hitGlobalPosition and hitLocalPosition.

Important rule: Make sure that variable names for physical quantities never hide their meaning. When in doubt, add the quantity type or coordinate system to the name.

Action and Analysis Naming

User actions such as RunAction, EventAction, and SteppingAction are natural places to accumulate statistics or call the analysis manager. If you use clear naming conventions for actions and analysis objects, you will more easily trace how data moves from the simulation core to your output files.

A common pattern is:

Name analysis related classes with the word Analysis included, such as GammaDetAnalysis.
Name member variables that store analysis tools clearly, for example analysisManager, not am or mgr.
Name histograms and ntuples with descriptive strings that match internal variables, such as "EdepInCrystal", "DepthDose", "HitTime".

For histograms and ntuple column names, keep them short but descriptive, and avoid ambiguous abbreviations. For example:

Use "Edep" instead of "E".
Use "x_mm", "y_mm", "z_mm" to carry unit meaning into the output, especially when writing into formats such as ROOT or CSV.
Use "TrackID", "ParentID", "ParticleName" for particle identification.

You can mirror these output names in your C++ variables, such as edep, x_mm, or trackID, which simplifies filling and reading the data.

In the main program or in the action initialization class, keep object names descriptive of their role:

auto runManager = new G4RunManager;
auto detector = new GammaDetDetectorConstruction;
auto physicsList = new FTFP_BERT;
auto actionInitialization = new GammaDetActionInitialization;

Even if you use auto, the pointer or variable name still carries meaning that will help future readers of the code.

Important rule: Align the names of analysis objects, histograms, and output columns with the physical quantity they represent. Output data should be understandable without guessing.

Macro Commands and User Interface Names

Macro files in Geant4 let you configure sources, geometry, runs, and visualization without recompiling. Names used in macros should match or closely resemble names used in C++ so that it is obvious what a given command refers to.

When you define new UI commands through G4UIcmdWithAString, G4UIcmdWithADoubleAndUnit, or other classes, give the command paths clear and structured names, such as:

/detector/setCrystalLength
/detector/setShieldMaterial
/source/setEnergy
/analysis/setOutputFileName

Include the high level object or concept as the first part of the path (/detector, /source, /analysis) and then use verbs like set, enable, disable, add for actions. The last part of the path should match the internal variable name or at least the physical quantity, such as CrystalLength or ShieldThickness.

For macro variables that you implement by hand or as comments, keep them readable as well. Even though macro commands are not compiled, they are part of your application's public interface, so they deserve the same care as C++ code.

In visualization macros, names such as /vis/scene/add/volume world should use volume names that appear clearly in your geometry, such as "world" for the physical world volume. Avoid mismatches between C++ volume names and macro usage since they will lead to confusing errors when Geant4 cannot find a requested object.

Important rule: Treat macro command paths as an API. Use consistent, hierarchical names that mirror your C++ classes and variable names.

Project Level Naming and Namespaces

Beyond individual classes and variables, it is helpful to think about naming at the level of the whole project. This becomes important when you start reusing code between applications or when several detectors live in the same repository.

Choose a short and unique project or detector prefix, such as GammaDet, PETSim, or ShieldSim. Use this prefix in:

Top level directories, such as GammaDet/include, GammaDet/src.
Main classes, such as GammaDetDetectorConstruction, GammaDetActionInitialization.
Common utility classes, such as GammaDetGeometryUtils if you create helpers.

If you use C++ namespaces, a simple pattern is to use a namespace that matches your project name:

namespace GammaDet { ... }

Within the namespace, you can shorten class names slightly because the namespace itself already carries the project identity. However, keep the roles in the class names:

GammaDet::DetectorConstruction, GammaDet::RunAction.

This helps avoid name collisions with other code and makes it easier to integrate your Geant4 application into larger software systems.

In CMake or other build configuration files, keep the targets' names descriptive as well, for example:

add_executable(GammaDet gammaDet.cc)
target_link_libraries(GammaDet Geant4::G4run Geant4::G4vis ... )

The executable name should reflect the application or detector rather than generic names such as main or test.

Views: 8

Comments

Please login to add a comment.

Don't have an account? Register now!