An introduction to the Geant4 Monte Carlo - Indico

advertisement
A practical introduction to the
Geant4 Monte Carlo simulation toolkit
Sébastien Incerti
IN2P3 / CNRS
Université Bordeaux 1
Centre d'Etudes Nucléaires de Bordeaux-Gradignan, France
E-mail : incerti@cenbg.in2p3.fr
Content
Abstract
1.
Introduction
2.
Overview of Geant4
2.1 General Structure of Geant4
2.2 Units of simulation
2.3 Internal units of Geant4
2.4 The G4 prefix
3.
Geant4 installation and user code development
3.1 Geant4 installation
3.2 How to write your own user code
a)
The main() - mandatory
b)
Detector Construction - mandatory
c)
Physics : particles and processes - mandatory
d)
Primary particles - mandatory
e)
User actions - optional
f)
User interface - optional
g)
Visualization – optional
4.
Sample user code in eight steps
a)
STEP 1 : code edition and compilation
b)
STEP 2 : the main()
c)
STEP 3 : define a detector geometry
d)
STEP 4 : define Physics and particles
e)
STEP 5 : generation of primary particles
f)
STEP 6 : collect data
g)
STEP 7 : run the example
h)
STEP 8 : data analysis
5.
Documentation
Acknowledgements
Geant4 collaboration publications
1
A practical introduction to the
Geant4 Monte Carlo simulation toolkit
Abstract
This manuscript to users a brief overview of the Geant4 toolkit required fundamentals and proposes
them to develop quickly a basic Geant4 simulation application, assuming they already have a
reasonable knowledge of C++, so that they can start to work on their own application immediately after
the Do Son school Geant4 tutorial. The slides shown at this tutorial present in details a large panel of
Geant4 functionalities available to users in all Geant4 application domains.
1. Introduction
Simulation plays a fundamental role in various domains and phases of an experimental physics
project : design of the experimental set-up, evaluation and definition of the potential physics output of
the project, evaluation of potential risks to the project, assessment of the performance of the
experiment, development, test and optimization of reconstruction and physics analysis software,
contribution to the calculation and validation of physics results… The Geant4 object oriented toolkit is
a full set of libraries written in C++ allowing the user to simulate his/her own detector system.
Specifying the detector geometry, the software system automatically transports the particles shot into
the detector by simulating the particle interactions in matter based on the Monte Carlo method. Such a
method searches for solutions to mathematical problems using statistical sampling with random
numbers.
Geant4 has initially been developed for the simulation of next generation HEP detectors (ATLAS, Alice,
CMS, LHCb…), it is used widely today for the simulation of the current generation detectors and also
in the space and medical Physics communities. In principle, any experimental system based on
particle interactions could be simulated in Geant4, as long as the corresponding interaction processes
have been implemented in the toolkit. The toolkit is developed by an international collaboration of
physicists and software engineers (about ~100), collaborating all together in a distributed software
production and management environment. It started in 1993 at CERN as a R&D phase (RD44) and
the first release of the software occurred in December 1998. Since then, two released per year are
produced. Geant4 is entirely open, entirely free, regularly updated and can be installed on common
computing platforms (Linux, Windows©, Mac©,…) . It contains pedagogical examples and a user
forum is available from the Internet at the address: http://cern.ch/geant4, which centralizes all
information regarding Geant4. Short, long and specialized Geant4 tutorials are regularly organized
worldwide. Geant4 is the successor of Geant3, which was written in Fortran. Its design, use,
maintenance and portability follow rigorous object oriented programming rules
After a description of the Geant4 structure, we will describe the different steps necessary for the
development of a basic Geant4 application. Code samples are provided.
2. Overview of Geant4
2.1 General Structure of Geant4
Particles are generated in Geant4 from a single point; their trajectory in a given material is computed
from a modeling of the physics processes applicable to them. Each physics process (e. g. proton
ionization in water) is represented through a C++ class, allowing the computation of the probability of
interaction (mean free path) via this process as well as the final state generation of the particle through
this process. Each process can be described by several complementary models (like ionization
parameterized from ICRU reports or from Ziegler’s parameterization) and a single particle can have
different processes (like proton excitation in water, proton ionization in water, …). All secondary
particles are computed the same way. Tracking occurs till the particles are stopped or leave the
simulation volume. Most of the physics quantities (energy, position, energy deposit…) are accessible
at anytime during the simulation and can be extracted according to the user’s needs. Many types of
particles are available as well as physics processes, mainly classified into electromagnetic processes
and hadronic processes. Particles include a “geantino” which is not associated to any interaction
process and can be used to check a user-defined geometry.
2
Geant4 consists of 17 class categories, shown in Fig. 1; each is independently developed and
maintained by a working group. The Geant4 kernel consists of categories in red. It provides central
functionality of the toolkit : handles runs, events, tracks, steps, hits, trajectories, implements Geant4 as
a state machine and provides a framework for : physics processes, visualization drivers, GUIs,
persistency, histogramming/analysis and user code.
.
Fig. 1 : class categories
Categories at the bottom of the diagram are used by virtually all higher categories and provide the
foundation of the toolkit. The global category covers the system of units, constants, numerics and
random number handling. The two categories, material and particle implement facilities necessary to
describe the physical properties of particles and materials for the simulation of particle-matter
interactions. The geometry module offers the ability to describe a geometrical structure and propagate
particles efficiently through it. Above these reside categories required to describe the tracking of
particles and the physical processes they undergo. The track category contains classes for tracks and
steps, used by the processes category, which contains implementations of models of physical
interactions: electromagnetic interactions of leptons, photons, hadrons and ions, and hadronic
interactions. All processes are invoked by the tracking category, which manages their contribution to
the evolution of a track's state and provides information in sensitive volumes for hits and digitization.
Above these the event category manages events in terms of their tracks and the run category
manages collections of events that share a common beam and detector implementation. A readout
category allows the handling of pile-up.
2.2 Units of simulation
Several units of simulation are used in Geant4 and must be introduced to the user before starting to
build an application.

A run
The largest unit of simulation in Geant4 is a run. It is represented by the class G4Run. A run is a
collection of events which are produced under identical conditions. Within a run, the user cannot
change the detector or apparatus geometry, nor the Physics process settings. By analogy to high
3
energy physics, a Geant4 run begins with the command “beamOn”. The detector is inaccessible once
the beam is on. At the beginning of a run, the geometry is optimized for navigation, cross sections are
calculated according to materials in the setup, low-energy cutoff values are defined.

An event
At he beginning of processing, an event contains primary particles (from a generator, a particle
gun, ...), which are pushed onto a stack. During the processing, each particle is popped from the stack
and tracked. When the stack is empty, processing of the event is over. The class G4Event describes
an event. At the end of processing, it has the following objects: list of primary vertices and particles
(the input), hits collections, trajectory collections (optional), digitization collections (optional).

A track
A track is a snapshot of a particle within its environment as the particle moves. The quantities in the
snapshot change at any particular instance, a track has a position and physical quantities, it is not a
collection of steps. A track object (class G4Track) has a lifetime, it is created by a generator or a
physics process (e.g. decay) and it is deleted when it leaves the World mother volume, disappears
(particle decays or is absorbed), goes to zero energy and no “at rest” process is defined or the user
kills it. No track object survives the end of an event (not persistent). The user must take action to store
track record in trajectory.

A step
The step (class G4Step) is the basic unit of simulation; it has two points (pre-step, post-step) – see
Fig. 2 – and it contains the incremental particle information (energy loss, elapsed time, etc.). Each
point contains volume and material information. If the step is limited by a boundary, the end point
stands exactly on the boundary, but is logically part of next volume. Hence boundary processes such
as refraction and transition radiation can be simulated.
Fig. 2 : step definition
In Geant4, each particle has its own list of applicable processes. At the beginning of each step, all of
these processes are queried for a proposed physical interaction length. The process with the shortest
proposed length (in space-time) is the one that occurs. The chosen process also limits the step size.
2.3 Internal units of Geant4
The internal units system used in Geant4 is completely hidden from the user code and from the
Geant4 source code implementation. Each hard-coded number must be multiplied by its proper unit
(e.g. radius=10.0*cm; kineticE=1.0*GeV;). To retrieve a number, it must be divided by the
desired unit: G4cout << eDep / MeV. Most commonly used units are provided, but user can add
new ones. With this system, importing/exporting physical quantities is straightforward and source code
is more readable
2.4 The G4 prefix
For portability “G4” is prepended to raw C++ type names, like G4int, G4double, .... This way,
Geant4 implements correct type for a given architecture. G4cout and G4cerr are ostream objects
defined by Geant4 and G4endl is also provided. Some Graphical User Interfaces are buffer output
streams so that they display print-outs on another window or provide storing/editing functionality. The
user should not use std::cout, etc. Users should not use std::cin for input. Instead use the userdefined commands provided by the intercoms category, e.g. G4UIcmdWithADouble.
3. Geant4 installation and user code development
4
3.1 Geant4 installation
The Geant4 installation procedure is entirely described on the Geant4 web site.
As an alternative, for users who do not wish to bother with the installation, a useful virtualization
configuration based on VMware© can be downloaded freely from http://geant4.in2p3.fr, under the
Geant4 for VMware© section. It contains a fully up-to-date and ready-to-use installation of Geant4
under Scientific Linux 4.5 running under Windows© or Mac OS© with many useful tools – see Fig. 3..
Fig. 3 : Geant4 for WMware website
3.2 How to write your own user code
The steps leading to the development of a full application are presented hereafter.
The user must write a main() which is not provided and needs to use classes to build an application
on top of the Geant4 toolkit; the usual classes are:

Initialization classes
• G4VUserDetectorConstruction
• G4VUserPhysicsList

Action classes
• G4VUserPrimaryGeneratorAction
• G4UserRunAction
• G4UserEventAction
• G4UserStackingAction
• G4UserTrackingAction
• G4UserSteppingAction
Classes names in red bold are mandatory.
a) The main() - mandatory
Geant4 does not provide a main(). However, many examples are provided in the Application
Developers Guide.
In main(), you must construct a G4RunManager (or a class derived from it) and provide to
G4RunManager pointers to mandatory user classes : G4VUserDetectorConstruction,
5
G4VUserPhysicsList and G4VUserPrimaryGeneratorAction. Manager classes broker
transactions between objects within a category and communicate with other managers. They are
singletons. The user will have the most contact with G4RunManager. He/she must register the
detector geometry, the physics list and the particle generator to it. There are other manager classes:
 G4EventManager – handles event processing, user actions
 G4TrackingManager – handles tracks, trajectory storage, user actions
 G4SteppingManager – handles steps, physics processes, hit scoring, user actions
 G4VisManager – handles visualization drivers
Other optional classes can be defined in main() like (G)UI session to define a (graphical) user
interface.
b) Detector Construction - mandatory
The user must derive his/her own concrete class from G4VUserDetectorConstruction. In the
virtual method Construct(), one has to assemble all necessary materials and build the volumes of
the detector geometry. Optionally, one may construct sensitive detector classes and assign them to
the detector volumes, define regions for any part of the detector (for production ranges), define
visualization attributes of detector elements and magnetic (or other) fields.
c) Physics : particles and processes - mandatory
Geant4 does not have any default particles or processes even particle transportation must be explicitly
defined by the user. The user must derive his/her own concrete class from the
G4VUserPhysicsList abstract base class, where he defines all necessary particles, defines all
necessary processes and assign them to the proper particles and defines production threshold (cutoff)
ranges and assign them to the world mother volume and each region.
Geant4 provides many utility classes/methods to assist in the above tasks. Example physics lists exist
for electromagnetic (EM) and hadronic physics.
Cuts are often used in Geant4 applications. A “cut” in Geant4 is a production threshold; it only applies
to physics processes which have infrared divergence, it is not a tracking cut. An energy threshold must
be determined at which discrete energy loss is replaced by continuous energy loss. Specify range
(which is converted to energy for each material) at which continuous energy loss begins, track primary
down to zero range. Above specified range create secondaries, below range add to continuous energy
loss of primary.
d) Primary particles - mandatory
For each event, the user must define all details of initial particle. He must derive a concrete class from
the G4VUserPrimaryGeneratorAction abstract base class. Geant4 provides several ways to do
this: derive your own generator from G4VPrimaryGenerator or use provided generators:
 G4ParticleGun : user provides number, energy, direction, type of particle
 G4HEPEvtInterface, G4HepMCInterface : interfaces to high energy generator programs
 G4GeneralParticleSource : mostly for radioactivity
e) User actions - optional
Several optional user action classes with specific methods may be used for a large variety of purposes.
In particular, the G4USerRunAction, G4UserEventAction and G4UserSteppingAction classes
allows the user to access useful stages in the simulation.

G4UserRunAction
• BeginOfRunAction (define histograms)
• EndOfRunAction (fill histograms)

G4UserEventAction
• BeginOfEventAction (event selection)
6
•
EndOfEventAction (analyze event)

G4UserTrackingAction
• PreUserTrackingAction (create user defined trajectory)
• PostUserTrackingAction

G4UserSteppingAction
• UserSteppingAction (kill, suspend, postpone track)
• BeginOfSteppingAction
• EndOfSteppingAction

G4UserStackingAction
• PrepareNewEvent (reset priority control)
• ClassifyNewTrack
o invoked when new track is pushed
o can set track as urgent, waiting, postpone or kill
• NewStage
o invoked when urgent stack is empty
o event filtering
f)
User interface - optional
Geant4 provides several G4UISession concrete classes for user interface functionalities (e. g.
terminal like interface to interact with Geant4 kernel). You can select the one that is appropriate for
your computing environment. In main(), construct one of them and invoke its sessionStart()
method.
User Interface sessions provided are :
• G4UIterminal : C- and TC-shell like character terminal, widely used
• G4GAG : Tcl/Tk of Java PVM based GUI
• G4JAG : interface to JAS (Java Analysis Studio)
• G4UIBatch : batch job with macro file
g) Visualization - optional
For visualization of the simulated setup and interactions, the user can derive his/her own concrete
class from G4VVisManager according to his/her computing environment. Geant4 provides interfaces
to several graphics drivers:
• DAWN – Fukui renderer
• WIRED – event display
• RayTracer – ray tracing by Geant4 tracking
• OpenGL – the simplest and most used
• OpenInventor
• VRML
4. Sample user code in eight steps
In this section, we show an implementation of source files that can be used for the construction of a
standard simulation application presented during the tutorial, working on the ready-to-use freely
downloadable installation of Geant4 (http://geant4.in2p3.fr). This application shows how to calculate
dose deposits by incident protons in a liquid water spherical cell – see Fig. 4. Code lines are
commented. The corresponding header files are indicated as well.
7
Fig. 4 : graphical output of the proposed user application
a) STEP 1 : Code edition and compilation
Usually, the simulation code is stored in a dedicated project directory (called “simulation” in this
tutorial); in this directory, two subdirectories, “include” and “src”, contain respectively the project
header files and the project source files – see Fig. 5. The main is placed in the project directory in the
Simulation.cc file, as well as a GNUmakefile file that will be used during compilation and link.
Under Linux, the project is simply compiled and linked using the gmake command.
in simulation directory
Simulation.cc
GNUmakefile
run.mac
DetectorConstruction.hh
PrimaryGeneratorAction.hh
PhysicsList.hh
RunAction.hh
EventAction.hh
SteppingAction.hh
DetectorConstruction.cc
PrimaryGeneratorAction.cc
PhysicsList.cc
RunAction.cc
EventAction.cc
SteppingAction.cc
in simulation/include directory
in simulation/src directory
Fig. 5 : location of files in the proposed application
Sample of GNUmakefile file for the compilation and link of the Simulation project; to be placed
in the “simulation” directory:
# Add your project executable name
name := Simulation
G4TARGET := $(name)
G4EXLIB := true
ifndef G4INSTALL
G4INSTALL = ../../..
endif
.PHONY: all
all: lib bin
include $(G4INSTALL)/config/binmake.gmk
8
The project files can be edited with any text editor or Integrated Development Environment tool. In this
tutorial, we use the free snavigator© tool (available from http://sourcenav.sourceforge.net/).
.
b) STEP 2 : the main()
Sample of Simulation.cc file to be placed in the “simulation” directory:
// Geant4 and user header files to include
#include "G4RunManager.hh"
#include "G4UImanager.hh"
#include "G4UIterminal.hh"
#include "G4UItcsh.hh"
#include
#include
#include
#include
#include
#include
"DetectorConstruction.hh"
"PhysicsList.hh"
"PrimaryGeneratorAction.hh"
"RunAction.hh"
"EventAction.hh"
"SteppingAction.hh"
// If one wishes to use vizualisation
#ifdef G4VIS_USE
#include "G4VisExecutive.hh"
#endif
// Main called with optional arguments
int main(int argc,char** argv) {
// Construct the default run manager
G4RunManager * runManager = new G4RunManager;
// Set mandatory user initialization classes
DetectorConstruction* detector = new DetectorConstruction;
runManager->SetUserInitialization(detector);
runManager->SetUserInitialization(new PhysicsList);
// Set mandatory user action classes
runManager->SetUserAction(new PrimaryGeneratorAction(detector));
PrimaryGeneratorAction* primary = new PrimaryGeneratorAction(detector);
// Set optional user action classes
RunAction* RunAct = new RunAction(detector);
runManager->SetUserAction(RunAct);
runManager->SetUserAction(new EventAction(RunAct));
runManager->SetUserAction(new SteppingAction(RunAct,detector,primary));
// Visualization manager
#ifdef G4VIS_USE
G4VisManager* visManager = new G4VisExecutive;
visManager->Initialize();
#endif
// Initialize Geant4 kernel
runManager->Initialize();
// Remove user output files
system ("rm -rf dose.txt");
// Get the pointer to the User Interface manager
G4UImanager* UI = G4UImanager::GetUIpointer();
if (argc==1)
// Define UI session for interactive mode.
{
G4UIsession * session = new G4UIterminal(new G4UItcsh);
// Use of a command macro file
UI->ApplyCommand("/control/execute /home/local1/simulation/run.mac");
session->SessionStart();
delete session;
}
else
// Batch mode
9
{
G4String command = "/control/execute ";
G4String fileName = argv[1];
UI->ApplyCommand(command+fileName);
}
#ifdef G4VIS_USE
delete visManager;
#endif
delete runManager;
return 0;
}
There is no corresponding header file.
c) STEP 3 : define a detector geometry
In the proposed example we define the mandatory mother world volume containing air and a sphere of
liquid water. These materials are defined as well as the geometry. Each volume has three mandatory
descriptions: solid, logic and physical. Visualization attributes as well as step size limitation are
introduced.
Sample of DetectorConstruction.cc file to be placed in the “simulation/src” directory:
#include "DetectorConstruction.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
DetectorConstruction::DetectorConstruction()
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
DetectorConstruction::~DetectorConstruction()
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
// Mandatory implementation of Construct method
G4VPhysicalVolume* DetectorConstruction::Construct()
{
DefineMaterials();
return ConstructDetector();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void DetectorConstruction::DefineMaterials()
{
G4String name, symbol;
G4double density;
G4int ncomponents, natoms;
G4double z, a;
G4double fractionmass;
// Define Elements
// Example: G4Element* Notation = new G4Element ("Element", "Notation", z, a);
G4Element*
H = new G4Element ("Hydrogen", "H", 1. , 1.01*g/mole);
G4Element*
N = new G4Element ("Nitrogen", "N", 7., 14.01*g/mole);
G4Element*
O = new G4Element ("Oxygen" , "O", 8. , 16.00*g/mole);
// Define Material
// Case 1: chemical molecule
// Water
density = 1.000*g/cm3;
G4Material* H2O = new G4Material(name="H2O"
H2O->AddElement(H, natoms=2);
, density, ncomponents=2);
10
H2O->AddElement(O, natoms=1);
// Case 2: mixture by fractional mass
// Air
density = 1.290*mg/cm3;
G4Material* Air = new G4Material(name="Air"
Air->AddElement(N, fractionmass=0.7);
Air->AddElement(O, fractionmass=0.3);
, density, ncomponents=2);
// Vacuum standard definition...
density = universe_mean_density;
G4Material* vacuum = new G4Material(name="Vacuum", z=1., a=1.01*g/mole,
density);
// Display list of defined materials
G4cout << G4endl << *(G4Material::GetMaterialTable()) << G4endl;
// Default materials in setup
defaultMaterial = Air;
waterMaterial = H2O;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4VPhysicalVolume* DetectorConstruction::ConstructDetector()
{
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
// MANDATORY MOTHER “WORLD” VOLUME
WorldSizeX
WorldSizeY
WorldSizeZ
= 50*micrometer;
= 50*micrometer;
= 50*micrometer;
//---Solid
solidWorld = new G4Box("World",
WorldSizeX/2,WorldSizeY/2,WorldSizeZ/2);
//its name
//its size
//---Logic
logicWorld = new G4LogicalVolume(solidWorld,
//its solid
defaultMaterial, //its material
"World");
//its name
//---Physical
physiWorld = new G4PVPlacement(0,
G4ThreeVector(),
"World",
logicWorld,
NULL,
false,
0);
//no rotation
//at (0,0,0)
//its name
//its logical volume
//its mother volume
//no boolean operation
//copy number
// TARGET VOLUME
solidTarget = new G4Sphere("Target",
0,10*micrometer,
0,2*M_PI,
0,M_PI);
//its name
//its minRadius and maxRadius
//its phiMin and deltaPhi
//its thetaMin and deltaTheta
logicTarget = new G4LogicalVolume(solidTarget,
waterMaterial,
"Target");
//its solid
//its material
//its name
physiTarget = new G4PVPlacement(0,
//rotation
G4ThreeVector(0,0,0),// transl
"Target",
//its name
logicTarget,
//its logical volume
physiWorld,
//its mother volume
false,
//no boolean operation
0);
//copy number
// Visualization attributes
11
G4VisAttributes* worldVisAtt= new G4VisAttributes(G4Colour(1.0,1.0,1.0)); //White
worldVisAtt->SetVisibility(true);
logicWorld->SetVisAttributes(worldVisAtt);
G4VisAttributes* targetVisAtt= new G4VisAttributes(G4Colour(0,1.0,1.0)); //Blue
targetVisAtt->SetForceSolid(true);
targetVisAtt->SetVisibility(true);
logicTarget->SetVisAttributes(targetVisAtt);
// User Limits on step size
logicWorld->SetUserLimits(new G4UserLimits(1*micrometer));
logicTarget->SetUserLimits(new G4UserLimits(1*micrometer));
return physiWorld;
}
Sample of DetectorConstruction.hh file to be placed in the “simulation/include”
directory:
#ifndef DetectorConstruction_h
#define DetectorConstruction_h 1
#include
#include
#include
#include
#include
#include
"G4VUserDetectorConstruction.hh"
"G4VPhysicalVolume.hh"
"G4LogicalVolume.hh"
"G4Box.hh"
"G4Sphere.hh"
"G4Material.hh"
#include "G4PVPlacement.hh"
#include "G4UserLimits.hh"
#include "G4VisAttributes.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
// Class deriving from the virtual G4VUserDetectorConstruction class
class DetectorConstruction : public G4VUserDetectorConstruction
{
public:
DetectorConstruction();
~DetectorConstruction();
G4VPhysicalVolume* Construct();
private:
G4double
G4double
G4double
WorldSizeX;
WorldSizeY;
WorldSizeZ;
G4VPhysicalVolume* physiWorld;
G4LogicalVolume*
logicWorld;
G4Box*
solidWorld;
G4VPhysicalVolume* physiTarget;
G4LogicalVolume*
logicTarget;
G4Sphere*
solidTarget;
G4Material*
G4Material*
defaultMaterial;
waterMaterial;
void DefineMaterials();
G4VPhysicalVolume* ConstructDetector();
};
#endif
12
d) STEP 5 : define Physics and particles
The following explains how to define particles and associate to them physics processes. Low energy
electromagnetic processes for gammas, electrons, positrons and light ions are introduced as well as
production cuts.
Sample of PhysicsList.cc file to be placed in the “simulation/src” directory:
#include "PhysicsList.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
PhysicsList::PhysicsList(): G4VUserPhysicsList()
{
// Specify production cut for EM processes
defaultCutValue = 1*nanometer;
cutForGamma
= defaultCutValue;
cutForElectron = defaultCutValue;
cutForPositron = defaultCutValue;
cutForProton
= defaultCutValue;
// Specify verbosity level
SetVerboseLevel(1);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
PhysicsList::~PhysicsList()
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
// ***** Construction of particles
void PhysicsList::ConstructParticle()
{
ConstructBosons();
ConstructLeptons();
ConstructBaryons();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void PhysicsList::ConstructBosons()
{
// gamma
G4Gamma::GammaDefinition();
// optical photon
G4OpticalPhoton::OpticalPhotonDefinition();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void PhysicsList::ConstructLeptons()
{
// leptons
G4Electron::ElectronDefinition();
G4Positron::PositronDefinition();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void PhysicsList::ConstructBaryons()
{
// baryons
G4Proton::ProtonDefinition();
G4AntiProton::AntiProtonDefinition();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
// ***** Processses and particles
void PhysicsList::ConstructProcess()
13
{
AddTransportation();
ConstructEM();
ConstructGeneral();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#include
#include
#include
#include
"G4MultipleScattering.hh"
"G4eIonisation.hh"
"G4eBremsstrahlung.hh"
"G4eplusAnnihilation.hh"
#include
#include
#include
#include
"G4LowEnergyPhotoElectric.hh"
"G4LowEnergyCompton.hh"
"G4LowEnergyGammaConversion.hh"
"G4LowEnergyRayleigh.hh"
#include "G4LowEnergyIonisation.hh"
#include "G4LowEnergyBremsstrahlung.hh"
#include "G4hLowEnergyIonisation.hh"
#include "G4StepLimiter.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void PhysicsList::ConstructEM()
{
theParticleIterator->reset();
while( (*theParticleIterator)() ){
G4ParticleDefinition* particle = theParticleIterator->value();
G4ProcessManager* pmanager = particle->GetProcessManager();
G4String particleName = particle->GetParticleName();
if (particleName == "gamma") {
pmanager->AddDiscreteProcess(new G4LowEnergyCompton);
G4LowEnergyPhotoElectric * LePeprocess = new G4LowEnergyPhotoElectric();
pmanager->AddDiscreteProcess(LePeprocess);
pmanager->AddDiscreteProcess(new G4LowEnergyGammaConversion());
pmanager->AddDiscreteProcess(new G4LowEnergyRayleigh());
// Allow use of step size limitation specified in DetectorConstruction
pmanager->AddProcess(new G4StepLimiter(),-1,-1,3);
} else if (particleName == "e-") {
pmanager->AddProcess(new G4MultipleScattering,-1, 1,1);
G4LowEnergyIonisation * LeIoprocess = new G4LowEnergyIonisation("IONI");
pmanager->AddProcess(LeIoprocess, -1, 2, 2);
G4LowEnergyBremsstrahlung * LeBrprocess = new G4LowEnergyBremsstrahlung();
pmanager->AddProcess(LeBrprocess, -1, -1, 3);
// Allow use of step size limitation specified in DetectorConstruction
pmanager->AddProcess(new G4StepLimiter(),-1,-1,3);
} else if (particleName == "e+") {
pmanager->AddProcess(new
pmanager->AddProcess(new
pmanager->AddProcess(new
pmanager->AddProcess(new
G4MultipleScattering,-1, 1,1);
G4eIonisation,
-1, 2,2);
G4eBremsstrahlung,
-1,-1,3);
G4eplusAnnihilation, 0,-1,4);
// Allow use of step size limitation specified in DetectorConstruction
pmanager->AddProcess(new G4StepLimiter(),-1,-1,3);
} else if ((!particle->IsShortLived()) &&
(particle->GetPDGCharge() != 0.0) &&
14
(particle->GetParticleName() != "chargedgeantino")) {
pmanager->AddProcess(new G4MultipleScattering(),-1,1,1);
G4hLowEnergyIonisation* hLowEnergyIonisation = new G4hLowEnergyIonisation();
pmanager->AddProcess(hLowEnergyIonisation,-1,2,2);
hLowEnergyIonisation->SetElectronicStoppingPowerModel(particle,"ICRU_R49p");
// Allow use of step size limitation specified in DetectorConstruction
pmanager->AddProcess(new G4StepLimiter(),-1,-1,3);
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void PhysicsList::ConstructGeneral()
{ }
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
// ***** Set production cuts
void PhysicsList::SetCuts()
{
if (verboseLevel >0)
{
G4cout << "PhysicsList::SetCuts:";
G4cout << "CutLength : " << G4BestUnit(defaultCutValue,"Length") << G4endl;
}
// set cut values for gamma at first and for e- second and next for e+,
// because some processes for e+/e- need cut values for gamma
SetCutValue(cutForGamma, "gamma");
SetCutValue(cutForElectron, "e-");
SetCutValue(cutForPositron, "e+");
// set cut values for proton and anti_proton before all other hadrons
// because some processes for hadrons need cut values for proton/anti_proton
SetCutValue(cutForProton, "proton");
SetCutValue(cutForProton, "anti_proton");
if (verboseLevel>0) DumpCutValuesTable();
}
Sample of PhysicsList.hh file to be placed in the “simulation/include” directory:
#ifndef PhysicsList_h
#define PhysicsList_h 1
#include "G4VUserPhysicsList.hh"
#include "G4ProcessManager.hh"
#include "G4ParticleTypes.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
class PhysicsList: public G4VUserPhysicsList
{
public:
PhysicsList();
~PhysicsList();
void
void
void
void
SetGammaCut(G4double);
SetElectronCut(G4double);
SetPositronCut(G4double);
SetProtonCut(G4double);
protected:
// these methods construct particles
void ConstructBosons();
void ConstructLeptons();
void ConstructBarions();
15
// these methods construct physics processes and register them
void ConstructGeneral();
void ConstructEM();
// Construct particle and physics
void ConstructParticle();
void ConstructProcess();
// set cuts
void SetCuts();
private:
G4double
G4double
G4double
G4double
cutForGamma;
cutForElectron;
cutForPositron;
cutForProton;
};
#endif
e) STEP 4 : generation of primary particles
This sample shows how to define a simple particle gun shooting protons of 3 MeV just before the
target.
Sample of PrimaryGeneratorAction.cc file to be placed in the “simulation/src”
directory:
#include "PrimaryGeneratorAction.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
// Specify constructed detector in argument
PrimaryGeneratorAction::PrimaryGeneratorAction(DetectorConstruction* DC)
:Detector(DC)
{
// Define particle gun object
G4int n_particle = 1;
particleGun = new G4ParticleGun(n_particle);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
PrimaryGeneratorAction::~PrimaryGeneratorAction()
{
delete particleGun;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void PrimaryGeneratorAction::GeneratePrimaries(G4Event* anEvent)
{
// Get simulation current event number
G4int numEvent;
numEvent=anEvent->GetEventID()+1;
G4double x0,y0,z0,theta,phi,xMom0,yMom0,zMom0,e0;
// Specify kinetic energy
e0 = 3*MeV ;
particleGun->SetParticleEnergy(e0);
// Specify emission direction
theta = 0;
phi = 0;
xMom0 = std::sin(theta);
yMom0 = std::sin(phi);
zMom0 = std::sqrt(1.-xMom0*xMom0-yMom0*yMom0);
particleGun->SetParticleMomentumDirection(G4ThreeVector(xMom0,yMom0,zMom0));
//
x0
y0
z0
Specify emission point
= 0;
= 0;
= -20*micrometer;
16
particleGun->SetParticlePosition(G4ThreeVector(x0,y0,z0));
// Select proton
G4ParticleDefinition* particle=
G4ParticleTable::GetParticleTable()->FindParticle("proton");
particleGun->SetParticleDefinition(particle);
// Example of output display
G4cout
<< "-> Event= " << numEvent
<< " : Theta (mrad)= " << theta/mrad
<< " - Phi (mrad)= " << phi/mrad
<< " - x0 (um)= " << x0/um
<< " - y0 (um)= " << y0/um
<< " - z0 (um)= " << z0/um
<< " - e0 (MeV)= " << e0/MeV
<< G4endl;
// Shoot
particleGun->GeneratePrimaryVertex(anEvent);
}
Sample of PrimaryGeneratorAction.hh file to be placed in the “simulation/include”
directory:
#ifndef PrimaryGeneratorAction_h
#define PrimaryGeneratorAction_h 1
#include
#include
#include
#include
#include
"G4VUserPrimaryGeneratorAction.hh"
"G4ParticleGun.hh"
"DetectorConstruction.hh"
"G4Event.hh"
"G4ParticleTable.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
class PrimaryGeneratorAction : public G4VUserPrimaryGeneratorAction
{
public:
PrimaryGeneratorAction(DetectorConstruction*);
~PrimaryGeneratorAction();
void GeneratePrimaries(G4Event*);
private:
G4ParticleGun*
DetectorConstruction*
};
particleGun;
Detector;
#endif
f)
STEP 6 : collect data
One may use action classes to extract useful information from the simulation. In our example, a run
would represent a set of 103 protons sent to the target, an event would represent one proton among
these 103 protons, a step would represent any interaction step of a proton or all secondary particles
generated in any part of the simulated setup.
Then,
o
o
o
we calculate the target mass at Run Action, that is when the run starts
the total deposited dose by each incident proton as well has the proton beam output position
from the target are stored in a text file for later analysis at the end of Event Action, that is
after each single shot proton has completely interacted with the setup
the dose value is computed for each proton and secondary electrons within the interaction
medium at Stepping Action, as well as the linear energy transfer and beam spread at cell exit
Let’s first start with the largest unit of the simulation: a run.
Sample of RunAction.cc file to be placed in the “simulation/src” directory :
17
#include "RunAction.hh"
#include "G4Run.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
// Specify constructed detector in argument
RunAction::RunAction(DetectorConstruction* det)
:Detector(det)
{
// Initialize total deposited dose
doseTarget=0;
// Compute target mass
G4double radius = 10*1e-6;
G4double density = 1000;
massTarget=(4/3)*M_PI*pow(radius,3)*density;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
RunAction::~RunAction()
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void RunAction::BeginOfRunAction(const G4Run* aRun)
{
// Display run number
G4cout << "---> Run " << (aRun->GetRunID())+1 << " start." << G4endl;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void RunAction::EndOfRunAction(const G4Run*)
{
}
The header file contains accessor methods; these methods are useful when one needs to compute
quantities that must be updated at different stages in the simulation.
Sample of RunAction.hh file to be placed in the “simulation/include” directory:
#ifndef RunAction_h
#define RunAction_h 1
#include "DetectorConstruction.hh"
#include "G4UserRunAction.hh"
#include "globals.hh"
#include <iostream>
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
class G4Run;
class RunAction : public G4UserRunAction
{
public:
RunAction(DetectorConstruction*);
~RunAction();
void BeginOfRunAction(const G4Run*);
void EndOfRunAction(const G4Run*);
// Accessor methods for dose computation
void AddDoseTarget(G4double dose){ doseTarget += dose;}
void SetDoseTarget(G4double dose){ doseTarget = dose;}
G4double GetDoseTarget(){return doseTarget;}
// Accessor methods for mass computation
void SetMassTarget(G4double mT){ massTarget = mT;}
G4double GetMassTarget(){return massTarget;}
private:
18
DetectorConstruction* Detector;
G4double doseTarget;
G4double massTarget;
};
#endif
We now move to the Event simulation unit (one event corresponds to one proton shot).
Sample of EventAction.cc file to be placed in the “simulation/src” directory:
#include "EventAction.hh"
#include "RunAction.hh"
#include
#include
#include
#include
#include
#include
"G4Event.hh"
"G4EventManager.hh"
"G4TrajectoryContainer.hh"
"G4Trajectory.hh"
"G4VVisManager.hh"
"Randomize.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
// Specify run action object in argument
// Initialize a flag for trajectory drawing on visualization window
EventAction::EventAction(RunAction* run)
:Run(run),drawFlag("all")
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
EventAction::~EventAction()
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void EventAction::BeginOfEventAction(const G4Event* /*evt*/)
{
// Dose is accessed through accessor and is set to zero at beginning of new event
Run->SetDoseTarget(0);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void EventAction::EndOfEventAction(const G4Event* evt)
{
// Dose is written in text file at the end of event
if (Run->GetDoseTarget()>0)
{
FILE* myFile;
myFile=fopen("dose.txt","a");
fprintf(myFile,"%e\n",float(Run->GetDoseTarget()) );
fclose (myFile);
G4cout << "
===> The incident particle has reached the targeted cell :" << G4endl;
G4cout << "
-----> total absorbed dose is (Gy) = " << Run->GetDoseTarget() << G4endl;
G4cout << G4endl;
}
else
{
G4cout << "
===> Sorry, the incident alpha particle has missed the targeted cell !"
<< G4endl;
G4cout << G4endl;
}
// Mandatory for trajectory drawing in vizualisation window
if (G4VVisManager::GetConcreteInstance())
{
G4TrajectoryContainer * trajectoryContainer = evt->GetTrajectoryContainer();
19
G4int n_trajectories = 0;
if (trajectoryContainer) n_trajectories = trajectoryContainer->entries();
for (G4int i=0; i<n_trajectories; i++)
{
G4Trajectory* trj = (G4Trajectory*)((*(evt->GetTrajectoryContainer()))[i]);
if (drawFlag == "all")
{
trj->DrawTrajectory(50);
}
else if ((drawFlag == "charged")&&(trj->GetCharge() != 0.))
{
trj->DrawTrajectory(50);
}
}
}
}
Sample of EventAction.hh file to be placed in the “simulation/include” directory:
#ifndef EventAction_h
#define EventAction_h 1
#include "G4UserEventAction.hh"
#include "globals.hh"
class RunAction;
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
class EventAction : public G4UserEventAction
{
public:
EventAction(RunAction*);
~EventAction();
void BeginOfEventAction(const G4Event*);
void
EndOfEventAction(const G4Event*);
private:
RunAction*
G4String
G4int
Run;
drawFlag;
printModulo;
};
#endif
Finally, we extract physics quantities at the step level (interaction step of any particle generated in the
simulation).
Sample of SteppingAction.cc file to be placed in the “simulation/src” directory:
#include
#include
#include
#include
"SteppingAction.hh"
"RunAction.hh"
"DetectorConstruction.hh"
"PrimaryGeneratorAction.hh"
#include "G4SteppingManager.hh"
#include "G4VTouchable.hh"
#include "G4VPhysicalVolume.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
// RunAction, DetectorConstruction, PrimaryGeneratorAction objets in argument
SteppingAction::SteppingActio
(RunAction* run,DetectorConstruction* det,PrimaryGeneratorAction* pri)
:Run(run),Detector(det),Primary(pri)
{ }
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
SteppingAction::~SteppingAction()
20
{ }
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void SteppingAction::UserSteppingAction(const G4Step* s)
{
// Dose incrementation
if (s->GetPreStepPoint()->GetPhysicalVolume()->GetName() == "Target")
{
G4double dose = (e_SI*(s->GetTotalEnergyDeposit()/eV))/(Run->GetMassTarget());
Run->AddDoseTarget(dose);
}
// Beam spread after target
if ( (s->GetTrack()->GetDynamicParticle()->GetDefinition() ->GetParticleName() == "proton")
&& (s->GetPreStepPoint()->GetPhysicalVolume()->GetName() == "Target")
&& (s->GetPostStepPoint()->GetPhysicalVolume()->GetName() == "World")
)
{
FILE* myFile;
myFile=fopen("dose.txt","a");
fprintf
( myFile,"%e %e %e ",
(s->GetTrack()->GetPosition().x())/micrometer,
(s->GetTrack()->GetPosition().y())/micrometer,
(s->GetTrack()->GetPosition().z())/micrometer
);
fclose (myFile);
}
// Linear energy transfer computation
if ( (s->GetPreStepPoint()->GetPhysicalVolume()->GetName() == "Target")
&& (s->GetPostStepPoint()->GetPhysicalVolume()->GetName() == "World")
&& (s->GetTrack()->GetDynamicParticle()->GetDefinition() ->GetParticleName() == "proton")
)
{
FILE *myFile;
myFile=fopen("dose.txt","a");
fprintf(myFile,"%e ",(s->GetTotalEnergyDeposit()/keV)/
(s->GetStepLength()/micrometer));
fclose (myFile);
}
}
g) STEP 7 : run the example
After the code has been compiled with gmake, it can be executed with the command:
$G4WORKDIR/bin/Linux-g++/Simulation
As specified in the Simulation.cc code, the user interface will read built-in commands given in the
run.mac file located in the “simulation” directory. This file specifies in particular that 103 protons will
be shot towards the target.
Sample of macro file run.mac file to be placed in the “simulation” directory:
# Visualization enabled
/vis/scene/create
/vis/scene/add/volume
/vis/sceneHandler/create OGLIX
/vis/viewer/create
/vis/viewer/set/viewpointThetaPhi 70 10
# Storing of trajectories
/tracking/storeTrajectory 1
/vis/scene/endOfEventAction accumulate
21
# Verbose control
/tracking/verbose 0
/run/verbose 0
# Shoot 1000 protons
/run/beamOn 1000
A description of all command is accessible by typing help at the prompt in the Geant4 user session.
The user can define his/her own commands for a better interactivity with his/her application.
h) STEP 8 : data analysis
Geant4 does not endorse or support particular analysis packages. However, an abstract analysis
interface is provided : AIDA (Abstract Interfaces for Data Analysis). It will be built and linked to your
application if the environment variable $G4ANALYSIS_USE is set to 1. AIDA headers must be installed
in the code where the analysis is set up, with #include AIDA/AIDA.h. The user must then use
AIDA-compliant analysis tools. More AIDA information is available at http://aida.freehep.org. The
OpenScientist
Lab
package
is
an
AIDA-compliant
Analysis
Package
(http://www.lal.in2p3.fr/OpenScientist). An example using Open Scientist can be found in
$G4INSTALL/examples/extended/analysis/AnaEx01. It allows in particular the production of result files
containing histograms, tuples, …in PAW (hbook) or ROOT (root) format, widely used in the community
of high energy physics. This package is already installed on the downloadable VMware© installation of
Geant4. Several Geant4 examples (see next paragraph) illustrate how to use these libraries, allowing
the creation of such histograms directly in Geant4.
In this tutorial, we simply create output result text files directly in the Geant4 application and analyze
them with the ROOT package, outside the simulation. For this purpose, we use the simple ROOT
macro file plot.C to plot the dose distribution, the linear energy transfer distribution at target exit and
the beam spread. Gauss fits are also applied. This macro reads the text file dose.txt created by the
application and placed in the “simulation” directory. The plot.C file is located in the
“simulation” directory and can be edited with any text editor. Open a ROOT session in the
simulation “simulation” by typing root and at prompt and execute the macro file with the
command .X plot.C. Typical results are shown in Fig. 6 for 106 incident 3 MeV protons.
Fig. 6 : application results analyzed with ROOT
The OpenScientist package developed at IN2P3 (http://openscientist.lal.in2p3.fr/)
5. Documentation
Extensive Geant4 documentation is available from the Geant4 web site : http://cern.ch/geant4.
In particular, a full documentation is accessible from the User Support section (Fig. 7) of this web site,
including detailed installation instructions, an application developer guide, a toolkit developer guide, a
physics reference manual as well as a software reference manual. An interactive hypernews forum is
available for information sharing and question asking as well as a code browser.
22
Seven easy novice examples ranging from very easy to complex are available in the Geant4 source
code in the $G4INSTALL/examples directory. They can be used as templates for your own
application. Extended examples for testing and validation, demonstrating Geant4 tools, extending
Geant4 are also provided. Advanced Examples show practical applications and examples from outside
HEP (space, medical, etc. Their description is accessible from the html version of the application
developer guide.
Fig. 7 : user support section of the Geant4 web site
Acknowledgements
We would like to thank the Do Son school organizers, in particular Vincent Breton, for their kind
invitation to participate to the school. We also would like to thank the whole Geant4 collaboration for
the preparation the Geant4 tutorial material from which the presented slides and this manuscript are
extracted. This contribution would not have been possible without the support of IN2P3.
Geant4 collaboration publications
[1] S. Agostinelli et al., Geant4 - a simulation toolkit, Nucl. Instrum. Meth. A 506 (3) (2003) 250-303
[2] J. Allison et al., Geant4 Developments and Applications, IEEE Trans. Nucl. Sci. 53 (1) (2006) 270278
The Geant4 collaboration, Bordeaux, France, 11/2005
23
http://geant4.cern.ch
24
Download