Geant4 Developers
Geant4 Developers
Release 10.5
Geant4 Collaboration
1 Introduction 3
1.1 How to use this manual . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
i
2.7.3 Macro Commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
2.7.4 Example Macro File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
2.8 How to Make an Executable Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
2.8.1 Using CMake to Build Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
2.8.2 Using Geant4Make to build Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
2.9 How to Set Up an Interactive Session . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
2.9.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
2.9.2 A Short Description of Available Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . 42
2.9.3 How to Select Interface in Your Applications . . . . . . . . . . . . . . . . . . . . . . . . . 44
2.10 How to Execute a Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
2.10.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
2.10.2 ‘Hard-coded’ Batch Mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
2.10.3 Batch Mode with Macro File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
2.10.4 Interactive Mode Driven by Command Lines . . . . . . . . . . . . . . . . . . . . . . . . . 47
2.10.5 General Case . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
2.11 How to Visualize the Detector and Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
2.11.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
2.11.2 Visualization Drivers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
2.11.3 How to Incorporate Visualization Drivers into an Executable . . . . . . . . . . . . . . . . . 51
2.11.4 Writing the main() Method to Include Visualization . . . . . . . . . . . . . . . . . . . . . 52
2.11.5 Sample Visualization Sessions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
2.11.6 For More Information on GEANT4 Visualization . . . . . . . . . . . . . . . . . . . . . . . . 53
3 Toolkit Fundamentals 55
3.1 Class Categories and Domains . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
3.1.1 What is a class category? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
3.1.2 Class categories in GEANT4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
3.2 Global Usage Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
3.2.1 Signature of GEANT4 classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
3.2.2 The HEPRandom module in CLHEP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
3.2.3 The HEPNumerics module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
3.2.4 General management classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
3.3 System of units . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
3.3.1 Basic units . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
3.3.2 Input your data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
3.3.3 Output your data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
3.3.4 Introduce new units . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
3.3.5 Print the list of units . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
3.4 Run . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
3.4.1 Basic concept of Run . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
3.4.2 GEANT4 as a state machine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
3.4.3 User’s hook for state change . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
3.4.4 Customizing the Run Manager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
3.4.5 Managing worker thread . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
3.5 Event . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
3.5.1 Representation of an event . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
3.5.2 Structure of an event . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
3.5.3 Mandates of G4EventManager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
3.5.4 Stacking mechanism . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
3.6 Event Generator Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
3.6.1 Structure of a primary event . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
3.6.2 Interface to a primary generator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
3.6.3 Event overlap using multiple generators . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
3.7 Event Biasing Techniques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
ii
3.7.1 Scoring, Geometrical Importance Sampling and Weight Roulette . . . . . . . . . . . . . . . 74
3.7.2 Physics Based Biasing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
3.7.3 Adjoint/Reverse Monte Carlo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
3.7.4 Generic Biasing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
iii
4.9.3 Drawing scores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
4.9.4 Writing scores to a file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
iv
5.9.3 Geometry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258
7 Control 271
7.1 Built-in Commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271
7.2 User Interface - Defining New Commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271
7.2.1 G4UImessenger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271
7.2.2 G4UIcommand and its derived classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272
7.2.3 An example messenger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276
7.2.4 How to control the output of G4cout/G4cerr . . . . . . . . . . . . . . . . . . . . . . . . . . 279
8 Visualization 281
8.1 Introduction to Visualization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281
8.1.1 What Can be Visualized . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281
8.1.2 You have a Choice of Visualization Drivers . . . . . . . . . . . . . . . . . . . . . . . . . . 281
8.1.3 Choose the Driver that Meets Your Needs . . . . . . . . . . . . . . . . . . . . . . . . . . . 283
8.1.4 Controlling Visualization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 284
8.1.5 Visualization Details . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 284
8.2 Adding Visualization to Your Executable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285
8.2.1 Installing Visualization Drivers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285
8.2.2 How to Realize Visualization Drivers in an Executable . . . . . . . . . . . . . . . . . . . . 285
8.2.3 Visualization Manager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286
8.2.4 How to Write the main() Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286
8.3 The Visualization Drivers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288
8.3.1 Availability of drivers on the supported systems . . . . . . . . . . . . . . . . . . . . . . . . 288
8.3.2 OpenGL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 289
8.3.3 Qt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 290
8.3.4 OpenInventor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 290
8.3.5 OpenInventor Extended Viewer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291
8.3.6 HepRepFile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292
8.3.7 HepRepXML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293
8.3.8 DAWN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295
8.3.9 Remote Visualization with the DAWN-Network Driver . . . . . . . . . . . . . . . . . . . . 295
8.3.10 VRML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296
8.3.11 RayTracer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298
8.3.12 gMocren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298
8.3.13 Wt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299
8.3.14 Visualization of detector geometry tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302
v
8.3.15 GAG Tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303
8.3.16 XML Tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303
8.4 Controlling Visualization from Commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304
8.4.1 Scene, scene handler, and viewer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305
8.4.2 Create a scene handler and a viewer: /vis/open command . . . . . . . . . . . . . . . . . 306
8.4.3 Create an empty scene: /vis/scene/create command . . . . . . . . . . . . . . . . . 306
8.4.4 Visualization of a physical volume: /vis/drawVolume command . . . . . . . . . . . . . 306
8.4.5 Visualization of a logical volume: /vis/drawLogicalVolume command . . . . . . . . 307
8.4.6 Visualization of trajectories: /vis/scene/add/trajectories command . . . . . . . 307
8.4.7 Visualization of hits: /vis/scene/add/hits command . . . . . . . . . . . . . . . . . 308
8.4.8 Visualization of fields: /vis/scene/add/magneticField command . . . . . . . . . 309
8.4.9 Visualization of Scored Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 309
8.4.10 Additional attributes for Hits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 309
8.4.11 Basic camera workings: /vis/viewer/ commands . . . . . . . . . . . . . . . . . . . . 310
8.4.12 Declare the end of visualization for flushing: /vis/viewer/flush command . . . . . . 312
8.4.13 End of Event Action and End of Run Action: /vis/scene/endOfEventAction and
/vis/scene/endOfRunAction commands . . . . . . . . . . . . . . . . . . . . . . . 312
8.4.14 HepRep Attributes for Trajectories . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313
8.4.15 How to save a view. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313
8.4.16 How to save a view to an image file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313
8.4.17 Culling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315
8.4.18 Cut view . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315
8.4.19 Multithreading commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316
8.5 Controlling Visualization from Compiled Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316
8.5.1 G4VVisManager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316
8.5.2 Visualization of detector components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317
8.5.3 Visualization of trajectories . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317
8.5.4 Enhanced trajectory drawing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318
8.5.5 HepRep Attributes for Trajectories . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318
8.5.6 Visualization of hits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318
8.5.7 HepRep Attributes for Hits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321
8.5.8 Visualization of text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321
8.5.9 Visualization of polylines and tracking steps . . . . . . . . . . . . . . . . . . . . . . . . . . 321
8.5.10 Visualization User Actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 322
8.5.11 Standalone Visualization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323
8.5.12 Drawing a solid as a cloud of points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324
8.6 Visualization Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325
8.6.1 Visibility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325
8.6.2 Colour . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 326
8.6.3 Forcing attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328
8.6.4 Other attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329
8.6.5 Constructors of G4VisAttributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329
8.6.6 How to assign G4VisAttributes to a logical volume . . . . . . . . . . . . . . . . . . . . . . 330
8.6.7 Additional User-Defined Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 330
8.7 Enhanced Trajectory Drawing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331
8.7.1 Default Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331
8.7.2 Trajectory Drawing Models . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332
8.7.3 Controlling from Commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333
8.7.4 Controlling from Compiled Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 335
8.7.5 Drawing by time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 335
8.8 Trajectory Filtering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 336
8.8.1 Controlling from Commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337
8.8.2 Example commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337
8.8.3 Hit and Digi Filtering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338
vi
8.9 Polylines, Markers and Text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338
8.9.1 Polylines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338
8.9.2 Markers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 339
8.9.3 Text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 340
8.10 Making a Movie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341
8.10.1 Using /vis/viewer/interpolate . . . . . . . . . . . . . . . . . . . . . . . . . . . 342
8.10.2 OGLX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 342
8.10.3 Qt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 343
8.10.4 DAWNFILE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 343
8.10.5 RayTracerX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344
8.11 Debugging geometry with vis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344
8.11.1 Using advanced vis tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345
9 Analysis 349
9.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349
9.2 Analysis Manager Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349
9.2.1 Analysis Manager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 350
9.2.2 Files handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 350
9.2.3 Histograms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 351
9.2.4 Profiles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 357
9.2.5 Plotting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 360
9.2.6 Ntuples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 361
9.2.7 Parallel Processing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 362
9.2.8 Coexistence of Several Managers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363
9.2.9 Supported Features and Limitations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364
9.3 Analysis Reader Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364
9.3.1 Analysis Reader . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 365
9.3.2 File handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 365
9.3.3 Histograms and Profiles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 366
9.3.4 Ntuples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 366
9.4 Accumulables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367
9.4.1 G4Accumulable<T> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367
9.4.2 User defined accumulables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 369
9.5 g4tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370
9.5.1 g4tools package . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370
9.5.2 User API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 371
10 Examples 375
10.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375
10.2 Basic Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375
10.2.1 Basic Examples Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375
10.2.2 Basic Examples Macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 378
10.2.3 Multi-threading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 379
10.2.4 Example B1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 379
10.2.5 Example B2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 380
10.2.6 Example B3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 381
10.2.7 Example B4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 382
10.2.8 Example B5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 383
10.3 Extended Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 385
10.3.1 Analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 385
10.3.2 Biasing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 385
10.3.3 Common . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 386
10.3.4 Electromagnetic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 386
10.3.5 Error Propagation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 387
vii
10.3.6 Event Generator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 387
10.3.7 Exotic Physics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 387
10.3.8 Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 388
10.3.9 Geant3 to Geant4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 388
10.3.10 Geometry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 388
10.3.11 Hadronic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 388
10.3.12 Medical Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 388
10.3.13 Optical Photons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 389
10.3.14 Parallel Computing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 389
10.3.15 Parameterisations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 390
10.3.16 Persistency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 390
10.3.17 Physics lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 390
10.3.18 Polarisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 390
10.3.19 Radioactive Decay . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 390
10.3.20 Run & Event . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 391
10.3.21 Visualization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 391
10.4 Advanced Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 391
10.5 Novice Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 392
11 Appendix 393
11.1 CLHEP Foundation Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 393
11.1.1 Origin and current situation of CLHEP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 393
11.1.2 GEANT4 and CLHEP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 393
11.2 Geant4Config.cmake CMake Config File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 393
11.2.1 CMake Build System: Geant4Config.cmake . . . . . . . . . . . . . . . . . . . . . . . . . . 393
11.2.2 Building an Application against a Build of GEANT4 . . . . . . . . . . . . . . . . . . . . . . 398
11.3 GNUMake System: Makefiles and Environment Variables . . . . . . . . . . . . . . . . . . . . . . . 398
11.3.1 Geant4Make System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 398
11.3.2 Environment variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 399
11.3.3 Linking External Libraries with GEANT4 . . . . . . . . . . . . . . . . . . . . . . . . . . . 402
11.4 Development and Debug Tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404
11.4.1 Unix/Linux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404
11.4.2 Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404
11.5 Python Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 405
11.5.1 Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 405
11.5.2 Using Geant4Py . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 405
11.5.3 Site-modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 406
11.5.4 Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 407
11.6 GEANT4 Material Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 408
11.6.1 Simple Materials (Elements) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 408
11.6.2 NIST Compounds . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 410
11.6.3 HEP and Nuclear Materials . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 422
11.6.4 Space (ISS) Materials . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 423
11.6.5 Bio-Chemical Materials . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 423
11.7 Transportation in Magnetic Field - Further Details . . . . . . . . . . . . . . . . . . . . . . . . . . . 425
11.7.1 The challenge of integrating all tracks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 425
11.7.2 Using preset thresholds for killing loopers . . . . . . . . . . . . . . . . . . . . . . . . . . . 426
11.7.3 Fine grained control of the parameters for killing looping particles . . . . . . . . . . . . . . 427
Bibliography 433
viii
Book For Application Developers, Release 10.5
CONTENTS 1
Book For Application Developers, Release 10.5
2 CONTENTS
CHAPTER
ONE
INTRODUCTION
A very basic introduction to GEANT4 is presented in Section Getting Started with Geant4 - Running a Simple Example.
It is a recipe for writing and running a simple GEANT4 application program. New users of GEANT4 should read this
chapter first. It is strongly recommended that this chapter be read in conjunction with a GEANT4 system installed and
running on your computer. It is helpful to run the provided examples as they are discussed in the manual. To install
the GEANT4 system on your computer, please refer to the Installation Guide for Setting up Geant4 in Your Computing
Environment.
Section Toolkit Fundamentals discusses general GEANT4 issues such as class categories and the physical units system.
It goes on to discuss runs and events, which are the basic units of a simulation.
Section Detector Definition and Response describes how to construct a detector from customized materials and geo-
metric shapes, and embed it in electromagnetic fields. It also describes how to make the detector sensitive to particles
passing through it and how to store this information.
How particles are propagated through a material is treated in Section Tracking and Physics. The GEANT4 “philosophy”
of particle tracking is presented along with summaries of the physics processes provided by the toolkit. The definition
and implementation of GEANT4 particles is discussed and a list of particle properties is provided.
Section User Actions is a description of the “user hooks” by which the simulation code may be customized to perform
special tasks.
Section Control provides a summary of the commands available to the user to control the execution of the simulation.
After Chapter 2, Chapters 6 and 7 are of foremost importance to the new application developer.
The display of detector geometry, tracks and events may be incorporated into a simulation application by using the
tools described in Section Visualization.
Section Examples provides a set of basic, novice, extended and advanced simulation codes which may be compiled
and run “as is” from the GEANT4 source code. These examples may be used as educational tools or as base code from
which more complex applications are developed.
3
Book For Application Developers, Release 10.5
4 Chapter 1. Introduction
CHAPTER
TWO
The contents of main() will vary according to the needs of a given simulation application and therefore must be
supplied by the user. The GEANT4 toolkit does not provide a main() method, but a sample is provided here as a
guide to the beginning user. Listing 2.1 is the simplest example of main() required to build a simulation program.
#include "ExG4DetectorConstruction01.hh"
#include "ExG4PhysicsList00.hh"
#include "ExG4ActionInitialization01.hh"
int main()
{
// construct the default run manager
G4RunManager* runManager = new G4RunManager;
// initialize G4 kernel
runManager->Initialize();
// start a run
int numberOfEvent = 3;
runManager->BeamOn(numberOfEvent);
// job termination
delete runManager;
return 0;
}
The main() method is implemented by two toolkit classes, G4RunManager and G4UImanager, and three classes,
ExG4DetectorConstruction01, ExG4PhysicsList00 and ExG4ActionInitialization01, which
5
Book For Application Developers, Release 10.5
are derived from toolkit classes. Each of these are explained in the following sections.
2.1.2 G4RunManager
The first thing main() must do is create an instance of the G4RunManager class. This is the only manager class
in the GEANT4 kernel which should be explicitly constructed in the user’s main(). It controls the flow of the
program and manages the event loop(s) within a run. If the user wants to make the simulation code multi-threaded,
G4MTRunManager should be instantiated instead of G4RunManager.
When G4RunManager is created, the other major manager classes are also created. They are deleted automatically
when G4RunManager is deleted. The run manager is also responsible for managing initialization procedures, in-
cluding methods in the user initialization classes. Through these the run manager must be given all the information
necessary to build and run the simulation, including
1. how the detector should be constructed,
2. all the particles and all the physics processes to be simulated,
3. how the primary particle(s) in an event should be produced, and
4. any additional requirements of the simulation.
In the sample main() the lines
runManager->SetUserInitialization(new ExG4DetectorConstruction01);
runManager->SetUserInitialization(new ExG4PhysicsList00);
runManager->SetUserInitialization(new ExG4ActionInitialization01);
create objects which specify the detector geometry, physics processes and primary particle, respectively, and pass their
pointers to the run manager. ExG4DetectorConstruction01 is an example of a user initialization class which
is derived from G4VUserDetectorConstruction. This is where the user describes the entire detector setup,
including
• its geometry,
• the materials used in its construction,
• a definition of its sensitive regions and
• the readout schemes of the sensitive regions.
Similarly ExG4PhysicsList01 is derived from G4VUserPhysicsList and requires the user to define
• the particles to be used in the simulation,
• all the physics processes to be simulated.
User can also override the default implementation for
• the range cuts for these particles and
Also ExG4ActionInitialization01 is derived from G4VUserActionInitialization and requires the
user to define
• so-called user action classes (see next section) that are invoked during the simulation,
• which includes one mandatory user action to define the primary particles.
The next instruction
runManager->Initialize();
performs the detector construction, creates the physics processes, calculates cross sections and otherwise sets up the
run. The final run manager method in main()
int numberOfEvent = 3;
runManager->beamOn(numberOfEvent);
begins a run of three sequentially processed events. The beamOn() method may be invoked any number of times
within main() with each invocation representing a separate run. Once a run has begun neither the detector setup nor
the physics processes may be changed. They may be changed between runs, however, as described in Customizing the
Run Manager. More information on G4RunManager in general is found in Run.
As mentioned above, other manager classes are created when the run manager is created. One of these is the user
interface manager, G4UImanager. In main() a pointer to the interface manager must be obtained
G4UImanager* UI = G4UImanager::getUIpointer();
in order for the user to issue commands to the program. In the present example the applyCommand() method is
called three times to direct the program to print out information at the run, event and tracking levels of simulation.
A wide range of commands is available which allows the user detailed control of the simulation. A list of these
commands can be found in Built-in Commands.
User Classes
There are two kinds of user classes, user initialization classes and user action classes. User initialization classes are
used during the initialization phase, while user action classes are used during the run. User initialization classes should
be directly set to G4RunManager through SetUserInitialization() method, while user action classes
should be defined in G4VUserActionInitialization class.
All three user initialization classes are mandatory. They must be derived from the abstract base classes provided by
GEANT4:
• G4VUserDetectorConstruction
• G4VUserPhysicsList
• G4VUserActionInitialization
GEANT4 does not provide default behavior for these classes. G4RunManager checks for the existence of these
mandatory classes when the Initialize() and BeamOn() methods are invoked.
As mentioned in the previous section, G4VUserDetectorConstruction requires the user to define the de-
tector and G4VUserPhysicsList requires the user to define the physics. Detector definition will be discussed
in Sections How to Define a Detector Geometry and How to Specify Materials in the Detector. Physics def-
inition will be discussed in How to Specify Particles and How to Specify Physics Processes. The user action
G4VUserPrimaryGeneratorAction requires that the initial event state be defined. Primary event generation
will be discussed in How to Make an Executable Program.
G4VUserActionInitialization should include at least one mandatory user action class
G4VUserPrimaryGeneratorAction. All user action classes are described in the next section.
GEANT4 provides a category named intercoms. G4UImanager is the manager class of this category. Using the
functionalities of this category, you can invoke set methods of class objects of which you do not know the pointer. In
Listing 2.3, the verbosities of various GEANT4 manager classes are set. Detailed mechanism description and usage of
intercoms will be given in the next chapter, with a list of available commands. Command submission can be done all
through the application.
#ifdef G4UI_USE
#include "G4VisExecutive.hh"
#endif
#include "ExG4DetectorConstruction01.hh"
#include "ExG4PhysicsList00.hh"
#include "ExG4PrimaryGeneratorAction01.hh"
int main()
{
// construct the default run manager
G4RunManager* runManager = new G4RunManager;
// initialize G4 kernel
runManager->Initialize();
if ( argc == 1 ) {
// interactive mode : define UI session
#ifdef G4UI_USE
G4UIExecutive* ui = new G4UIExecutive(argc, argv);
UImanager->ApplyCommand("/control/execute init.mac");
ui->SessionStart();
delete ui;
#endif
}
else {
// batch mode
G4String command = "/control/execute ";
G4String fileName = argv[1];
UImanager->ApplyCommand(command+fileName);
}
// job termination
delete runManager;
return 0;
}
Although not yet included in the above examples, output streams will be needed. G4cout and G4cerr are iostream
objects defined by GEANT4. The usage of these objects is exactly the same as the ordinary cout and cerr, except that
the output streams will be handled by G4UImanager. Thus, output strings may be displayed on another window or
stored in a file. Manipulation of these output streams will be described in How to control the output of G4cout/G4cerr.
These objects should be used instead of the ordinary cout and cerr.
A detector geometry in GEANT4 is made of a number of volumes. The largest volume is called the World volume. It
must contain, with some margin, all other volumes in the detector geometry. The other volumes are created and placed
inside previous volumes, included in the World volume. The most simple (and efficient) shape to describe the World
is a box.
Each volume is created by describing its shape and its physical characteristics, and then placing it inside a containing
volume.
When a volume is placed within another volume, we call the former volume the daughter volume and the latter the
mother volume. The coordinate system used to specify where the daughter volume is placed, is the coordinate system
of the mother volume.
To describe a volume’s shape, we use the concept of a solid. A solid is a geometrical object that has a shape and
specific values for each of that shape’s dimensions. A cube with a side of 10 centimeters and a cylinder of radius 30
cm and length 75 cm are examples of solids.
To describe a volume’s full properties, we use a logical volume. It includes the geometrical properties of the solid,
and adds physical characteristics: the material of the volume; whether it contains any sensitive detector elements; the
magnetic field; etc.
We have yet to describe how to position the volume. To do this you create a physical volume, which places a copy of
the logical volume inside a larger, containing, volume.
To create a simple box, you only need to define its name and its extent along each of the Cartesian axes.
G4Box* worldBox
= new G4Box("World", world_hx, world_hy, world_hz);
This creates a box named “World” with the extent from -3.0 meters to +3.0 meters along the X axis, from -1.0 to 1.0
meters in Y, and from -1.0 to 1.0 meters in Z. Note that the G4Box constructor takes as arguments the halves of the
total box size.
It is also very simple to create a cylinder. To do this, you can use the G4Tubs class.
G4Tubs* trackerTube
= new G4Tubs("Tracker",
innerRadius,
outerRadius,
hz,
startAngle,
spanningAngle);
This creates a full cylinder, named “Tracker”, of radius 60 centimeters and length 50 cm (the hz parameter represents
the half length in Z).
To create a logical volume, you must start with a solid and a material. So, using the box created above, you can create
a simple logical volume filled with argon gas (see How to Specify Materials in the Detector) by entering:
G4LogicalVolume* worldLog
= new G4LogicalVolume(worldBox, Ar, "World");
G4LogicalVolume* trackerLog
= new G4LogicalVolume(trackerTube, Al, "Tracker");
How do you place a volume? You start with a logical volume, and then you decide the already existing volume inside
of which to place it. Then you decide where to place its center within that volume, and how to rotate it. Once you have
made these decisions, you can create a physical volume, which is the placed instance of the volume, and embodies all
of these attributes.
You create a physical volume starting with your logical volume. A physical volume is simply a placed instance of the
logical volume. This instance must be placed inside a mother logical volume. For simplicity it is unrotated:
G4VPhysicalVolume* trackerPhys
= new G4PVPlacement(0, // no rotation
G4ThreeVector(pos_x, pos_y, pos_z),
// translation position
trackerLog, // its logical volume
"Tracker", // its name
worldLog, // its mother (logical) volume
false, // no boolean operations
0); // its copy number
This places the logical volume trackerLog at the origin of the mother volume worldLog, shifted by one meter
along X and unrotated. The resulting physical volume is named “Tracker” and has a copy number of 0.
An exception exists to the rule that a physical volume must be placed inside a mother volume. That exception is for
the World volume, which is the largest volume created, and which contains all other volumes. This volume obviously
cannot be contained in any other. Instead, it must be created as a G4PVPlacement with a null mother pointer. It
also must be unrotated, and it must be placed at the origin of the global coordinate system.
Generally, it is best to choose a simple solid as the World volume, the G4Box solid type is used in all basic examples.
In GEANT4, the rotation matrix associated to a placed physical volume represents the rotation of the reference system
of this volume with respect to its mother.
A rotation matrix is normally constructed as in CLHEP, by instantiating the identity matrix and then applying a rotation
to it. This is also demonstrated in Example B3.
In nature, general materials (chemical compounds, mixtures) are made of elements, and elements are made of isotopes.
Therefore, these are the three main classes designed in GEANT4. Each of these classes has a table as a static data
member, which is for keeping track of the instances created of the respective classes. All three objects automatically
register themselves into the corresponding table on construction, and should never be deleted in user code.
The G4Element class describes the properties of the atoms:
• atomic number,
• number of nucleons,
• atomic mass,
• shell energy,
• as well as quantities such as cross sections per atom, etc.
The G4Material class describes the macroscopic properties of matter:
• density,
• state,
• temperature,
• pressure,
• as well as macroscopic quantities like radiation length, mean free path, dE/dx, etc.
The G4Material class is the one which is visible to the rest of the toolkit, and is used by the tracking, the geometry,
and the physics. It contains all the information relative to the eventual elements and isotopes of which it is made, at
the same time hiding the implementation details.
In the example below, liquid argon is created, by specifying its name, density, mass per mole, and atomic number.
The pointer to the material, lAr, will be used to specify the matter of which a given logical volume is made:
G4LogicalVolume* myLbox = new G4LogicalVolume(aBox,lAr,"Lbox",0,0,0);
In the example below, the water, H2O, is built from its components, by specifying the number of atoms in the molecule.
a = 1.01*g/mole;
(continues on next page)
a = 16.00*g/mole;
G4Element* elO = new G4Element(name="Oxygen" ,symbol="O" , z= 8., a);
density = 1.000*g/cm3;
G4Material* H2O = new G4Material(name="Water",density,ncomponents=2);
H2O->AddElement(elH, natoms=2);
H2O->AddElement(elO, natoms=1);
In the example below, air is built from nitrogen and oxygen, by giving the fractional mass of each component.
Listing 2.9: Creating air by defining the fractional mass of its compo-
nents.
G4double z, a, fractionmass, density;
G4String name, symbol;
G4int ncomponents;
a = 14.01*g/mole;
G4Element* elN = new G4Element(name="Nitrogen",symbol="N" , z= 7., a);
a = 16.00*g/mole;
G4Element* elO = new G4Element(name="Oxygen" ,symbol="O" , z= 8., a);
density = 1.290*mg/cm3;
G4Material* Air = new G4Material(name="Air ",density,ncomponents=2);
Air->AddElement(elN, fractionmass=70*perCent);
Air->AddElement(elO, fractionmass=30*perCent);
In the example below, air and water are accessed via the GEANT4 material database.
Listing 2.10: Defining air and water from the internal GEANT4 database.
G4NistManager* man = G4NistManager::Instance();
It is possible to build new material on base of an existing “base” material. This feature is useful for electromagnetic
physics allowing to peak up for the derived material all correction data and precomputed tables of stopping powers
and cross sections of the base material. In the example below, two methods how to create water with unusual density
are shown.
density = 1.03*mg/cm3;
G4NistManager* man = G4NistManager::Instance();
G4Material* water2 = man->BuildMaterialWithNewDensity("Water_1.03","G4_WATER",density);
In GEANT4 examples you with find all possible ways to build a material.
G4VUserPhysicsList is one of the mandatory user base classes described in How to Define the main() Program.
Within this class all particles and physics processes to be used in your simulation must be defined. The range cut-off
parameter should also be defined in this class.
The user must create a class derived from G4VuserPhysicsList and implement the following pure virtual meth-
ods:
ConstructParticle(); // construction of particles
ConstructProcess(); // construct processes and register them to particles
The user may also want to override the default implementation of the following virtual method:
SetCuts(); // setting a range cut value for all particles
This section provides some simple examples of the ConstructParticle() and SetCuts() methods. For
information on ConstructProcess() methods, please see How to Specify Physics Processes.
• resonant particles with very short lifetimes, such as vector mesons and delta baryons
• nuclei, such as deuteron, alpha, and heavy ions (including hyper-nuclei)
• quarks, di-quarks, and gluon
Each particle is represented by its own class, which is derived from G4ParticleDefinition. (Exception: G4Ions
represents all heavy nuclei. Please see Particles.) Particles are organized into six major categories:
• lepton,
• meson,
• baryon,
• boson,
• shortlived and
• ion,
each of which is defined in a corresponding sub-directory under geant4/source/particles. There is also a
corresponding granular library for each particle category.
G4ParticleDefinition has properties which characterize individual particles, such as, name, mass,
charge, spin, and so on. Most of these properties are “read-only” and can not be changed directly.
G4ParticlePropertyTable is used to retrieve (load) particle property of G4ParticleDefinition into
(from) G4ParticlePropertyData.
Each particle class type represents an individual particle type, and each class has a single object. This object can be
accessed by using the static method of each class. There are some exceptions to this rule; please see Particles for
details.
For example, the class G4Electron represents the electron and the member G4Electron::theInstance
points its only object. The pointer to this object is available through the static methods
G4Electron::ElectronDefinition(). G4Electron::Definition().
More than 100 types of particles are provided by default, to be used in various physics processes. In normal applica-
tions, users will not need to define their own particles.
The unique object for each particle class is created when its static method to get the pointer is called at the first time.
Because particles are dynamic objects and should be instantiated before initialization of physics processes, you must
explicitly invoke static methods of all particle classes required by your program at the initialization step. (NOTE: The
particle object was static and created automatically before 8.0 release)
Dictionary of Particles
The G4ParticleTable class is provided as a dictionary of particles. Various utility methods are provided, such as:
FindParticle(G4String name); // find the particle by name
FindParticle(G4int PDGencoding) // find the particle by PDG encoding .
Particles are registered automatically during construction. The user has no control over particle registration.
Constructing Particles
ConstructParticle() is a pure virtual method, in which the static member functions for all the particles you
require should be called. This ensures that objects of these particles are created.
Warning: You must define “ALL PARTICLE TYPES” which are used in your application, except for heavy ions.
“ALL PARTICLE TYPES” means not only primary particles, but also all other particles which may appear as
secondaries generated by physics processes you use. Beginning with GEANT4 version 8.0, you should keep this
rule strictly because all particle definitions are revised to “non-static” objects.
For example, suppose you need a proton and a geantino, which is a virtual particle used for simulation and which does
not interact with materials. The ConstructParticle() method is implemented as below:
Due to the large number of pre-defined particles in GEANT4, it is cumbersome to list all the particles by this method.
If you want all the particles in a GEANT4 particle category, there are six utility classes, corresponding to each of the
particle categories, which perform this function:
• G4BosonConstructor
• G4LeptonConstructor
• G4MesonConstructor
• G4BaryonConstructor
• G4IonConstructor
• G4ShortlivedConstructor.
An example of this is shown in ExN05PhysicsList, listed below.
To avoid infrared divergence, some electromagnetic processes require a threshold below which no secondary will
be generated. Because of this requirement, gammas, electrons and positrons require production threshold. This
threshold should be defined as a distance, or range cut-off, which is internally converted to an energy for individ-
ual materials. The range threshold should be defined in the initialization phase using the SetCuts() method of
G4VUserPhysicsList. Cuts per Region discusses threshold and tracking cuts in detail.
Production threshold values should be defined in SetCuts() which is a virtual method of the
G4VUserPhysicsList. Construction of particles, materials, and processes should precede the invocation of
SetCuts(). G4RunManager takes care of this sequence in usual applications.
This range cut value is converted threshold energies for each material and for each particle type (i.e. electron, positron
and gamma) so that the particle with threshold energy stops (or is absorbed) after traveling the range cut distance.
In addition, from the 9.3 release ,this range cut value is applied to the proton as production thresholds of nuclei for
hadron elastic processes. In this case, the range cut value does not means the distance of traveling. Threshold energies
are calculated by a simple formula from the cut in range.
Note that the upper limit of the threshold energy is defined as 10 GeV. If you want to set higher threshold energy, you
can change the limit by using “/cuts/setMaxCutEnergy” command before setting the range cut.
The idea of a “unique cut value in range” is one of the important features of GEANT4 and is used to handle cut values
in a coherent manner. For most applications, users need to determine only one cut value in range, and apply this value
to gammas, electrons and positrons alike. (and proton too)
The default implementation of SetCuts() method provides a defaultCutValue member as the unique range
cut-off value for all particle types. The defaultCutValue is set to 1.0 mm by default. User can change this
value by SetDefaultCutValue() The “/run/setCut” command may be used to change the default cut value
interactively.
Warning: DO NOT change cut values inside the event loop. Cut values may however be changed between runs.
It is possible to set different range cut values for gammas, electrons and positrons by using SetCutValue() methods
(or using “/run/setCutForAGivenParticle” command). However, user must be careful with physics outputs because
GEANT4 processes (especially energy loss) are designed to conform to the “unique cut value in range” scheme.
Beginning with GEANT4 version 5.1, it is now possible to set production thresholds for each geometrical region. This
new functionality is described in Cuts per Region.
Physics processes describe how particles interact with materials. GEANT4 provides seven major categories of pro-
cesses:
• electromagnetic,
• hadronic,
• transportation,
• decay,
• optical,
• photolepton_hadron, and
• parameterisation.
All physics processes are derived from the G4VProcess base class. Its virtual methods
• AtRestDoIt,
• AlongStepDoIt, and
• PostStepDoIt
and the corresponding methods
• AtRestGetPhysicalInteractionLength,
• AlongStepGetPhysicalInteractionLength, and
• PostStepGetPhysicalInteractionLength
describe the behavior of a physics process when they are implemented in a derived class. The details of these methods
are described in Physics Processes.
The following are specialized base classes to be used for simple processes:
G4VAtRestProcess Processes with only AtRestDoIt
G4VContinuousProcess Processes with only AlongStepDoIt
G4VDiscreteProcess processes with only PostStepDoIt
Another 4 virtual classes, such as G4VContinuousDiscreteProcess, are provided for complex processes.
The G4ProcessManager class contains a list of processes that a particle can undertake. It has information on the
order of invocation of the processes, as well as which kind of DoIt method is valid for each process in the list. A
G4ProcessManager object corresponds to each particle and is attached to the G4ParticleDefiniton class.
In order to validate processes, they should be registered with the particle’s G4ProcessManager. Process ordering
information is included by using the AddProcess() and SetProcessOrdering() methods. For registration of
simple processes, the AddAtRestProcess(), AddContinuousProcess() and AddDiscreteProcess()
methods may be used.
G4ProcessManager is able to turn some processes on or off during a run by using the ActivateProcess()
and InActivateProcess() methods. These methods are valid only after process registration is complete, so they
must not be used in the PreInit phase.
The G4VUserPhysicsList class creates and attaches G4ProcessManager objects to all particle classes defined
in the ConstructParticle() method.
G4VUserPhysicsList is the base class for a “mandatory user class” (see How to Define the main() Program), in
which all physics processes and all particles required in a simulation must be registered. The user must create a class
derived from G4VUserPhysicsList and implement the pure virtual method ConstructProcess().
For example, if just the G4Geantino particle class is required, only the transportation process need be registered.
The ConstructProcess() method would then be implemented as follows:
Here, the AddTransportation() method is provided in the G4VUserPhysicsList class to register the
G4Transportation class with all particle classes. The G4Transportation class (and/or related classes) de-
scribes the particle motion in space and time. It is the mandatory process for tracking particles.
In the ConstructProcess() method, physics processes should be created and registered with each particle’s
instance of G4ProcessManager.
An example of process registration is given in the G4VUserPhysicsList::AddTransportation() method.
Registration in G4ProcessManager is a complex procedure for other processes and particles because the relations
between processes are crucial for some processes. In order to ease registration procedures, G4PhysicsListHelper is
provided. Users do not care about type of processes (i.e. AtRest and/or Discrete and/or Continuous ) or ordering
parameters.
An example of electromagnetic process registration for the gamma is shown below
void MyPhysicsList::ConstructEM()
{
// Get pointer to G4PhysicsListHelper
G4PhysicsListHelper* ph = G4PhysicsListHelper::GetPhysicsListHelper();
G4VuserPrimaryGeneratorAction is one of the mandatory classes available for deriving your own concrete
class. In your concrete class, you have to specify how a primary event should be generated. Actual generation of
primary particles will be done by concrete classes of G4VPrimaryGenerator, explained in the following sub-
section. Your G4VUserPrimaryGeneratorAction concrete class just arranges the way primary particles are
generated.
#ifndef ExG4PrimaryGeneratorAction01_h
#define ExG4PrimaryGeneratorAction01_h 1
#include "G4VUserPrimaryGeneratorAction.hh"
(continues on next page)
class G4ParticleGun;
class G4Event;
// methods
virtual void GeneratePrimaries(G4Event*);
private:
// data members
G4ParticleGun* fParticleGun; //pointer a to G4 service class
};
#endif
//////////////////////////////////
// ExG4PrimaryGeneratorAction01.cc
//////////////////////////////////
#include "ExG4PrimaryGeneratorAction01.hh"
#include "G4Event.hh"
#include "G4ParticleGun.hh"
#include "G4ParticleTable.hh"
#include "G4ParticleDefinition.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
ExG4PrimaryGeneratorAction01::ExG4PrimaryGeneratorAction01(
const G4String& particleName,
G4double energy,
G4ThreeVector position,
G4ThreeVector momentumDirection)
: G4VUserPrimaryGeneratorAction(),
fParticleGun(0)
{
G4int nofParticles = 1;
fParticleGun = new G4ParticleGun(nofParticles);
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
ExG4PrimaryGeneratorAction01::~ExG4PrimaryGeneratorAction01()
{
delete fParticleGun;
}
(continues on next page)
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
fParticleGun->GeneratePrimaryVertex(anEvent);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
In the constructor of your G4VUserPrimaryGeneratorAction, you should instantiate the primary generator(s).
If necessary, you need to set some initial conditions for the generator(s).
In ExG4PrimaryGeneratorAction01, G4ParticleGun is constructed to use as the actual primary particle generator.
Methods of G4ParticleGun are described in the following section. Please note that the primary generator object(s)
you construct in your G4VUserPrimaryGeneratorAction concrete class must be deleted in your destructor.
Generation of an event
2.6.2 G4VPrimaryGenerator
GEANT4 provides three G4VPrimaryGenerator concrete classes. Among these G4ParticleGun and
G4GeneralParticleSource will be discussed here. The third one is G4HEPEvtInterface, which will be
discussed in Event Generator Interface.
G4ParticleGun
G4ParticleGun is a generator provided by GEANT4. This class generates primary particle(s) with a given mo-
mentum and position. It does not provide any sort of randomizing. The constructor of G4ParticleGun takes an
integer which causes the generation of one or more primaries of exactly same kinematics. It is a rather frequent user
requirement to generate a primary with randomized energy, momentum, and/or position. Such randomization can be
achieved by invoking various set methods provided by G4ParticleGun. The invocation of these methods should be
implemented in the generatePrimaries() method of your concrete G4VUserPrimaryGeneratorAction
class before invoking generatePrimaryVertex() of G4ParticleGun. GEANT4 provides various random
number generation methods with various distributions (see Global Usage Classes).
The following methods are provided by G4ParticleGun, and all of them can be invoked from the
generatePrimaries() method in your concrete G4VUserPrimaryGeneratorAction class.
• void SetParticleDefinition(G4ParticleDefinition*)
• void SetParticleMomentum(G4ParticleMomentum)
• void SetParticleMomentumDirection(G4ThreeVector)
• void SetParticleEnergy(G4double)
• void SetParticleTime(G4double)
• void SetParticlePosition(G4ThreeVector)
• void SetParticlePolarization(G4ThreeVector)
• void SetNumberOfParticles(G4int)
G4GeneralParticleSource
For many applications G4ParticleGun is a suitable particle generator. However if you want to generate primary
particles in more sophisticated manner, you can utilize G4GeneralParticleSource, the GEANT4 General Par-
ticle Source module (GPS), discussed in the next section ( General Particle Source).
2.7.1 Introduction
The G4GeneralParticleSource (GPS) is part of the GEANT4 toolkit for Monte-Carlo, high-energy particle
transport. Specifically, it allows the specifications of the spectral, spatial and angular distribution of the primary
source particles. An overview of the GPS class structure is presented here. Configuration covers the configuration of
GPS for a user application, and Macro Commands describes the macro command interface. Example Macro File gives
an example input file to guide the first time user.
G4GeneralParticleSource is used exactly the same way as G4ParticleGun in a GEANT4 application. In
existing applications one can simply change your PrimaryGeneratorAction by globally replacing G4ParticleGun
with G4GeneralParticleSource. GPS may be configured via command line, or macro based, input. The
experienced user may also hard-code distributions using the methods and classes of the GPS that are described in
more detail in a technical note1 .
The class diagram of GPS is shown in Fig. 2.1. As of version 10.01, a split-class mechanism was introduced to
reduce memory usage in multithreaded mode. The G4GeneralParticleSourceData class is a thread-safe
singleton which provides access to the source information for the G4GeneralParticleSource class. The
G4GeneralParticleSourceData class can have multiple instantiations of the G4SingleParticleSource
class, each with independent positional, angular and energy distributions as well as incident particle types. To the user,
this change should be transparent.
2.7.2 Configuration
GPS allows the user to control the following characteristics of primary particles:
• Spatial sampling: on simple 2D or 3D surfaces such as discs, spheres, and boxes.
• Angular distribution: unidirectional, isotropic, cosine-law, beam or arbitrary (user defined).
• Spectrum: linear, exponential, power-law, Gaussian, blackbody, or piece-wise fits to data.
• Multiple sources: multiple independent sources can be used in the same run.
As noted above, G4GeneralParticleSource is used exactly the same way as G4ParticleGun in a GEANT4
application, and may be substituted for the latter by “global search and replace” in existing application source code.
1 General purpose Source Particle Module for GEANT4/SPARSET: Technical Note, UoS-GSPM-Tech, Issue 1.1, C Ferguson, February 2000.
Position Distribution
The position distribution can be defined by using several basic shapes to contain the starting positions of the particles.
The easiest source distribution to define is a point source. One could also define planar sources, where the particles
emanate from circles, annuli, ellipses, squares or rectangles. There are also methods for defining 1D or 2D accelerator
beam spots. The five planes are oriented in the x-y plane. To define a circle one gives the radius, for an annulus one
gives the inner and outer radii, and for an ellipse, a square or a rectangle one gives the half-lengths in x and y.
More complicated still, one can define surface or volume sources where the input particles can be confined to ei-
ther the surface of a three dimensional shape or to within its entire volume. The four 3D shapes used within
G4GeneralParticleSource are sphere, ellipsoid, cylinder and parallelepiped. A sphere can be defined simply by spec-
ifying the radius. Ellipsoids are defined by giving their half-lengths in x, y and z. Cylinders are defined such that the
axis is parallel to the z-axis, the user is therefore required to give the radius and the z half-length. Parallelepipeds are
defined by giving x, y and z half-lengths, plus the angles 𝛼, 𝜃, and 𝜑 (Fig. 2.2).
To allow easy definition of the sources, the planes and shapes are assumed to be orientated in a particular direction
to the coordinate axes, as described above. For more general applications, the user may supply two vectors (x’ and a
vector in the plane x’-y’) to rotate the co-ordinate axes of the shape with respect to the overall co-ordinate system (Fig.
2.3). The rotation matrix is automatically calculated within G4GeneralParticleSource. The starting points of particles
are always distributed homogeneously over the 2D or 3D surfaces, although biasing can change this.
Fig. 2.3: An illustration of the use of rotation matrices. A cylinder is defined with its axis parallel to the z-axis (black
lines), but the definition of 2 vectors can rotate it into the frame given by x’, y’, z’ (red lines).
Angular Distribution
The angular distribution is used to control the directions in which the particles emanate from/incident upon the source
point. In general there are three main choices, isotropic, cosine-law or user-defined. In addition there are options for
specifying parallel beam as well as diverse accelerator beams. The isotropic distribution represents what would be
seen from a uniform 4𝜋 flux. The cosine-law represents the distribution seen at a plane from a uniform 2𝜋 flux.
It is possible to bias (Biasing) both 𝜃 and 𝜑 for any of the predefined distributions, including setting lower and upper
limits to 𝜃 and 𝜑. User-defined distributions cannot be additionally biased (any bias should obviously be incorporated
into the user definition).
Incident with zenith angle 𝜃 = 0 means the particle is travelling along the -z axis. It is important to bear this in mind
when specifying user-defined co-ordinates for angular distributions. The user must be careful to rotate the co-ordinate
axes of the angular distribution if they have rotated the position distribution (Fig. 2.3).
The user defined distribution requires the user to enter a histogram in either 𝜃 or 𝜑 or both. The user-defined distribution
may be specified either with respect to the coordinate axes or with respect to the surface-normal of a shape or volume.
For the surface-normal distribution, 𝜃 should only be defined between 0 and 𝜋/2, not the usual 0 to 𝜋 range.
The top-level /gps/direction command uses direction cosines to specify the primary particle direction, as fol-
lows:
𝑃𝑥 = − sin 𝜃 cos 𝜑
𝑃𝑦 = − sin 𝜃 sin 𝜑 (2.1)
𝑃𝑧 = − cos 𝜃
Energy Distribution
The energy of the input particles can be set to follow several built-in functions or a user-defined one, as shown in Table
2.1. The user can bias any of the pre-defined energy distributions in order to speed up the simulation (user-defined
distributions are already biased, by construction).
There is also the option for the user to define a histogram in energy (“User”) or energy per nucleon (“Epn”) or to give
an arbitrary point-wise spectrum (“Arb”) that can be fit with various simple functions. The data for histograms or point
spectra must be provided in ascending bin (abscissa) order. The point-wise spectrum may be differential (as with a
binned histogram) or integral (a cumulative distribution function). If integral, the data must satisfy 𝑠(𝑒1) ≥ 𝑠(𝑒2) for
𝑒1 < 𝑒2 when entered; this is not validated by the GPS code. The maximum energy of an integral spectrum is defined
by the last-but-one data point, because GPS converts to a differential spectrum internally.
Unlike the other spectral distributions it has proved difficult to integrate indefinitely the black-body spectrum and this
has lead to an alternative approach. Instead it has been decided to use the black-body formula to create a 10,000 bin
histogram and then to produce random energies from this.
Similarly, the broken power-law for cosmic diffuse gamma rays makes generating an indefinite integral CDF problem-
atic. Instead, the minimum and maximum energies specified by the user are used to construct a definite-integral CDF
from which random energies are selected.
Biasing
The user can bias distributions by entering a histogram. It is the random numbers from which the quantities are picked
that are biased and so one only needs a histogram from 0 to 1. Great care must be taken when using this option, as the
way a quantity is calculated will affect how the biasing works, as discussed below. Bias histograms are entered in the
same way as other user-defined histograms.
When creating biasing histograms it is important to bear in mind the way quantities are generated from those numbers.
For example let us compare the biasing of a 𝜃 distribution with that of a 𝜑 distribution. Let us divide the 𝜃 and 𝜑 ranges
up into 10 bins, and then decide we want to restrict the generated values to the first and last bins. This gives a new 𝜑
range of 0 to 0.628 and 5.655 to 6.283. Since 𝜑 is calculated using 𝜑 = 2𝜋 × RNDM, this simple biasing will work
correctly.
If we now look at 𝜃, we expect to select values in the two ranges 0 to 0.314 (for 0 ≤ RNDM ≤ 0.1) and 2.827 to 3.142
(for 0 ≤ RNDM ≤ 0.9). However, the polar angle 𝜃 is calculated from the formula 𝜃 = arccos(1 − 2 × RNDM).
From this, we see that 0.1 gives a 𝜃 of 0.644 and a RNDM of 0.9 gives a 𝜃 of 2.498. This means that the above
will not bias the distribution as the user had wished. The user must therefore take into account the method used to
generate random quantities when trying to apply a biasing scheme to them. Some quantities such as x, y, z and 𝜑 will
be relatively easy to bias, but others may require more thought.
User-Defined Histograms
The user can define histograms for several reasons: angular distributions in either 𝜃 or 𝜑; energy distributions; energy
per nucleon distributions; or biasing of x, y, z, 𝜃, 𝜑, or energy. Even though the reasons may be different the approach
is the same.
To choose a histogram the command /gps/hist/type is used (Macro Commands). If one wanted to enter an
angular distribution one would type “theta” or “phi” as the argument. The histogram is loaded, one bin at a time,
by using the /gps/hist/point command, followed by its two arguments the upper boundary of the bin and the
weight (or area) of the bin. Histograms are therefore differential functions.
Currently histograms are limited to 1024 bins. The first value of each user input data pair is treated as the upper edge
of the histogram bin and the second value is the bin content. The exception is the very first data pair the user input
whose first value is the treated as the lower edge of the first bin of the histogram, and the second value is not used.
This rule applies to all distribution histograms, as well as histograms for biasing.
The user has to be aware of the limitations of histograms. For example, in general 𝜃 is defined between 0 and 𝜋 and 𝜑
is defined between 0 and 2𝜋, so histograms defined outside of these limits may not give the user what they want (see
also Biasing).
G4GeneralParticleSource can be configured by typing commands from the /gps command directory tree, or
including the /gps commands in a g4macro file.
Energy spectra
# Macro test2.g4mac
/control/verbose 0
/tracking/verbose 0
/event/verbose 0
/gps/verbose 2
/gps/particle gamma
/gps/pos/type Plane
/gps/pos/shape Square
/gps/pos/centre 1 2 1 cm
/gps/pos/halfx 2 cm
/gps/pos/halfy 2 cm
/gps/ang/type cos
/gps/ene/type Lin
/gps/ene/min 2 MeV
/gps/ene/max 10 MeV
/gps/ene/gradient 1
/gps/ene/intercept 1
/run/beamOn 10000
The above macro defines a planar source, square in shape, 4 cm by 4 cm and centred at (1,2,1) cm. By default the
normal of this plane is the z-axis. The angular distribution is to follow the cosine-law. The energy spectrum is linear,
with gradient and intercept equal to 1, and extends from 2 to 10 MeV. 10,000 primaries are to be generated.
The standard GEANT4 output should show that the primary particles start from between 1, 0, 1 and 3, 4, 1 (in cm) and
have energies between 2 and 10 MeV, as shown in Fig. 2.4, in which we plotted the actual energy, position and angular
distributions of the primary particles generated by the above macro file.
Fig. 2.4: Energy, position and angular distributions of the primary particles as generated by the macro file shown
above.
The code for the user examples in Geant4 is placed in the subdirectory examples of the main GEANT4 source
package. This directory is installed to the share/Geant4-G4VERSION/examples (where G4VERSION is the
GEANT4 version number) subdirectory under the installation prefix. In the following sections, a quick overview will
be given on how to build a concrete example, “ExampleB1”, which is part of the GEANT4 distribution, using CMake
and the older, and now deprecated, Geant4Make system.
which is designed for use with the CMake find_package command. Building a GEANT4 application using CMake
therefore involves writing a CMakeLists.txt script using this and other CMake commands to locate GEANT4 and
describe the build of your client application. Whilst it requires a bit of effort to write the script, CMake provides a
very friendly yet powerful tool, especially if you are working on multiple platforms. It is therefore the method we
recommend for building GEANT4 applications.
We’ll use Basic Example B1, which you may find in the GEANT4 source directory under examples/basic/B1,
to demonstrate the use of CMake to build a GEANT4 application. You’ll find links to the latest CMake documentation
for the commands used throughout, so please follow these for further information. The application sources and scripts
are arranged in the following directory structure:
+- B1/
+- CMakeLists.txt
(continues on next page)
Here, exampleB1.cc contains main() for the application, with include/ and src/ containing the implemen-
tation class headers and sources respectively. This arrangement of source files is not mandatory when building with
CMake, apart from the location of the CMakeLists.txt file in the root directory of the application.
The text file CMakeLists.txt is the CMake script containing commands which describe how to build the exam-
pleB1 application
# (1)
cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
project(B1)
# (2)
option(WITH_GEANT4_UIVIS "Build example with Geant4 UI and Vis drivers" ON)
if(WITH_GEANT4_UIVIS)
find_package(Geant4 REQUIRED ui_all vis_all)
else()
find_package(Geant4 REQUIRED)
endif()
# (3)
include(${Geant4_USE_FILE})
include_directories(${PROJECT_SOURCE_DIR}/include)
# (4)
file(GLOB sources ${PROJECT_SOURCE_DIR}/src/*.cc)
file(GLOB headers ${PROJECT_SOURCE_DIR}/include/*.hh)
# (5)
add_executable(exampleB1 exampleB1.cc ${sources} ${headers})
target_link_libraries(exampleB1 ${Geant4_LIBRARIES})
# (6)
set(EXAMPLEB1_SCRIPTS
exampleB1.in
exampleB1.out
init_vis.mac
run1.mac
run2.mac
vis.mac
)
foreach(_script ${EXAMPLEB1_SCRIPTS})
configure_file(
${PROJECT_SOURCE_DIR}/${_script}
${PROJECT_BINARY_DIR}/${_script}
COPYONLY
)
endforeach()
# (7)
install(TARGETS exampleB1 DESTINATION bin)
For clarity, the above listing has stripped out the main comments (CMake comments begin with a “#”) you’ll find in
the actual file to highlight each distinct task:
1. Basic Configuration
The cmake_minimum_required command simply ensures we’re using a suitable version of CMake.
Though the build of GEANT4 itself requires CMake 3.3 and we recommend this version for your own projects,
Geant4Config.cmake can support the 2.6 and 2.8 series. The project command sets the name of the
project and enables and configures C and C++ compilers.
2. Find and Configure GEANT4
The aforementioned find_package command is used to locate and configure GEANT4 (we’ll see how to
specify the location later when we run CMake), the REQUIRED argument being supplied so that CMake will
fail with an error if it cannot find GEANT4. The option command specifies a boolean variable which defaults
to ON, and which can be set when running CMake via a -D command line argument, or toggled in the CMake
GUI interfaces. We wrap the calls to find_package in a conditional block on the option value. This allows
us to configure the use of GEANT4 UI and Visualization drivers by exampleB1 via the ui_all vis_all
“component” arguments to find_package. These components and their usage is described later.
3. Configure the Project to Use GEANT4 and B1 Headers
To automatically configure the header path, and force setting of compiler flags and compiler definitions needed
for compiling against GEANT4, we use the include command to load a CMake script supplied by GEANT4.
The CMake variable named Geant4_USE_FILE is set to the path to this module when GEANT4 is located
by find_package. We use the include_directories command to add the B1 header directory to the
compiler’s header search path. The CMake variable PROJECT_SOURCE_DIR points to the top level directory
of the project and is set by the earlier call to the project command.
4. List the Sources to Build the Application
Use the globbing functionality of the file command to prepare lists of the B1 source and header files.
Note however that CMake globbing is only used here as a convenience. The expansion of the glob only
happens when CMake is run, so if you later add or remove files, the generated build scripts will not know a
change has taken place. Kitware strongly recommend listing sources explicitly as CMake automatically
makes the build depend on the CMakeLists.txt file. This means that if you explicitly list the sources in
CMakeLists.txt, any changes you make will be automatically picked when you rebuild. This is most useful
when you are working on a project with sources under version control and multiple contributors.
5. Define and Link the Executable
The add_executable command defines the build of an application, outputting an executable named by its
first argument, with the sources following. Note that we add the headers to the list of sources so that they will
appear in IDEs like Xcode.
After adding the executable, we use the target_link_libraries command to link it with the GEANT4
libraries. The Geant4_LIBRARIES variable is set by find_package when GEANT4 is located, and is a
list of all the libraries needed to link against to use GEANT4.
6. Copy any Runtime Scripts to the Build Directory
Because we want to support out of source builds so that we won’t mix CMake generated files with our actual
sources, we copy any scripts used by the B1 application to the build directory. We use foreach to loop over
the list of scripts we constructed, and configure_file to perform the actual copy.
Here, the CMake variable PROJECT_BINARY_DIR is set by the earlier call to the project command and
points to the directory where we run CMake to configure the build.
7. If Required, Install the Executable
Use the install command to create an install target that will install the executable to a bin directory under
CMAKE_INSTALL_PREFIX.
If you don’t intend your application to be installable, i.e. you only want to use it locally when built, you can
leave this out.
This sequence of commands is the most basic needed to compile and link an application with GEANT4, and is easily
extendable to more involved use cases such as platform specific configuration or using other third party packages (via
find_package).
With the CMake script in place, using it to build an application is a two step process. First CMake is run to generate
buildscripts to describe the build. By default, these will be Makefiles on Unix platforms, and Visual Studio solutions
on Windows, but you can generate scripts for other tools like Xcode and Eclipse if you wish. Second, the buildscripts
are run by the chosen build tool to compile and link the application.
A key concept with CMake is that we generate the buildscripts and run the build in a separate directory, the so-called
build directory, from the directory in which the sources reside, the so-called source directory. This is the exact same
technique we used when building GEANT4 itself. Whilst this may seem awkward to begin with, it is a very useful
technique to employ. It prevents mixing of CMake generated files with those of your application, and allows you to
have multiple builds against a single source without having to clean up, reconfigure and rebuild.
We’ll illustrate this configure and build process on Linux/macOS using Makefiles, and on Windows using Visual
Studio. The example script and GEANT4’s Geant4Config.cmake script are vanilla CMake, so you should be able
to use other Generators (such as Xcode and Eclipse) without issue.
We’ll assume, for illustration only, that you’ve copied the exampleB1 sources into a directory under your home area
so that we have:
+- /home/you/B1/
+- CMakeLists.txt
+- exampleB1.cc
+- include/
+- src/
+- ...
Here, our source directory is /home/you/B1, in other words the directory holding the CMakeLists.txt file.
Let’s also assume that you have already installed GEANT4 in your home area under, for illustration only, /home/
you/geant4-install.
Our first step is to create a build directory in which build the example. We will create this alongside our B1 source
directory as follows:
$ cd $HOME
$ mkdir B1-build
We now change to this build directory and run CMake to generate the Makefiles needed to build the B1 application.
We pass CMake two arguments
$ cd $HOME/B1-build
$ cmake -DGeant4_DIR=/home/you/geant4-install/lib64/Geant4-G4VERSION $HOME/B1
Here, the first argument points CMake to our install of GEANT4. Specifically, it is the directory holding the
Geant4Config.cmake file that GEANT4 installs to help CMake find and use GEANT4. You should of course
adapt the value of this variable to the location of your actual GEANT4 install. This provides the most specific way to
point CMake to the GEANT4 install you want to use. You may also use the CMAKE_PREFIX_PATH variable, e.g:
$ cd $HOME/B1-build
$ cmake -DCMAKE_PREFIX_PATH=/home/you/geant4-install $HOME/B1
This is most useful for system integrators as it may be extended via the environment or command line with paths to
the install prefixes of additional required software packages.
The second argument to CMake is the path to the source directory of the application we want to build. Here it’s just
the B1 directory as discussed earlier. You should of course adapt the value of that variable to where you copied the B1
source directory.
CMake will now run to configure the build and generate Makefiles and you will see output similar to
$ cmake -DGeant4_DIR=/home/you/geant4-install/lib64/Geant4-G4VERSION $HOME/B1
-- The C compiler identification is GNU 4.9.2
-- The CXX compiler identification is GNU 4.9.2
-- Check for working C compiler: /usr/bin/gcc-4.9
-- Check for working C compiler: /usr/bin/gcc-4.9 -- works
-- Detecting C compiler ABI info
(continues on next page)
The exact output will depend on the UNIX variant and compiler, but the last three lines should be identical to within
the exact path used.
If you now list the contents of you build directory, you can see the files generated:
$ ls
CMakeCache.txt exampleB1.in Makefile vis.mac
CMakeFiles exampleB1.out run1.mac
cmake_install.cmake init_vis.mac run2.mac
Note the Makefile and that all the scripts for running the exampleB1 application we’re about to build have been
copied across. With the Makefile available, we can now build by simply running make:
$ make -jN
CMake generated Makefiles support parallel builds, so N can be set to the number of cores on your machine (e.g. on a
dual core processor, you could set N to 2). When make runs, you should see the output:
$ make
Scanning dependencies of target exampleB1
[ 16%] Building CXX object CMakeFiles/exampleB1.dir/exampleB1.cc.o
[ 33%] Building CXX object CMakeFiles/exampleB1.dir/src/B1PrimaryGeneratorAction.cc.o
[ 50%] Building CXX object CMakeFiles/exampleB1.dir/src/B1EventAction.cc.o
[ 66%] Building CXX object CMakeFiles/exampleB1.dir/src/B1RunAction.cc.o
[ 83%] Building CXX object CMakeFiles/exampleB1.dir/src/B1DetectorConstruction.cc.o
[100%] Building CXX object CMakeFiles/exampleB1.dir/src/B1SteppingAction.cc.o
Linking CXX executable exampleB1
[100%] Built target exampleB1
CMake Unix Makefiles are quite terse, but you can make them more verbose by adding the VERBOSE argument to
make:
$ make VERBOSE=1
If you now list the contents of your build directory you will see the exampleB1 application executable has been
created::
$ ls
CMakeCache.txt exampleB1 init_vis.mac run2.mac
CMakeFiles exampleB1.in Makefile vis.mac
cmake_install.cmake exampleB1.out run1.mac
*************************************************************
(continues on next page)
Note that the exact output shown will depend on how both GEANT4 and your application were configured. Further out-
put and behaviour beyond the Registering graphics systems... line will depend on what UI and Visual-
ization drivers your GEANT4 install supports. If you recall the use of the ui_all vis_all in the find_package
command, this results in all available UI and Visualization drivers being activated in your application. If you didn’t
want any UI or Visualization, you could rerun CMake in your build directory with arguments:
$ cmake -DWITH_GEANT4_UIVIS=OFF .
This would switch the option we set up to false, and result in find_package not activating any UI or Visualiza-
tion for the application. You can easily adapt this pattern to provide options for your application such as additional
components or features.
Once the build is configured, you can edit code for the application in its source directory. You only need to rerun
make in the corresponding build directory to pick up and compile the changes. However, note that due to the use of
CMake globbing to create the source file list, if you add or remove files, you must remember to rerun CMake to pick
up the changes. This is another reason why Kitware recommend listing the sources explicitly.
As with building GEANT4 itself, the simplest system to use for building applications on Windows is a Visual Studio
Developer Command Prompt, which can be started from Start → Visual Studio 2017 → Developer Command Prompt
for VS2017 (similarly for VS2015)
We’ll assume, for illustration only, that you’ve copied the exampleB1 sources into a directory
C:\Users\YourUsername\B1 so that we have:
+- C:\Users\YourUsername\B1
+- CMakeLists.txt
+- exampleB1.cc
+- include\
+- src\
+- ...
Here, our source directory is C:\Users\YourUsername\B1, in other words the directory holding the
CMakeLists.txt file.
Let’s also assume that you have already installed GEANT4 in your home area under, for illustration only,
C:\Users\YourUsername\Geant4-install.
Our first step is to create a build directory in which build the example. We will create this alongside our B1 source
directory as follows, working from the Visual Studio Developer Command Prompt:
> cd %HOMEPATH%
> mkdir B1-build
We now change to this build directory and run CMake to generate the Visual Studio solution needed to build the B1
application. We pass CMake two arguments
> cd %HOMEPATH%\Geant4\B1-build
> cmake -DGeant4_DIR="%HOMEPATH%\Geant4-install\lib\Geant4-G4VERSION" "
˓→%HOMEPATH%\B1"
Here, the first argument points CMake to our install of GEANT4. Specifically, it is the directory holding the
Geant4Config.cmake file that GEANT4 installs to help CMake find and use GEANT4. You should of course
adapt the value of this variable to the location of your actual GEANT4 install. As with the examples above, you can
also use the CMAKE_PREFIX_PATH variable. The second argument is the path to the source directory of the appli-
cation we want to build. Here it’s just the B1 directory as discussed earlier. You should of course adapt it to where you
copied the B1 source directory. In both cases the arguments are quoted in case of the paths containing spaces.
CMake will now run to configure the build and generate Visual Studio solutions and you will see output similar to
-- Building for: Visual Studio 15 2017
-- The C compiler identification is MSVC 19.11.25547.0
-- The CXX compiler identification is MSVC 19.11.25547.0
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/
˓→VC/Tools/MSVC/14.11.25503/bin/Hostx86/x86/cl.exe
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/
˓→VC/Tools/MSVC/14.11.25503/bin/Hostx86/x86/cl.exe -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/
˓→VC/Tools/MSVC/14.11.25503/bin/Hostx86/x86/cl.exe
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/
˓→VC/Tools/MSVC/14.11.25503/bin/Hostx86/x86/cl.exe -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: C:/Users/YourUsername/B1-build
If you now list the contents of you build directory, you can see the files generated:
> dir /B
ALL_BUILD.vcxproj
ALL_BUILD.vcxproj.filters
B1.sln
B1.vcxproj
B1.vcxproj.filters
CMakeCache.txt
CMakeFiles
cmake_install.cmake
exampleB1.in
exampleB1.out
exampleB1.vcxproj
exampleB1.vcxproj.filters
init_vis.mac
INSTALL.vcxproj
INSTALL.vcxproj.filters
run1.mac
run2.mac
vis.mac
ZERO_CHECK.vcxproj
ZERO_CHECK.vcxproj.filters
Note the B1.sln solution file and that all the scripts for running the exampleB1 application we’re about to build have
been copied across. With the solution available, we can now build by running cmake to drive MSBuild:
Solution based builds are quite verbose, but you should not see any errors at the end. In the above, we have built the B1
program in Release mode, meaning that it is optimized and has no debugging symbols. As with building GEANT4
itself, this is chosen to provide optimum performance. If you require debugging information for your application,
simply change the argument to RelWithDebInfo. Note that in both cases you must match the configuration of
your application with that of the GEANT4 install, i.e. if you are building the application in Release mode, then
ensure it uses a Release build of GEANT4. Link and/or runtime errors may result if mixed configurations are used.
After running the build, if we list the contents of the build directory again we see:
> dir /B
ALL_BUILD.vcxproj
ALL_BUILD.vcxproj.filters
B1.sln
B1.vcxproj
B1.vcxproj.filters
CMakeCache.txt
CMakeFiles
cmake_install.cmake
exampleB1.dir
exampleB1.in
exampleB1.out
exampleB1.vcxproj
exampleB1.vcxproj.filters
init_vis.mac
INSTALL.vcxproj
INSTALL.vcxproj.filters
Release
run1.mac
run2.mac
vis.mac
Win32
ZERO_CHECK.vcxproj
ZERO_CHECK.vcxproj.filters
Here, the Release subdirectory contains the executable, and the main build directory contains all the .mac scripts
for running the program. If you build in different modes, the executable for that mode will be in a directory named for
that mode, e.g. RelWithDebInfo/exampleB1.exe. You can now run the application in place:
> .\Release\exampleB1.exe
*************************************************************
Geant4 version Name: geant4-10-05 [MT] (07-December-2018)
<< in Multi-threaded mode >>
Copyright : Geant4 Collaboration
References : NIM A 506 (2003), 250-303
: IEEE-TNS 53 (2006), 270-278
: NIM A 835 (2016), 186-225
WWW : http://geant4.org/
*************************************************************
Note that the exact output shown will depend on how both GEANT4 and your application were configured. Fur-
ther output and behaviour beyond the Registering graphics systems... line will depend on what UI and
Visualization drivers your GEANT4 install supports.
Whilst the Visual Studio Developer Command prompt provides the simplest way to build an application, the generated
Visual Studio Solution file (B1.sln in the above example) may also be opened directly in the Visual Studio IDE. This
provides a more comprehensive development and debugging environment, and you should consult its documentation
if you wish to use this.
One key CMake related item to note goes back to our listing of the headers for the application in the call to
add_executable. Whilst CMake will naturally ignore these for configuring compilation of the application, it
will add them to the Visual Studio Solution. If you do not list them, they will not be editable in the Solution in the
Visual Studio IDE.
Please note that this system is deprecated, meaning that it is no longer supported and may be removed
in future releases without warning. You should migrate your application to be built using CMake via the
Geant4Config.cmake script, or any other build tool of your choice, using the geant4-config program
to query the relevant compiler/linker flags.
Geant4Make is the GEANT4 GNU Make toolchain formerly used to build the toolkit and applications. It is installed
on UNIX systems (except for Cygwin) for backwards compatibility with the GEANT4 Examples and your existing
applications which use a GNUmakefile and the Geant4Make binmake.gmk file. The files for Geant4Make are
installed under:
+- CMAKE_INSTALL_PREFIX/
+- share/
+- geant4make/
+- geant4make.sh
+- geant4make.csh
+- config/
+- binmake.gmk
+- ...
The system is designed to form a self-contained GNUMake system which is configured primarily by environment
variables (though you may manually replace these with Make variables if you prefer). Building a GEANT4 application
using Geant4Make therefore involves configuring your environment followed by writing a GNUmakefile using the
Geant4Make variables and GNUMake modules.
To configure your environment, simply source the relevant configuration script CMAKE_INSTALL_PREFIX/
share/Geant4-G4VERSION/geant4make/geant4make.(c)sh for your shell. Whilst both scripts can be
sourced interactively, if you are using the C shell and need to source the script inside another script, you must use the
commands:
$ cd CMAKE_INSTALL_PREFIX/share/Geant4-G4VERSION/geant4make
$ source geant4make.csh
or alternatively
$ source CMAKE_INSTALL_PREFIX/share/Geant4-G4VERSION/geant4make/geant4make.
˓→csh \
CMAKE_INSTALL_PREFIX/share/Geant4-G4VERSION/geant4make
In both cases, you should replace CMAKE_INSTALL_PREFIX with the actual prefix you installed GEANT4 under.
Both of these commands work around a limitation in the C shell which prevents the script locating itself.
Please also note that due to limitations of Geant4Make, you should not rely on the environment variables
it sets for paths into GEANT4 itself. In particular, note that the G4INSTALL variable is not equivalent to
CMAKE_INSTALL_PREFIX.
Once you have configured your environment, you can start building your application. Geant4Make enforces a specific
organization and naming of your sources in order to simplify the build. We’ll use Basic Example B1, which you
may find in the GEANT4 source directory under examples/basic/B1, as the canonical example again. Here, the
sources are arranged as follows:
+- B1/
+- GNUmakefile
+- exampleB1.cc
+- include/
... headers.hh ...
+- src/
... sources.cc ...
As before, exampleB1.cc contains main() for the application, with include/ and src/ containing the im-
plementation class headers and sources respectively. You must organise your sources in this structure with these
filename extensions to use Geant4Make as it will expect this structure when it tries to build the application.
With this structure in place, the GNUmakefile for exampleB1 is very simple:
name := exampleB1
G4TARGET := $(name)
G4EXLIB := true
.PHONY: all
all: lib bin
include $(G4INSTALL)/config/binmake.gmk
Here, name is set to the application to be built, and it must match the name of the file containing the main()
program without the .cc extension. The rest of the variables are structural to prepare the build, and finally the core
Geant4Make module is included. The G4INSTALL variable is set in the environment by the geant4make script to
point to the root of the Geant4Make directory structure.
With this structure in place, simply run make to build your application:
$ make
If you need extra detail on the build, append CPPVERBOSE=1 to the make command to see a detailed log of the
command executed.
The application executable will be output to $(G4WORKDIR)/bin/$(G4SYSTEM)/exampleB1, where
$(G4SYSTEM) is the system and compiler combination you are running on, e.g. Linux-g++. By default,
$(G4WORKDIR) is set by the geant4make scripts to $(HOME)/geant4_workdir, and also prepends this
directory to your PATH. You can therefore run the application directly once it’s built:
$ exampleB1
If you prefer to keep your application builds separate, then you can set G4WORKDIR in the GNUmakefile before
including binmake.gmk. In this case you would have to run the executable by supplying the full path.
Further documentation of the usage of Geant4Make and syntax and extensions for the GNUMakefile is described in
the FAQ and Appendices of the Geant4 User’s Guide for Application Developers.
Please note that the Geant4Make toolchain is provided purely for convenience and backwards compatibil-
ity. We encourage you to use and migrate your applications to the new CMake and geant4-config tools.
Geant4Make is deprecated from Geant4 10.0.
2.9.1 Introduction
The “intercoms” category provides an expandable command interpreter. It is the key mechanism of GEANT4 to
realize secure user interactions across categories without being annoyed by dependencies among categories. GEANT4
commands can be used in an interactive session, a batch mode with a macro file, or a direct C++ call.
GEANT4 can be controlled by a series of GEANT4 UI commands. The “intercoms” category provides the abstract class
G4UIsession that processes interactive commands. The concrete implementations of (graphical) user interface are
provided in the “interfaces” category. The strategy realize to adopt various user interface tools, and allows GEANT4 to
utilize the state-of-the-art GUI tools such as Motif, Qt, and Java etc. The following interfaces is currently available;
1. Command-line terminal (dumb terminal and tcsh-like terminal)
2. Xm, Qt, Win32, variations of the above terminal by using a Motif, Qt, Windows widgets
3. GAG, a fully graphical user interface and its network extension GainServer of the client/server type.
Implementation of the user sessions (1 and 2) is included in the source/interfaces/basic directory. As for
GAG, the front-end class is included in the source/interfaces/GAG directory, while its partner GUI package
MOMO.jar is available under the environments/MOMO directory. MOMO.jar, Java archive file, contains not only
GAG, but also GGE and other helper packages. Supplementary information is available from the author’s web page
(see URL below).
GAG, GainServer’s client GUI Gain: http://www-geant4.kek.jp/~yoshidah/
G4UIterminal
This interface opens a session on a command-line terminal. G4UIterminal runs on all supported platforms. There
are two kinds of shells, G4UIcsh and G4UItcsh. G4UItcsh supports tcsh-like readline features (cursor and
command completion) and works on Linux on Mac, while G4UIcsh is a plain standard input (cin) shell that works
on all platforms. The following built-in commands are available in G4UIterminal;
cd, pwd change, display the current command directory.
ls, lc list commands and subdirectories in the current directory.
history show previous commands.
!historyID reissue previous command.
?command show current parameter values of the command.
help command show command help.
exit terminate the session.
G4UItcsh supports user-friendly key bindings a-la-tcsh. G4UItcsh runs on Linux and Mac. The following keybind-
ings are supported;
^A move cursor to the top
^B backward cursor ([LEFT] cursor)
^C (except Windows terminal) abort a run ( soft abort ) during event processing. A program will be terminated
while accepting a user command.
^D delete/exit/show matched list
These interfaces are versions of G4UIterminal implemented over libraries Motif, Qt and WIN32 respectively.
G4UIXm uses the Motif XmCommand widget, G4UIQt the Qt dialog widget, and G4UIWin32 the Windows “edit”
component to do the command capturing. These interfaces are useful if working in conjunction with visualization
drivers that use the Xt library, Qt library or the WIN32 one.
A command box is at disposal for entering or recalling GEANT4 commands. Command completion by typing “TAB”
key is available in the command box. The shell commands “exit, cont, help, ls, cd. . . ” are also supported. A menu bar
can be customized through the AddMenu and AddButton method. Ex:
/gui/addMenu test Test
/gui/addButton test Init /run/initialize
/gui/addButton test “Set gun” “/control/execute gun.g4m”
/gui/addButton test “Run one event” “/run/beamOn 1”
G4UIXm runs on Unix/Linux with Motif. G4UIQt run everywhere with Qt. G4UIWin32 runs on Windows.
They are front-end classes of GEANT4 which make connections with their respective graphical user interfaces, GAG
(GEANT4 Adaptive GUI) via pipe, and Gain (GEANT4 adaptive interface for network) via sockets. While GAG must
run on the same system (Windows or Unixen) as a GEANT4 application, Gain can run on a remote system (Windows,
Linux, etc.) in which JRE (Java Runtime Environment) is installed. A GEANT4 application is invoked on a Unix
(Linux) system and behaves as a network server. It opens a port, waiting the connection from the Gain. Gain has
capability to connect to multiple GEANT4 “servers” on Unixen systems at different hosts.
Client GUIs, GAG and Gain have almost similar look-and-feel. So, GAG’s functionalities are briefly explained here.
Please refer to the URL previously mentioned for details.
Using GAG, user can select a command, set its parameters and execute it. It is adaptive, in the sense that it reflects
the internal states of GEANT4 that is a state machine. So, GAG always provides users with the GEANT4 commands
which may be added, deleted, enabled or disabled during a session. GAG does nothing by itself but to play an
intermediate between user and an executable simulation program via pipes. GEANT4’s front-end class G4UIGAG
must be instantiated to communicate with GAG. GAG runs on Linux and Windows. MOMO.jar is supplied in the
GEANT4 source distribution and can be run by a command:
%java -jar /path/to/geant4.10.00/environments/MOMO/MOMO.jar
To choose an interface (G4UIxxx where xxx = terminal,Xm, Win32, Qt, GAG, GainServer) in your
programs, there are two ways.
• Calling G4UIxxx directly:
#include "G4Uixxx.hh"
delete session;
If the user wants to deactivate the default signal handler (soft abort) raised by “Ctr-C”, the false flag can be set
in the second argument of the G4UIterminal constructor like
G4UIsession* session = new G4UIterminal(new G4UItcsh, false).
• Using G4UIExecutive This is more convenient way for choosing a session type, that can select a session at
run-time according to a rule described below.
#include "G4UIExecutive.hh"
delete ui;
G4UIExecutive has several ways to choose a session type. A session is selected in the following rule. Note that
session types are identified by a case-insensitive characters (“qt”, “xm”, “win32”, “gag”, “tcsh”, “csh”).
1. Check the argument of the constructor of G4UIExecutive. You can specify a session like new
G4UIExecutive(argc, argv, "qt");
2. Check environment variables, G4UI_USE_XX (XX= QT, XM, WIN32, GAG, TCSH). Select a session
if the corresponding environment variable is defined. Variables are checked in the order of QT, XM, WIN32,
GAG, TCSH if multiple variables are set.
3. Check ~/.g4session . You can specify the default session type and a session type by each application in
that file. The below shows a sample of .g4session.
tcsh # default session
exampleN03 Qt # (application name / session type)
myapp tcsh
hoge csh
4. Guess the best session type according to build session libraries. The order of the selection is Qt, tcsh, Xm.
In any cases, G4UIExecutive checks if a specified session is build or not. If not, it goes the next step. A terminal
session with csh is the fallback session. If none of specified session is available, then it will be selected.
2.10.1 Introduction
Below is a modified main program of the basic example B1 to represent an application which will run in batch mode.
// Initialize G4 kernel
runManager->Initialize();
(continues on next page)
// start a run
int numberOfEvent = 1000;
runManager->BeamOn(numberOfEvent);
// job termination
delete runManager;
return 0;
}
Even the number of events in the run is ‘frozen’. To change this number you must at least recompile main().
Below is a modified main program of the basic example B1 to represent an application which will run in batch mode,
but reading a file of commands.
// Initialize G4 kernel
runManager->Initialize();
// job termination
delete runManager;
return 0;
}
where exampleB1 is the name of the executable and run1.mac is a macro of commands located in the current
directory, which could look like:
Indeed, you can re-execute your program with different run conditions without recompiling anything.
Note: many G4 category of classes have a verbose flag which controls the level of ‘verbosity’.
Usually verbose=0 means silent. For instance
• /run/verbose is for the RunManager
• /event/verbose is for the EventManager
• /tracking/verbose is for the TrackingManager
• . . . etc. . .
Below is an example of the main program for an application which will run interactively, waiting for command lines
entered from the keyboard.
// Initialize G4 kernel
runManager->Initialize();
// job termination
delete runManager;
return 0;
}
and you can start your session. An example session could be:
Run 5 events:
Idle> /run/beamOn 5
For the meaning of the machine state Idle, see as a state machine.
This mode is useful for running a few events in debug mode and visualizing them. How to include visualization will
be shown in the next, general case, example.
All basic examples in the examples/basic subdirectory of the GEANT4 source distribution have the following
main() structure. The application can be run either in batch or interactive mode.
Listing 2.23: The typical main() routine from the examples directory.
int main(int argc,char** argv)
{
// Construct the default run manager
G4RunManager* runManager = new G4RunManager;
// Initialize G4 kernel
runManager->Initialize();
#ifdef G4VIS_USE
(continues on next page)
if (argc!=1) {
// batch mode
G4String command = "/control/execute ";
G4String fileName = argv[1];
UImanager->ApplyCommand(command+fileName);
}
else {
// interactive mode : define UI session
#ifdef G4UI_USE
G4UIExecutive* ui = new G4UIExecutive(argc, argv);
#ifdef G4VIS_USE
UImanager->ApplyCommand("/control/execute init_vis.mac");
#else
UImanager->ApplyCommand("/control/execute init.mac");
#endif
ui->SessionStart();
delete ui;
#endif
}
// Job termination
// Free the store: user actions, physics_list and detector_description are
// owned and deleted by the run manager, so they should not be deleted
// in the main() program !
#ifdef G4VIS_USE
delete visManager;
#endif
delete runManager;
}
Notice that both user interface and visualization systems are under the control of the compiler preprocessor sym-
bols G4UI_USE and G4VIS_USE. GEANT4’s CMake support script automatically adds definitions for these sym-
bols to the compiler flags, unless you set the CMake variables G4UI_NONE and G4VIS_NONE before calling
find_package(Geant4). This provides you with a simple system to control the enabling of the user inter-
face and visualization systems, though you are free to use your own names for the preprocessor symbols if your use
case requires (though you must then add them to the compiler flags yourself). Notice also that, in interactive mode,
few intializations have been put in the macros init_vis.mac, or init_vis.mac, which is executed before the
session start.
The init_vis.mac macro has just added a line with a call to vis.mac:
# Macro file for the initialization phase of example B1
# when running in interactive mode with visualization
#
# Set some default verbose
#
/control/verbose 2
/control/saveHistory
/run/verbose 2
#
# Visualization setting
/control/execute vis.mac
The vis.mac macro defines a minimal setting for drawing volumes and trajectories accumulated for all events of a
given run:
# Macro file for the visualization setting in the initialization phase
# of the B1 example when running in interactive mode
#
#
# Use this open statement to create an OpenGL view:
/vis/open OGL 600x600-0+0
#
# Draw geometry:
/vis/drawVolume
#
# Specify view angle:
/vis/viewer/set/viewpointThetaPhi 90. 180.
#
# Draw smooth trajectories at end of event, showing trajectory points
# as markers 2 pixels wide:
/vis/scene/add/trajectories smooth
#
# To superimpose all of the events from a given run:
/vis/scene/endOfEventAction accumulate
#
# Re-establish auto refreshing and verbosity:
/vis/viewer/set/autoRefresh true
/vis/verbose warnings
#
# For file-based drivers, use this to create an empty detector view:
#/vis/viewer/flush
Also, this example demonstrates that you can read and execute a macro from another macro or interactively:
Idle> /control/execute mySubMacro.mac
2.11.1 Introduction
This section briefly explains how to perform GEANT4 Visualization. The description here is based on the sample
program examples/basic/B1. More details are given in Visualization.
The GEANT4 visualization system was developed in response to a diverse set of requirements:
1. Quick response to study geometries, trajectories and hits
2. High-quality output for publications
3. Flexible camera control to debug complex geometries
4. Tools to show volume overlap errors in detector geometries
5. Interactive picking to get more information on visualized objects
No one graphics system is ideal for all of these requirements, and many of the large software frameworks into which
GEANT4 has been incorporated already have their own visualization systems, so GEANT4 visualization was designed
around an abstract interface that supports a diverse family of graphics systems. Some of these graphics systems use
a graphics library compiled with GEANT4, such as OpenGL, Qt or OpenInventor, while others involve a separate
application, such as HepRApp or DAWN.
You need not use all visualization drivers. You can select those suitable to your purposes. In the following, for
simplicity, we assume that the GEANT4 libraries are built with the Qt driver.
If you build GEANT4 using the standard CMake procedure, you include Qt by setting GEANT4_USE_QT to ON.
In order to use the the Qt driver, you need the OpenGL library, which is installed in many platforms by default and
CMake will find it. (If you wish to “do-it-yourself”, see Installing Visualization Drivers.) The makefiles then set
appropriate C-pre-processor flags to select appropriate code at compilation time.
If you are using multithreaded mode, from GEANT4 version 10.2 event drawing is performed by a separate thread and
you may need to optimise this with special /vis/multithreading commands - see Multithreading commands.
Most GEANT4 examples already incorporate visualization drivers. If you want to include visualization in your own
GEANT4 application, you need to instantiate and initialize a subclass of G4VisManager that implements the pure
virtual function RegisterGraphicsSystems().
The provided class G4VisExecutive can handle all of this work for you. G4VisExecutive is sensitive to the
G4VIS_... variables (that you either set by hand or that are set for you by GNUMake or CMake configuration). See
any of the GEANT4 examples for how to use G4VisExecutive.
If you really want to write your own subclass, rather than use G4VisExecutive, you may do so. You will see how
to do this by looking at G4VisExecutive.icc. This subclass must be compiled in the user’s domain to force the
loading of appropriate libraries in the right order. A typical extract is:
...
RegisterGraphicsSystem (new G4DAWNFILE);
...
#ifdef G4VIS_USE_OPENGLX
RegisterGraphicsSystem (new G4OpenGLImmediateX);
RegisterGraphicsSystem (new G4OpenGLStoredX);
#endif
...
The G4VisExecutive takes ownership of all registered graphics systems, and will delete them when it is deleted
at the end of the user’s job (see below).
If you wish to use G4VisExecutive but register an additional graphics system, XXX say, you may do so either
before or after initializing:
visManager->RegisterGraphicsSytem(new XXX);
visManager->Initialize();
Now we explain how to write a visualization manager and the main() function for GEANT4 visualization. In order
that your GEANT4 executable is able to perform visualization, you must instantiate and initialize your Visualization
Manager in the main() function. The typical main() function available for visualization is written in the following
style:
.....
.....
.....
// Job termination
#ifdef G4VIS_USE
delete visManager;
#endif
.....
return 0;
}
In the instantiation, initialization, and deletion of the Visualization Manager, the use of the macro G4VIS_USE is
recommended as it is set automatically by the CMake and GNUmake support scripts. This allows one easily to
build an executable without visualization, if required, without changing the code (but remember you have to force
recompilation whenever you change the environment). Note that it is your responsibility to delete the instantiated
Visualization Manager by yourself. A complete description of a sample main() function is described in examples/
basic/B1/exampleB1.cc.
Most GEANT4 examples include a vis.mac. Run that macro to see a typical visualization. Read the comments in the
macro to learn a little bit about some visualization commands. The vis.mac also includes commented-out optional
visualization commands. By uncommenting some of these, you can see additional visualization features.
THREE
TOOLKIT FUNDAMENTALS
In the design of a large software system such as GEANT4, it is essential to partition it into smaller logical units. This
makes the design well organized and easier to develop. Once the logical units are defined independent to each other
as much as possible, they can be developed in parallel without serious interference.
In object-oriented analysis and design methodology by Grady Booch [Booch1994], class categories are used to create
logical units. They are defined as “clusters of classes that are themselves cohesive, but are loosely coupled relative
to other clusters.” This means that a class category contains classes which have a close relationship (for example, the
“has-a” relation). However, relationships between classes which belong to different class categories are weak, i.e.,
only limited classes of these have “uses” relations. The class categories and their relations are presented by a class
category diagram. The class category diagram designed for GEANT4 is shown in the figure below (Fig. 3.1). Each box
in the figure represents a class category, and a “uses” relation by a straight line. The circle at an end of a straight line
means the class category which has this circle uses the other category.
The file organization of the GEANT4 codes follows basically the structure of this class category. This User’s Manual
is also organized according to class categories.
In the development and maintenance of GEANT4, one software team will be assigned to a class category. This team
will have a responsibility to develop and maintain all classes belonging to the class category.
The following is a brief summary of the role of each class category in GEANT4.
1. Run and Event
These are categories related to the generation of events, interfaces to event generators, and any secondary parti-
cles produced. Their roles are principally to provide particles to be tracked to the Tracking Management.
2. Tracking and Track
These are categories related to propagating a particle by analyzing the factors limiting the step and applying the
relevant physics processes. The important aspect of the design was that a generalized GEANT4 physics process
(or interaction) could perform actions, along a tracking step, either localized in space, or in time, or distributed
in space and time (and all the possible combinations that could be built from these cases).
3. Geometry and Magnetic Field
These categories manage the geometrical definition of a detector (solid modeling) and the computation of dis-
tances to solids (also in a magnetic field). The GEANT4 geometry solid modeler is based on the ISO STEP
standard and it is fully compliant with it. A key feature of the GEANT4 geometry is that the volume definitions
are independent of the solid representation. By this abstract interface for the G4 solids, the tracking compo-
nent works identically for various representations. The treatment of the propagation in the presence of fields
55
Book For Application Developers, Release 10.5
has been provided within specified accuracy. An OO design allows to exchange different numerical algorithms
and/or different fields (not only B-field), without affecting any other component of the toolkit.
4. Particle Definition and Matter
These two categories manage the the definition of materials and particles.
5. Physics
This category manages all physics processes participating in the interactions of particles in matter. The abstract
interface of physics processes allows multiple implementations of physics models per interaction or per channel.
Models can be selected by energy range, particle type, material, etc. Data encapsulation and polymorphism make
it possible to give transparent access to the cross sections (independently of the choice of reading from an ascii
file, or of interpolating from a tabulated set, or of computing analytically from a formula). Electromagnetic and
hadronic physics were handled in a uniform way in such a design, opening up the physics to the users.
6. Hits and Digitization
These two categories manage the creation of hits and their use for the digitization phase. The basic design and
implementation of the Hits and Digi had been realized, and also several prototypes, test cases and scenarios
had been developed before the alpha-release. Volumes (not necessarily the ones used by the tracking) are
aggregated in sensitive detectors, while hits collections represent the logical read out of the detector. Different
ways of creating and managing hits collections had been delivered and tested, notably for both single hits and
calorimetry hits types. In all cases, hits collections had been successfully stored into and retrieved from an
Object Data Base Management System.
7. Visualization
This manages the visualization of solids, trajectories and hits, and interacts with underlying graphical libraries
(the Visualization class category). The basic and most frequently used graphics functionality had been imple-
mented already by the alpha-release. The OO design of the visualization component allowed us to develop
several drivers independently, such as for OpenGL, Qt and OpenInventor (for X11 and Windows), DAWN,
Postscript (via DAWN) and VRML.
8. Interfaces
This category handles the production of the graphical user interface (GUI) and the interactions with external
software (OODBMS, reconstruction etc.).
The “global” category in GEANT4 collects all classes, types, structures and constants which are considered of general
use within the GEANT4 toolkit. This category also defines the interface with third-party software libraries (CLHEP,
STL, etc.) and system-related types, by defining, where appropriate, typedefs according to the GEANT4 code
conventions.
In order to keep an homogeneous naming style, and according to the GEANT4 coding style conventions, each class
part of the GEANT4 kernel has its name beginning with the prefix G4, e.g., G4VHit, G4GeometryManager,
G4ProcessVector, etc. Instead of the raw C types, G4 types are used within the GEANT4 code. For the basic
numeric types (int, float, double, etc.), different compilers and different platforms provide different value
ranges. In order to assure portability, the use of G4int, G4float, G4double, G4bool, globally defined, is
preferable. G4 types implement the right generic type for a given architecture.
Basic types
The following classes are typedefs to the corresponding classes of the CLHEP (Computing Library for High
Energy Physics) distribution. For more detailed documentation please refer to the CLHEP documentation.
• G4ThreeVector, G4RotationMatrix, G4LorentzVector and G4LorentzRotation:
Vector classes: defining 3-component (x,y,z) vector entities, rotation of such objects as 3x3 matrices, 4-
component (x,y,z,t) vector entities and their rotation as 4x4 matrices.
• G4Plane3D, G4Transform3D, G4Normal3D, G4Point3D, G4Scale3D, and G4Vector3D:
Geometrical classes: defining geometrical entities and transformations in 3D space.
The HEPRandom module, originally part of the GEANT4 kernel, and now distributed as a module of CLHEP, has
been designed and developed starting from the Random class of MC++, the original CLHEP’s HepRandom module
and the Rogue Wave approach in the Math.h++ package. For detailed documentation on the HEPRandom classes see
the CLHEP documentation.
Information written in this manual is extracted from the original manifesto distributed with the HEPRandom package.
The HEPRandom module consists of classes implementing different random engines and different random
distributions. A distribution associated to an engine constitutes a random generator. A distribution class
can collect different algorithms and different calling sequences for each method to define distribution parameters or
range-intervals. An engine implements the basic algorithm for pseudo-random numbers generation.
There are 3 different ways of shooting random values:
1. Using the static generator defined in the HepRandom class: random values are shot using static methods
shoot() defined for each distribution class. The static generator will use, as default engine, a MixMaxRng
object, and the user can set its properties or change it with a new instantiated engine object by using the static
methods defined in the HepRandom class.
2. Skipping the static generator and specifying an engine object: random values are shot using static methods
shoot(*HepRandomEngine) defined for each distribution class. The user must instantiate an engine object
and give it as argument to the shoot method. The generator mechanism will then be by-passed by using the basic
flat() method of the specified engine. The user must take care of the engine objects he/she instantiates.
3. Skipping the static generator and instantiating a distribution object: random values are shot using fire()
methods (NOT static) defined for each distribution class. The user must instantiate a distribution object giving
as argument to the constructor an engine by pointer or by reference. By doing so, the engine will be associated
to the distribution object and the generator mechanism will be by-passed by using the basic flat() method of
that engine.
In this guide, we’ll only focus on the static generator (point 1.), since the static interface of HEPRandom is the only
one used within the GEANT4 toolkit.
HEPRandom engines
The class HepRandomEngine is the abstract class defining the interface for each random engine. It implements the
getSeed() and getSeeds() methods which return the initial seed value and the initial array of seeds (if
any) respectively. Many concrete random engines can be defined and added to the structure, simply making them
inheriting from HepRandomEngine. Several different engines are currently implemented in HepRandom, we describe
here five of them:
• HepJamesRandom
It implements the algorithm described in F.James, Comp. Phys. Comm. 60 (1990) 329 for pseudo-random
number generation.
• DRand48Engine
Random engine using the drand48() and srand48() system functions from C standard library to imple-
ment the flat() basic distribution and for setting seeds respectively. DRand48Engine uses the seed48()
function from C standard library to retrieve the current internal status of the generator, which is represented by
3 short values. DRand48Engine is the only engine defined in HEPRandom which intrinsically works in 32 bits
precision. Copies of an object of this kind are not allowed.
• MixMaxRng
Random number engine implementing the MixMax Matrix Generator of Pseudorandom Numbers generator
proposed by N.Z.Akopov, G.K.Saviddy and N.G.Ter-Arutyunian, J.Compt.Phy. 97, (1991) 573 and G.Savvidy
and N.Savvidy, J.Comput.Phys. 97 (1991) 566. This is the default random engine for the static generator; it will
be invoked by each distribution class unless the user sets a different one.
• RanluxEngine
The algorithm for RanluxEngine has been taken from the original implementation in FORTRAN77 by Fred
James, part of the MATHLIB HEP library. The initialisation is carried out using a Multiplicative Congruential
generator using formula constants of L’Ecuyer as described in F.James, Comp. Phys. Comm. 60 (1990) 329-
344. The engine provides five different luxury levels for quality of random generation. When instantiating a
RanluxEngine, the user can specify the luxury level to the constructor (if not, the default value 3 is taken). For
example:
RanluxEngine theRanluxEngine(seed,4);
// instantiates an engine with `seed' and the best luxury-level
... or
RanluxEngine theRanluxEngine;
// instantiates an engine with default seed value and luxury-level
...
The class provides a getLuxury() method to get the engine luxury level.
The SetSeed() and SetSeeds() methods to set the initial seeds for the engine, can be invoked specifying
the luxury level. For example:
// static interface
HepRandom::setTheSeed(seed,4); // sets the seed to `seed' and luxury to 4
HepRandom::setTheSeed(seed); // sets the seed to `seed' keeping
// the current luxury level
• RanecuEngine
The algorithm for RanecuEngine is taken from the one originally written in FORTRAN77 as part of the MATH-
LIB HEP library. The initialisation is carried out using a Multiplicative Congruential generator using formula
constants of L’Ecuyer as described in F.James, Comp. Phys. Comm. 60 (1990) 329-344. Handling of seeds for
this engine is slightly different than the other engines in HEPRandom. Seeds are taken from a seed table given
an index, the getSeed() method returns the current index of seed table. The setSeeds() method will set
seeds in the local SeedTable at a given position index (if the index number specified exceeds the table’s size,
[index%size] is taken). For example:
// static interface
const G4long* table_entry;
table_entry = HepRandom::getTheSeeds();
// it returns a pointer `table_entry' to the local SeedTable
// at the current `index' position. The couple of seeds
// accessed represents the current `status' of the engine itself !
...
G4int index=n;
G4long seeds[2];
HepRandom::setTheSeeds(seeds,index);
// sets the new `index' for seeds and modify the values inside
// the local SeedTable at the `index' position. If the index
// is not specified, the current index in the table is considered.
...
The setSeed() method resets the current ‘status’ of the engine to the original seeds stored in the static table
of seeds in HepRandom, at the specified index.
Except for the RanecuEngine, for which the internal status is represented by just a couple of longs, all the other engines
have a much more complex representation of their internal status, which currently can be obtained only through the
methods saveStatus(), restoreStatus() and showStatus(), which can also be statically called from
HepRandom. The status of the generator is needed for example to be able to reproduce a run or an event in a run at a
given stage of the simulation.
RanecuEngine is probably the most suitable engine for this kind of operation, since its internal status can be
fetched/reset by simply using getSeeds()/setSeeds() (getTheSeeds()/setTheSeeds() for the static
interface in HepRandom).
HepRandom a singleton class and using a MixMaxRng engine as default algorithm for pseudo-random number gener-
ation. HepRandom defines a static private data member, theGenerator, and a set of static methods to manipulate
it. By means of theGenerator, the user can change the underlying engine algorithm, get and set the seeds, and use
any kind of defined random distribution. The static methods setTheSeed() and getTheSeed() will set and get
respectively the initial seed to the main engine used by the static generator. For example:
HepRandom::setTheSeed(seed); // to change the current seed to 'seed'
int startSeed = HepRandom::getTheSeed(); // to get the current initial seed
HepRandom::saveEngineStatus(); // to save the current engine status on file
HepRandom::restoreEngineStatus(); // to restore the current engine to a previous
// saved configuration
HepRandom::showEngineStatus(); // to display the current engine status to stdout
...
int index=n;
long seeds[2];
HepRandom::getTheTableSeeds(seeds,index);
// fills `seeds' with the values stored in the global
// seedTable at position `index'
Only one random engine can be active at a time, the user can decide at any time to change it, define a new one (if not
done already) and set it. For example:
RanecuEngine theNewEngine;
HepRandom::setTheEngine(&theNewEngine);
...
or simply setting it to an old instantiated engine (the old engine status is kept and the new random sequence will start
exactly from the last one previously interrupted). For example:
HepRandom::setTheEngine(&myOldEngine);
HEPRandom distributions
A distribution-class can collect different algorithms and different calling sequences for each method to define distribu-
tion parameters or range-intervals; it also collects methods to fill arrays, of specified size, of random values, according
to the distribution. This class collects either static and not static methods. A set of distribution classes are defined in
HEPRandom. Here is the description of some of them:
• RandFlat Class to shoot flat random values (integers or double) within a specified interval. The class provides
also methods to shoot just random bits.
• RandExponential Class to shoot exponential distributed random values, given a mean (default mean = 1)
• RandGauss Class to shoot Gaussian distributed random values, given a mean (default = 0) or specifying also a
deviation (default = 1). Gaussian random numbers are generated two at the time, so every other time a number
is shot, the number returned is the one generated the time before.
• RandBreitWigner Class to shoot numbers according to the Breit-Wigner distribution algorithms (plain or
mean^2).
• RandPoisson Class to shoot numbers according to the Poisson distribution, given a mean (default = 1) (Algo-
rithm taken from W.H.Press et al., Numerical Recipes in C, Second Edition).
A set of classes implementing numerical algorithms has been developed in GEANT4. Most of the algorithms and
methods have been implemented mainly based on recommendations given in the books:
• B.H. Flowers, An introduction to Numerical Methods In C++, Clarendon Press, Oxford 1995.
• M. Abramowitz, I. Stegun, Handbook of mathematical functions, DOVER Publications INC, New York 1965 ;
chapters 9, 10, and 22.
This set of classes includes:
• G4ChebyshevApproximation Class creating the Chebyshev approximation for a function pointed by
fFunction data member. The Chebyshev polynomial approximation provides an efficient evaluation of the min-
imax polynomial, which (among all polynomials of the same degree) has the smallest maximum deviation from
the true function.
• G4DataInterpolation Class providing methods for data interpolations and extrapolations: Polynomial,
Cubic Spline, . . .
• G4GaussChebyshevQ
• G4GaussHermiteQ
• G4GaussJacobiQ
• G4GaussLaguerreQ Classes implementing the Gauss-Chebyshev, Gauss-Hermite, Gauss-Jacobi, Gauss-
Laguerre and Gauss-Legendre quadrature methods. Roots of orthogonal polynomials and corresponding weights
are calculated based on iteration method (by bisection Newton algorithm).
• G4Integrator Template class collecting integrator methods for generic functions (Legendre, Simpson,
Adaptive Gauss, Laguerre, Hermite, Jacobi).
• G4SimpleIntegration Class implementing simple numerical methods (Trapezoidal, MidPoint, Gauss,
Simpson, Adaptive Gauss, for integration of functions with signature: double f(double).
The global category defines also a set of utility classes generally used within the kernel of GEANT4. These
classes include:
• G4Allocator
A class for fast allocation of objects to the heap through paging mechanism. It’s meant to be used by associating
it to the object to be allocated and defining for it new and delete operators via MallocSingle() and
FreeSingle() methods of G4Allocator.
Note: G4Allocator assumes that objects being allocated have all the same size for the type they represent.
For this reason, classes which are handled by G4Allocator should avoid to be used as base-classes for oth-
ers. Similarly, base-classes of sub-classes handled through G4Allocator should not define their (eventually
empty) virtual destructors inlined; such measure is necessary in order also to prevent bad aliasing optimisations
by compilers which may potentially lead to crashes in the attempt to free allocated chunks of memory when
using the base-class pointer or not.
The list of allocators implicitly defined and used in GEANT4 is reported here:
– events (G4Event): anEventAllocator
– tracks (G4Track): aTrackAllocator
– stacked tracks (G4StackedTrack): aStackedTrackAllocator
– primary particles (G4PrimaryParticle): aPrimaryParticleAllocator
– primary vertices (G4PrimaryVertex): aPrimaryVertexAllocator
• G4ReferenceCountedHandle
Template class acting as a smart pointer and wrapping the type to be counted. It performs the reference counting
during the life-time of the counted object.
• G4FastVector
Template class defining a vector of pointers, not performing boundary checking.
• G4PhysicsVector
Defines a physics vector which has values of energy-loss, cross-section, and other physics values of a particle in
matter in a given range of the energy, momentum, etc. This class serves as the base class for a vector having var-
ious energy scale, for example like ‘log’ (G4PhysicsLogVector) ‘linear’ (G4PhysicsLinearVector),
‘free’ (G4PhysicsFreeVector), etc.
• G4LPhysicsFreeVector
Implements a free vector for low energy physics cross-section data. A subdivision method is used to find the
energy|momentum bin.
• G4PhysicsOrderedFreeVector
A physics ordered free vector inherits from G4PhysicsVector. It provides, in addition, a method for the
user to insert energy/value pairs in sequence. Methods to retrieve the max and min energies and values from the
vector are also provided.
• G4Timer
Utility class providing methods to measure elapsed user/system process time. Uses <sys/times.h> and
<unistd.h> - POSIX.1.
• G4UserLimits
Class collecting methods for get and set any kind of step limitation allowed in GEANT4.
• G4UnitsTable
Placeholder for the system of units in GEANT4.
GEANT4 offers the user the possibility to choose and use the preferred units for any quantity. In fact, GEANT4 takes
care of the units. Internally a consistent set on units based on the HepSystemOfUnits is used:
millimeter (mm)
nanosecond (ns)
Mega electron Volt (MeV)
positron charge (eplus)
degree Kelvin (kelvin)
the amount of substance (mole)
luminous intensity (candela)
radian (radian)
steradian (steradian)
The user must give the units for the data to introduce:
G4double Size = 15*km, KineticEnergy = 90.3*GeV, density = 11*mg/cm3;
GEANT4 assumes that these specifications for the units are respected, in order to assure independence from the units
chosen in the client application.
If units are not specified in the client application, data are implicitly treated in internal GEANT4 system units; this
practice is however strongly discouraged.
If the data set comes from an array or from an external file, it is strongly recommended to set the units as soon as the
data are read, before any treatment. For instance:
for (int j=0, j<jmax, j++) CrossSection[j] *= millibarn;
...
my calculations
...
Interactive commands
Some built-in commands from the User Interface (UI) also require units to be specified.
For instance:
/gun/energy 15.2 keV
/gun/position 3 2 -7 meter
If units are not specified, or are not valid, the command is refused.
You can output your data with the wished units. To do so, it is sufficient to divide the data by the corresponding unit:
G4cout << KineticEnergy/keV << " keV";
G4cout << density/(g/cm3) << " g/cm3";
Of course, G4cout << KineticEnergy will print the energy in the internal units system.
There is another way to output the data. Let GEANT4 choose the most appropriate units for the actual numerical value
of the data. It is sufficient to specify to which category the data belong to (Length, Time, Energy, etc.). For example:
G4cout << G4BestUnit(StepSize, "Length");
StepSize will be printed in km, m, mm, fermi, etc. depending of its actual value.
Using this method, it is not easy to define composed units. It is better to do the following:
• Instantiate an object of the class G4UnitDefinition. These objects are owned by the global
G4UnitsTable at construction, and must not be deleted by the user.
new G4UnitDefinition ( name, symbol, category, value )
The category “Speed” does not exist by default in G4UnitsTable, but it will be created automatically. The
class G4UnitDefinition is defined in source/global/management/G4UnitsTable.hh.
You can print the list of units with the static function: G4UnitDefinition::PrintUnitsTable(); or with
the interactive command: /units/list
3.4 Run
In GEANT4, Run is the largest unit of simulation. A run consists of a sequence of events. Within a run, the detector
geometry, the set up of sensitive detectors, and the physics processes used in the simulation should be kept unchanged.
A run is represented by a G4Run class object. A run starts with BeamOn() method of G4RunManager.
Representation of a run
G4Run represents a run. It has a run identification number, which should be set by the user, and the number of events
simulated during the run. Please note that the run identification number is not used by the GEANT4 kernel, and thus
can be arbitrarily assigned at the user’s convenience.
G4Run has pointers to the tables G4VHitsCollection and G4VDigiCollection. These tables are associ-
ated in case sensitive detectors and digitizer modules are simulated, respectively. The usage of these tables will be
mentioned in Hits and Digitization.
G4Run has two virtual methods, and thus you can extend G4Run class. In particular if you use GEANT4 in multi-
threaded mode and need to accumulate values, these two virtual method must be overwritten to specify how such
values should be collected firstly for a worker thread, and then for the entire run. These virtual methods are the
following.
virtual void RecordEvent(const G4Event*) Method to be overwritten by the user for recording
events in this (thread-local) run. At the end of the implementation, G4Run base-class method for must be
invoked for recording data members in the base class.
void Merge(const G4Run*) Method to be overwritten by the user for merging local Run object to the global
Run object. At the end of the implementation, G4Run base-class method for must be invoked for merging data
members in the base class.
G4RunManager manages the procedures of a run. In the constructor of G4RunManager, all of the manager classes
in GEANT4 kernel, except for some static managers, are constructed. These managers are deleted in the destructor of
G4RunManager. G4RunManager must be a singleton created in the user’s main() program; the pointer to this
singleton object can be obtained by other code using the GetRunManager() static method.
As already mentioned in How to Define the main() Program, all of the user initialization classes defined by the user
should be assigned to G4RunManager before starting initialization of the GEANT4 kernel. The assignments of these
user classes are done by SetUserInitialization() methods. All user classes defined by the GEANT4 kernel
will be summarized in User Actions.
G4RunManager has several public methods, which are listed below.
Initialize() All initializations required by the GEANT4 kernel are triggered by this method. Initializations are:
• construction of the detector geometry and set up of sensitive detectors and/or digitizer modules,
• construction of particles and physics processes,
• calculation of cross-section tables.
This method is thus mandatory before proceeding to the first run. This method will be invoked automatically
for the second and later runs in case some of the initialized quantities need to be updated.
BeamOn(G4int numberOfEvent) This method triggers the actual simulation of a run, that is, an event loop. It
takes an integer argument which represents the number of events to be simulated.
GetRunManager() This static method returns the pointer to the G4RunManager singleton object.
3.4. Run 65
Book For Application Developers, Release 10.5
GetCurrentEvent() This method returns the pointer to the G4Event object which is currently being simulated.
This method is available only when an event is being processed. At this moment, the application state of
GEANT4, which is explained in the following sub-section, is “EventProc”. When GEANT4 is in a state other
than “EventProc”, this method returns null. Please note that the return value of this method is const G4Event *
and thus you cannot modify the contents of the object.
SetNumberOfEventsToBeStored(G4int nPrevious) When simulating the “pile up” of more than one
event, it is essential to access more than one event at the same moment. By invoking this method,
G4RunManager keeps nPrevious G4Event objects. This method must be invoked before proceeding to Bea-
mOn().
GetPreviousEvent(G4int i_thPrevious) The pointer to the i_thPrevious G4Event object can be ob-
tained through this method. A pointer to a const object is returned. It is inevitable that i_thPrevious events
must have already been simulated in the same run for getting the i_thPrevious event. Otherwise, this method
returns null.
AbortRun() This method should be invoked whenever the processing of a run must be stopped. It is valid for
GeomClosed and EventProc states. Run processing will be safely aborted even in the midst of processing an
event. However, the last event of the aborted run will be incomplete and should not be used for further analysis.
G4MTRunManager is the replacement of G4RunManager for multi-threading mode. At the very end of
Initialize() method, G4MTRunManager creates and starts worker threads. The event each thread is tasked
is in first-come-first-served basis, so that event numbers each thread has are not sequential.
G4WorkerRunManager is the local RunManager automatically instantiated by G4MTRunManager to take care
of initialization and event handling of a thread. Both G4MTRunManager and G4WorkerRunManager are derived
classes of G4RunManager base class.
The static method G4RunManager::GetRunManager() returns the following pointer.
• It returns the pointer to the G4WorkerRunManager of the local thread when it is invoked from thread-local
object.
• It returns the pointer to the G4MTRunManager when it is invoked from shared object.
• It returns the pointer to the base G4RunManager if it is used in the sequential mode.
G4RunManager has a method GetRunManagerType() that returns an enum named RMType to indicate what
kind of RunManager it is. RMType is defined as { sequentialRM, masterRM, workerRM }. From the
thread-local object, a static method G4MTRunManager::GetMasterRunManager() is available to access to
G4MTRunManager. From a worker thread, the user may access to, for example, detector construction (it is a shared
class) through this GetMasterRunManager() method.
G4UserRunAction
G4UserRunAction is one of the user action classes from which you can derive your own concrete class. This base
class has three virtual methods as follows:
GenerateRun() This method is invoked at the beginning of the BeamOn() method but after confirmation of the
conditions of the GEANT4 kernel. This method should be used to instantiate a user-specific run class object.
BeginOfRunAction() This method is invoked at the beginning of the BeamOn() method but after confirmation
of the conditions of the GEANT4 kernel. Likely uses of this method include:
• setting a run identification number,
• booking histograms,
• setting run specific conditions of the sensitive detectors and/or digitizer modules (e.g., dead channels).
EndOfRunAction() This method is invoked at the very end of the BeamOn() method. Typical use cases of this
method are
• store/print histograms,
GEANT4 is designed as a state machine. Some methods in GEANT4 are available for only a certain state(s).
G4RunManager controls the state changes of the GEANT4 application. States of GEANT4 are represented by the
enumeration G4ApplicationState. It has six states through the life cycle of a GEANT4 application.
G4State_PreInit state A GEANT4 application starts with this state. The application needs to be initialized when
it is in this state. The application occasionally comes back to this state if geometry, physics processes, and/or
cut-off have been changed after processing a run.
G4State_Init state The application is in this state while the Initialize() method of G4RunManager is being in-
voked. Methods defined in any user initialization classes are invoked during this state.
G4State_Idle state The application is ready for starting a run.
G4State_GeomClosed state When BeamOn() is invoked, the application proceeds to this state to process a run.
Geometry, physics processes, and cut-off cannot be changed during run processing.
G4State_EventProc state A GEANT4 application is in this state when a particular event is being processed.
GetCurrentEvent() and GetPreviousEvent() methods of G4RunManager are available only at this state.
G4State_Quit state When the destructor of G4RunManager is invoked, the application comes to this “dead end”
state. Managers of the GEANT4 kernel are being deleted and thus the application cannot come back to any other
state.
G4State_Abort state When a G4Exception occurs, the application comes to this “dead end” state and causes a
core dump. The user still has a hook to do some “safe” operations, e.g. storing histograms, by implement-
ing a user concrete class of G4VStateDependent. The user also has a choice to suppress the occurrence of
G4Exception by a UI command /control/suppressAbortion. When abortion is suppressed, you will still get error
messages issued by G4Exception, and there is NO guarantee of a correct result after the G4Exception error
message.
G4StateManager belongs to the intercoms category.
In case the user wants to do something at the moment of state change of GEANT4, the user can create a concrete class
of the G4VStateDependent base class. For example, the user can store histograms when G4Exception occurs and
GEANT4 comes to the Abort state, but before the actual core dump.
The following is an example user code which stores histograms when GEANT4 becomes to the Abort state. This class
object should be made in, for example main(), by the user code. This object will be automatically registered to
G4StateManager at its construction.
#include "G4VStateDependent.hh"
3.4. Run 67
Book For Application Developers, Release 10.5
UserHookForAbortState::UserHookForAbortState() {;}
UserHookForAbortState::~UserHookForAbortState() {;}
return true;
}
G4RunManager is a concrete class with a complete set of functionalities for managing the GEANT4 kernel. It
is the only manager class in the GEANT4 kernel which must be constructed in the main() method of the user’s
application. Thus, instead of constructing the G4RunManager provided by GEANT4, you are free to construct
your own RunManager. It is recommended, however, that your RunManager inherit G4RunManager. For this
purpose, G4RunManager has various virtual methods which provide all the functionalities required to handle the
GEANT4 kernel. Hence, your customized run manager need only override the methods particular to your needs; the
remaining methods in G4RunManager base class can still be used. A summary of the available methods is presented
here:
public: virtual void Initialize(); main entry point of GEANT4 kernel initialization
protected: virtual void InitializeGeometry(); geometry construction
protected: virtual void InitializePhysics(); physics processes construction
public: virtual void BeamOn(G4int n_event); main entry point of the event loop
protected: virtual G4bool ConfirmBeamOnCondition(); check the kernel conditions for the
event loop
protected: virtual void RunInitialization(); prepare a run
protected: virtual void DoEventLoop(G4int n_events); manage an event loop
protected: virtual G4Event* GenerateEvent(G4int i_event); generation of G4Event object
protected: virtual void AnalyzeEvent(G4Event* anEvent); storage/analysis of an event
protected: virtual void RunTermination(); terminate a run
public: virtual void DefineWorldVolume(G4VPhysicalVolume * worldVol); set the
world volume to G4Navigator
public: virtual void AbortRun(); abort the run
In G4RunManager the event loop is handled by the virtual method DoEventLoop(). This method is implemented
by a for loop consisting of the following steps:
1. construct a G4Event object and assign to it primary vertex(es) and primary particles. This is done by the virtual
GeneratePrimaryEvent() method.
2. send the G4Event object to G4EventManager for the detector simulation. Hits and trajectories will be
associated with the G4Event object as a consequence.
3. perform bookkeeping for the current G4Event object. This is done by the virtual AnalyzeEvent() method.
DoEventLoop() performs the entire simulation of an event. However, it is often useful to split the above three
steps into isolated application programs. If, for example, you wish to examine the effects of changing discriminator
thresholds, ADC gate widths and/or trigger conditions on simulated events, much time can be saved by performing
steps 1 and 2 in one program and step 3 in another. The first program need only generate the hit/trajectory information
once and store it, perhaps in a database. The second program could then retrieve the stored G4Event objects and
perform the digitization (analysis) using the above threshold, gate and trigger settings. These settings could then be
changed and the digitization program re-run without re-generating the G4Events.
The detector geometry defined in your G4VUserDetectorConstruction concrete class can be changed during
a run break (between two runs). Two different cases are considered.
The first is the case in which you want to delete the entire structure of your old geometry and build up a completely
new set of volumes. For this case, you need to delete them by yourself, and let RunManager invokes Construct()
and ConstructSDandField() methods of your detector construction once again when RunManager starts the
next run.
G4RunManager* runManager = G4RunManager::GetRunManager();
runManager->ReinitializeGeometry();
before proceeding to the next run. An example of changing geometry is given in a GEANT4 tutorial in GEANT4
Training kit #2.
3.4. Run 69
Book For Application Developers, Release 10.5
It is a likely case to change cut-off values in a run. You can change defaultCutValue in
G4VUserPhysicsList during the Idle state. In this case, all cross section tables need to be recalculated be-
fore the event loop. You should use the CutOffHasBeenModified() method when you change cut-off values so
that the SetCuts method of your PhysicsList concrete class will be invoked.
G4UserWorkerInitialization is an additional user initialization class to be used only for the multi-
threaded mode. The object of this class can be set to G4MTRunManager, but not to G4RunManager.
G4UserWorkerInitialization class has five virtual methods as the user hooks which are invoked at several
occasions of the life cycle of each thread.
virtual void WorkerInitialize() const This method is called after the tread is created but before the
G4WorkerRunManager is instantiated.
virtual void WorkerStart() const This method is called once at the beginning of simulation job when
kernel classes and user action classes have already instantiated but geometry and physics have not been yet
initialized. This situation is identical to “PreInit” state in the sequential mode.
virtual void WorkerStartRun() const This method is called before an event loop. Geometry and
physics have already been set up for the thread. All threads are synchronized and ready to start the local event
loop. This situation is identical to “Idle” state in the sequential mode.
virtual void WorkerRunEnd() const This method is called for each thread when the local event loop is
done, but before the synchronization over all worker threads.
virtual void WorkerStop() const This method is called once at the end of simulation job.
3.5 Event
G4Event represents an event. An object of this class contains all inputs and outputs of the simulated event. This
class object is constructed in G4RunManager and sent to G4EventManager. The event currently being processed
can be obtained via the getCurrentEvent() method of G4RunManager.
A G4Event object has four major types of information. Get methods for this information are available in G4Event.
Primary vertexes and primary particles Details are given in Event Generator Interface.
Trajectories Trajectories are stored in G4TrajectoryContainer class objects and the pointer to this container is stored
in G4Event. The contents of a trajectory are given in Trajectory and Trajectory Point.
Hits collections Collections of hits generated by sensitive detectors are kept in G4HCofThisEvent class object
and the pointer to this container class object is stored in G4Event. See Hits for the details.
Digits collections Collections of digits generated by digitizer modules are kept in G4DCofThisEvent class object
and the pointer to this container class object is stored in G4Event. See Digitization for the details.
G4EventManager is the manager class to take care of one event. It is responsible for:
• converting G4PrimaryVertex and G4PrimaryParticle objects associated with the current G4Event
object to G4Track objects. All of G4Track objects representing the primary particles are sent to
G4StackManager.
• Pop one G4Track object from G4StackManager and send it to G4TrackingManager. The current
G4Track object is deleted by G4EventManager after the track is simulated by G4TrackingManager, if
the track is marked as “killed”.
• In case the primary track is “suspended” or “postponed to next event” by G4TrackingManager, it is sent
back to the G4StackManager. Secondary G4Track objects returned by G4TrackingManager are also
sent to G4StackManager.
• When G4StackManager returns NULL for the “pop” request, G4EventManager terminates the current
processing event.
• invokes the user-defined methods beginOfEventAction() and endOfEventAction() from the
G4UserEventAction class. See User Information Classes for details.
G4StackManager has three stacks, named urgent, waiting and postpone-to-next-event, which are objects of the
G4TrackStack class. By default, all G4Track objects are stored in the urgent stack and handled in a “last in first
out” manner. In this case, the other two stacks are not used. However, tracks may be routed to the other two stacks by
the user-defined G4UserStackingAction concrete class.
If the methods of G4UserStackingAction have been overridden by the user, the postpone-to-next-event and
waiting stacks may contain tracks. At the beginning of an event, G4StackManager checks to see if any tracks left
over from the previous event are stored in the postpone-to-next-event stack. If so, it attempts to move them to the
urgent stack. But first the PrepareNewEvent() method of G4UserStackingAction is called. Here tracks
may be re-classified by the user and sent to the urgent or waiting stacks, or deferred again to the postpone-to-next-event
stack. As the event is processed G4StackManager pops tracks from the urgent stack until it is empty. At this point
the NewStage() method of G4UserStackingAction is called. In this method tracks from the waiting stack
may be sent to the urgent stack, retained in the waiting stack or postponed to the next event.
Details of the user-defined methods of G4UserStackingAction and how they affect track stack management are
given in User Information Classes.
The G4Event class object should have a set of primary particles when it is sent to G4EventManager via
processOneEvent() method. It is the mandate of your G4VUserPrimaryGeneratorAction concrete class
to send primary particles to the G4Event object.
The G4PrimaryParticle class represents a primary particle with which GEANT4 starts simulating an event.
This class object has information on particle type and its three momenta. The positional and time information of
primary particle(s) are stored in the G4PrimaryVertex class object and, thus, this class object can have one or
more G4PrimaryParticle class objects which share the same vertex. Primary vertexes and primary particles are
associated with the G4Event object by a form of linked list.
A concrete class of G4VPrimaryGenerator, the G4PrimaryParticle object is constructed with either a
pointer to G4ParticleDefinition or an integer number which represents P.D.G. particle code. For the case of
some artificial particles, e.g., geantino, optical photon, etc., or exotic nuclear fragments, which the P.D.G. particle code
does not cover, the G4PrimaryParticle should be constructed by G4ParticleDefinition pointer. On the
other hand, elementary particles with very short life time, e.g., weak bosons, or quarks/gluons, can be instantiated
as G4PrimaryParticle objects using the P.D.G. particle code. It should be noted that, even though primary
particles with such a very short life time are defined, GEANT4 will simulate only the particles which are defined as
G4ParticleDefinition class objects. Other primary particles will be simply ignored by G4EventManager.
But it may still be useful to construct such “intermediate” particles for recording the origin of the primary event.
The G4PrimaryParticle class object can have a list of its daughter particles. If the parent particle is an “inter-
mediate” particle, which GEANT4 does not have a corresponding G4ParticleDefinition, this parent particle is
ignored and daughters are assumed to start from the vertex with which their parent is associated. For example, a Z
boson is associated with a vertex and it has positive and negative muons as its daughters, these muons will start from
that vertex.
There are some kinds of particles which should fly some reasonable distances and, thus, should be simulated by
GEANT4, but you still want to follow the decay channel generated by an event generator. A typical case of these
particles is B meson. Even for the case of a primary particle which has a corresponding G4ParticleDefinition,
it can have daughter primary particles. GEANT4 will trace the parent particle until it comes to decay, obeying multiple
scattering, ionization loss, rotation with the magnetic field, etc. according to its particle type. When the parent comes
to decay, instead of randomly choosing its decay channel, it follows the “pre-assigned” decay channel. To conserve
the energy and the momentum of the parent, daughters will be Lorentz transformed according to their parent’s frame.
G4HEPEvtInterface
Unfortunately, almost all event generators presently in use, commonly are written in FORTRAN. For GEANT4, it was
decided to not link with any FORTRAN program or library, even though the C++ language syntax itself allows such
a link. Linking to a FORTRAN package might be convenient in some cases, but we will lose many advantages of
object-oriented features of C++, such as robustness. Instead, GEANT4 provides an ASCII file interface for such event
generators.
G4HEPEvtInterface is one of G4VPrimaryGenerator concrete class and thus it can be used in your
G4VUserPrimaryGeneratorAction concrete class. G4HEPEvtInterface reads an ASCII file produced
by an event generator and reproduces G4PrimaryParticle objects associated with a G4PrimaryVertex ob-
ject. It reproduces a full production chain of the event generator, starting with primary quarks, etc. In other words,
G4HEPEvtInterface converts information stored in the /HEPEVT/ common block to an object-oriented data
structure. Because the /HEPEVT/ common block is commonly used by almost all event generators written in FOR-
TRAN, G4HEPEvtInterface can interface to almost all event generators currently used in the HEP commu-
nity. The constructor of G4HEPEvtInterface takes the file name. Listing 3.3 shows an example how to use
G4HEPEvtInterface. Note that an event generator is not assumed to give a place of the primary particles, the
interaction point must be set before invoking GeneratePrimaryVertex() method.
#include "G4VUserPrimaryGeneratorAction.hh"
#include "globals.hh"
class G4VPrimaryGenerator;
class G4Event;
public:
void GeneratePrimaries(G4Event* anEvent);
private:
G4VPrimaryGenerator* HEPEvt;
};
#endif
#include "ExN04PrimaryGeneratorAction.hh"
#include "G4Event.hh"
#include "G4HEPEvtInterface.hh"
ExN04PrimaryGeneratorAction::ExN04PrimaryGeneratorAction()
{
HEPEvt = new G4HEPEvtInterface("pythia_event.data");
}
ExN04PrimaryGeneratorAction::~ExN04PrimaryGeneratorAction()
{
delete HEPEvt;
}
An ASCII file, which will be fed by G4HEPEvtInterface should have the following format.
• The first line of each primary event should be an integer which represents the number of the following lines of
primary particles.
• Each line in an event corresponds to a particle in the /HEPEVT/ common. Each line has ISTHEP, IDHEP,
JDAHEP(1), JDAHEP(2), PHEP(1), PHEP(2), PHEP(3), PHEP(5). Refer to the /HEPEVT/
manual for the meanings of these variables.
Listing 3.4 shows an example FORTRAN code to generate an ASCII file.
Several activities have already been started for developing object-oriented event generators. Such new generators
can be easily linked and used with a GEANT4 based simulation. Furthermore, we need not distinguish a primary
generator from the physics processes used in GEANT4. Future generators can be a kind of physics process plugged-in
by inheriting G4VProcess.
Your G4VUserPrimaryGeneratorAction concrete class can have more than one G4VPrimaryGenerator
concrete class. Each G4VPrimaryGenerator concrete class can be accessed more than once per event. Using
these class objects, one event can have more than one primary event.
One possible use is the following. Within an event, a G4HEPEvtInterface class object instantiated with a mini-
mum bias event file is accessed 20 times and another G4HEPEvtInterface class object instantiated with a signal
event file is accessed once. Thus, this event represents a typical signal event of LHC overlapping 20 minimum bias
events. It should be noted that a simulation of event overlapping can be done by merging hits and/or digits associ-
ated with several events, and these events can be simulated independently. Digitization over multiple events will be
mentioned in Digitization.
GEANT4 provides event biasing techniques which may be used to save computing time in such applications as
the simulation of radiation shielding. These are geometrical splitting and Russian roulette (also called geomet-
rical importance sampling), and weight roulette. Scoring is carried out by G4MultiFunctionalDetector
(see G4MultiFunctionalDetector and G4VPrimitiveScorer and Concrete classes of G4VPrimitiveScorer) using the
standard GEANT4 scoring technique. Biasing specific scorers have been implemented and are described within
G4MultiFunctionalDetector documentation. In this chapter, it is assumed that the reader is familiar with
both the usage of GEANT4 and the concepts of importance sampling. More detailed documentation may be found in
the documents ‘Scoring, geometrical importance sampling and weight roulette’.
A detailed description of different use-cases which employ the sampling and scoring techniques can be found in the
document ‘Use cases of importance sampling and scoring in Geant4’.
The purpose of importance sampling is to save computing time by sampling less often the particle histories entering
“less important” geometry regions, and more often in more “important” regions. Given the same amount of com-
puting time, an importance-sampled and an analogue-sampled simulation must show equal mean values, while the
importance-sampled simulation will have a decreased variance.
The implementation of scoring is independent of the implementation of importance sampling. However both share
common concepts. Scoring and importance sampling apply to particle types chosen by the user, which should be
borne in mind when interpreting the output of any biased simulation.
Examples on how to use scoring and importance sampling may be found in examples/extended/biasing.
Geometries
The kind of scoring referred to in this note and the importance sampling apply to spatial cells provided by the user.
A cell is a physical volume (further specified by it’s replica number, if the volume is a replica). Cells may be defined
in two kinds of geometries:
1. mass geometry: the geometry setup of the experiment to be simulated. Physics processes apply to this geometry.
2. parallel-geometry: a geometry constructed to define the physical volumes according to which scoring and/or
importance sampling is applied.
The user has the choice to score and/or sample by importance the particles of the chosen type, according to mass
geometry or to parallel geometry. It is possible to utilize several parallel geometries in addition to the mass geometry.
This provides the user with a lot of flexibility to define separate geometries for different particle types in order to apply
scoring or/and importance sampling.
Note: Parallel geometries should be constructed using the implementation as described in Parallel Geometries. There
are a few conditions for parallel geometries:
• The world volume for parallel and mass geometries must be identical copies.
• Scoring and importance cells must not share boundaries with the world volume.
Samplers are higher level tools which perform the necessary changes of the GEANT4 sampling in order to apply
importance sampling and weight roulette.
Variance reduction (and scoring through the G4MultiFunctionalDetector) may be combined arbitrarily for
chosen particle types and may be applied to the mass or to parallel geometries.
The G4GeometrySampler can be applied equally to mass or parallel geometries with an abstract interface supplied
by G4VSampler. G4VSampler provides Prepare... methods and a Configure method:
class G4VSampler
{
public:
G4VSampler();
virtual ~G4VSampler();
virtual void PrepareImportanceSampling(G4VIStore *istore,
const G4VImportanceAlgorithm
*ialg = 0) = 0;
virtual void PrepareWeightRoulett(G4double wsurvive = 0.5,
G4double wlimit = 0.25,
G4double isource = 1) = 0;
virtual void PrepareWeightWindow(G4VWeightWindowStore *wwstore,
G4VWeightWindowAlgorithm *wwAlg = 0,
G4PlaceOfAction placeOfAction =
onBoundary) = 0;
virtual void Configure() = 0;
virtual void ClearSampling() = 0;
virtual G4bool IsConfigured() const = 0;
};
The methods for setting up the desired combination need specific information:
• Importance sampling: message PrepareImportanceSampling with a G4VIStore and optionally a
G4VImportanceAlgorithm
• Weight window: message PrepareWeightWindow with the arguments:
– *wwstore: a G4VWeightWindowStore for retrieving the lower weight bounds for the energy-space
cells
– *wwAlg: a G4VWeightWindowAlgorithm if a customized algorithm should be used
– placeOfAction: a G4PlaceOfAction specifying where to perform the biasing
• Weight roulette: message PrepareWeightRoulett with the optional parameters:
– wsurvive: survival weight
– wlimit: minimal allowed value of weight * source importance / cell importance
– isource: importance of the source cell
Each object of a sampler class is responsible for one particle type. The particle type is given to the constructor of the
sampler classes via the particle type name, e.g. “neutron”. Depending on the specific purpose, the Configure() of
a sampler will set up specialized processes (derived from G4VProcess) for transportation in the parallel geometry,
importance sampling and weight roulette for the given particle type. When Configure() is invoked the sampler
places the processes in the correct order independent of the order in which user invoked the Prepare... methods.
Note:
• The Prepare...() functions may each only be invoked once.
• To configure the sampling the function Configure() must be called after the G4RunManager has been
initialized and the PhysicsList has been instantiated.
The interface and framework are demonstrated in the examples/extended/biasing directory, with the main
changes being to the G4GeometrySampler class and the fact that in the parallel case the WorldVolume is a copy of
the Mass World. The parallel geometry now has to inherit from G4VUserParallelWorld which also has the
GetWorld() method in order to retrieve a copy of the mass geometry WorldVolume.
class B02ImportanceDetectorConstruction : public G4VUserParallelWorld
ghostWorld = GetWorld();
The constructor for G4GeometrySampler takes a pointer to the physical world volume and the particle type name
(e.g. “neutron”) as arguments. In a single mass geometry the sampler is created as follows:
G4GeometrySampler mgs(detector->GetWorldVolume(),"neutron");
mgs.SetParallel(false);
Whilst the following lines of code are required in order to set up the sampler for the parallel geometry case:
G4VPhysicalVolume* ghostWorld = pdet->GetWorldVolume();
G4GeometrySampler pgs(ghostWorld,"neutron");
pgs.SetParallel(true);
Also note that the preparation and configuration of the samplers has to be carried out after the instantiation of the
UserPhysicsList. With the modular reference PhysicsList the following set-up is required (first is for biasing, the
second for scoring):
physicsList->RegisterPhysics(new G4ImportanceBiasing(&pgs,parallelName));
physicsList->RegisterPhysics(new G4ParallelWorldPhysics(parallelName));
If the a UserPhysicsList is being implemented, then the following should be used to give the pointer to the Geome-
trySampler to the PhysicsList:
physlist->AddBiasing(&pgs,parallelName);
Then to instantiate the biasing physics process the following should be included in the UserPhysicsList and called
from ConstructProcess():
AddBiasingProcess(){
fGeomSampler->SetParallel(true); // parallelworld
G4IStore* iStore = G4IStore::GetInstance(fBiasWorldName);
fGeomSampler->SetWorld(iStore->GetParallelWorldVolumePointer());
// fGeomSampler->PrepareImportanceSampling(G4IStore::
// GetInstance(fBiasWorldName), 0);
static G4bool first = true;
if(first) {
fGeomSampler->PrepareImportanceSampling(iStore, 0);
fGeomSampler->Configure();
G4cout << " GeomSampler Configured!!! " << G4endl;
first = false;
}
#ifdef G4MULTITHREADED
fGeomSampler->AddProcess();
#else
G4cout << " Running in singlethreaded mode!!! " << G4endl;
#endif
pgs.PrepareImportanceSampling(G4IStore::GetInstance(pdet->GetName()), 0);
pgs.Configure();
Due to the fact that biasing is a process and has to be inserted after all the other processes have been created.
Importance Sampling
Importance sampling acts on particles crossing boundaries between “importance cells”. The action taken depends on
the importance values assigned to the cells. In general a particle history is either split or Russian roulette is played
if the importance increases or decreases, respectively. A weight assigned to the history is changed according to the
action taken.
The tools provided for importance sampling require the user to have a good understanding of the physics in the
problem. This is because the user has to decide which particle types require importance sampled, define the cells,
and assign importance values to the cells. If this is not done properly the results cannot be expected to describe a real
experiment.
The assignment of importance values to a cell is done using an importance store described below.
An “importance store” with the interface G4VIStore is used to store importance values related to cells. In order
to do importance sampling the user has to create an object (e.g. of class G4IStore) of type G4VIStore. The
samplers may be given a G4VIStore. The user fills the store with cells and their importance values. The store is
now a singleton class so should be created using a GetInstance method:
G4IStore *aIstore = G4IStore::GetInstance();
An importance store has to be constructed with a reference to the world volume of the geometry used for importance
sampling. This may be the world volume of the mass or of a parallel geometry. Importance stores derive from the
interface G4VIStore:
class G4VIStore
{
public:
G4VIStore();
virtual ~G4VIStore();
(continues on next page)
A concrete implementation of an importance store is provided by the class G4VStore. The public part of the class is:
class G4IStore : public G4VIStore
{
public:
explicit G4IStore(const G4VPhysicalVolume &worldvolume);
virtual ~G4IStore();
virtual G4double GetImportance(const G4GeometryCell &gCell) const;
virtual G4bool IsKnown(const G4GeometryCell &gCell) const;
virtual const G4VPhysicalVolume &GetWorldVolume() const;
void AddImportanceGeometryCell(G4double importance,
const G4GeometryCell &gCell);
void AddImportanceGeometryCell(G4double importance,
const G4VPhysicalVolume &,
G4int aRepNum = 0);
void ChangeImportance(G4double importance,
const G4GeometryCell &gCell);
void ChangeImportance(G4double importance,
const G4VPhysicalVolume &,
G4int aRepNum = 0);
G4double GetImportance(const G4VPhysicalVolume &,
G4int aRepNum = 0) const ;
private: .....
};
The member function AddImportanceGeometryCell() enters a cell and an importance value into the impor-
tance store. The importance values may be returned either according to a physical volume and a replica number or
according to a G4GeometryCell. The user must be aware of the interpretation of assigning importance values to
a cell. If scoring is also implemented then this is attached to logical volumes, in which case the physical volume and
replica number method should be used for assigning importance values. See examples/extended/biasing
B01 and B02 for examples of this.
Importance sampling supports using a customized importance sampling algorithm. To this end, the sampler interface
Changing the Sampling may be given a pointer to the interface G4VImportanceAlgorithm:
class G4VImportanceAlgorithm
{
(continues on next page)
G4int fN;
G4double fW;
};
class G4VWeightWindowStore {
public:
G4VWeightWindowStore();
virtual ~G4VWeightWindowStore();
virtual G4double GetLowerWeitgh(const G4GeometryCell &gCell,
G4double partEnergy) const = 0;
virtual G4bool IsKnown(const G4GeometryCell &gCell) const = 0;
virtual const G4VPhysicalVolume &GetWorldVolume() const = 0;
};
private::
...
};
The user may choose equal energy bounds for all cells. In this case a set of upper energy bounds must be given to
the store using the method SetGeneralUpperEnergyBounds. If a general set of energy bounds have been set
AddLowerWeights can be used to add the cells.
Alternatively, the user may chose different energy regions for different cells. In this case the user must
provide a mapping of upper energy bounds to lower weight bounds for every cell using the method
AddUpperEboundLowerWeightPairs.
Weight window algorithms implementing the interface class G4VWeightWindowAlgorithm can be used to define
a customized algorithm:
class G4VWeightWindowAlgorithm {
public:
G4VWeightWindowAlgorithm();
virtual ~G4VWeightWindowAlgorithm();
virtual G4Nsplit_Weight Calculate(G4double init_w,
G4double lowerWeightBound) const = 0;
};
The constructor takes three parameters which are used to: calculate the upper weight bound (upperLimitFaktor),
calculate the survival weight (survivalFaktor), and introduce a maximal number (maxNumberOfSplits) of copies to be
created in one go.
In addition, the inverse of the maxNumberOfSplits is used to specify the minimum survival probability in case of
Russian roulette.
Weight roulette (also called weight cutoff) is usually applied if importance sampling and implicit capture are used
together. Implicit capture is not described here but it is useful to note that this procedure reduces a particle weight in
every collision instead of killing the particle with some probability.
Together with importance sampling the weight of a particle may become so low that it does not change any result
significantly. Hence tracking a very low weight particle is a waste of computing time. Weight roulette is applied in
order to solve this problem.
The weight roulette concept
Weight roulette takes into account the importance “Ic” of the current cell and the importance “Is” of the cell in which
the source is located, by using the ratio “R=Is/Ic”.
Weight roulette uses a relative minimal weight limit and a relative survival weight. When a particle falls below the
weight limit Russian roulette is applied. If the particle survives, tracking will be continued and the particle weight will
be set to the survival weight.
The weight roulette uses the following parameters with their default values:
• wsurvival: 0.5
• wlimit: 0.25
• isource: 1
The following algorithm is applied:
GEANT4 supports physics based biasing through a number of general use, built in biasing techniques. A utility class,
G4WrapperProcess, is also available to support user defined biasing.
Primary particle biasing can be used to increase the number of primary particles generated in a particular phase space
region of interest. The weight of the primary particle is modified as appropriate. A general implementation is provided
through the G4GeneralParticleSource class. It is possible to bias position, angular and energy distributions.
G4GeneralParticleSource is a concrete implementation of G4VPrimaryGenerator. To use, instantiate
G4GeneralParticleSource in the G4VUserPrimaryGeneratorAction class, as demonstrated below.
MyPrimaryGeneratorAction::MyPrimaryGeneratorAction() {
generator = new G4GeneralParticleSource;
}
void
MyPrimaryGeneratorAction::GeneratePrimaries(G4Event*anEvent){
generator->GeneratePrimaryVertex(anEvent);
}
The biasing can be configured through interactive commands, as described in General Particle Source. Examples are
also distributed with the GEANT4 distribution in examples/extended/eventgenerator/exgps.
One hadronic leading particle biasing technique is implemented in the G4HadLeadBias utility. This method keeps
only the most important part of the event, as well as representative tracks of each given particle type. So the track
with the highest energy as well as one of each of Baryon, pi0, mesons and leptons. As usual, appropriate weights are
assigned to the particles. Setting the SwitchLeadBiasOn environmental variable will activate this utility.
Cross section biasing artificially enhances/reduces the cross section of a process. This may be useful for studying
thin layer interactions or thick layer shielding. The built in hadronic cross section biasing applies to photon inelastic,
electron nuclear and positron nuclear processes.
The biasing is controlled through the BiasCrossSectionByFactor method in G4HadronicProcess, as demonstrated
below.
void MyPhysicsList::ConstructProcess()
{
...
G4ElectroNuclearReaction * theElectroReaction =
new G4ElectroNuclearReaction;
(continues on next page)
G4ElectronNuclearProcess theElectronNuclearProcess;
theElectronNuclearProcess.RegisterMe(theElectroReaction);
theElectronNuclearProcess.BiasCrossSectionByFactor(100);
pManager->AddDiscreteProcess(&theElectronNuclearProcess);
...
}
The G4RadioactiveDecay (GRDM) class simulates the decay of radioactive nuclei and implements the following
biasing options:
• Increase the sampling rate of radionuclides within observation times through a user defined probability distribu-
tion function
• Nuclear splitting, where the parent nuclide is split into a user defined number of nuclides
• Branching ratio biasing where branching ratios are sampled with equal probability
G4RadioactiveDecay is a process which must be registered with a process manager, as demonstrated below.
void MyPhysicsList::ConstructProcess()
{
...
G4RadioactiveDecay* theRadioactiveDecay =
new G4RadioactiveDecay();
Biasing can be controlled either in compiled code or through interactive commands. Radioactive decay biasing exam-
ples are also distributed with the GEANT4 distribution in examples/extended/radioactivedecay/exrdm.
To select biasing as part of the process registration, use
theRadioactiveDecay->SetAnalogueMonteCarlo(false);
In both cases, true specifies that the unbiased (analogue) simulation will be done, and false selects biasing.
Limited Radionuclides
Radioactive decay may be restricted to only specific nuclides, in order (for example) to avoid tracking extremely long-
lived daughters in decay chains which are not of experimental interest. To limit the range of nuclides decayed as part
of the process registration (above), use
G4NucleusLimits limits(aMin, aMax, zMin, zMax);
theRadioactiveDecay->SetNucleusLimits(limits);
Geometric Biasing
Radioactive decays may be generated throughout the user’s detector model, in one or more specified volumes, or
nowhere. The detector geometry must be defined before applying these geometric biases.
Volumes may be selected or deselected programmatically using
theRadioactiveDecay->SelectAllVolumes();
theRadioactiveDecay->DeselectAllVolumes();
In macro commands, the volumes are specified by name, and found by searching the G4LogicalVolumeStore.
The decay time function (normally an exponential in the natural lifetime) of the primary particle may be replaced with
a time profile F(t), as discussed in Section 40.6 of the Physics Reference Manual. The profile function is represented
as a two-column ASCII text file with up to 100 time points (first column) with fractions (second column).
theRadioactiveDecay->SetSourceTimeProfile(fileName);
theRadioactiveDecay->SetDecayBias(fileName);
/grdm/sourceTimeProfile [fileName]
/grdm/decayBiasProfile [fileName]
Radionuclides with rare decay channels may be biased by forcing all channels to be selected uniformly (BRBias =
true below), rather than according to their natural branching fractions (false).
theRadioactiveDecay->SetBRBias(true);
/grdm/BRbias [true|false]
Nuclear Splitting
The statistical efficiency of generated events may be increased by generating multiple “copies” of nuclei in an event,
each of which is decayed independently, with an assigned weight of 1/Nsplit. Scoring the results of tracking the decay
daughters, using their corresponding weights, can improve the statistical reach of a simulation while preserving the
shape of the resulting distributions.
theRadioactiveDecay->SetSplitNuclei(Nsplit);
/grdm/splitNucleus [Nsplit]
G4WrapperProcess
G4WrapperProcess can be used to implement user defined event biasing. G4WrapperProcess, which is a process itself,
wraps an existing process. By default, all function calls are forwarded to the wrapped process. It is a non-invasive way
to modify the behaviour of an existing process.
To use this utility, first create a derived class inheriting from G4WrapperProcess. Override the methods whose be-
haviour you would like to modify, for example, PostStepDoIt, and register the derived class in place of the process to
be wrapped. Finally, register the wrapped process with G4WrapperProcess. The code snippets below demonstrate its
use.
class MyWrapperProcess : public G4WrapperProcess {
...
G4VParticleChange* PostStepDoIt(const G4Track& track,
const G4Step& step) {
// Do something interesting
}
};
void MyPhysicsList::ConstructProcess()
{
...
G4eBremsstrahlung* bremProcess =
new G4eBremsstrahlung();
Another powerful biasing technique available in GEANT4 is the Reverse Monte Carlo (RMC) method, also known
as the Adjoint Monte Carlo method. In this method particles are generated on the external boundary of the sensitive
part of the geometry and then are tracked backward in the geometry till they reach the external source surface, or
exceed an energy threshold. By this way the computing time is focused only on particle tracks that are contributing
to the tallies. The RMC method is much rapid than the Forward MC method when the sensitive part of the geometry
is small compared to the rest of the geometry and to the external source, that has to be extensive and not beam like.
At the moment the RMC method is implemented in GEANT4 only for some electromagnetic processes (see Reverse
processes). An example illustrating the use of the Reverse MC method in GEANT4 is distributed within the GEANT4
toolkit in examples/extended/biasing/ReverseMC01.
Different G4Adjoint classes have been implemented into the GEANT4 toolkit in order to run an adjoint/reverse simu-
lation in a GEANT4 application. This implementation is illustrated in Fig. 3.3. An adjoint run is divided in a series of
alternative adjoint and forward tracking of adjoint and normal particles. One GEANT4 event treats one of this tracking
phase.
Adjoint particles (adjoint_e-, adjoint_gamma,. . . ) are generated one by one on the so called adjoint source with
random position, energy (1/E distribution) and direction. The adjoint source is the external surface of a user defined
volume or of a user defined sphere. The adjoint source should contain one or several sensitive volumes and should
be small compared to the entire geometry. The user can set the minimum and maximum energy of the adjoint source.
After its generation the adjoint primary particle is tracked backward in the geometry till a user defined external surface
(spherical or boundary of a volume) or is killed before if it reaches a user defined upper energy limit that represents the
maximum energy of the external source. During the reverse tracking, reverse processes take place where the adjoint
particle being tracked can be either scattered or transformed in another type of adjoint particle. During the reverse
tracking the G4AdjointSimulationManager replaces the user defined primary, run, stepping, . . . actions, by its own
actions. A reverse tracking phase corresponds to one GEANT4 event.
When an adjoint particle reaches the external surface its weight, type, position, and direction are registered and a
normal primary particle, with a type equivalent to the last generated primary adjoint, is generated with the same
energy, position but opposite direction and is tracked in the forward direction in the sensitive region as in a forward
MC simulation. During this forward tracking phase the event, stacking, stepping, tracking actions defined by the user
for his forward simulation are used. By this clear separation between adjoint and forward tracking phases, the code
of the user developed for a forward simulation should be only slightly modified to adapt it for an adjoint simulation
(see How to update a G4 application to use the reverse Monte Carlo mode). Indeed the computation of the signals
is done by the same actions or classes that the one used in the forward simulation mode. A forward tracking phase
corresponds to one G4 event.
Reverse processes
During the reverse tracking, reverse processes act on the adjoint particles. The reverse processes that are at the moment
available in GEANT4 are the:
• Reverse discrete ionization for e-, proton and ions
• Continuous gain of energy by ionization and bremsstrahlung for e- and by ionization for protons and ions
• Reverse discrete e- bremsstrahlung
• Reverse photo-electric effect
• Reverse Compton scattering
The list of type of adjoint and forward particles that are generated on the adjoint source and considered in the simulation
is a function of the adjoint processes declared in the physics list. For example if only the e- and gamma electromagnetic
processes are considered, only adjoint e- and adjoint gamma will be considered as primaries. In this case an adjoint
event will be divided in four G4 event consisting in the reverse tracking of an adjoint e-, the forward tracking of its
equivalent forward e-, the reverse tracking of an adjoint gamma, and the forward tracking of its equivalent forward
gamma. In this case a run of 100 adjoint events will consist into 400 GEANT4 events. If the proton ionization is also
considered adjoint and forward protons are also generated as primaries and 600 GEANT4 events are processed for 100
adjoint events.
Some modifications are needed to an existing GEANT4 application in order to adapt it for the use of the reverse
simulation mode (see also the G4 example examples/extended/biasing/ReverseMC01). It consists into the:
• Creation of the adjoint simulation manager in the main code
• Optional declaration of user actions that will be used during the adjoint tracking phase
• Use of a special physics lists that combine the adjoint and forward processes
• Modification of the user analysis part of the code
The class G4AdjointSimManager represents the manager of an adjoint simulation. This static class should be created
somewhere in the main code. The way to do that is illustrated below
int main(int argc,char** argv) {
...
G4AdjointSimManager* theAdjointSimManager = G4AdjointSimManager::GetInstance();
...
}
By doing this the G4 application can be run in the reverse MC mode as well as in the forward MC mode. It is important
to note that G4AdjointSimManager is not a new G4RunManager and that the creation of G4RunManager in the main
and the declaration of the geometry, physics list, and user actions to G4RunManager is still needed. The definition
of the adjoint and external sources and the start of an adjoint simulation can be controlled by G4UI commands in the
directory /adjoint.
During an adjoint simulation the user stepping, tracking, stacking and event actions declared to G4RunManager are
used only during the G4 events dedicated to the forward tracking of normal particles in the sensitive region, while
during the events where adjoint particles are tracked backward the following happen concerning these actions:
• The user stepping action is replaced by G4AdjointSteppingAction that is responsible to stop an adjoint
track when it reaches the external source, exceed the maximum energy of the external source, or cross
the adjoint source surface. If needed the user can declare its own stepping action that will be called by
G4AdjointSteppingAction after the check of stopping track conditions. This stepping action can be different
that the stepping action used for the forward simulation. It is declared to G4AdjointSimManager by the follow-
ing lines of code:
G4AdjointSimManager* theAdjointSimManager = G4AdjointSimManager::GetInstance();
theAdjointSimManager->SetAdjointSteppingAction(aUserDefinedSteppingAction);
• No stacking, tracking and event actions are considered by default. If needed the user can declare to
G4AdjointSimManager stacking, tracking and event actions that will be used only during the adjoint tracking
phase. The following lines of code show how to declare these adjoint actions to G4AdjointSimManager:
G4AdjointSimManager* theAdjointSimManager = G4AdjointSimManager::GetInstance();
theAdjointSimManager->SetAdjointEventAction(aUserDefinedEventAction);
theAdjointSimManager->SetAdjointStackingAction(aUserDefinedStackingAction);
theAdjointSimManager->SetAdjointTrackingAction(aUserDefinedTrackingAction);
By default no user run action is considered in an adjoint simulation but if needed such action can be declared to
G4AdjointSimManager as such:
G4AdjointSimManager* theAdjointSimManager = G4AdjointSimManager::GetInstance();
theAdjointSimManager->SetAdjointRunAction(aUserDefinedRunAction);
To run an adjoint simulation a specific physics list should be used where existing G4 adjoint electromagnetic pro-
cesses and their forward equivalent have to be declared. An example of such physics list is provided by the class
G4AdjointPhysicsLits in the G4 example extended/biasing/ReverseMC01.
The user code should be modified to normalize the signals computed during the forward tracking phase to the weight
of the last adjoint particle that reaches the external surface. This weight represents the statistical weight that the last
full adjoint tracks (from the adjoint source to the external source) would have in a forward simulation. If multiplied
by a signal and registered in function of energy and/or direction the simulation results will give an answer matrix of
this signal. To normalize it to a given spectrum it has to be furthermore multiplied by a directional differential flux
corresponding to this spectrum The weight, direction, position , kinetic energy and type of the last adjoint particle
that reaches the external source, and that would represents the primary of a forward simulation, can be gotten from
G4AdjointSimManager by using for example the following line of codes
G4AdjointSimManager* theAdjointSimManager = G4AdjointSimManager::GetInstance();
G4String particle_name = theAdjointSimManager->GetFwdParticleNameAtEndOfLastAdjointTrack();
G4int PDGEncoding= theAdjointSimManager->GetFwdParticlePDGEncodingAtEndOfLastAdjointTrack();
G4double weight = theAdjointSimManager->GetWeightAtEndOfLastAdjointTrack();
G4double Ekin = theAdjointSimManager->GetEkinAtEndOfLastAdjointTrack();
G4double Ekin_per_nuc=theAdjointSimManager->GetEkinNucAtEndOfLastAdjointTrack(); // for ions
G4ThreeVector dir = theAdjointSimManager->GetDirectionAtEndOfLastAdjointTrack();
G4ThreeVector pos = theAdjointSimManager->GetPositionAtEndOfLastAdjointTrack();
In order to have a code working for both forward and adjoint simulation mode, the extra code needed in user actions
or analysis manager for the adjoint simulation mode can be separated to the code needed only for the normal forward
simulation by using the following public method of G4AdjointSimManager:
G4bool GetAdjointSimMode();
The following code example shows how to normalize a detector signal and compute an answer matrix in the case of
an adjoint simulation.
if (theAdjSimManager->GetFwdParticleNameAtEndOfLastAdjointTrack() == "e-") {
G4double ekin_prim = theAdjSimManager->GetEkinAtEndOfLastAdjointTrack();
G4ThreeVector dir_prim = theAdjointSimManager->GetDirectionAtEndOfLastAdjointTrack();
G4double weight_prim = theAdjSimManager->GetWeightAtEndOfLastAdjointTrack();
S_for_answer_matrix = S*weight_prim;
normalized_S = S_for_answer_matrix*F(ekin_prim,dir);
// F(ekin_prim,dir_prim) gives the differential directional flux of primary e-
}
//follows the code where normalized_S and S_for_answer_matrix are registered or whatever
....
}
In rare cases an adjoint track may get a wrong high weight when reaching the external source. While this happens not
often it may corrupt the simulation results significantly. This happens in some tracks where both reverse photo-electric
and bremsstrahlung processes take place at low energy. We still need some investigations to remove this problem at
the level of physical adjoint/reverse processes. However this problem can be solved at the level of event actions or
analysis in the user code by adding a test on the normalized signal during an adjoint simulation. An example of such
test has been implemented in the GEANT4 example extended/biasing/ReverseMC01. In this implementation an event
is rejected when the relative error of the computed normalized energy deposited increases during one event by more
than 50% while the computed precision is already below 10%.
Reverse bremsstrahlung
A difference between the differential cross sections used in the adjoint and forward bremsstrahlung models is the
source of a higher flux of >100 keV gamma in the reverse simulation compared to the forward simulation mode.
In principle the adjoint processes/models should make use of the direct differential cross section to sample the ad-
joint secondaries and compute the adjoint cross section. However due to the way the effective differential cross
section is considered in the forward model G4eBremsstrahlungModel this was not possible to achieve for the reverse
bremsstrahlung. Indeed the differential cross section used in G4AdjointeBremstrahlungModel is obtained by the nu-
merical derivation over the cut energy of the direct cross section provided by G4eBremsstrahlungModel. This would
be a correct procedure if the distribution of secondary in G4eBremsstrahlungModel would match this differential
cross section. Unfortunately it is not the case as independent parameterization are used in G4eBremsstrahlungModel
for both the cross sections and the sampling of secondaries. (It means that in the forward case if one would integrate
the effective differential cross section considered in the simulation we would not find back the used cross section). In
the future we plan to correct this problem by using an extra weight correction factor after the occurrence of a reverse
bremsstrahlung. This weight factor should be the ratio between the differential CS used in the adjoint simulation and
the one effectively used in the forward processes. As it is impossible to have a simple and direct access to the forward
differential CS in G4eBremsstrahlungModel we are investigating the feasibility to use the differential CS considered
in G4Penelope models.
For the reverse multiple scattering the same model is used than in the forward case. This approximation makes that
the discrepancy between the adjoint and forward simulation cases can get to a level of ~ 10-15% relative differences
in the test cases that we have considered. In the future we plan to improve the adjoint multiple scattering models by
forcing the computation of multiple scattering effect at the end of an adjoint step.
Overview
The generic biasing scheme relies on two abstract classes, that are meant to model the biasing problems. You have to
inherit from them to create your own concrete classes, or use some of the concrete instances provided (see Existing
biasing operations, operator and interaction laws), if they respond to your case. A dedicated process provides the
interface between these biasing classes and the tracking. In case of parallel geometry usage, an other process handles
the navigation in these geometries.
Getting Started
Examples
Six “Generic Biasing (GB)” examples are proposed (they have been introduced in 10.0, 10.1 and 10.3, two examples
each time):
• examples/extended/biasing/GB01:
– which shows how biasing of process cross-section can be done.
– This example uses the physics-based biasing operation G4BOptnChangeCrossSection de-
fined in geant4/source/processes/biasing/generic. This operation performs
the actual process cross-section change. In the example a first G4VBiasingOperator,
For making an existing G4VBiasingOperator used by your application, you have to do two things:
1. Attach the operator to the G4LogicalVolume where the biasing should take place: You have to make this
attachment in your ConstructSDandField() method (to make your application both sequential and MT-
compliant):
2. Setup the physics list you use to properly include the needed G4BiasingProcessInterface instances.
You have several options for this.
• The easiest way is if you use a pre-packaged physics list (e.g. FTFP_BERT, QGSP. . . ). As such a physics
list is of G4VModularPhysicsList type, you can alter it with a G4VPhysicsConstructor. The
constructor G4GenericBiasingPhysics is meant for this. It can be used, typically in your main
program, as:
Doing so, all physics processes will be wrapped, and, for example, the gamma conversion process,
"conv", will appear as "biasWrapper(conv)" when dumping the processes (/particle/
process/dump). An additional "biasWrapper(0)" process, for non-physics-based biasing is also
inserted.
Other methods to specifically chose some physics processes to be biased or to insert only
G4BiasingProcessInterface instances for non-physics-based biasing also exist.
• The second way is useful if you write your own physics list, and if this one is not a modular physics
list, but inherits directly from the lowest level abstract class G4VUserPhysicsList. In this case,
the above solution with G4GenericBiasingPhysics does not apply. Instead you can use the
G4BiasingHelper utility class (this one is indeed used by G4GenericBiasingPhysics).
• A last way to setup the physics list is by direct insertion of the G4BiasingProcessInterface in-
stances, but this requires solid expertise in physics list creation.
In case you also use parallel geometries, you have to make the generic biasing sensitive to these. Assum-
ing you have created three parallel geometries with names "parallelWorld1", "parallelWorld2" and
"parallelWorld3" that you want to be active for neutrons, the additional calls you have to make compared
to example EvtBias.GenericBiasing.Overview.UsePhysConstructor above are simply:
It is also possible, even though less convenient, to use the G4BiasingHelper utility class making
calls to the static method limiter = G4BiasingHelper::AddLimiterProcess(pmanager,
"limiterProcessName") in addition to the ones of example EvtBias.GenericBiasing.Overview.UseBiasingHelper
above. This call returns a pointer limiter on the constructed G4ParallelGeometriesLimiterProcess
process, setting its name as "limiterProcessName", this pointer has then to be used to specify the parallel
geometries to the process : limiter->AddParallelWorld("parallelWorld1"). . .
This is set of biasing operations and one operator available in 10.1, as well as a set of biasing interaction laws. These
are defined in source/processes/biasing/generic. Please note that several examples (Examples) also
implement dedicated operators and operations.
These classes have been tested for now with neutral particles.
• G4VBiasingOperation classes:
– G4BOptnCloning: a non-physics-based biasing operation that clones the current track. Each of the two
copies is given freely a weight.
– G4BOptnChangeCrossSection: a physics-based biasing operation to change one process cross-
section
– G4BOptnForceFreeFlight: a physics-based biasing operation to force a flight with no interaction
through the current volume. This operation is better said a “silent flight”: the flight is conducted under a
zero weight, and the track weight is restored at the end of the free flight, taking into account the cumulative
weight change for the non-interaction flight. This special feature is because this class in used in the MCNP-
like force collision scheme G4BOptrForceCollision.
– G4BOptnForceCommonTruncatedExp: a physics-based biasing operation to force a collision inside
the current volume. It is “common” as several processes may be forced together, driving the related
interaction law by the sum of these processes cross-section. The relative natural occurrence of processes
is conserved. This operation makes use of a “truncated exponential” law, which is the exponential law
limited to a segment [0,L], where L is the distance to exit the current volume.
• G4VBiasingOperator class:
– G4BOptrForceCollision: a biasing operator that implements a force collision scheme quite close to
the one provided by MCNP. It handles the scheme though the following sequence:
1. The operator starts by using a G4BOptnCloning cloning operation, making a copy of the primary
entering the volume. The primary is given a zero weight.
2. The primary is then transported through to the volume, without interactions. This is done with the
operator requesting forced free flight G4BOptnForceFreeFlight operations to all physics pro-
cesses. The weight is zero to prevent the primary to contribute to scores. This flight purpose is to
accumulate the probability to fly through the volume without interaction. When the primary reaches
the volume boundary, the first free flight operation restores the primary weight to its initial weight
and all operations multiply this weight by their weight for non-interaction flight. The operator then
abandons here the primary track, letting it back to normal tracking.
3. The copy of the primary track starts and the track is forced to interact in the volume, using the
G4BOptnForceCommonTruncatedExp operation, itself using the total cross-section to compute
the forced interaction law (exponential law limited to path length in the volume). One of the physics
processes is randomly selected (on the basis of cross-section values) for the interaction.
4. Other processes are receiving a forced free flight operation, from the operator.
5. The copy of the primary is transported up to its interaction point. With these operations configured, the
G4BiasingProcessInterface instances have all needed information to automatically compute
the weight of the primary track and of its interaction products.
As this operation starts on the volume boundary, a single force interaction occurs: if the track survives
the interaction (e.g Compton process), as it moved apart the boundary, the operator does not consider it
further.
• G4VBiasingInteractionLaw classes. These classes describe the interaction law in term of a non-
interaction probability over a segment of length l, and an “effective” cross-section for an interaction at distance
l (see Physics Reference Manual, section generic biasing [to come]). An interaction law can also be sampled.
– G4InteractionLawPhysical: the usual exponential law, driven by a cross-section constant over a
step. The effective cross-section is the cross-section.
– G4ILawForceFreeFlight: an “interaction” law for, precisely, a non-interacting track, with non-
interaction probability always 1, and zero effective cross-section. It is a limit case of the modeling.
– G4ILawTruncatedExp: an exponential interaction law limited to a segment [0,L]. The non-interaction
probability and effective cross-section depend on l, the distance travelled, and become zero and infinite,
respectively, at l=L.
The G4VBiasingOperation class has been evolved to simplify the interface. The changes regard physics-based
biasing (occurrence biasing and final state biasing) and are:
• Suppression of the method virtual G4ForceCondition ProposeForceCondition(const
G4ForceCondition wrappedProcessCondition)
– The functionality has been kept, absorbing the ProposeForceCondition(...) method by the
ProvideOccurenceBiasingInteractionLaw(...) one, which has now the signature:
virtual const G4VBiasingInteractionLaw*
ProvideOccurenceBiasingInteractionLaw ( const
(continues on next page)
Changes in 10.2 derive from the introduction of the track feature G4VAuxiliaryTrackInformation. They
regard essentially the force collision operator G4BOptrForceCollision and related features. These changes are
transparent to the user if using G4BOptrForceCollision and following examples/extended/biasing/
GB02. The information below are provided for developers of biasing classes.
The G4VAuxiliaryTrackInformation functionality allows to extend the G4Track attributes with an in-
stance of a concrete class deriving from G4VAuxiliaryTrackInformation. Such an object is registered
to the G4Track using an ID that has to be previously obtained from the G4PhysicsModelCatalog. The
G4VBiasingOperator class defines two new virtual methods, Configure() and ConfigureForWorker(),
to help with the creation of these ID's at the proper time (see G4BOptrForceCollision as an example).
Before 10.2, the G4BOptrForceCollision class was using state variables to make the bookkeeping of the
tracks handled by the scheme. Now this bookkeeping is handled using a G4VAuxiliaryTrackInformation,
G4BOptrForceCollisionTrackData.
To help with the bookkeeping, the base class G4VBiasingOperator was defining a set of methods
(GetBirthOperation(..), RememberSecondaries(..), ForgetTrack(..)), these have been re-
moved in 10.2 and are easy to overpass with a dedicated G4VAuxiliaryTrackInformation.
FOUR
4.1 Geometry
4.1.1 Introduction
The detector definition requires the representation of its geometrical elements, their materials and electronics prop-
erties, together with visualization attributes and user defined properties. The geometrical representation of detector
elements focuses on the definition of solid models and their spatial position, as well as their logical relations to one
another, such as in the case of containment.
GEANT4 uses the concept of “Logical Volume” to manage the representation of detector element properties. The
concept of “Physical Volume” is used to manage the representation of the spatial positioning of detector elements
and their logical relations. The concept of “Solid” is used to manage the representation of the detector element solid
modeling. Volumes and solids must be dynamically allocated using ‘new’ in the user program; they must not be
declared as local objects. Volumes and solids are automatically registered on creation to dedicated stores; these stores
will delete all objects at the end of the job.
4.1.2 Solids
The GEANT4 geometry modeller implements Constructive Solid Geometry (CSG) representations for geometrical
primitives. CSG representations are easy to use and normally give superior performance.
All solids must be allocated using ‘new’ in the user’s program; they get registered to a G4SolidStore at construc-
tion, which will also take care to deallocate them at the end of the job, if not done already in the user’s code.
All constructed solids can stream out their contents via appropriate methods and streaming operators.
For all solids it is possible to estimate the geometrical volume and the surface area by invoking the methods:
G4double GetCubicVolume()
G4double GetSurfaceArea()
which return an estimate of the solid volume and total area in internal units respectively. For elementary solids the
functions compute the exact geometrical quantities, while for composite or complex solids an estimate is made using
Monte Carlo techniques.
For all solids it is also possible to generate pseudo-random points lying on their surfaces, by invoking the method
G4ThreeVector GetPointOnSurface() const
which returns the generated point in local coordinates relative to the solid. To be noted that this function is not meant
to provide a uniform distribution of points on the surfaces of the solids.
97
Book For Application Developers, Release 10.5
Since release 10.3, solids can be scaled in their dimensions along the Cartesian axes X, Y or Z, by providing a scale
transformation associated to the original solid.
G4ScaledSolid( const G4String& pName,
G4VSolid* pSolid ,
const G4Scale3D& pScale )
CSG solids are defined directly as three-dimensional primitives. They are described by a minimal set of parameters
necessary to define the shape and size of the solid. CSG solids are Boxes, Tubes and their sections, Cones and their
sections, Spheres, Wedges, and Toruses.
Box:
To create a box one can use the constructor:
In the picture:
pX = 30, pY = 40, pZ = 60
by giving the box a name and its half-lengths along the X, Y and Z axis:
This will create a box that extends from -pX to +pX in X, from -pY to +pY in Y, and from -pZ to +pZ in Z.
For example to create a box that is 2 by 6 by 10 centimeters in full length, and called BoxA one should use the
following code:
G4Box* aBox = new G4Box("BoxA", 1.0*cm, 3.0*cm, 5.0*cm);
In the picture:
pRMin = 10, pRMax = 15, pDz = 20
In the picture:
pRMin = 12, pRMax = 20, pDz = 30,
pSPhi = 0, pDPhi = 1.5*pi, pLowNorm =
(0,-0.7,-0.71), pHighNorm = (0.7,0,0.
71)
4.1. Geometry 99
Book For Application Developers, Release 10.5
In the picture:
pRmin1 = 5, pRmax1 = 10, pRmin2 =
20, pRmax2 = 25, pDz = 40, pSPhi = 0,
pDPhi = 4/3*Pi
Parallelepiped:
A parallelepiped is constructed using:
In the picture:
dx = 30, dy = 40, dz = 60
Trapezoid:
To construct a trapezoid use:
In the picture:
dx1 = 30, dx2 = 10, dy1 = 40, dy2 =
15, dz = 60
Generic Trapezoid:
To build a generic trapezoid, the G4Trap class is provided. Here are the two constructors for a Right Angular Wedge
and for the general trapezoid for it:
pZ Length along z
pY Length along y
pX Length along x at the wider side
pLTX Length along x at the narrower side (plTX<=pX)
Note: The angle pAlph1 and pAlph2 have to be the same due to the planarity condition.
In the picture:
pRmin = 100, pRmax = 120, pSPhi =
0*Degree, pDPhi = 180*Degree, pSTheta
= 0 Degree, pDTheta = 180*Degree
In the picture:
pRmax = 100
The Orb can be obtained from a Sphere with: pRmin = 0, pSPhi = 0, pDPhi = 2 * 𝜋, pSTheta = 0, pDTheta = 𝜋
Torus:
To build a torus use:
In the picture:
pRmin = 40, pRmax = 60, pRtor = 200,
pSPhi = 0, pDPhi = 90*degree
In addition, the GEANT4 Design Documentation shows in the Solids Class Diagram the complete list of CSG classes.
Specific CSG Solids
Polycons:
Polycons (PCON) are implemented in GEANT4 through the G4Polycone class:
In the picture:
phiStart = 1/4*Pi, phiTotal = 3/2*Pi,
numZPlanes = 9, rInner = { 0, 0, 0,
0, 0, 0, 0, 0, 0}, rOuter = { 0, 10,
10, 5 , 5, 10 , 10 , 2, 2}, z = { 5,
7, 9, 11, 25, 27, 29, 31, 35 }
where:
A Polycone where Z planes position can also decrease is implemented through the G4GenericPolycone class:
where:
Polyhedra (PGON):
Polyhedra (PGON) are implemented through G4Polyhedra:
In the picture:
phiStart = -1/4*Pi, phiTotal= 5/4*Pi,
numSide = 3, nunZPlanes = 7, rInner =
{ 0, 0, 0, 0, 0, 0, 0 }, rOuter = {
0, 15, 15, 4, 4, 10, 10 }, z = { 0,
5, 8, 13 , 30, 32, 35 }
where:
In the picture
Dx = 5, Dy = 10, Dz = 20
General Ellipsoid:
The general ellipsoid with possible cut in Z can be defined as follows:
In the picture:
pxSemiAxis = 10, pySemiAxis = 20,
pzSemiAxis = 50, pzBottomCut = -10,
pzTopCut = 40
A general (or triaxial) ellipsoid is a quadratic surface which is given in Cartesian coordinates by:
1.0 = (x/pxSemiAxis)**2 + (y/pySemiAxis)**2 + (z/pzSemiAxis)**2
where:
pxSemiAxis Semiaxis in X
pySemiAxis Semiaxis in Y
pzSemiAxis Semiaxis in Z
pzBottomCut lower cut plane level, z
pzTopCut upper cut plane level, z
In the picture:
pxSemiAxis = 30/75, pySemiAxis = 60/
75, zMax = 50, pzTopCut = 25
where:
pxSemiAxis Semiaxis in X
pySemiAxis Semiaxis in Y
zMax Height of elliptical cone
pzTopCut upper cut plane level
An elliptical cone of height zMax, with two bases at -pzTopCut and +pzTopCut, semiaxis pxSemiAxis, and
semiaxis pySemiAxis is given by the parametric equations:
x = pxSemiAxis * ( zMax - u ) / u * Cos(v)
y = pySemiAxis * ( zMax - u ) / u * Sin(v)
z = u
Where v is between 0 and 2𝜋, and u between -pzTopCut and +pzTopCut respectively.
Paraboloid, a solid with parabolic profile:
A solid with parabolic profile and possible cuts along the Z axis can be defined as follows:
In the picture:
R1 = 20, R2 = 35, Dz = 20
In the picture:
innerStereo = 0.7, outerStereo = 0.
7, halfLenZ = 50, innerRadius = 20,
outerRadius = 30
G4Hype is shaped with curved sides parallel to the z-axis, has a specified half-length along the z axis about which it
is centred, and a given minimum and maximum radius.
A minimum radius of 0 defines a filled Hype (with hyperbolic inner surface), i.e. inner radius = 0 AND inner stereo
angle = 0.
The inner and outer hyperbolic surfaces can have different stereo angles. A stereo angle of 0 gives a cylindrical
surface:
Tetrahedra:
A tetrahedra solid can be defined as follows:
In the picture:
anchor = {0, 0, sqrt(3)}, p2 = { 0,
2*sqrt(2/3), -1/sqrt(3) }, p3 = {
-sqrt(2), -sqrt(2/3),-1/sqrt(3) }, p4
= { sqrt(2), -sqrt(2/3) , -1/sqrt(3)
}
Extruded Polygon:
The extrusion of an arbitrary polygon (extruded solid) with fixed outline in the defined Z sections can be defined as
follows (in a general way, or as special construct with two Z sections):
In the picture:
poligon = {-30,-30},{-30,30},{30,30},{30,-30},
{15,-30},{15,15},{-15,15},{-15,
-30}
zsections = [-60,{0,30},0.8], [-15, {0,-30},1.],
[10,{0,0},0.6], [60,{0,30},1.2]
The z-sides of the solid are the scaled versions of the same polygon.
Box Twisted:
A box twisted along one axis can be defined as follows:
In the picture:
twistedangle = 30*Degree, pDx = 30,
pDy =40, pDz = 60
G4TwistedBox is a box twisted along the z-axis. The twist angle cannot be greater than 90 degrees:
The first constructor of G4TwistedTrap produces a regular trapezoid twisted along the z-axis, where the caps of
the trapezoid are of the same shape and size.
The second constructor produces a generic trapezoid with polar, azimuthal and tilt angles.
The twist angle cannot be greater than 90 degrees:
In the picture:
dx1 = 30, dx2 = 10, dy1 = 40, dy2 =
15, dz = 60, twistedangle = 30*Degree
where:
where:
The order of specification of the coordinates for the vertices in G4GenericTrap is important. The first four points
are the vertices sitting on the -hz plane; the last four points are the vertices sitting on the +hz plane.
The order of defining the vertices of the solid is the following:
• point 0 is connected with points 1,3,4
• point 1 is connected with points 0,2,5
• point 2 is connected with points 1,3,6
• point 3 is connected with points 0,2,7
• point 4 is connected with points 0,5,7
• point 5 is connected with points 1,4,6
• point 6 is connected with points 2,5,7
• point 7 is connected with points 3,4,6
Points can be identical in order to create shapes with less than 8 vertices; the only limitation is to have at least one
triangle at +hz or -hz; the lateral surfaces are not necessarily planar. Not planar lateral surfaces are represented by a
surface that linearly changes from the edge on -hz to the corresponding edge on +hz; it represents a sweeping surface
with twist angle linearly dependent on Z, but it is not a real twisted surface mathematically described by equations as
for the other twisted solids described in this chapter.
Tube Section Twisted along Its Axis:
A tube section twisted along its axis can be defined as follows:
In the picture:
endinnerrad = 10, endouterrad = 15,
halfzlen = 20, dphi = 90*Degree,
twistedangle = 60*Degree
G4TwistedTubs is a sort of twisted cylinder which, placed along the z-axis and divided into phi-segments is
shaped like an hyperboloid, where each of its segmented pieces can be tilted with a stereo angle.
It can have inner and outer surfaces with the same stereo angle:
Additional constructors are provided, allowing the shape to be specified either as:
• the number of segments in phi and the total angle for all segments, or
• a combination of the above constructors providing instead the inner and outer radii at z=0 with different z-
lengths along negative and positive z-axis.
Simple solids can be combined using Boolean operations. For example, a cylinder and a half-sphere can be combined
with the union Boolean operation.
Creating such a new Boolean solid, requires:
• Two solids
• A Boolean operation: union, intersection or subtraction.
• Optionally a transformation for the second solid.
The solids used should be either CSG solids (for examples a box, a spherical shell, or a tube) or another Boolean solid:
the product of a previous Boolean operation. An important purpose of Boolean solids is to allow the description of
solids with peculiar shapes in a simple and intuitive way, still allowing an efficient geometrical navigation inside them.
Note: The constituent solids of a Boolean operation should possibly avoid be composed by sharing all or part of their
surfaces. This precaution is necessary in order to avoid the generation of ‘fake’ surfaces due to precision loss, or errors
in the final visualization of the Boolean shape. In particular, if any one of the subtractor surfaces is coincident with a
surface of the subtractee, the result is undefined. Moreover, the final Boolean solid should represent a single ‘closed’
solid, i.e. a Boolean operation between two solids which are disjoint or far apart each other, is not a valid Boolean
composition.
Note: The tracking cost for navigating in a Boolean solid in the current implementation, is proportional to the number
of constituent solids. So care must be taken to avoid extensive, unnecessary use of Boolean solids in performance-
critical areas of a geometry description, where each solid is created from Boolean combinations of many other solids.
Examples of the creation of the simplest Boolean solids are given below:
G4Box* box =
new G4Box("Box",20*mm,30*mm,40*mm);
G4Tubs* cyl =
new G4Tubs("Cylinder",0,50*mm,50*mm,0,twopi); // r: 0 mm -> 50 mm
// z: -50 mm -> 50 mm
// phi: 0 -> 2 pi
G4UnionSolid* union =
new G4UnionSolid("Box+Cylinder", box, cyl);
G4IntersectionSolid* intersection =
new G4IntersectionSolid("Box*Cylinder", box, cyl);
G4SubtractionSolid* subtraction =
new G4SubtractionSolid("Box-Cylinder", box, cyl);
where the union, intersection and subtraction of a box and cylinder are constructed.
The more useful case where one of the solids is displaced from the origin of coordinates also exists. In this case the
second solid is positioned relative to the coordinate system (and thus relative to the first). This can be done in two
ways:
• Either by giving a rotation matrix and translation vector that are used to transform the coordinate system of the
second solid to the coordinate system of the first solid. This is called the passive method.
• Or by creating a transformation that moves the second solid from its desired position to its standard position,
e.g., a box’s standard position is with its centre at the origin and sides parallel to the three axes. This is called
the active method.
In the first case, the translation is applied first to move the origin of coordinates. Then the rotation is used to rotate the
coordinate system of the second solid to the coordinate system of the first.
G4RotationMatrix* yRot = new G4RotationMatrix; // Rotates X and Z axes only
yRot->rotateY(M_PI/4.*rad); // Rotates 45 degrees
G4ThreeVector zTrans(0, 0, 50);
G4UnionSolid* unionMoved =
new G4UnionSolid("Box+CylinderMoved", box, cyl, yRot, zTrans);
//
// The new coordinate system of the cylinder is translated so that
// its centre is at +50 on the original Z axis, and it is rotated
// with its X axis halfway between the original X and Z axes.
Note that the first constructor that takes a pointer to the rotation-matrix (G4RotationMatrix*), does NOT copy
it. Therefore once used a rotation-matrix to construct a Boolean solid, it must NOT be modified.
In contrast, with the alternative method shown, a G4Transform3D is provided to the constructor by value, and its
transformation is stored by the Boolean solid. The user may modify the G4Transform3D and eventually use it
again.
When positioning a volume associated to a Boolean solid, the relative center of coordinates considered for the posi-
tioning is the one related to the first of the two constituent solids.
Multi-Union Structures
Since release 10.4, the possibility to define multi-union structures is part of the standard set of constructs in GEANT4.
A G4MultiUnion structure allows for the description of a Boolean union of many displaced solids at once, therefore
representing volumes with the same associated material. An example on how to define a simple MultiUnion structure
is given here:
#include "G4MultiUnion.hh"
Fast detection of intersections in tracking is assured by the adoption of a specialised optimisation applied to the 3D
structure itself and generated at initialisation.
Tessellated Solids
In GEANT4 it is also implemented a class G4TessellatedSolid which can be used to generate a generic solid
defined by a number of facets (G4VFacet). Such constructs are especially important for conversion of complex
geometrical shapes imported from CAD systems bounded with generic surfaces into an approximate description with
facets of defined dimension (see Fig. 4.1).
Fig. 4.1: Example of geometries imported from CAD system and converted to tessellated solids.
They can also be used to generate a solid bounded with a generic surface made of planar facets. It is important that the
supplied facets shall form a fully enclose space to represent the solid, and that adjacent facets always share a complete
edge (no vertex on one facet can lie between vertices on an adjacent facet).
Two types of facet can be used for the construction of a G4TessellatedSolid: a triangular facet
(G4TriangularFacet) and a quadrangular facet (G4QuadrangularFacet).
An example on how to generate a simple tessellated shape is given below.
Listing 4.1: Example of geometries imported from CAD system and con-
verted to tessellated solids.
// First declare a tessellated solid
//
G4TessellatedSolid solidTarget = new G4TessellatedSolid("Solid_name");
The G4TriangularFacet class is used for the construction of G4TessellatedSolid. It is defined by three
vertices, which shall be supplied in anti-clockwise order looking from the outside of the solid where it belongs. Its
constructor looks like:
G4TriangularFacet ( const G4ThreeVector Pt0,
const G4ThreeVector vt1,
const G4ThreeVector vt2,
G4FacetVertexType fType )
G4FacetVertexType ABSOLUTE in which case Pt0, vt1 and vt2 are the three vertices in anti-clockwise
order looking from the outside.
G4FacetVertexType RELATIVE in which case the first vertex is Pt0, the second vertex is Pt0+vt1
and the third vertex is Pt0+vt2, all in anti-clockwise order when looking from the
outside.
The G4QuadrangularFacet class can be used for the construction of G4TessellatedSolid as well. It is
defined by four vertices, which shall be in the same plane and be supplied in anti-clockwise order looking from the
outside of the solid where it belongs. Its constructor looks like:
G4QuadrangularFacet ( const G4ThreeVector Pt0,
const G4ThreeVector vt1,
const G4ThreeVector vt2,
const G4ThreeVector vt3,
G4FacetVertexType fType )
G4FacetVertexType ABSOLUTE in which case Pt0, vt1, vt2 and vt3 are the four vertices required in
anti-clockwise order when looking from the outside.
G4FacetVertexType RELATIVE in which case the first vertex is Pt0, the second vertex is Pt0+vt, the
third vertex is Pt0+vt2 and the fourth vertex is Pt0+vt3, in anti-clockwise order
when looking from the outside.
Tessellated solids can also be used to import geometrical models from CAD systems (see fig-geom-solid-1). In order to
do this, it is required to convert first the CAD shapes into tessellated surfaces. A way to do this is to save the shapes in
the geometrical model as STEP files and convert them to tessellated (faceted surfaces) solids, using a tool which allows
such conversion. At the time of writing, at least one tool is available for such purpose: FASTRAD. This strategy allows
to import any shape with some degree of approximation; the converted CAD models can then be imported through
GDML (Geometry Description Markup Language) into GEANT4 and be represented as G4TessellatedSolid
shapes.
Other tools which can be used to generate meshes to be then imported in GEANT4 as tessellated solids are:
• InStep - A free STL to GDML conversion tool.
• SALOME - Open-source software allowing to import STEP/BREP/IGES/STEP/ACIS formats, mesh them and
export to STL.
• ESABASE2 - Space environment analysis CAD, basic modules free for academic non-commercial use. Can
import STEP files and export to GDML shapes or complete geometries.
• CADMesh - Tool based on the VCG Library to read STL files and import in GEANT4.
• Cogenda - Commercial TCAD software for generation of 3D meshes through the module Gds2Mesh and final
export to GDML.
Unified Solids
An alternative implementation for some of the cited geometrical primitives is provided since release 10.0 of GEANT4.
The solids included in release 10.5 are: Box, Cons, Polycone, Polyhedra, Paraboloid, Orb, Sphere, Trd, Trap, Para,
GenericTrap, Tubs, CutTubs, Torus, Hyperboloid, Tet, Extruded Solid and Tessellated Solid.
The code for the new geometrical primitives originated as part of the AIDA Unified Solids Library and is now in-
tegrated in the VecGeom library (the vectorized geometry library for particle-detector simulation); it is provided for
experimental use and can be activated in place of the original primitives defined in GEANT4, by selecting the appro-
priate compilation flag when configuring the GEANT4 libraries installation. The installation allows to build against an
external system installation of the VecGeom library, therefore the appropriate installation path must also be provided
during the installation configuration:
-DGEANT4_USE_USOLIDS="all" // to replace all available shapes
-DGEANT4_USE_USOLIDS="box;tubs" // to replace only individual shapes
The Logical Volume manages the information associated with detector elements represented by a given Solid and
Material, independently from its physical position in the detector.
G4LogicalVolumes must be allocated using ‘new’ in the user’s program; they get registered to a
G4LogicalVolumeStore at construction, which will also take care to deallocate them at the end of the job, if
not done already in the user’s code.
A Logical Volume knows which physical volumes are contained within it. It is uniquely defined to be their mother
volume. A Logical Volume thus represents a hierarchy of unpositioned volumes whose positions relative to one another
are well defined. By creating Physical Volumes, which are placed instances of a Logical Volume, this hierarchy or tree
can be repeated.
A Logical Volume also manages the information relative to the Visualization attributes (Visualization Attributes) and
user-defined parameters related to tracking, electro-magnetic field or cuts (through the G4UserLimits interface).
By default, tracking optimization of the geometry (voxelization) is applied to the volume hierarchy identified by a
logical volume. It is possible to change the default behavior by choosing not to apply geometry optimization for a
given logical volume. This feature does not apply to the case where the associated physical volume is a parameterised
volume; in this case, optimization is always applied.
G4LogicalVolume( G4VSolid* pSolid,
G4Material* pMaterial,
const G4String& Name,
G4FieldManager* pFieldMgr=0,
G4VSensitiveDetector* pSDetector=0,
G4UserLimits* pULimits=0,
G4bool Optimise=true )
Through the logical volume it is also possible to tune the granularity of the optimisation algorithm to be applied to the
sub-tree of volumes represented. This is possible using the methods:
G4double GetSmartless() const
void SetSmartless(G4double s)
The default smartless value is 2 and controls the average number of slices per contained volume which are used in the
optimisation. The smaller the value, the less fine grained optimisation grid is generated; this will translate in a possible
reduction of memory consumed for the optimisation of that portion of geometry at the price of a slight CPU time
increase at tracking time. Manual tuning of the optimisation is in general not required, since the optimal granularity
level is computed automatically and adapted to the specific geometry setup; however, in some cases (like geometry
portions with ‘dense’ concentration of volumes distributed in a non-uniform way), it may be necessary to adopt manual
tuning for helping the optimisation process in dealing with the most critical areas. By setting the verbosity to 2 through
the following UI run-time command:
/run/verbose 2
a statistics of the memory consumed for the allocated optimisation nodes will be displayed volume by volume, allowing
to easily identify the critical areas which may eventually require manual intervention.
The logical volume provides a way to estimate the mass of a tree of volumes defining a detector or sub-detector. This
can be achieved by calling the method:
G4double GetMass(G4bool forced=false)
The mass of the logical volume tree is computed from the estimated geometrical volume of each solid and material
associated with the logical volume and its daughters. Note that this computation may require a considerable amount
of time, depending on the complexity of the geometry tree. The returned value is cached by default and can be used
for successive calls, unless recomputation is forced by providing true for the Boolean argument forced in input.
Computation should be forced if the geometry setup has changed after the previous call.
Finally, the Logical Volume manages the information relative to the Envelopes hierarchy required for fast Monte Carlo
parameterisations (Parameterization).
Sub-detector Regions
In complex geometry setups, such as those found in large detectors in particle physics experiments, it is useful to think
of specific Logical Volumes as representing parts (sub-detectors) of the entire detector setup which perform specific
functions. In such setups, the processing speed of a real simulation can be increased by assigning specific production
cuts to each of these detector parts. This allows a more detailed simulation to occur only in those regions where it is
required.
The concept of detector Region is introduced to address this need. Once the final geometry setup of the detector has
been defined, a region can be specified by constructing it with:
G4Region( const G4String& rName )
where:
G4Regions must be allocated using ‘new’ in the user’s program; they get registered to a G4RegionStore at
construction, which will also take care to deallocate them at the end of the job, if not done already in the user’s code.
A G4Region must then be assigned to a logical volume, in order to make it a Root Logical Volume:
G4Region* emCalorimeter = new G4Region("EM-Calorimeter");
emCalorimeterLV->SetRegion(emCalorimeter);
emCalorimeter->AddRootLogicalVolume(emCalorimeterLV);
A root logical volume is the first volume at the top of the hierarchy to which a given region is assigned. Once the
region is assigned to the root logical volume, the information is automatically propagated to the volume tree, so that
each daughter volume shares the same region. Propagation on a tree branch will be interrupted if an already existing
root logical volume is encountered.
A specific Production Cut can be assigned to the region, by defining and assigning to it a G4ProductionCut object
emCalorimeter->SetProductionCuts(emCalCuts);
Set production threshold (SetCut methods) describes how to define a production cut. The same region can be assigned
to more than one root logical volume, and root logical volumes can be removed from an existing region. A logical
volume can have only one region assigned to it. Regions will be automatically registered in a store which will take
care of destroying them at the end of the job. A default region with a default production cut is automatically created
and assigned to the world volume.
Regions can also become ‘envelopes’ for fast-simulation; can be assigned user-limits or generic user-information
(G4VUserRegionInformation); can be associated to specific stepping-actions (G4UserSteppingAction)
or have assigned a local magnetic-field (local fields specifically associated to logical volumes take precedence any-
how).
Physical volumes represent the spatial positioning of the volumes describing the detector elements. Several techniques
can be used. They range from the simple placement of a single copy to the repeated positioning using either a simple
linear formula or a user specified function.
Any physical volume must be allocated using ‘new’ in the user’s program; they get registered to a
G4PhysicalVolumeStore at construction, which will also take care to deallocate them at the end of the job,
if not done already in the user’s code.
The simple placement involves the definition of a transformation matrix for the volume to be positioned. Repeated
positioning is defined using the number of times a volume should be replicated at a given distance along a given
direction. Finally it is possible to define a parameterised formula to specify the position of multiple copies of a
volume. Details about these methods are given below.
Note: For geometries which vary between runs and for which components of the old geometry setup are explicitly
-deleted-, it is required to consider the proper order of deletion (which is the exact inverse of the actual construction,
i.e., first delete physical volumes and then logical volumes). Deleting a logical volume does NOT delete its daughter
volumes.
It is not necessary to delete the geometry setup at the end of a job, the system will take care to free the volume and
solid stores at the end of the job. The user has to take care of the deletion of any additional transformation or rotation
matrices allocated dynamically in his/her own application.
In this case, the Physical Volume is created by associating a Logical Volume with a Transformation that defines the
position of the current volume in the mother volume. The solid itself is moved by rotating and translating it to bring
it into the system of coordinates of the mother volume. The decomposition of the Transformation must contain only
rotation and translation (reflection and scaling are not allowed).
To create a Placement one must construct it using:
G4PVPlacement( G4Transform3D solidTransform,
G4LogicalVolume* pCurrentLogical,
const G4String& pName,
G4LogicalVolume* pMotherLogical,
G4bool pMany,
G4int pCopyNo,
G4bool pSurfChk=false )
where:
Currently Boolean operations are not implemented at the level of physical volume. So pMany must be false. However,
an alternative implementation of Boolean operations exists. In this approach a solid can be created from the union,
intersection or subtraction of two solids. See Solids made by Boolean operations above for an explanation of this.
The mother volume must be specified for all volumes except the world volume.
An alternative way to specify a Placement is to use a Rotation Matrix and a Translation Vector. If compared with the
previous construct, the Rotation Matrix is the inverse of the rotation from the decomposition of the transformation,
but the Translation Vector is the same. The Rotation Matrix represents the rotation of the reference frame of the
considered volume relatively to its mother volume’s reference frame. The Translation Vector represents the translation
of the current volume in the reference frame of its mother volume. This passive method can be utilized using the
following constructor:
G4PVPlacement( G4RotationMatrix* pRot,
const G4ThreeVector& tlate,
G4LogicalVolume* pCurrentLogical,
const G4String& pName,
G4LogicalVolume* pMotherLogical,
G4bool pMany,
G4int pCopyNo,
G4bool pSurfChk=false )
where:
Care must be taken because the rotation matrix is not copied by a G4PVPlacement. So the user must not modify it
after creating a Placement that uses it. However the same rotation matrix can be re-used for many volumes.
An alternative method to specify the mother volume is to specify its placed physical volume. It can be used in either
of the above methods of specifying the placement’s position and rotation. The effect will be exactly the same as for
using the mother logical volume.
Note that a Placement Volume can still represent multiple detector elements. This can happen if several copies exist
of the mother logical volume. Then different detector elements will belong to different branches of the tree of the
hierarchy of geometrical volumes.
An example demonstrating various ways of placement and constructing the rotation matrix is provided in examples/
extended/geometry/transforms.
Repeated volumes
In this case, a single Physical Volume represents multiple copies of a volume within its mother volume, allowing to
save memory. This is normally done when the volumes to be positioned follow a well defined rotational or translational
symmetry along a Cartesian or cylindrical coordinate. The Repeated Volumes technique is available for most volumes
described by CSG solids.
Replicas
Replicas are repeated volumes in the case when the multiple copies of the volume are all identical. The coordinate
axis and the number of replicas need to be specified for the program to compute at run time the transformation matrix
corresponding to each copy.
G4PVReplica( const G4String& pName,
G4LogicalVolume* pCurrentLogical,
G4LogicalVolume* pMotherLogical, // OR G4VPhysicalVolume*
const EAxis pAxis,
const G4int nReplicas,
const G4double width,
const G4double offset=0 )
where:
G4PVReplica represents nReplicas volumes differing only in their positioning, and completely filling the con-
taining mother volume. Consequently if a G4PVReplica is ‘positioned’ inside a given mother it MUST be the
mother’s only daughter volume. Replica’s correspond to divisions or slices that completely fill the mother volume and
have no offsets. For Cartesian axes, slices are considered perpendicular to the axis of replication.
The replica’s positions are calculated by means of a linear formula. Replication may occur along:
• Cartesian axes (kXAxis,kYAxis,kZAxis)
The replications, of specified width have coordinates of form (-width*(nReplicas-1)*0.
5+n*width,0,0) where n=0.. nReplicas-1 for the case of kXAxis, and are unrotated.
• Radial axis (cylindrical polar) (kRho)
The replications are cons/tubs sections, centred on the origin and are unrotated.
They have radii of width*n+offset to width*(n+1)+offset where n=0..nReplicas-1
• Phi axis (cylindrical polar) (kPhi)
The replications are phi sections or wedges, and of cons/tubs form.
They have phi of offset+n*width to offset+(n+1)*width where n=0..nReplicas-1
The coordinate system of the replicas is at the centre of each replica for the Cartesian axis. For the radial case, the
coordinate system is unchanged from the mother. For the phi axis, the new coordinate system is rotated such that the
X axis bisects the angle made by each wedge, and Z remains parallel to the mother’s Z axis.
The solid associated via the replicas’ logical volume should have the dimensions of the first volume created and must
be of the correct symmetry/type, in order to assist in good visualisation.
ex. For X axis replicas in a box, the solid should be another box with the dimensions of the replications. (same Y & Z
dimensions as mother box, X dimension = mother’s X dimension/nReplicas).
Replicas may be placed inside other replicas, provided the above rule is observed. Normal placement volumes may be
placed inside replicas, provided that they do not intersect the mother’s or any previous replica’s boundaries. Parame-
terised volumes may not be placed inside.
Because of these rules, it is not possible to place any other volume inside a replication in radius.
The world volume cannot act as a replica, therefore it cannot be sliced.
During tracking, the translation + rotation associated with each G4PVReplica object is modified according to the
currently ‘active’ replication. The solid is not modified and consequently has the wrong parameters for the cases of
phi and r replication and for when the cross-section of the mother is not constant along the replication.
Example
G4PVReplica repR("RSlices",
pRepRLogical,
pContainingMotherTub,
kRho, 5, 10*mm, 0);
G4PVReplica repZ("ZSlices",
pRepZLogical,
pContainingMotherTub,
kZAxis, 5, 10*mm);
G4PVReplica repPhi("PhiSlices",
pRepPhiLogical,
pContainingMotherTub,
kPhi, 4, M_PI*0.5*rad, 0);
RepX is an array of 5 replicas of width 10*mm, positioned inside and completely filling the volume pointed by
pContainingMotherBox. The mother’s X length must be 5*10*mm=50*mm (for example, if the mother’s solid
were a Box of half lengths [25,25,25] then the replica’s solid must be a box of half lengths [25,25,5]).
If the containing mother’s solid is a tube of radius 50*mm and half Z length of 25*mm, RepR divides the mother tube
into 5 cylinders (hence the solid associated with pRepRLogical must be a tube of radius 10*mm, and half Z length
25*mm); repZ divides the tube into 5 shorter cylinders (the solid associated with pRepZLogical must be a tube of
radius 10*mm, and half Z length 5*mm); finally, repPhi divides the tube into 4 tube segments with full angle of 90
degrees (the solid associated with pRepPhiLogical must be a tube segment of radius 10*mm, half Z length 5*mm
and delta phi of M_PI*0.5*rad).
No further volumes may be placed inside these replicas. To do so would result in intersecting boundaries due to the r
replications.
Parameterised Volumes
Parameterised Volumes are repeated volumes in the case in which the multiple copies of a volume can be different in
size, solid type, or material. The solid’s type, its dimensions, the material and the transformation matrix can all be
parameterised in function of the copy number, both when a strong symmetry exist and when it does not. The user
implements the desired parameterisation function and the program computes and updates automatically at run time the
information associated to the Physical Volume.
An example of creating a parameterised volume (by dimension and position) exists in basic exam-
ple B2b. The implementation is provided in the two classes B2bDetectorConstruction and
B2bChamberParameterisation.
To create a parameterised volume, one must first create its logical volume like trackerChamberLV below. Then
one must create his own parameterisation class (B2bChamberParameterisation) and instantiate an object of this class
(chamberParam). We will see how to create the parameterisation below.
G4Tubs* chamberS
= new G4Tubs("tracker",0, 100*cm, 100*cm, 0.*deg, 360.*deg);
fLogicChamber
= new G4LogicalVolume(chamberS,fChamberMaterial,"Chamber",0,0,0);
G4VPVParameterisation* chamberParam =
new B2bChamberParameterisation(
NbOfChambers, // NoChambers
firstPosition, // Z of center of first
chamberSpacing, // Z spacing of centers
chamberWidth, // chamber width
firstLength, // initial length
lastLength); // final length
Note that for a parameterised volume the user must always specify a mother volume. So the world volume can never
be a parameterised volume, nor it can be sliced. The mother volume can be specified either as a physical or a logical
volume.
pAxis specifies the tracking optimisation algorithm to apply: if a valid axis (the axis along which the parameterisation
is performed) is specified, a simple one-dimensional voxelisation algorithm is applied; if “kUndefined” is specified
instead, the default three-dimensional voxelisation algorithm applied for normal placements will be activated. In the
latter case, more voxels will be generated, therefore a greater amount of memory will be consumed by the optimisation
algorithm.
pSurfChk if true activates a check for overlaps with existing volumes or paramaterised instances.
The parameterisation mechanism associated to a parameterised volume is defined in the parameterisation class and its
methods. Every parameterisation must create two methods:
• ComputeTransformation defines where one of the copies is placed,
• ComputeDimensions defines the size of one copy, and
• a constructor that initializes any member variables that are required.
Note that the translation and rotation given in this scheme are those for the frame of coordinates (the passive method).
They are not for the active method, in which the solid is rotated into the mother frame of coordinates.
Similarly the ComputeDimensions method is used to set the size of that copy.
void B2bChamberParameterisation::ComputeDimensions
(G4Tubs& trackerChamber, const G4int copyNo, const G4VPhysicalVolume*) const
{
// Note: copyNo will start with zero!
G4double rmax = fRmaxFirst + copyNo * fRmaxIncr;
trackerChamber.SetInnerRadius(0);
trackerChamber.SetOuterRadius(rmax);
trackerChamber.SetZHalfLength(fHalfWidth);
trackerChamber.SetStartPhiAngle(0.*deg);
trackerChamber.SetDeltaPhiAngle(360.*deg);
}
The user must ensure that the type of the first argument of this method (in this example G4Tubs &) corresponds to
the type of object the user give to the logical volume of parameterised physical volume.
More advanced usage allows the user:
• to change the type of solid by creating a ComputeSolid method, or
• to change the material of the volume by creating a ComputeMaterial method. This method can also utilise
information from a parent or other ancestor volume (see the Nested Parameterisation below.)
for the parameterisation.
Example examples/extended/runAndEvent/RE02 shows a simple parameterisation by material. A more
complex example is provided in examples/extended/medical/DICOM, where a phantom grid of cells is built
using a parameterisation by material defined through a map.
Note: Currently for many cases it is not possible to add daughter volumes to a parameterised volume. Only param-
eterised volumes all of whose solids have the same size are allowed to contain daughter volumes. When the size or
type of solid varies, adding daughters is not supported. So the full power of parameterised volumes can be used only
for “leaf” volumes, which contain no other volumes.
Note: A hierarchy of volumes included in a parameterised volume cannot vary. Therefore, it is not possible to
implement a parameterisation which can modify the hierarchy of volumes included inside a specific parameterised
copy.
Note: For parameterisations of tubes or cons, where the starting Phi and its DeltaPhi angles
vary, it is possible to optimise the regeneration of the trigonometric parameters of the shape, by invoking
SetStartPhiAngle(newPhi, false); SetDeltaPhiAngle (newDPhi), i.e. by specifying with
false flag to skip the computation of the parameters which will be later on properly initialised with the call for
DeltaPhi.
Note: Parameterisations of composed solids like Boolean, Reflected or Displaced solids are not recommended, given
the complexity in handling transformations that this might imply, and limitations in making persistent representations
(i.e. GDML) of the geometry itself.
Note: For multi-threaded applications, one must be careful in the implementation of the parameterisation functions
for the geometrical objects being created in the parameterisation. In particular, when parameterising by the type of a
solid, it is assumed that the solids being parameterised are being declared thread-local in the user’s parameterisation
class and allocated just once.
A different type of parameterisation enables a user to have the daughter’s material also depend on the copy number
of the parent when a parameterised volume (daughter) is located inside another (parent) repeated volume. The parent
volume can be a replica, a parameterised volume, or a division if the key feature of modifying its contents is utilised.
(Note: a ‘nested’ parameterisation inside a placement volume is not supported, because all copies of a placement
volume must be identical at all levels.)
In such a ” nested” parameterisation , the user must provide a ComputeMaterial method that utilises the new
argument that represents the touchable history of the parent volume:
// Sample Parameterisation
class SampleNestedParameterisation : public G4VNestedParameterisation
{
public:
// .. other methods ...
// Mandatory method, required and reason for this class
virtual G4Material* ComputeMaterial(G4VPhysicalVolume *currentVol,
const G4int no_lev,
const G4VTouchable *parentTouch);
private:
G4Material *material1, *material2;
};
The implementation of the method can utilise any information from a parent or other ancestor volume of its parame-
terised physical volume, but typically it will use only the copy number:
G4Material*
SampleNestedParameterisation::ComputeMaterial(G4VPhysicalVolume *currentVol,
const G4int no_lev,
const G4VTouchable *parentTouchable)
{
G4Material *material=0;
Nested parameterisations are suitable for the case of regular, ‘voxel’ geometries in which a large number of ‘equal’
volumes are required, and their only difference is in their material. By creating two (or more) levels of parameterised
physical volumes it is possible to divide space, while requiring only limited additional memory for very fine-level
optimisation. This provides fast navigation. Alternative implementations, taking into account the regular structure of
such geometries in navigation are under study.
Divisions of Volumes
where:
The parameterisation is calculated automatically using the values provided in input. Therefore the di-
mensions of the solid associated with pCurrentLogical will not be used, but recomputed through the
G4VParameterisation::ComputeDimension() method.
Since G4VPVParameterisation may have different ComputeDimension() methods for each solid type, the
user must provide a solid that is of the same type as of the one associated to the mother volume.
As for any replica, the coordinate system of the divisions is related to the centre of each division for the Cartesian
axis. For the radial axis, the coordinate system is the same of the mother volume. For the phi axis, the new coordinate
system is rotated such that the X axis bisects the angle made by each wedge, and Z remains parallel to the mother’s Z
axis.
As divisions are parameterised volumes with constant dimensions, they may be placed inside other divisions, except
in the case of divisions along the radial axis.
It is also possible to place other volumes inside a volume where a division is placed.
The list of volumes that currently support divisioning and the possible division axis are summarised below:
(*) - G4Polyhedra:
• kPhi - the number of divisions has to be the same as solid sides, (i.e. numSides), the width will not be taken
into account.
In the case of division along kRho of G4Cons, G4Polycone, G4Polyhedra, if width is provided, it is taken as
the width at the -Z radius; the width at other radii will be scaled to this one.
Examples are given below in listings Listing 4.3 and Listing 4.5.
• divBox1 is a division of a box along its X axis in 5 equal copies. Each copy will have a dimension in meters
of [0.2, 1., 1.].
• divBox2 is a division of the same box along its X axis with a width of 0.1 meters and an offset of 0.5
meters. As the mother dimension along X of 1 meter (0.5*m of halflength), the division will be sized in total
1 - 0.45 = 0.55 meters. Therefore, there’s space for 5 copies, the first extending from -0.05 to 0.05
meters in the mother’s frame and the last from 0.35 to 0.45 meters.
• divBox3 is a division of the same box along its X axis in 3 equal copies of width 0.1 meters and an offset of
0.5 meters. The first copy will extend from 0. to 0.1 meters in the mother’s frame and the last from 0.2 to
0.3 meters.
• divPconePhiW is a division of a polycone along its phi axis in equal copies of width 30 degrees with an
offset of 60 degrees. As the mother extends from 0 to 180 degrees, there’s space for 4 copies. All the copies
have a starting angle of 20 degrees (as for the mother) and a phi extension of 30 degrees. They are rotated
around the Z axis by 60 and 30 degrees, so that the first copy will extend from 80 to 110 and the last from 170
to 200 degrees.
• divPconeZN is a division of the same polycone along its Z axis. As the mother polycone has two sections, it
will be divided in two one-section polycones, the first one extending from -1 to -0.25 meters, the second from
-0.25 to 1 meters. Although specified, the offset will not be used.
Note: Divisions for polycone and polyhedra are NOT possible in a multi-threaded application.
Introduction to Touchables
A touchable for a volume serves the purpose of providing a unique identification for a detector element. This can
be useful for description of the geometry alternative to the one used by the GEANT4 tracking system, such as a
Sensitive Detectors based read-out geometry, or a parameterised geometry for fast Monte Carlo. In order to create a
touchable volume, several techniques can be implemented: for example, in GEANT4 touchables are implemented as
solids associated to a transformation-matrix in the global reference system, or as a hierarchy of physical volumes up
to the root of the geometrical tree.
A touchable is a geometrical entity (volume or solid) which has a unique placement in a detector description. It is
represented by an abstract base class which can be implemented in a variety of ways. Each way must provide the
capabilities of obtaining the transformation and solid that is described by the touchable.
All G4VTouchable implementations must respond to the two following “requests”, where in all cases, by depth it
is meant the number of levels up in the tree to be considered (the default and current one is 0):
1. GetTranslation(depth)
2. GetRotation(depth)
that return the components of the volume’s transformation.
Additional capabilities are available from implementations with more information. These have a default implementa-
tion that causes an exception.
Several capabilities are available from touchables with physical volumes:
1. GetSolid(depth) gives the solid associated to the touchable.
2. GetVolume(depth) gives the physical volume.
3. GetReplicaNumber(depth) or GetCopyNumber(depth) which return the copy number of the phys-
ical volume (replicated or not).
Touchables that store volume hierarchy (history) have the whole stack of parent volumes available. Thus it is possible
to add a little more state in order to extend its functionality. We add a “pointer” to a level and a member function to
move the level in this stack. Then calling the above member functions for another level the information for that level
can be retrieved.
The top of the history tree is, by convention, the world volume.
1. GetHistoryDepth() gives the depth of the history tree.
2. MoveUpHistory(num) moves the current pointer inside the touchable to point num levels up the history
tree. Thus, e.g., calling it with num=1 will cause the internal pointer to move to the mother of the current
volume.
Warning: this function changes the state of the touchable and can cause errors in tracking if applied to
Pre/Post step touchables.
These methods are valid only for the touchable-history type, as specified also below.
An update method, with different arguments is available, so that the information in a touchable can be updated:
1. UpdateYourself(vol, history) takes a physical volume pointer and can additionally take a
NavigationHistory pointer.
As shown in Sections Logical Volumes and Physical Volumes, a logical volume represents unpositioned detector ele-
ments, and a physical volume can represent multiple detector elements. On the other hand, touchables provide a unique
identification for a detector element. In particular, the GEANT4 transportation process and the tracking system exploit
touchables as implemented in G4TouchableHistory. The touchable history is the minimal set of information re-
quired to specify the full genealogy of a given physical volume (up to the root of the geometrical tree). These touchable
volumes are made available to the user at every step of the GEANT4 tracking in G4VUserSteppingAction.
To create/access a G4TouchableHistory the user must message G4Navigator which provides the method
CreateTouchableHistoryHandle():
G4TouchableHistoryHandle CreateTouchableHistoryHandle() const;
The first method is used to find out how many levels deep in the geometry tree the current volume is. The second
method asks the touchable to eliminate its deepest level.
As mentioned above, MoveUpHistory(num) significantly modifies the state of a touchable.
G4AssemblyVolume is a helper class which allows several logical volumes to be combined together in an arbitrary
way in 3D space. The result is a placement of a normal logical volume, but where final physical volumes are many.
However, an assembly volume does not act as a real mother volume, being an envelope for its daughter volumes. Its
role is over at the time the placement of the logical assembly volume is done. The physical volume objects become
independent copies of each of the assembled logical volumes.
This class is particularly useful when there is a need to create a regular pattern in space of a complex component which
consists of different shapes and can’t be obtained by using replicated volumes or parametrised volumes (see also Fig.
4.2. Careful usage of G4AssemblyVolume must be considered though, in order to avoid cases of “proliferation” of
physical volumes all placed in the same mother.
Participating logical volumes are represented as a triplet of <logical volume, translation, rotation>
(G4AssemblyTriplet class).
The adopted approach is to place each participating logical volume with respect to the assembly’s coordinate system,
according to the specified translation and rotation.
An assembly volume object is composed of a set of logical volumes; imprints of it can be made inside a mother logical
volume.
Since the assembly volume class generates physical volumes during each imprint, the user has no way to specify
identifiers for these. An internal counting mechanism is used to compose uniquely the names of the physical volumes
created by the invoked MakeImprint(...) method(s).
The name for each of the physical volume is generated with the following format:
av_WWW_impr_XXX_YYY_ZZZ
where:
• WWW - assembly volume instance number
• XXX - assembly volume imprint number
• YYY - the name of the placed logical volume
• ZZZ - the logical volume index inside the assembly volume
It is however possible to access the constituent physical volumes of an assembly and eventually customise ID and
copy-number.
At destruction all the generated physical volumes and associated rotation matrices of the imprints will be destroyed. A
list of physical volumes created by MakeImprint() method is kept, in order to be able to cleanup the objects when
not needed anymore. This requires the user to keep the assembly objects in memory during the whole job or during
the life-time of the G4Navigator, logical volume store and physical volume store may keep pointers to physical
volumes generated by the assembly volume.
The MakeImprint() method will operate correctly also on transformations including reflections and can be applied
also to recursive assemblies (i.e., it is possible to generate imprints of assemblies including other assemblies). Giving
true as the last argument of the MakeImprint() method, it is possible to activate the volumes overlap check for
the assembly’s constituents (the default is false).
At destruction of a G4AssemblyVolume, all its generated physical volumes and rotation matrices will be freed.
Example
This example shows how to use the G4AssemblyVolume class. It implements a layered detector where each layer
consists of 4 plates.
In the code below, at first the world volume is defined, then solid and logical volume for the plate are created, followed
by the definition of the assembly volume for the layer.
The assembly volume for the layer is then filled by the plates in the same way as normal physical volumes are placed
inside a mother volume.
Finally the layers are placed inside the world volume as the imprints of the assembly volume (see Listing 4.7).
void TstVADetectorConstruction::ConstructAssembly()
{
// Define world volume
G4Box* WorldBox = new G4Box( "WBox", worldX/2., worldY/2., worldZ/2. );
G4LogicalVolume* worldLV = new G4LogicalVolume( WorldBox, selectedMaterial,
"WLog", 0, 0, 0 );
G4VPhysicalVolume* worldVol = new G4PVPlacement( 0, G4ThreeVector(), "WPhys",worldLV,
0, false, 0 );
// Define a plate
G4Box* PlateBox = new G4Box( "PlateBox", plateX/2., plateY/2., plateZ/2. );
G4LogicalVolume* plateLV = new G4LogicalVolume( PlateBox, Pb, "PlateLV", 0, 0, 0 );
Hierarchies of volumes based on CSG or specific solids can be reflected by means of the G4ReflectionFactory
class and G4ReflectedSolid, which implements a solid that has been shifted from its original reference frame
to a new ‘reflected’ one. The reflection transformation is applied as a decomposition into rotation and translation
transformations.
The factory is a singleton object which provides the following methods:
G4PhysicalVolumesPair Place(const G4Transform3D& transform3D,
const G4String& name,
G4LogicalVolume* LV,
G4LogicalVolume* motherLV,
G4bool isMany,
G4int copyNo,
G4bool surfCheck=false)
(continues on next page)
The method Place() used for placements, evaluates the passed transformation. In case the transformation contains
a reflection, the factory will act as follows:
1. Performs the transformation decomposition.
2. Creates a new reflected solid and logical volume, or retrieves them from a map if the reflected object was already
created.
3. Transforms the daughters (if any) and place them in the given mother.
If successful, the result is a pair of physical volumes, where the second physical volume is a placement in a re-
flected mother. Optionally, it is also possible to force the overlaps check at the time of placement, by activating the
surfCheck flag.
The method Replicate() creates replicas in the given mother. If successful, the result is a pair of physical volumes,
where the second physical volume is a replica in a reflected mother.
The method Divide() creates divisions in the given mother. If successful, the result is a pair of physical volumes,
where the second physical volume is a division in a reflected mother. There exists also two more variants of this
method which may specify or not width or number of divisions.
Note: In order to reflect hierarchies containing divided volumes, it is necessary to explicitly instantiate a concrete
division factory -before- applying the actual reflection: (i.e. - G4PVDivisionFactory::GetInstance();).
G4VPhysicalVolume* physiCalor =
new G4PVPlacement(rotD3, // rotation
G4ThreeVector(Xpos,0.,0.), // at (Xpos,0,0)
logicCalor, // its logical volume (defined elsewhere)
"Calorimeter", // its name
logicHall, // its mother volume (defined elsewhere)
(continues on next page)
G4ReflectionFactory::Instance()
->Place(transform, // the transformation with reflection
"Calorimeter", // the actual name
logicCalor, // the logical volume
logicHall, // the mother volume
false, // no boolean operation
1, // copy number
false); // no overlap check triggered
// Replicate layers
//
G4ReflectionFactory::Instance()
->Replicate("Layer", // layer name
logicLayer, // layer logical volume (defined elsewhere)
logicCalor, // its mother
kXAxis, // axis of replication
5, // number of replica
20*cm); // width of replica
Navigation through the geometry at tracking time is implemented by the class G4Navigator. The navigator is used
to locate points in the geometry and compute distances to geometry boundaries. At tracking time, the navigator is
intended to be the only point of interaction with tracking.
Internally, the G4Navigator has several private helper/utility classes:
• G4NavigationHistory - stores the compounded transformations, replication/parameterisation information, and
volume pointers at each level of the hierarchy to the current location. The volume types at each level are also
stored - whether normal (placement), replicated or parameterised.
• G4NormalNavigation - provides location & distance computation functions for geometries containing ‘place-
ment’ volumes, with no voxels.
• G4VoxelNavigation - provides location and distance computation functions for geometries containing ‘place-
ment’ physical volumes with voxels. Internally a stack of voxel information is maintained. Private functions
allow for isotropic distance computation to voxel boundaries and for computation of the ‘next voxel’ in a speci-
fied direction.
• G4ParameterisedNavigation - provides location and distance computation functions for geometries containing
parameterised volumes with voxels. Voxel information is maintained similarly to G4VoxelNavigation, but
computation can also be simpler by adopting voxels to be one level deep only (unrefined, or 1D optimisation)
• G4ReplicaNavigation - provides location and distance computation functions for replicated volumes.
In addition, the navigator maintains a set of flags for exiting/entry optimisation. A navigator is not a singleton class;
this is mainly to allow a design extension in future (e.g. geometrical event biasing).
The main functions required for tracking in the geometry are described below. Additional functions are provided to
return the net transformation of volumes and for the creation of touchables. None of the functions implicitly requires
More than one navigator object can be created inside an application; these navigators can act independently for dif-
ferent purposes. The main navigator which is activated automatically at the startup of a simulation program is the
navigator used for the tracking and attached the world volume of the main tracking (or mass) geometry.
The navigator for tracking can be retrieved at any state of the application by messaging the
G4TransportationManager:
G4Navigator* tracking_navigator =
G4TransportationManager::GetInstance()->GetNavigatorForTracking();
This also allows to retrieve at any time a pointer to the world volume assigned for tracking:
The navigator for tracking also retains all the information of the current history of volumes traversed at a precise
moment of the tracking during a run. Therefore, if the navigator for tracking is used during tracking for locating a
generic point in the tree of volumes, the actual particle gets also -relocated- in the specified position and tracking will
be of course affected !
In order to avoid the problem above and provide information about location of a point without affecting the tracking,
it is suggested to either use an alternative G4Navigator object (which can then be assigned to the world-volume),
or access the information through the step.
If the user instantiates an alternative G4Navigator, ownership is retained by the user’s code, and the navigator
object should be deleted by that code.
During the tracking run, geometrical information can be retrieved through the touchable handle associated to the
current step. For example, to identify the exact copy-number of a specific physical volume in the mass geometry, one
should do the following:
// Given the pointer to the step object ...
//
G4Step* aStep = ..;
To determine the exact position in global coordinates in the mass geometry and convert to local coordinates (local to
the current volume):
G4ThreeVector worldPosition = preStepPoint->GetPosition();
G4ThreeVector localPosition = theTouchable->GetHistory()->
GetTopTransform().TransformPoint(worldPosition);
In order to know (when in the idle state of the application) in which physical volume a given point is located in the
detector geometry, it is necessary to create an alternative navigator object first and assign it to the world volume:
G4Navigator* aNavigator = new G4Navigator();
aNavigator->SetWorldVolume(worldVolumePointer);
Then, locate the point myPoint (defined in global coordinates), retrieve a touchable handle and do whatever you
need with it:
aNavigator->LocateGlobalPointAndSetup(myPoint);
G4TouchableHistoryHandle aTouchable =
aNavigator->CreateTouchableHistoryHandle();
If outside of the tracking run and given a generic local position (local to a given volume in the geometry tree), it is
-not- possible to determine a priori its global position and convert it to the global coordinates system. The reason for
this is rather simple, nobody can guarantee that the given (local) point is located in the right -copy- of the physical
volume ! In order to retrieve this information, some extra knowledge related to the absolute position of the physical
volume is required first, i.e. one should first determine a global point belonging to that volume, eventually making a
dedicated scan of the geometry tree through a dedicated G4Navigator object and then apply the method above after
having created the touchable for it.
Since release 8.2 of GEANT4, it is possible to define geometry trees which are parallel to the tracking geometry and
having them assigned to navigator objects that transparently communicate in sync with the normal tracking geometry.
Parallel geometries can be defined for several uses (fast shower parameterisation, geometrical biasing, particle scoring,
readout geometries, etc . . . ) and can overlap with the mass geometry defined for the tracking. The parallel
transportation will be activated only after the registration of the parallel geometry in the detector description setup; see
Section Parallel Geometries for how to define a parallel geometry and register it to the run-manager.
The G4TransportationManager provides all the utilities to verify, retrieve and activate the navigators associated
to the various parallel geometries defined.
Since release 9.1 of GEANT4, a specialised navigation algorithm has been introduced to allow for optimal memory use
and extremely efficient navigation in geometries represented by a regular pattern of volumes and particularly three-
dimensional grids of boxes. A typical application of this kind is the case of DICOM phantoms for medical physics
studies.
The class G4RegularNavigation is used and automatically activated when such geometries are defined. It is
required to the user to implement a parameterisation of the kind G4PhantomParameterisation and place the
parameterised volume containing it in a container volume, so that all cells in the three-dimensional grid (voxels)
completely fill the container volume. This way the location of a point inside a voxel can be done in a fast way,
transforming the position to the coordinate system of the container volume and doing a simple calculation of the kind:
copyNo_x = (localPoint.x()+fVoxelHalfX*fNoVoxelX)/(fVoxelHalfX*2.)
where fVoxelHalfX is the half dimension of the voxel along X and fNoVoxelX is the number of vox-
els in the X dimension. Voxel 0 will be the one closest to the corner (fVoxelHalfX*fNoVoxelX,
fVoxelHalfY*fNoVoxelY, fVoxelHalfZ*fNoVoxelZ).
Having the voxels filling completely the container volume allows to avoid the lengthy computation of
ComputeStep() and ComputeSafety methods required in the traditional navigation algorithm. In this case,
when a track is inside the parent volume, it has always to be inside one of the voxels and it will be only necessary to
calculate the distance to the walls of the current voxel.
Another speed optimisation can be provided by skipping the frontiers of two voxels which the same material assigned,
so that bigger steps can be done. This optimisation may be not very useful when the number of materials is very big
(in which case the probability of having contiguous voxels with same material is reduced), or when the physical step
is small compared to the voxel dimensions (very often the case of electrons). The optimisation can be switched off in
such cases, by invoking the following method with argument skip = 0:
If you want to describe a phantom of a unique material, you may spare some memory by not filling the set of indices
of materials of each voxel. If the method SetMaterialIndices() is not invoked, the index for all voxels will be
0, that is the first (and unique) material in your list.
G4RegularParameterisation::SetSkipEqualMaterials( G4bool skip );
Example
To use the specialised navigation, it is required to first create an object of type G4PhantomParameterisation:
G4PhantomParameterisation* param = new G4PhantomParameterisation();
The physical volume should be assigned as the container volume of the parameterisation:
param->BuildContainerSolid(cont_phys);
// Assure that the voxels are completely filling the container volume
//
param->CheckVoxelsFillContainer( cont_solid->GetXHalfLength(),
cont_solid->GetyHalfLength(),
cont_solid->GetzHalfLength() );
An example showing the application of the optimised navigation algorithm for phantoms geometries is avail-
able in examples/extended/medical/DICOM. It implements a real application for reading DICOM im-
ages and convert them to GEANT4 geometries with defined materials and densities, allowing for different imple-
mentation solutions to be chosen (non-optimised, classical 3D optimisation, nested parameterisations and use of
G4PhantomParameterisation).
Run-time commands
When running in verbose mode (i.e. the default, G4VERBOSE set while installing the GEANT4 kernel libraries), the
navigator provides a few commands to control its behavior. It is possible to select different verbosity levels (up to 5),
with the command:
geometry/navigator/verbose [verbose_level]
The latter will force more strict and less tolerant checks in step/safety computation to verify the correctness of the
solids’ response in the geometry.
By combining check_mode with verbosity level-1, additional verbosity checks on the response from the solids can be
activated.
The tolerance value defining the accuracy of tracking on the surfaces is by default set to a reasonably small value of
10E-9 mm. Such accuracy may be however redundant for use on simulation of detectors of big size or macroscopic
dimensions. Since release 9.0, it is possible to specify the surface tolerance to be relative to the extent of the world
volume defined for containing the geometry setup.
The class G4GeometryManager can be used to activate the computation of the surface tolerance to be relative to
the geometry setup which has been defined. It can be done this way:
G4GeometryManager::GetInstance()->SetWorldMaximumExtent(WorldExtent);
where, WorldExtent is the actual maximum extent of the world volume used for placing the whole geometry setup.
Such call to G4GeometryManager must be done before defining any geometrical component of the setup (solid
shape or volume), and can be done only once!
The class G4GeometryTolerance is to be used for retrieving the actual values defined for tolerances, surface
(Cartesian), angular or radial respectively:
G4GeometryTolerance::GetInstance()->GetSurfaceTolerance();
G4GeometryTolerance::GetInstance()->GetAngularTolerance();
G4GeometryTolerance::GetInstance()->GetRadialTolerance();
GGE is the acronym for GEANT4 Graphical Geometry Editor. GGE aims to assist physicists who have a little knowl-
edge on C++ and the GEANT4 toolkit to construct his or her own detector geometry. In essence, GGE is made up of a
set of tables which can contain all relevant parameters to construct a simple detector geometry. Tables for scratch or
compound materials, tables for logical and physical volumes are provided. From the values in the tables, C++ source
codes are automatically generated.
GGE provides methods to:
1. construct a detector geometry including G4Element, G4Material, G4Solids, G4LogicalVolume,
G4PVPlacement, etc.
2. view the detector geometry using existing visualization system, DAWN
3. keep the detector object in a persistent way, either in GDML format (currently only logical volumes are sup-
ported) or Java serialized format.
4. produce corresponding C++ codes after the norm of GEANT4 toolkit
5. make a GEANT4 executable, in collaboration with another component of MOMO, i.e., GPE, or GEANT4 Physics
Editor.
GGE can be found in the standard GEANT4 source package under the directory environments/MOMO/MOMO.
jar. JRE (Java Run-time Environment) is prerequisite to run MOMO.jar, Java archive file of MOMO. MOMO
contains GGE, GPE, GAG and other helper tools. Further information is available from the Web pages below.
MOMO = GGE + GPE + GAG: http://www-geant4.kek.jp/~yoshidah
GGE provides the database of elements in the form of the periodic table, from which users can select element(s) to
construct new materials. They can be loaded, used, edited and saved as Java persistent objects or in a GDML file. In
enviroments/MOMO, a pre-constructed database of materials taken from the PDG book, PDG.xml is present.
Users can also create new materials either from scratch or by combining other materials.
• By selecting an element in the periodic table, default values as shown below are copied to a row in the table.
Use marks the used materials. Only the elements and materials used in the logical volumes are kept in the
detector object and are used to generate C++ constructors.
• By selecting multiple elements in the periodic table, a material from a combination of elements is assigned to a
row of the compound material table. The minimum actions user have to do is to give a name to the material and
define its density.
Use Name Elements Density Unit State Temperature Unit Pressure Unit
By clicking the column Elements, a new window is open to select one of two methods:
– Add an element, giving its fraction by weight
– Add an element, giving its number of atoms.
Solids
The most popular CSG solids (G4Box, G4Tubs, G4Cons, G4Trd) and specific solids (Pcons, Pgons) are supported.
All relevant parameters of such a solid can be specified in the parameter table, which pops up upon selection.
Color, or the visualization attribute of a logical volume can be created, using color chooser panel. Users can view each
solid using DAWN.
Logical Volume
The lists of solid types, names of the materials defined in the material tables, and names of user-defined visualization
attributes are shown automatically in respective table cell for user’s choices.
The construction and assignment of appropriate entities for G4FieldManager and G4VSensitiveDetector
are left to the user.
Physical Volume
GEANT4 enables users to create a physical volume in different ways; the mother volume can be either a logical or a
physical one, spatial rotation can be either with respect to the volume or to the frame to which the volume is attached.
GGE is prepared for such four combinatorial cases to construct a physical volume.
Five simple cases of creating physical volumes are supported by GGE. Primo, a single copy of a physical volume can
be created by a translation and rotation. Secondo, repeated copies can be created by repeated linear translations. A
logical volume is translated in a Cartesian direction, starting from the initial position, with a given step size. Mother
volume can be either another logical volume or a physical volume.
Name LogicalVol- Type and name of Mother- Many X0, Y0, Direc- Step- Unit Copy-
ume Volume Z0 tion Size Number
Third, repeated copies are created by rotation around an axis, placing an object repeatedly on a “cylindrical” pattern.
Fourth, replicas are created by slicing a volume along a Cartesian direction. Fifth, replicas are created by cutting a
volume cylindrically.
User has to type in a class name to his geometry, for example, MyDetectorConstruction. Then, with a mouse
button click, source codes in the form of an include file and a source file are created and shown in the editor panel.
In this example, they are MyDetectorConstruction.cc and MyDetectorConstruction.hh files. They
reflect all current user modifications in the tables in real-time.
Visualization
The whole geometry can be visualized after the compilation of the source code MyDetectorConstruction.cc
with appropriate parts of GEANT4. (In particular only the geometry and visualization, together with the small other
parts they depend on, are needed.) MOMO provides Physics Editor to create standard electromagnetic physics and a
minimum main program. See the on-line document in MOMO.
Approach
G3toG4 is the GEANT4 facility to convert GEANT 3.21 geometries into GEANT4. This is done in two stages:
1. The user supplies a GEANT 3.21 RZ-file (.rz) containing the initialization data structures. An executable
rztog4 reads this file and produces an ASCII call list file containing instructions on how to build the ge-
ometry. The source code of rztog4 is FORTRAN.
2. A call list interpreter (G4BuildGeom.cc) reads these instructions and builds the geometry in the user’s client
code for GEANT4.
Two examples of how to use the call list interpreter are supplied in the directory examples/extended/g3tog4:
1. cltog4 is a simple example which simply invokes the call list interpreter method G4BuildGeom from the
G3toG4DetectorConstruction class, builds the geometry and exits.
2. clGeometry, is more complete and is patterned as for the basic GEANT4 examples. It also invokes the call
list interpreter, but in addition, allows the geometry to be visualized and particles to be tracked.
To compile and build the G3toG4 libraries, you need to have enabled GEANT4_USE_G3TOG4 at the build configura-
tion of GEANT4. The G3toG4 libraries are not built by default.
Current Status
The package has been tested with the geometries from experiments like: BaBar, CMS, Atlas, Alice, Zeus, L3, and
Opal.
Here is a comprehensive list of features supported and not supported or implemented in the current version of the
package:
• Supported shapes: all GEANT 3.21 shapes except for GTRA, CTUB.
• PGON, PCON are built using the specific solids G4Polycone and G4Polyhedra.
• GEANT 3.21 MANY feature is only partially supported. MANY positions are resolved in the G3toG4MANY()
function, which has to be processed before G3toG4BuildTree() (it is not called by default). In order
to resolve MANY, the user code has to provide additional info using G4gsbool(G4String volName,
G4String manyVolName) function for all the overlapping volumes. Daughters of overlapping volumes
are then resolved automatically and should not be specified via Gsbool.
Limitation: a volume with a MANY position can have only this one position; if more than one position is needed
a new volume has to be defined (gsvolu()) for each position.
• GSDV* routines for dividing volumes are implemented, using G4PVReplicas, for shapes:
– BOX, TUBE, TUBS, PARA - all axes;
– CONE, CONS - axes 2, 3;
– TRD1, TRD2, TRAP - axis 3;
– PGON, PCON - axis 2;
– PARA -axis 1; axis 2,3 for a special case
• GSPOSP is implemented via individual logical volumes for each instantiation.
• GSROTM is implemented. Reflections of hierarchies based on plain CSG solids are implemented through the
G3Division class.
• Hits are not implemented.
• Conversion of GEANT 3.21 magnetic field is currently not supported. However, the usage of magnetic field has
to be turned on.
Volumes are often positioned within other volumes with the intent that one is fully contained within the other. If,
however, a volume extends beyond the boundaries of its mother volume, it is defined as overlapping. It may also be
intended that volumes are positioned within the same mother volume such that they do not intersect one another. When
such volumes do intersect, they are also defined as overlapping.
The problem of detecting overlaps between volumes is bounded by the complexity of the solid model description.
Hence it requires the same mathematical sophistication which is needed to describe the most complex solid topology,
in general. However, a tunable accuracy can be obtained by approximating the solids via first and/or second order
surfaces and checking their intersections.
In general, the most powerful clash detection algorithms are provided by CAD systems, treating the intersection
between the solids in their topological form.
The GEANT4 geometry modeler provides the ability to detect overlaps of placed volumes (normal placements or
parameterised) at the time of construction. This check is optional and can be activated when instantiating a place-
ment (see G4PVPlacement constructor in Placements: single positioned copy) or a parameterised volume (see
G4PVParameterised constructor in Repeated volumes).
The positioning of that specific volume will be checked against all volumes in the same hierarchy level and its mother
volume. Depending on the complexity of the geometry being checked, the check may require considerable CPU time;
it is therefore suggested to use it only for debugging the geometry setup and to apply it only to the part of the geometry
setup which requires debugging.
The classes G4PVPlacement and G4PVParameterised also provide a method:
G4bool CheckOverlaps(G4int res=1000, G4double tol=0., G4bool verbose=true)
which will force the check for the specified volume, and can be therefore used to verify for overlaps also once the
geometry is fully built. The check verifies if each placed or parameterised instance is overlapping with other instances
or with its mother volume. A default resolution for the number of points to be generated and verified is provided. The
method returns true if an overlap occurs. It is also possible to specify a “tolerance” by which overlaps not exceeding
such quantity will not be reported; by default, all overlaps are reported.
Built-in run-time commands to activate verification tests for the user-defined geometry are also provided
geometry/test/run
--> to start verification of geometry for overlapping regions
recursively through the volumes tree.
geometry/test/recursion_start [int]
--> to set the starting depth level in the volumes tree from where
checking overlaps. Default is level '0' (i.e. the world volume).
The new settings will then be applied to any recursive test run.
geometry/test/recursion_depth [int]
--> to set the total depth in the volume tree for checking overlaps.
Default is '-1' (i.e. checking the whole tree).
Recursion will stop after having reached the specified depth (the
default being the full depth of the geometry tree).
The new settings will then be applied to any recursive test run.
geometry/test/tolerance [double] [unit]
--> to define tolerance by which overlaps should not be reported.
Default is '0'.
geometry/test/verbosity [bool]
--> to set verbosity mode. Default is 'true'.
geometry/test/resolution [int]
--> to establish the number of points on surface to be generated
and checked for each volume. Default is '10000'.
geometry/test/maximum_errors [int]
--> to fix the threshold for the number of errors to be reported
for a single volume. By default, for each volume, reports stop
after the first error reported.
To detect overlapping volumes, the built-in UI commands use the random generation of points on surface technique
described above. It allows to detect with high level of precision any kind of overlaps, as depicted below. For example,
consider Fig. 4.4:
Here we have a line intersecting some physical volume (large, black rectangle). Belonging to the volume are four
daughters: A, B, C, and D. Indicated by the dots are the intersections of the line with the mother volume and the four
daughters.
This example has two geometry errors. First, volume A sticks outside its mother volume (this practice, sometimes used
in GEANT3.21, is not allowed in GEANT4). This can be noticed because the intersection point (leftmost magenta dot)
lies outside the mother volume, as defined by the space between the two black dots.
The second error is that daughter volumes A and B overlap. This is noticeable because one of the intersections with A
(rightmost magenta dot) is inside the volume B, as defined as the space between the red dots. Alternatively, one of the
intersections with B (leftmost red dot) is inside the volume A, as defined as the space between the magenta dots.
Another difficult issue is roundoff error. For example, daughters C and D lie precisely next to each other. It is possible,
due to roundoff, that one of the intersections points will lie just slightly inside the space of the other. In addition, a
volume that lies tightly up against the outside of its mother may have an intersection point that just slightly lies outside
the mother.
Finally, notice that no mention is made of the possible daughter volumes of A, B, C, and D. To keep the code simple,
only the immediate daughters of a volume are checked at one pass. To test these “granddaughter” volumes, the
daughters A, B, C, and D each have to be tested themselves in turn. To make this automatic, a recursive algorithm is
applied; it first tests the target volume, then it loops over all daughter volumes and calls itself.
Note: for a complex geometry, checking the entire volume hierarchy can be extremely time consuming.
The GEANT4 visualization offers a powerful debugging tool for detecting potential intersections of physical volumes.
The GEANT4 DAVID visualization tool can automatically detect the overlaps between the volumes defined in GEANT4
and converted to a graphical representation for visualization purposes. The accuracy of the graphical representation
can be tuned onto the exact geometrical description. In the debugging, physical-volume surfaces are automatically
decomposed into 3D polygons, and intersections of the generated polygons are investigated. If a polygon intersects
with another one, physical volumes which these polygons belong to are visualized in color (red is the default). The
Fig. 4.5 figure below is a sample visualization of a detector geometry with intersecting physical volumes highlighted:
At present physical volumes made of the following solids can be debugged: G4Box, G4Cons, G4Para, G4Sphere,
G4Trd, G4Trap, G4Tubs. (Existence of other solids is harmless.)
Visual debugging of physical-volume surfaces is performed with the DAWNFILE driver defined in the visualization
category and with the two application packages, i.e. Fukui Renderer “DAWN” and a visual intersection debugger
“DAVID”. DAWN and DAVID can be downloaded from the Web.
How to compile GEANT4 with the DAWNFILE driver incorporated is described in The Visualization Drivers.
If the DAWNFILE driver, DAWN and DAVID are all working well in your host machine, the visual intersection
debugging of physical-volume surfaces can be performed as follows:
Run your GEANT4 executable, invoke the DAWNFILE driver, and execute visualization commands to visualize your
detector geometry:
Idle> /vis/open DAWNFILE
.....(setting camera etc)...
Idle> /vis/drawVolume
Idle> /vis/viewer/update
Then a file “g4.prim”, which describes the detector geometry, is generated in the current directory and DAVID is
invoked to read it. (The description of the format of the file g4.prim can be found from the DAWN web site documen-
tation.)
If DAVID detects intersection of physical-volume surfaces, it automatically invokes DAWN to visualize the detector
geometry with the intersected physical volumes highlighted (See the above sample visualization).
If no intersection is detected, visualization is skipped and the following message is displayed on the console:
------------------------------------------------------
!!! Number of intersected volumes : 0 !!!
!!! Congratulations ! \(^o^)/ !!!
------------------------------------------------------
If you always want to skip visualization, set an environmental variable as follows beforehand:
% setenv DAVID_NO_VIEW 1
To control the precision associated to computation of intersections (default precision is set to 9), it is possible to use
the environmental variable for the DAWNFILE graphics driver, as follows:
% setenv G4DAWNFILE_PRECISION 10
If necessary, re-visualize the detector geometry with intersected parts highlighted. The data are saved in a file
“g4david.prim” in the current directory. This file can be re-visualized with DAWN as follows:
% dawn g4david.prim
It is also helpful to convert the generated file g4david.prim into a VRML-formatted file and perform interactive visu-
alization of it with your WWW browser. The file conversion tool prim2wrml can be downloaded from the DAWN
web site download pages.
For more details, see the documentation of DAVID mentioned above.
GEANT4 can handle geometries which vary in time (e.g. a geometry varying between two runs in the same job).
It is considered a change to the geometry setup, whenever for the same physical volume:
• the shape or dimension of its related solid is modified;
• the positioning (translation or rotation) of the volume is changed;
• the volume (or a set of volumes, tree) is removed/replaced or added.
Whenever such a change happens, the geometry setup needs to be first “opened” for the change to be applied and
afterwards “closed” for the optimisation to be reorganised.
In the general case, in order to notify the GEANT4 system of the change in the geometry setup, the G4RunManager
has to be messaged once the new geometry setup has been finalised:
G4RunManager::GeometryHasBeenModified();
The above notification needs to be performed also if a material associated to a positioned volume is changed, in
order to allow for the internal materials/cuts table to be updated. However, for relatively complex geometries the
re-optimisation step may be extremely inefficient, since it has the effect that the whole geometry setup will be re-
optimised and re-initialised. In cases where only a limited portion of the geometry has changed, it may be suitable to
apply the re-optimisation only to the affected portion of the geometry (subtree).
Since release 7.1 of the GEANT4 toolkit, it is possible to apply re-optimisation local to the subtree of the geometry
which has changed. The user will have to explicitly “open/close” the geometry providing a pointer to the top physical
volume concerned:
Listing 4.9: Opening and closing a portion of the geometry without noti-
fying the G4RunManager.
#include "G4GeometryManager.hh"
If the existing geometry setup is modified locally in more than one place, it may be convenient to apply such a
technique only once, by specifying a physical volume on top of the hierarchy (subtree) containing all changed portions
of the setup.
An alternative solution for dealing with dynamic geometries is to specify NOT to apply optimisation for the subtree
affected by the change and apply the general solution of invoking the G4RunManager. In this case, a performance
penalty at run-time may be observed (depending on the complexity of the not-optimised subtree), considering that,
without optimisation, intersections to all volumes in the subtree will be explicitly computed each time.
Note: in multi-threaded runs, dynamic geometries are only allowed for runs consisting only of one event.
Geometry Description Markup Language (GDML) is a markup language based on XML and suited for the descrip-
tion of detector geometry models. It allows for easy exchange of geometry data in a human-readable XML-based
description and structured formatting.
The GDML parser is a component of GEANT4 which can be built and installed as an optional choice. It allows for
importing and exporting GDML files, following the schema specified in the GDML documentation. The installation
of the plugin is optional and requires the installation of the XercesC DOM parser.
Examples of how to import and export a detector description model based on GDML, and also how to extend the
GDML schema, are provided and can be found in examples/extended/persistency/gdml.
Since release 9.2 of GEANT4, it is also possible to import geometry setups based on a plain text description, according
to a well defined syntax for identifying the different geometrical entities (solids, volumes, materials and volume
attributes) with associated parameters. An example showing how to define a geometry in plain text format and import
it in a GEANT4 application is shown in examples/extended/persistency/P03. The example also covers
the case of associating a sensitive detector to one of the volumes defined in the text geometry, the case of mixing C++
and text geometry definitions and the case of defining new tags in the text format so that regions and cuts by region
can be defined in the text file. It also provides an example of how to write a geometry text file from the in-memory
GEANT4 geometry. For the details on the format see the dedicated manual.
The GEANT4 geometry tree can be stored in the Root binary file format using the Root-I/O technique provided by
in Root. Such a binary file can then be used to quickly load the geometry into the memory or to move geometries
between different GEANT4 applications.
See Object Persistency for details and references.
4.2 Material
In nature, materials (chemical compounds, mixtures) are made of elements, and elements are made of isotopes.
GEANT4 has three main classes designed to reflect this organization. Each of these classes has a table, which is a
static data member, used to keep track of the instances of the respective classes created.
G4Isotope This class describes the properties of atoms: atomic number, number of nucleons, mass per mole, etc.
G4Element This class describes the properties of elements: effective atomic number, effective number of nucleons,
effective mass per mole, number of isotopes, shell energy, and quantities like cross section per atom, etc.
G4Material This class describes the macroscopic properties of matter: density, state, temperature, pressure, and
macroscopic quantities like radiation length, mean free path, dE/dx, etc.
Only the G4Material class is visible to the rest of the toolkit and used by the tracking, the geometry and the
physics. It contains all the information relevant to its constituent elements and isotopes, while at the same time hiding
their implementation details.
G4Isotope
A G4Isotope object has a name, atomic number, number of nucleons, mass per mole, and an index in the table.
The constructor automatically stores “this” isotope in the isotopes table, which will assign it an index number. The
G4Isotope objects are owned by the isotopes table, and must not be deleted by user code.
G4Element
A G4Element object has a name, symbol, effective atomic number, effective number of nucleons, effective mass of
a mole, an index in the elements table, the number of isotopes, a vector of pointers to such isotopes, and a vector of
relative abundances referring to such isotopes (where relative abundance means the number of atoms per volume). In
addition, the class has methods to add, one by one, the isotopes which are to form the element.
The constructor automatically stores “this” element in the elements table, which will assign it an index number. The
G4Element objects are owned by the elements table, and must not be deleted by user code.
A G4Element object can be constructed by directly providing the effective atomic number, effective number of
nucleons, and effective mass of a mole, if the user explicitly wants to do so. Alternatively, a G4Element object can
be constructed by declaring the number of isotopes of which it will be composed. The constructor will “new” a vector
of pointers to G4Isotopes and a vector of doubles to store their relative abundances. Finally, the method to add an
isotope must be invoked for each of the desired (pre-existing) isotope objects, providing their addresses and relative
abundances. At the last isotope entry, the system will automatically compute the effective atomic number, effective
number of nucleons and effective mass of a mole, and will store “this” element in the elements table.
A few quantities, with physical meaning or not, which are constant in a given element, are computed and stored here
as “derived data members”.
Using the internal GEANT4 database, a G4Element can be accessed by atomic number or by atomic symbol (“Al”,
“Fe”, “Pb”. . . ). In that case G4Element will be found from the list of existing elements or will be constructed using
data from the GEANT4 database, which is derived from the NIST database of elements and isotope compositions.
Thus, the natural isotope composition can be built by default. The same element can be created as using the NIST
database with the natural composition of isotopes and from scratch in user code with user defined isotope composition.
G4Material
A G4Material object has a name, density, physical state, temperature and pressure (by default the standard con-
ditions), the number of elements and a vector of pointers to such elements, a vector of the fraction of mass for each
element, a vector of the atoms (or molecules) numbers of each element, and an index in the materials table. In addition,
the class has methods to add, one by one, the elements which will comprise the material.
The constructor automatically stores “this” material in the materials table, which will assign it an index number. The
G4Material objects are owned by the materials table, and must not be deleted by user code.
A G4Material object can be constructed by directly providing the resulting effective numbers, if the user explicitly
wants to do so (an underlying element will be created with these numbers). Alternatively, a G4Material object
can be constructed by declaring the number of elements of which it will be composed. The constructor will “new” a
vector of pointers to G4Element and a vector of doubles to store their fraction of mass. Finally, the method to add
an element must be invoked for each of the desired (pre-existing) element objects, providing their addresses and mass
fractions. At the last element entry, the system will automatically compute the vector of the number of atoms of each
element per volume, the total number of electrons per volume, and will store “this” material in the materials table. In
the same way, a material can be constructed as a mixture of other materials and elements.
It should be noted that if the user provides the number of atoms (or molecules) for each element comprising the
chemical compound, the system automatically computes the mass fraction. A few quantities, with physical meaning
or not, which are constant in a given material, are computed and stored here as “derived data members”.
Some materials are included in the internal GEANT4 database, which were derived from the NIST database of material
properties. Additionally a number of materials frequently used in HEP is included in the database. Materials are
interrogated or constructed by their names ( Material Database). There are UI commands for the material category,
which provide an interactive access to the database. If material is created using the NIST database by it will consist
by default of elements with the natural composition of isotopes.
Final Considerations
The classes will automatically decide if the total of the mass fractions is correct, and perform the necessary checks.
The main reason why a fixed index is kept as a data member is that many cross section and energy tables will be built
in the physics processes “by rows of materials (or elements, or even isotopes)”. The tracking gives the physics process
the address of a material object (the material of the current volume). If the material has an index according to which
the cross section table has been built, then direct access is available when a number in such a table must be accessed.
We get directly to the correct row, and the energy of the particle will tell us the column. Without such an index, every
access to the cross section or energy tables would imply a search to get to the correct material’s row. More details will
be given in the section on processes.
Isotopes, elements and materials must be instantiated dynamically in the user application; they are automatically
registered in internal stores and the system takes care to free the memory allocated at the end of the job.
int main() {
G4String name, symbol; // a=mass of a mole;
G4double a, z, density; // z=mean number of protons;
G4int iz, n; // iz=nb of protons in an isotope;
// n=nb of nucleons in an isotope;
G4int ncomponents, natoms;
G4double abundance, fractionmass;
G4double temperature, pressure;
G4UnitDefinition::BuildUnitsTable();
// define Elements
a = 1.01*g/mole;
G4Element* elH = new G4Element(name="Hydrogen",symbol="H" , z= 1., a);
a = 12.01*g/mole;
G4Element* elC = new G4Element(name="Carbon" ,symbol="C" , z= 6., a);
a = 14.01*g/mole;
G4Element* elN = new G4Element(name="Nitrogen",symbol="N" , z= 7., a);
a = 16.00*g/mole;
G4Element* elO = new G4Element(name="Oxygen" ,symbol="O" , z= 8., a);
a = 28.09*g/mole;
G4Element* elSi = new G4Element(name="Silicon", symbol="Si", z=14., a);
a = 55.85*g/mole;
G4Element* elFe = new G4Element(name="Iron" ,symbol="Fe", z=26., a);
a = 183.84*g/mole;
G4Element* elW = new G4Element(name="Tungsten" ,symbol="W", z=74., a);
a = 207.20*g/mole;
G4Element* elPb = new G4Element(name="Lead" ,symbol="Pb", z=82., a);
density = 1.390*g/cm3;
a = 39.95*g/mole;
G4Material* lAr = new G4Material(name="liquidArgon", z=18., a, density);
density = 8.960*g/cm3;
(continues on next page)
density = 1.032*g/cm3;
G4Material* Sci = new G4Material(name="Scintillator", density, ncomponents=2);
Sci->AddElement(elC, natoms=9);
Sci->AddElement(elH, natoms=10);
density = 2.200*g/cm3;
G4Material* SiO2 = new G4Material(name="quartz", density, ncomponents=2);
SiO2->AddElement(elSi, natoms=1);
SiO2->AddElement(elO , natoms=2);
density = 8.280*g/cm3;
G4Material* PbWO4= new G4Material(name="PbWO4", density, ncomponents=3);
PbWO4->AddElement(elO , natoms=4);
PbWO4->AddElement(elW , natoms=1);
PbWO4->AddElement(elPb, natoms=1);
density = 0.3*mg/cm3;
pressure = 2.*atmosphere;
temperature = 500.*kelvin;
G4Material* steam = new G4Material(name="Water steam ", density, ncomponents=1,
kStateGas,temperature,pressure);
steam->AddMaterial(H2O, fractionmass=1.);
// What about vacuum ? Vacuum is an ordinary gas with very low density
density = universe_mean_density; //from PhysicalConstants.h
pressure = 1.e-19*pascal;
temperature = 0.1*kelvin;
new G4Material(name="Galactic", z=1., a=1.01*g/mole, density,
kStateGas,temperature,pressure);
density = 1.e-5*g/cm3;
pressure = 2.e-2*bar;
temperature = STP_Temperature; //from PhysicalConstants.h
G4Material* beam = new G4Material(name="Beam ", density, ncomponents=1,
(continues on next page)
return EXIT_SUCCESS;
}
As can be seen in the later examples, a material has a state: solid (the default), liquid, or gas. The constructor checks
the density and automatically sets the state to gas below a given threshold (10 mg/cm3).
In the case of a gas, one may specify the temperature and pressure. The defaults are STP conditions defined in
PhysicalConstants.hh.
An element must have the number of nucleons >= number of protons >= 1.
A material must have non-zero values of density, temperature and pressure.
Materials can also be defined using the internal GEANT4 database. Listing 4.11 illustrates how to do this for the same
materials used in Listing 4.10. There are also UI commands which allow the database to be accessed. The list of
currently available material names ( Material Database) is extended permanently.
Listing 4.11: A program which shows how to define materials from the
internal database.
#include "globals.hh"
#include "G4Material.hh"
#include "G4NistManager.hh"
int main() {
G4NistManager* man = G4NistManager::Instance();
man->SetVerbose(1);
// define elements
G4Element* C = man->FindOrBuildElement("C");
G4Element* Pb = man->FindOrBuildMaterial("Pb");
// HEP materials
G4Material* PbWO4 = man->FindOrBuildMaterial("G4_PbWO4");
G4Material* lAr = man->FindOrBuildMaterial("G4_lAr");
G4Material* vac = man->FindOrBuildMaterial("G4_Galactic");
return EXIT_SUCCESS;
}
Print a constituent
GEANT4 is capable of describing and propagating in a variety of fields. Magnetic fields, electric fields, electromagnetic
fields, and gravity fields, uniform or non-uniform, can specified for a GEANT4 setup. The propagation of tracks inside
them can be performed to a user-defined accuracy.
In order to propagate a track inside a field, the equation of motion of the particle in the field is integrated. In general,
this is done using a Runge-Kutta method for the integration of ordinary differential equations. However, for specific
cases where an analytical solution is known, it is possible to utilize this instead. Several Runge-Kutta methods are
available, suitable for different conditions. In specific cases (such as a uniform field where the analytical solution is
known) different solvers can also be used. In addition, when an approximate analytical solution is known, it is possible
to utilize it in an iterative manner in order to converge to the solution to the precision required. This latter method is
currently implemented and can be used particularly well for magnetic fields that are almost uniform.
Once a method is chosen that calculates the track’s propagation in a specific field, the curved path is broken up into
linear chord segments. These chord segments are determined so that they closely approximate the curved path. The
chords are then used to interrogate the Navigator as to whether the track has crossed a volume boundary. Several pa-
rameters are available to adjust the accuracy of the integration and the subsequent interrogation of the model geometry.
How closely the set of chords approximates a curved trajectory is governed by a parameter called the miss distance
(also called the chord distance). This is an upper bound for the value of the sagitta - the distance between the ‘real’
curved trajectory and the approximate linear trajectory of the chord. By setting this parameter, the user can control the
precision of the volume interrogation. Every attempt has been made to ensure that all volume interrogations will be
made to an accuracy within this miss distance.
In addition to the miss distance there are two more parameters which the user can set in order to adjust the accuracy
(and performance) of tracking in a field. In particular these parameters govern the accuracy of the intersection with a
volume boundary and the accuracy of the integration of other steps. As such they play an important role for tracking.
The delta intersection parameter is the accuracy to which an intersection with a volume boundary is calculated. If
a candidate boundary intersection is estimated to have a precision better than this, it is accepted. This parameter is
especially important because it is used to limit a bias that our algorithm (for boundary crossing in a field) exhibits.
This algorithm calculates the intersection with a volume boundary using a chord between two points on the curved
particle trajectory. As such, the intersection point is always on the ‘inside’ of the curve. By setting a value for this
parameter that is much smaller than some acceptable error, the user can limit the effect of this bias on, for example,
the future estimation of the reconstructed particle momentum.
Fig. 4.6: The curved trajectory will be approximated by chords, so that the maximum estimated distance and chord is
less than the miss distance.
Fig. 4.7: The distance between the calculated chord intersection point C and a computed curve point D is used to
determine whether C is an accurate representation of the intersection of the curved path ADB with a volume boundary.
Here CD is likely too large, and a new intersection on the chord AD will be calculated.
The delta one step parameter is the accuracy for the endpoint of ‘ordinary’ integration steps, those which do not
intersect a volume boundary. This parameter is a limit on the estimated error of the endpoint of each physics step. It
can be seen as akin to a statistical uncertainty and is not expected to contribute any systematic behavior to physical
quantities. In contrast, the bias addressed by delta intersection is clearly correlated with potential systematic errors in
the momentum of reconstructed tracks. Thus very strict limits on the intersection parameter should be used in tracking
detectors or wherever the intersections are used to reconstruct a track’s momentum.
Delta intersection and delta one step are parameters of the Field Manager; the user can set them according to the
demands of his application. Because it is possible to use more than one field manager, different values can be set for
different detector regions.
Note that reasonable values for the two parameters are strongly coupled: it does not make sense to request an accuracy
of 1 nm for delta intersection and accept 100 𝜇m for the delta one step error value. Nevertheless delta intersection is
the more important of the two. It is recommended that these parameters should not differ significantly - certainly not
by more than an order of magnitude.
The simplest way to define a field for a detector involves the following steps:
1. create a field:
G4UniformMagField* magField
= new G4UniformMagField(G4ThreeVector(0.,0.,fieldValue));
Since 10.0 version, it is also possible to perform all three steps above at once using the
G4GlobalMagFieldMessenger class:
G4ThreeVector fieldValue = G4ThreeVector();
fMagFieldMessenger = new G4GlobalMagFieldMessenger(fieldValue);
fMagFieldMessenger->SetVerboseLevel(1);
The messenger creates the global uniform magnetic field, which is activated (set to the
G4TransportationManager object) only when the fieldValue is non zero vector. The messenger
class setter functions can be then used to change the field value (and activate or inactivate the field again) or the level
of output messages. The messenger also takes care of deleting the field.
As its class name suggests, the messenger creates also UI commands which can be used to change the field value and
the verbose level interactively or from a macro:
/globalField/setValue vx vy vz unit
/globalField/verbose level
It is possible to create a field for a part of the detector. In particular it can describe the field (with pointer fEmField,
for example) inside a logical volume and all its daughters. This can be done by simply creating a G4FieldManager
and attaching it to a logical volume (with pointer, logicVolumeWithField, for example) or set of logical volumes.
G4bool allLocal = true;
logicVolumeWithField->SetFieldManager(localFieldManager, allLocal);
Using the second parameter to SetFieldManager you choose whether daughter volumes of this logical volume
will also be given this new field. If it has the value true, the field will be assigned also to its daughters, and all their
sub-volumes. Else, if it is false, it will be copied only to those daughter volumes which do not have a field manager
already.
The design and implementation of the Field category allows and enables the use of an electric or combined electro-
magnetic field. These fields can also vary with time, as can magnetic fields.
Source listing Listing 4.12 shows how to define a uniform electric field for the whole of a detector.
Listing 4.12: How to define a uniform electric field for the whole of a
detector, extracted from example in examples/extended/field/field02 .
// in the header file (or first)
#include "G4EqMagElectricField.hh"
#include "G4UniformElectricField.hh"
#include "G4DormandPrince745.hh"
...
G4ElectricField* fEMfield;
G4EqMagElectricField* fEquation;
G4MagIntegratorStepper* fStepper;
G4FieldManager* fFieldMgr;
G4double fMinStep ;
G4ChordFinder* fChordFinder ;
{
fEMfield = new G4UniformElectricField(
G4ThreeVector(0.0,100000.0*kilovolt/cm,0.0));
G4int nvar = 8;
An example with an electric field is examples/extended/field/field02, where the class F02ElectricFieldSetup demon-
strates how to set these and other parameters, and how to choose different Integration Steppers. An example with a
uniform gravity field (G4UniformGravityField) is examples/extended/field/field06.
The user can also create their own type of field, inheriting from G4VField, and an associated Equation of Motion
class (inheriting from G4EqRhs) to simulate other types of fields.
Choosing a Stepper
Runge-Kutta integration is used to compute the motion of a charged track in a general field. There are many general
steppers from which to choose, of low and high order, and specialized steppers for pure magnetic fields. By default,
GEANT4 uses the established stepper of Dormand and Prince Runge-Kutta stepper, which is general purpose, efficient
and robust. It is a 5th order method which provides an error estimate directly , and requires fewer evaluations of the
derivative (and field) than the previous default, the classical 4th order method (for which an error estimate required
multiple sub-steps).
For somewhat smooth fields (intermediate), the choice between a fifth order stepper (such as the default
G4DormandPrince745):
G4int nvar = 8; // To integrate time & energy
// in addition to position, momentum
G4EqMagElectricField* fEquation= new G4EqMagElectricField(fEMfield);
Alternative fifth order embedded steppers beside the recommended and default G4DormandPrince745 which re-
quires 7 field evaluations (stages) include the older G4CashKarpRKF45 which requires fewer field evaluations (6
‘stages’)
fStepper = new G4CashKarpRKF45( fEquation, nvar );
// Alternative 4/5th order stepper for reasonably smooth fields
The newest experimental classes G4BogackiShampine45 or G4TsitourasRK45 implement some of the most
efficient fifth order methods in the literature, but require an additional derivative (field evaluation) per step.:
fStepper = new G4BogackiShampine45( fEquation, nvar );
// Alternative 4/5th order stepper with 8 stages (evaluations).
If there are particularly challenging accuracy demands (better than 1e-7) it may be worth to investigate higher order
steppers. Alternatively, if the field is known to have specific properties, lower or higher order steppers can be used to
obtain the results of the necessary accuracy using fewer computing cycles.
Sometimes the field changes greatly over short distances, and is estimated in ways that do not ensure that its derivatives
are smooth. These can present a challenge for fourth or fifth order Runge-Kutta methods.
What matters is the variation of the field in geometrical regions in which a large fraction of particles are tracked. In
particular, if the field is calculated from a field map and it varies significantly and in a non-smooth way over short
distances in important regions, it is suggested to investigate a lower order stepper.
Steppers of reduced order are also suitable when lower accuracy is required, such as errors of order 10-3 . Such accuracy
could be suitable for the least important tracks, such as low energy electrons near the end of their trajectory (but still
inside material.)
Steppers of reduced order require fewer derivative evaluations per step. The choice of lower order steppers includes
the third order embedded stepper G4BogackiShampine23, which provides a direct error estimate.:
fStepper = new G4BogackiShampine23( fEquation, nvar );
// 3rd order embbedded stepper
// Suitable for lower accuracy needs (<~ 10^-3) and/or 'rough' fields
Older type steppers, which do not provide a direct error estimate, offer an alternative for the roughest fields. ( Note:
these methods estimate the error in a step by subdividing it into two smaller steps and using the difference between
the new estimate and the estimate for the whole step as the estimated error. )
The recommended ones are the fourth order G4ClassicalRK4, which was the default in releases of GEANT4 up to
10.3, and is very robust:
fStepper = new ClassicalRK4( fEquation, nvar );
// 4th order, the old default - a robust alternative
the third order stepper G4SimpleHeum, and the second order steppers G4ImplicitEuler and
G4SimpleRunge.:
fStepper = new G4SimpleHeum( fEquation, nvar );
// 3rd order robust alternative for low accuracy and/or rought fields
A first order stepper is not recommended, but may be used only for the roughest fields, as a cross check for other
higher performance methods.
For somewhat smooth fields (intermediate), the choice between a fifth order stepper (such as the default
G4DormandPrince745):
fStepper = new G4DormandPrince745( fEquation, nvar );
// The recommended stepper, well suited for reasonably smooth fields
embedded third, the older type second or third order steppers, or the established fourth order G4ClassicalRK4 or
should be made by trial and error.
Trying a few different types of steppers for a particular field or application is suggested if maximum performance is a
goal.
The choice of stepper depends on the type of field: magnetic or general. A general field can be an electric or electro-
magnetic field, it can be a magnetic field or a user-defined field (which requires a user-defined equation of motion.)
For a general field all the above steppers are potential alternatives to the recommended / default
G4DormandPrince745.
But specialized steppers for pure magnetic fields are also available. The G4NystromRK4 stepper is a fourth order
method which estimates the integration error in a step directly from the variation of the field at the initial point, the
midpoint and near the endpoint of the step. Thus it requires no additional evaluations (stages.):
G4Mag_UsualEqRhs*
fEquation = new G4Mag_UsualEqRhs(fMagneticField);
fStepper = new G4NystromRK4( fEquation );
Others take into account the fact that a local trajectory in a slowly varying field will not vary significantly from a helix.
Combining this in with a variation the Runge-Kutta method can provide higher accuracy at lower computational cost
when large steps are possible.
fStepper = new G4HelixImplicitEuler( fEquation );
// Note that for magnetic field that do not vary with time,
// the default number of variables suffices.
// or ..
fStepper = new G4HelixExplicitEuler( fEquation );
fStepper = new G4HelixSimpleRunge( fEquation );
A new stepper for propagation in magnetic field is available in release 9.3. Choosing the G4NystromRK4 stepper
provides accuracy near that of G4ClassicalRK4 (4th order) with a significantly reduced cost in field evaluation. Using
a novel analytical expression for estimating the error of a proposed step and the Nystrom reuse of the mid-point field
value, it requires only 2 additional field evaluations per attempted step, in place of 10 field evaluations of ClassicalRK4
(which uses the general midpoint method for estimating the step error.)
G4Mag_UsualEqRhs*
pMagFldEquation = new G4Mag_UsualEqRhs(fMagneticField);
fStepper = new G4NystromRK4( pMagFldEquation );
It is proposed as an alternative stepper in the case of a pure magnetic field. It is not applicable for the simulation of
electric or full electromagnetic or other types of field. For a pure magnetic field, results should be fully compatible
with the results of ClassicalRK4 in nearly all cases. (The only potential exceptions are large steps for tracks with small
momenta - which cannot be integrated well by any RK method except the Helical extended methods.)
You can choose an alternative stepper either when the field manager is constructed or later. At the construction of the
ChordFinder it is an optional argument:
G4ChordFinder( G4MagneticField* itsMagField,
G4double stepMinimum = 1.0e-2 * mm,
G4MagIntegratorStepper* pItsStepper = 0 );
New in GEANT4 10.4 is the ability to use a property of RK methods known as ‘First Same as Last’ or FSAL. The
embedded steppers with this property evaluate the field (and thus the derivative in the equation of motion) at the
endpoint of each step. As a result, for a successful integration step, one in which the estimated error was acceptable,
there is no need to call the derivative evaluation - and thus an evaluation of the field is saved.
These methods can be used for a magnetic field by adding a flag to the constructor of G4ChordFinder:
G4MagneticField * pMagField;
G4double stepMinimum = 0.03 * millimeter;
G4bool useFSALstepper= true;
They must then be coupled to a new type of driver G4FSALIntegrationDriver in order to be used in integration.
( This is a derived class of the new base class for drivers G4VIntegrationDriver.)
auto intgrDriver = new
G4FSALIntegrationDriver<NewFsalStepperType>(stepMinimum,
fsalStepper,
fsalStepper->GetNumberOfVariables() );
This also demonstrates one of a new family of (FSAL) steppers G4RK547FEq1 ( others are G4RK547FEq2 and
G4RK547FEq3) which were created to provide an improved equilibrium in integration. When a integration step fails
due to an error above threshold, for some problems there can be oscillations in step size that cause multiple bounces
between a successful and a failed step. The coefficients of these steppers were optimised to reduce these oscillations,
and thus increase the success rate of steps. Initial tests demonstrated a potential small (1-2.5%) performance advantage.
In order to obtain a particular accuracy in tracking particles through an electromagnetic field, it is necessary to adjust
the parameters of the field propagation module. In the following section, some of these additional parameters are
discussed.
When integration is used to calculate the trajectory, it is necessary to determine an acceptable level of numerical
imprecision in order to get performant simulation with acceptable errors. The parameters in GEANT4 tell the field
module what level of integration inaccuracy is acceptable.
In all quantities which are integrated (position, momentum, energy) there will be errors. Here, however, we focus
on the error in two key quantities: the position and the momentum. (The error in the energy will come from the
momentum integration).
Three parameters exist which are relevant to the integration accuracy. DeltaOneStep is a distance and is roughly
the position error which is acceptable in an integration step. Since many integration steps may be required for a
single physics step, DeltaOneStep should be a fraction of the average physics step size. The next two parameters
impose a further limit on the relative error of the position/momentum inaccuracy. EpsilonMin and EpsilonMax im-
pose a minimum and maximum on this relative error - and take precedence over DeltaOneStep. (Note: if you set
EpsilonMin=EpsilonMax=your-value, then all steps will be made to this relative precision.
Listing 4.13: How to set accuracy parameters for the ‘global’ field of the
setup.
G4FieldManager *globalFieldManager;
globalFieldManager = transportMgr->GetFieldManager();
// Relative accuracy values:
G4double minEps= 1.0e-5; // Minimum & value for largest steps
G4double maxEps= 1.0e-4; // Maximum & value for smallest steps
globalFieldManager->SetMinimumEpsilonStep( minEps );
globalFieldManager->SetMaximumEpsilonStep( maxEps );
globalFieldManager->SetDeltaOneStep( 0.5e-3 * mm ); // 0.5 micrometer
G4cout << "EpsilonStep: set min= " << minEps << " max= " << maxEps << G4endl;
We note that the relevant parameters above limit the inaccuracy in each step. The final inaccuracy due to the full
trajectory will accumulate!
The exact point at which a track crosses a boundary is also calculated with finite accuracy. To limit this inaccuracy, a
parameter called DeltaIntersection is used. This is a maximum for the inaccuracy of a single boundary crossing. Thus
the accuracy of the position of the track after a number of boundary crossings is directly proportional to the number of
boundaries.
An additional method to reduce the number of field evaluations is to utilise the new class G4CachedMagneticField
class. It is applicable only for pure magnetic fields which do not vary with time.
G4MagneticField * pMagField; // Your field - Defined elsewhere
It is possible to create a FieldManager which has different properties for particles of different momenta (or depending
on other parameters of a track). This is useful, for example, in obtaining high accuracy for ‘important’ tracks (e.g.
muons) and accept less accuracy in tracking others (e.g. electrons). To use this, you must create your own field
manager which uses the method
void ConfigureForTrack( const G4Track * );
to configure itself using the parameters of the current track. An example of this will be available in exam-
ples/extended/field05.
The default settings of this module are for problems with the physical size of a typical high energy physics setup,
that is, distances smaller than about one kilometer. A few parameters are necessary to carry this information to the
magnetic field module, and must typically be rescaled for problems of vastly different sizes in order to get reasonable
performance and robustness. Two of these parameters are the maximum acceptable step and the minimum step size.
The maximum acceptable step should be set to a distance larger than the biggest reasonable step. If the apparatus in
a setup has a diameter of two meters, a likely maximum acceptable steplength would be 10 meters. A particle could
then take large spiral steps, but would not attempt to take, for example, a 1000-meter-long step in the case of a very
low-density material. Similarly, for problems of a planetary scale, such as the earth with its radius of roughly 6400
km, a maximum acceptable steplength of a few times this value would be reasonable.
An upper limit for the size of a step is a parameter of G4PropagatorInField, and can be set by calling its
SetLargestAcceptableStep method.
The minimum step size is used during integration to limit the amount of work in difficult cases. It is possible that
strong fields or integration problems can force the integrator to try very small steps; this parameter stops them from
becoming unnecessarily small.
Trial steps smaller than this parameter will be treated with less accuracy, and may even be ignored, depending on the
situation.
The minimum step size is a parameter of the MagInt_Driver, but can be set in the constructor of G4ChordFinder, as in
the source listing above.
Known Issues
Currently it is computationally expensive to change the miss distance to very small values, as it causes tracks to be
limited to curved sections whose ‘bend’ is smaller than this value. (The bend is the distance of the mid-point from the
chord between endpoints.) For tracks with small curvature (typically low momentum particles in strong fields) this
can cause a large number of steps
• even in areas where there are no volumes to intersect (something that is expected to be addressed in future
development, in which the safety will be utilized to partially alleviate this limitation)
• especially in a region near a volume boundary (in which case it is necessary in order to discover whether a track
might intersect a volume for only a short distance.)
Requiring such precision at the intersection is clearly expensive, and new development would be necessary to minimize
the expense.
By contrast, changing the intersection parameter is less computationally expensive. It causes further calculation for
only a fraction of the steps, in particular those that intersect a volume boundary.
The effects of a particle’s motion on the precession of its spin angular momentum in slowly varying external fields are
simulated. The relativistic equation of motion for spin is known as the BMT equation. The equation demonstrates a
remarkable property; in a purely magnetic field, in vacuum, and neglecting small anomalous magnetic moments, the
particle’s spin precesses in such a manner that the longitudinal polarization remains a constant, whatever the motion
of the particle. But when the particle interacts with electric fields of the medium and multiple scatters, the spin, which
is related to the particle’s magnetic moment, does not participate, and the need thus arises to propagate it independent
of the momentum vector. In the case of a polarized muon beam, for example, it is important to predict the muon’s spin
direction at decay-time in order to simulate the decay electron (Michel) distribution correctly.
In order to track the spin of a particle in a magnetic field, you need to code the following:
1. in your DetectorConstruction
#include "G4Mag_SpinEqRhs.hh"
2. in your PrimaryGenerator
particleGun->SetParticlePolarization(G4ThreeVector p)
for example:
particleGun->
SetParticlePolarization(-(particleGun->GetParticleMomentumDirection()));
// or
particleGun->
SetParticlePolarization(particleGun->GetParticleMomentumDirection()
.cross(G4ThreeVector(0.,1.,0.)));
sets the muon anomaly by default, the class also comes with the public method:
inline void SetAnomaly(G4double a) { anomaly = a; }
with which you can set the magnetic anomaly to any value you require.
The code has been rewritten (in Release 9.5) such that field tracking of the spin can now be done for charged and
neutral particles with a magnetic moment, for example spin tracking of ultra cold neutrons. This requires the user
to set EnableUseMagneticMoment, a method of the G4Transportation process. The force resulting from
the term, MUSDOTNABLAB, is not yet implemented in GEANT4 (for example, simulated trajectory of a neutral
hydrogen atom trapped by its magnetic moment in a gradient B-field.)
4.4 Hits
4.4.1 Hit
A hit is a snapshot of the physical interaction of a track in the sensitive region of a detector. In it you can store
information associated with a G4Step object. This information can be
• the position and time of the step,
• the momentum and energy of the track,
• the energy deposition of the step,
• geometrical information,
or any combination of the above.
G4VHit
G4VHit is an abstract base class which represents a hit. You must inherit this base class and derive your own concrete
hit class(es). The member data of your concrete hit class can be, and should be, your choice.
As with G4THitsCollection, authors of subclasses must declare templated G4Allocators for their class. They
must also implement operator new() and operator delete() which use these allocators.
G4VHit has two virtual methods, Draw() and Print(). To draw or print out your concrete hits, these methods
should be implemented. How to define the drawing method is described in Polylines, Markers and Text.
G4THitsCollection
G4VHit is an abstract class from which you derive your own concrete classes. During the processing of a given
event, represented by a G4Event object, many objects of the hit class will be produced, collected and associ-
ated with the event. Therefore, for each concrete hit class you must also prepare a concrete class derived from
G4VHitsCollection, an abstract class which represents a vector collection of user defined hits.
G4THitsCollection is a template class derived from G4VHitsCollection, and the concrete hit collection
class of a particular G4VHit concrete class can be instantiated from this template class. Each object of a hit collection
must have a unique name for each event.
G4Event has a G4HCofThisEvent class object, that is a container class of collections of hits. Hit collections are
stored by their pointers, whose type is that of the base class.
#ifndef B2TrackerHit_h
#define B2TrackerHit_h 1
#include "G4VHit.hh"
#include "G4THitsCollection.hh"
#include "G4Allocator.hh"
#include "G4ThreeVector.hh"
private:
G4double fEdep;
G4ThreeVector pos;
public:
inline void SetEdep(G4double edep)
{ fEdep = edep; }
inline G4double GetEdep() const
{ return fEdep; }
inline void SetPos(G4ThreeVector xyz)
{ fPos = xyz; }
inline G4ThreeVector GetPos() const
{ return fPos; }
};
#endif
#include "B2TrackerHit.hh"
G4Allocator is a class for fast allocation of objects to the heap through the paging mechanism. For details of
G4Allocator, refer to General management classes. Use of G4Allocator is not mandatory, but it is recom-
mended, especially for users who are not familiar with the C++ memory allocation mechanism or alternative tools of
memory allocation. On the other hand, note that G4Allocator is to be used only for the concrete class that is not
used as a base class of any other classes. For example, do not use the G4Trajectory class as a base class for a
customized trajectory class, since G4Trajectory uses G4Allocator.
G4THitsMap
G4THitsMap is an alternative to G4THitsCollection. G4THitsMap does not demand G4VHit, but in-
stead any variable which can be mapped with an integer key. Typically the key is a copy number of the volume,
and the mapped value could for example be a double, such as the energy deposition in a volume. G4THitsMap
is convenient for applications which do not need to output event-by-event data but instead just accumulate them.
All the G4VPrimitiveScorer classes discussed in G4MultiFunctionalDetector and G4VPrimitiveScorer use
G4THitsMap.
G4THitsMap is derived from the G4VHitsCollection abstract base class and all objects of this class are also
stored in G4HCofThisEvent at the end of an event. How to access a G4THitsMap object is discussed in the
following section (G4MultiFunctionalDetector and G4VPrimitiveScorer).
G4VSensitiveDetector
G4VSensitiveDetector is an abstract base class which represents a detector. The principal mandate of
a sensitive detector is the construction of hit objects using information from steps along a particle track. The
ProcessHits() method of G4VSensitiveDetector performs this task using G4Step objects as input. In
the case of a “Readout” geometry, objects of the G4TouchableHistory class may be used as an optional input.
Your concrete detector class should be instantiated with the unique name of your detector. The name can be associated
with one or more global names with “/” as a delimiter for categorizing your detectors. For example
myEMcal = new MyEMcal("/myDet/myCal/myEMcal");
where myEMcal is the name of your detector. The detector must be constructed in
G4VUserDetectorConstruction::ConstructSDandField() method. It must be assigned to one
or more G4LogicalVolume objects to set the sensitivity of these volumes. Such assignment must be made in the
same G4VUserDetectorConstruction::ConstructSDandField() method. The pointer should also be
registered to G4SDManager, as described in G4SDManager.
G4VSensitiveDetector has three major virtual methods.
ProcessHits() This method is invoked by G4SteppingManager when a step is composed in the
G4LogicalVolume which has the pointer to this sensitive detector. The first argument of this method is
a G4Step object of the current step. The second argument is a G4TouchableHistory object for the
Readout geometry described in the next section. The second argument is NULL if Readout geometry
is not assigned to this sensitive det