The energy deposition simulation is a wrapper around the GEANT4 particle propagation simulation and is intended as a tool to simulate all of the particle propagation and geometry related issues. GEANT4 is an excellent toolkit, but it requires you to provide the main programs, as well as the input, and output tools. This has proven to be a very good design choice; unfortunately, it means that there is no standard wrapper code. I've found myself using (and writing) almost identical input/output wrappers several times, so edep-sim is intended to provide a general starting point and allow users to concentrate on the physics. As a standalone program, edep-sim provides a simple ROOT based file format which will record the output of GEANT4. It can also be linked as a library into another application, and makes the same information as a class.
This documentation assumes that you have a passing familiarity with how to write GEANT4 macro control files.
Where it's available (and in particular for argon), the simulation implements a fairly detailed model of the energy deposited as ionization and non-ionizing (e.g. scintillation) energy loss. The liquid argon model uses using the NEST model (M Szydagis et al 2013 JINST 8 C10003 and references therein). All other models use the EM saturation model provided by geant 4.
Input file translators are provided for several standard input file formats. In particular, this support input from both NEUT and GENIE. The GENIE input is read using the RooTracker format.
Be aware that the sequence of random numbers depends on the floating point accuracy of the machine, so given runs are machine dependent and may not be reproducible.
It's quite possible that you are working in an environment where edep-sim
has already been installed (check with your local expert). However, if you
are installing it from source, you need to run the local setup and then
build it. Assuming you've already cloned it from someplace and have the
source directories, then source
the setup script in the top level
directory to define some simple aliases and define necessary environment
variables. The only explicitly external requirements are that GEANT and
ROOT must be available (and found by cmake). The setup script will make
sure that they can be located (using thisroot.sh
and geant4.sh
).
. setup.sh
The simulation is built using cmake. CMake can be run by hand, but there
is a script in the build directory that can be run using the edep-build
alias. The build has been tested with GEANT4 10.2 and ROOT 6.08, but it
will probably build with any recent version of GEANT4 and ROOT.
If you have doxygen installed in a place where cmake
can find it, then
you can compile using
edep-build doc
which will create the html sub-directory containing Doxygen class documentation. The html is in the build directory.
The edep-sim code will build with very standard installations of GEANT4 and ROOT, but a few non-default options are needed:
-
Requires GEANT4 GDML Persistence: "-DGEANT4_USE_GDML=ON"
-
Recommended GEANT4 Datafiles: "-DGEANT4_INSTALL_DATA=ON"
These options are already turned on in most GEANT4 and ROOT installations.
If you are compiling ROOT and GEANT4 by hand, following will generally work (changed for your versions):
tar xvzf root_v6.22.00.source.tar.gz
mkdir root-6.22.00-install root-6.22.00-build
cd root-6.22.00-build
cmake -DCMAKE_INSTALL_PREFIX=../root-6.22.00-install ../root-6.22.00
make
make install
tar xzvf geant4.10.06.p02.tar.gz
mkdir geant4.10.06.p02-install geant4.10.06.p02-build
cd geant4.10.06.p02-build
cmake -DCMAKE_INSTALL_PREFIX=../geant4.10.06.p02-install \
-DGEANT4_INSTALL_DATA=ON \
-DGEANT4_USE_GDML=ON ../geant4.10.06.p02
make
make install
This is actually just a generic cmake build system, so everything can be done by hand. It's a usual cmake build, but you need to make sure root and geant are "in the path". Assuming that you have the source in "the-edep-sim-directory", will build in "the-build-directory", and want to install in "the-install-directory", the commands are:
cd the-build-directory
cmake -DCMAKE_INSTALL_PREFIX=the-install-directory the-edep-sim-directory
make
make doc
make install
You can make sure that ROOT and GEANT are correctly setup using
source thisroot.sh
source geant4.sh
The detector simulation is run using the edep-sim
program which
is a standard GEANT main program with minimal customization. This
can be run in any directory. You will need to provide some sort of event
kinematics generator (NEUT, NUANCE, NEUGEN, GPS, &c). The preferred input
format is a rooTracker tree, but you can also use the text based tracker
input format (NUANCE may be the only program in the world still using this
format. It was developed as a standard kinematics format for the IMB3
experiment in about 1990)
The program is generally run from the command line:
edep-sim [options] macro-file.mac [macro-file.mac] ...
with one or more macro files. The output file will contain a root tree of event information and a TGeoManager object summarizing the simulated geometry. There are example input files in the inputs sub-directory.
Some important options:
- -e : Add a
/run/beamOn <n>
command after the last macro is processed so thatn
events are generated. - -g : Load a gdml file. This is equivalent to the
/edep/gdml/read
macro command. - -o : Write the output to the root file. This is equivalent
to the
/edep/db/open
macro command. - -u : Add a
/edep/update
command before the first macro is processed. - -p : Set the physics list (see G4 documentation for the available lists.
- -C : Toggle checking for overlaps in the geometry.
If edep-sim
is run with the -h
option, it will print a help message.
There are example macro files in the "inputs" subdirectory.
EDepSim uses some GEANT4 macro files to control how it is run. These are not usually visible to the user, but occasionally the executable can't find them. In that case, you can specify the location by setting the EDEPSIM_ROOT environment variable to the root of the INSTALLATION area. For example
export EDEPSIM_ROOT=$(dirname $(which edep-sim))/..
should find the right location for the necessary files.
An example of a command line is
edep-sim -o my-output.root -g geometry.gdml -u -e 100 muon-10000.mac
which will write 100 events to my-output.root
using the geometry in
my-geometry.gdml
according to the commands in muon-10000.mac.
The muon-10000.mac might contain:
####################################################################
#
# Generate a 10000 MeV muon beamed in the down stream direction.
#
# Define the particle and it's energy.
/gps/particle mu+
/gps/energy 10000 MeV
# Set the position of the particle gun.
/gps/position 0.0 0.0 -10.0 m
# This generates the direction of the muon. This aims
# the particle downstream with the directions uniformly distributed in
# a 5 deg cone around the Z axis.
/gps/ang/type iso
/gps/ang/maxtheta 5 deg
/gps/ang/rot1 1 0 0
/gps/ang/rot2 0 -1 0
The output file is a standard root tree. A simple example of how to read the tree can be found in the test sub-directory (see the testTree.sh) script and the associated readTree.C file.
The output is generic root with two keys: EDepSimGeometry
for a
TGeoManager object with the simulated geometry, and EDepSimEvents
for a
tree with the event data. It can be read with any of your favorite ROOT
tree access techniques (e.g. MakeProject
). There are some ROOT ".C"
macro files in the tools directory, written to help test and debug the MC,
in the "tools" directory. They can be helpful to process the file (and do
simple event displays).
All of the values in the output file are given in CLHEP units. Namely, distances are in millimeters, energies are in MeV, and times are in nanoseconds. The output file uses the global coordinate system defined by the input geometry. Be aware that in the saved TGeoManager object, the masses and densities are also in CLHEP units, so that 1 kilogram equals 6.24x10^24^ MeV ns^2^ mm^-2^, and densities are in units of 6.24x^24^ MeV ns^2^ mm^-5^.
In addition to accessing the tree using "normal" root methods, you can also directly line the edepsim_io library. The i/o library can be compiled without depending on GEANT4, and can be used via CMAKE. If the EDepSim package is in your path, the
find_package(EDepSim)
in a CMakeLists.text file will include the edepsim_io library as the EDepSim::edepsim_io. For example
# Configure the dependencies
find_package(EDepSim)
add_executable(my-code myCode.cc)
target_link_libraries(my-code
PUBLIC EDepSim::edepsim_io)
This will automatically include any ROOT dependencies needed by edepsim_io, and GEANT4 if necessary.
The edep-sim
executable produces a root TTree
containing a single
branch. You can access this from either C++, a root macro or python. For
C++ based access, you must include the TG4Event.h header, and then attach
to the tree.
#include "TG4Event.h"
/// Get the event tree.
TTree* events = (TTree*) gFile->Get("EDepSimEvents");
/// Set the branch address.
TG4Event* event=NULL;
events->SetBranchAddress("Event",&event);
/// Get event zero.
events->GetEntry(0);
Or in python:
# Get the event tree.
events = tFile.Get("EDepSimEvents")
# Set the branch address.
event = ROOT.TG4Event()
events.SetBranchAddress("Event",ROOT.AddressOf(event))
# Get event zero.
events.GetEntry(0)
print "event number", event.EventId
print "number of trajectories", event.Trajectories.size()
The detailed documentation is available via doxygen, but is summarized here.
The main event class (TG4Event) is a data-only class defined in the
TG4Event.h
include file. It has the following fields which should be
access using the matching accessor:
-
EventId: The event number
-
RunId: The run number
-
Primaries: The GEANT4 primary particles (A vector of TG4PrimaryVertex)
-
Trajectories: The GEANT4 particle trajectories (A vector of TG4Trajectory)
-
SegmentDetectors: The energy deposition information (A map keyed by sensitive detector name, containing a vector of TG4HitSegments).
The trajectory information for each particle simulated in GEANT4 is contained in a TG4Trajectory object. This is a data-only class defined in TG4Trajectory.h. It has the deprecated public fields, and accessor that should be used instead of the field:
-
TrackId [GetTrackId()]: The track identifier for this particular trajectory. This is a positive integer.
-
ParentId [GetParentId()]: The track identifier for the parent of this trajectory. This is an integer. If the track is from a primary particle, the parent identifier will be zero.
-
Name [GetName()]: The type of particle creating this track.
-
PDGCode [GetPDGCode()]: The PDG MC code for the type of particle creating this track.
-
InitialMomentum [GetInitialMomentum()]: The initial momentum of track (A TLorentzVector).
-
Points: This has type TrajectoryPoitns and is equivalent to vector of TG4TrajectoryPoints along the track.
The TG4TrajectoryPoint is a data-only class with the following information.
-
Position [GetPosition()]: The position of the trajectory point (A TLorentzVector)
-
Momentum [GetMomentum()]: The momentum (a TVector3) as the trajectory leaves the point.
-
Process [GetProcess()]: The process type which created this point. These are defined by GEANT4.
-
Subprocess [GetSubprocess()]: The subprocess type which create this point. These are defined by GEANT4.
There are several macro commands provided which will allow the saved trajectories to be filtered before they are saved to an output file. Check the edep-sim-command-list.txt file and search for the "/edep/db/set/" directory for details.
The energy deposition in each sensitive detector is recorded using the TG4HitSegment class. This class records the starting and stopping position of each energy deposition step (the energy is not deposited at a point). It also records the particle depositing the energy, as well as the primary particle, or ultimate parent, associated with the energy deposit.
The generated hit segment contains fields with the following
information. The public
fields are deprecated, and you should
use the accessors instead of the field:
-
Contrib: A vector of track identifiers which contributed to this hit segment. There is almost always only one contributor, but for certain run settings there may be several particles associated with one segment (this is a very unusual situation). This has type TG4HitSegment::Contributors and is equivalent to a vector of integers.
-
PrimaryId [GetPrimaryId()]: The track identifier for the primary particle creating this hit.
-
EnergyDeposit [GetEnergyDeposit()]: The total energy deposited over the length of this track. The energy should be assumed to have been uniformly deposited along the segment (not at the beginning or the end). This is the total dEdX of the track between the start and stop position of the segment.
-
SecondaryDeposit [GetSecondaryDeposit()]: The "secondary" energy deposited over the length of the segment. This is generally used to help simulate the energy emitted as scintillation light vs the total dE/dX of the track. In other words, when the secondary deposit simulation is turned on, This is the energy deposited as optical photons. The remaining energy is usually deposited as ionization. For example, in liquid argon, the mean number of quanta crated will be N
q= (EnergyDeposit/WAr), where WAris the work function for argon (typically 19.5 eV). The number of optical photons is Nph= Nq* SecondaryDeposit/EnergyDeposit, and the number of ionization electrons is Ne= Nq- Nph. For liquid argon the Doke-Birks model as implemented by NEST used. -
TrackLength [GetTrackLength()]: The total track length between the start and stop points (as estimated by GEANT4)
-
Start, Stop [GetStart(), GetStop()]: The starting and stopping points of the segment (TLorentzVector).
The hit segment length is determined by a combination the GEANT4
physics step and a segment target length. The GEANT4 physics step
length is determined by the interaction cross sections, the energy
loss, and the multiple scattering. The physics step length control
parameters (but not explicitly the step length) can be controlled
using the macro commands in the /process/eLoss/
and
/process/msc/
directories. A geometry can set an explicit step
length limit for a logical volume (see below). The steps taken by
GEANT4 are summarized by hit segments (see above), that will combine
steps until the next step would make the segment longer than the
target length. The target length of the hit segment can be controlled
using the /edep/hitLength
macro, and the maximum sagitta of the
segment can be controlled using the /edep/hitSagitta
macro.
Notice that the segment will grow until it is approximately as long as
the target hit length value, but depending on the underlying
simulation, will probably be shorter, or longer than the target. Typically,
the segment length should be a little smaller than the resolution of the
detector. Hit segments will not cross geometry boundaries.
Note: All of the step length controls must occur during the
PREINIT
stage. In practice, this means they need to occur
before the /edep/update
command has been given. You can
explicitly add the /edep/update
command to the job macro, or it
will be added automatically using the -u command which will insert an
/edep/update
before running the macro on the command line.
It is important to notice that the hit segments can have a length that is long compared to the resolution of the detector, but the "diameter" of the segment controlled by the hitSagitta, energy loss and multiple scattering parameters will be small so the segment can be represented by a straight line between the starting and stopping points. The hitSagitta and physics stepping parameters should be set so that that the maximum displacement of the track from a straight line is small compared to the detector resolution.
There is a simple Eve based event display that will read the ROOT output
file and. It is not a complete event display, but can be useful to help
debug geometries, and input kinematics files. It can also be helpful to
understand what events "look like". It can be run using the edep-disp
command. A help message is printed if it is run without any arguments.
The detector geometry can be specified in more than one way. The
first is to compile it into the executable by defining the appropriate
EDepSimBuilder classes. There is an example of a simplified geometry
for the CAPTAIN LArTPC contained in the source. The alternative is to
import a GDML definition using the /edep/gdml/read
macro
command. The gdml file can be specified from the command line using
the -g
option
edep-sim -g geometry.gdml -o output.root macro-file.mac
Several auxiliary fields are parsed to help describe volumes in the detector geometry and attach more meaning to the GDML description. For example, here is a simple LAr detector description that is attached as a sensitive detector, and has both an electric and a magnetic field.
<volume name="LArD_lv">
<materialref ref="LAr"/>
<solidref ref="LArD"/>
<physvol>
<volumeref ref="LArMod_lv"/>
<positionref ref="LArD_el0_pos"/>
<rotationref ref="identity"/>
</physvol>
<auxiliary auxtype="SensDet" auxvalue="LArD"/>
<auxiliary auxtype="EField"
auxvalue="(500.0 V/cm, 1.0 V/m, 500.0 V/cm)"/>
<auxiliary auxtype="BField
" auxvalue="(2.0 tesla, 3.0 T, 1.0 G)"/>
<auxiliary auxtype="StepLimit" auxValue="1.0 cm"/>
</volume>
Sensitive logical volumes recording energy deposition are specified using the "SensDet" type. It takes a value which is the name of the sensitive detector that will record the deposition.
<auxiliary auxtype="SensDet" auxvalue="MySensDetName"/>
In the example above, the energy is recorded in a sensitive detector named
MySensDetName
. After an event is simulated, the deposited energy is
recorded in an internal map keyed by the sensitive detector name, and with
a value that is a vector of TG4HitSegment objects. See the example in the
./test
subdirectory for how to read this information from the output
tree.
Uniform electric and magnetic fields can be set using the EField
and
BField
auxiliary types. The value for each is the field vector in
the volume specified by the X, Y and Z components (global
coordinates). It is assumed that the field applies to all of the
daughter volumes.
<auxiliary auxtype="EField" auxvalue="(500.0 V/cm, 1.0 V/cm, 500.0 V/cm)"/>
<auxiliary auxtype="BField" auxvalue="(2.0 T, 3.0 T, 1.0 G)"/>
The possible units for the electric field are volt/cm
, volt/m
,
V/cm
, and V/m
. You should specify a unit. If no units are
provided, it is assumed that the units are volt/cm
.
The possible units for the magnetic field are tesla
, gauss
, T
,
and G
. If no units are provided, it is assumed that the units are
tesla
.
Arbitrary electric and magnetic fields can be set using the
ArbEField
and BField
auxiliary types. The value for each is the
name of the grid file which specifies the value of the field at a set
of X, Y, and Z grid points (global coordinates).
<auxiliary auxtype="ArbEField" auxvalue="efield_grid_file.txt"/>
<auxiliary auxtype="ArbBField" auxvalue="bfield_grid_file.txt"/>
The grid file is specified in the following format:
# First row is a header defining the origin offset and grid spacing
# in each position coordinate X, Y, Z then hX, hY, hZ.
-2600.00 -4200.00 12300.00 200.00 200.00 200.00
# Next, each row contains one grid point: x,y,z,fx,fy,fz,f
0.00 0.00 000.00 0.40 0.00 0.00 0.40
0.00 0.00 200.00 0.40 0.40 0.00 0.57
0.00 0.00 400.00 0.40 0.40 0.40 0.69
...and so on...
The position, XYZ, is specified in mm
, the electric field is
specified in V/cm
, and the magnetic field is specified in T
. The
grid spacing for each axis can be different.
FX, FY, FZ are the magnitudes of the fields in the X,Y,Z directions and F is the total magnitude of the field vector. The Z coordinate iterates first, then Y, and finally X when incrementing the lines.
To save space, the position of each point is not stored. Instead the
position is calculated using the offset and the index of the array: x = hx * i + offset_x
, where hx is the grid spacing in x, i is the ith
element of the array, and offset_x is the offset specified in the
first line for the x coordinate.
Comment lines starting with the #
character are supported in the
grid file. They will be ignored when parsing the file.
The display properties for the logical volume can be set using the Color
and Opacity
auxiliary types.
The color of a volume can be set in two forms. The first form allows a few primary colors to be set by names. These colors are defined by the G4Colour class and are one of the list "white", "gray", "grey", "black", "brown", "red", "green", "blue", "cyan", "magenta", and "yellow". A color can be set with one of these as the value.
<auxiliary auxtype="Color" auxvalue="red"/>
The color can also be set as an RGB triplet, or an RGBA quartet.
<auxiliary auxtype="Color" auxvalue="(1.0,0.0,0.0)"/>
<auxiliary auxtype="Color" auxvalue="(1.0,0.0,0.0,0.5)"/>
The fourth component of the color is the "alpha" which can run between zero and one. A value of zero is transparent, and a value of one is opaque. The alpha value can also be set using the opacity auxiliary type.
<auxiliary auxtype="Opacity" auxvalue="0.5"/>
The step limit can be set using
The value takes a number and a unit.
Detector materials are described using the standard GEANT4 methods, but with a few minor extentions to simplify usage. For geometries that are coded using the native GEANT4 routines (i.e. implementing a specialized UserDetectorGeometry class and built by deriving builders from EDepSimBuilder) should mostly depend the standard GEANT4 interface.
Internally, GEANT4 manages the Birks constant for a material using stippets that look like
G4Material* material = G4Material::FindMaterial("Scintillator");
// Set the Birks' constant for a material
double birks_constant = 0.12;
material->GetIonization()->SetBirksConstant(birks_constant);
// Get the Birks' constant for a material
birks_constant = material->GetIonization()->GetBirksConstant();
Unfortunately, this interface is not exposed when defining materials using GDML.
As a work-around, there is an edep-sim
macro that will
override the Birks' constant for an existing material. The macro must
be used immediately before using the /edep/update
macro. The
Birks' constant is set using
/edep/material/birksConstant [material] [value] [unit]
where material
is the name of an existing material, value
is a floating point number (e.g. 0.126), and unit
is a string
describing the units (e.g. mm/MeV
). The unit must be a
[Length]/[Energy]
, and must contain a '/
', however there is
only minimal error checking to make sure the result is reasonable.
For standard polystyrene (which must have already been defined), the
Birks' constant would be set using
/edep/material/birksConstant Polystyrene 0.126 mm/MeV
/edep/update
An error is thrown if the material has not been defined, or if the units are malformed (e.g. the unit is missing a '/')
While GDML does not provide an element that will directly set the Birks' constant value for a material, it does define and interface allowing material properties to be set. For instance,
<define>
<matrix name="BIRKSVALUE" coldim="1" values="0.126"/>
</define>
<materials>
<material formula="Scintillator">
<property name="BIRKSCONSTANT" ref="BIRKSVALUE"/>
</material>
</materials>
will add a constant material property to the material properties table
for the "Scintillator" material. By default, GEANT4 will ignore these
extra properties, but edep-sim
has been modified to look for
specific properties and to use them to set values in the G4Material
class. Properties that will be interpreted are
BIRKSCONSTANT
-- Set the Birks' constant value. The value must be in units ofmm/MeV
.
The simulation is developed as a library separated from a main program wrapping the library. The entire main program is only a few hundred lines long, of which about twenty lines are needed to actually setup and run the simulation. It is relatively straight forward to take this and include edep-sim into a separate package. The example main program (i.e. app/edepSim.cc) is commented and the library is started beginning at about line 230.
The simulation is available for CMake projects using the find_package macro. It can be included using
find_package(EDepSim)
and then added to an executable using the
target_add_library(your-target PUBLIC EDepSim::edepsim)
which will add all of the required dependencies.
If you only want to use the i/o library, and don't need access to geant4, you can use
target_add_library(your-target PUBLIC EDepSim::edepsim_io)
which only depends on ROOT.
The primary particle kinematics are controlled using the /generator
macro
commands.
## Don't repeat the random number sequence (not limited to GENIE input)
/edep/random/timeRandomSeed
## Replace this with the name of a GENIE rooTracker file
/generator/kinematics/rooTracker/input <rooTracker-file>
## Use the rooTracker input format. This is directly supported by GENIE.
/generator/kinematics/set rooTracker
## Place one interaction per event
/generator/count/fixed/number 1
/generator/count/set fixed
## Distribute the events based on the density of the material. When done
## this way, the composition of the detector is ignored, so it's not the
## best way for physics, but it's good for an example since you don't
## need to syncronize the GENIE and EDEPSIM geometries.
/generator/position/set density
## Make sure EDEPSIM updates the kinematics generator.
/generator/add
The primary vertex timing is often taken directly from the kinematics generator, or set to be at time equal to zero, but it can be overridden to simulation the event spill. To control the primary vertex timing distribution use the following macro commands (substitute the values you want.
Set the vertices to occur at a specific time
/generator/time/fixed/time 100 ns
/generator/time/set fixed
Let the vertex use the time provided by the kinematics generator. This is the default behavior, and usually results in a vertex time of zero
/generator/time/set free
Distribute the event according to a beam spill timing distribution. The following macros will approximate the FNAL beam structure.
/generator/time/spill/start 0 ns
/generator/time/spill/bunchCount 1000
/generator/time/spill/bunchSep 10 ns
/generator/time/spill/bunchLength 5 ns
/generator/time/set spill
There are further commands to provide limited control over the power of each bunch.
This describes how to use the GPS particle source provided by GEANT. It is part of GEANT, so deviates from the normal way that EDEPSIM accepts kinemtics.
This particle source is incredibly useful, but extremely is idiosyncratic. It's also has relatively little documentation, and the documentation that exists is often misleading. This page attempts to cover the basics of using GPS to write GEANT macros that produce samples of events to be used for testing ND280 software (meaning I got annoyed enough at the GPS documentation make notes).
The general particle source as developed for the ESA, so it tends to use astronomical conventions. This is particularly relevant with describing angles and directions. Astronomers (and apparently space scientists) tend to speak about where the particle is coming from, not where it is going. This makes for an odd match when dealing with a particle simulation which is concerned with tracking the particles, and not determining the position of the source. Once you get beyond the idiosyncratic definitions (which are at odds with the rest of GEANT), the GPS can be used to create almost any sort of particle distribution for testing programs.
The particle being simulated is set using the /gps/particle
command. The
particles are set by name, and can be any of the ones simulated by GEANT.
The most common particles are mu-
, mu+
, pi+
, pi-,
e-,
e+,
gamma, and
proton`. For example
/gps/particle mu-
/gps/particle pi+
/gps/particle gamma
/gps/particle proton
The vertex position is controlled using the commands in the /gps/pos/ subdirectory. The most useful distributions are the Point, Plane, and Volume. To generate a point source the following commands are used
/gps/position 0 0 -50 cm
/gps/pos/type Point
where the first line specifies that this is a point and the second line
specifies the position. Notice that all three coordinates must have the
same units. For a point source, it's not necessary to specify the type.
GEANT is very inconsistent about the spelling of centre
vs center
with
19 classes using centre
and 33 using center
. You just have to check
which version is being used by which class. For consistency, avoid the
problem by prefering /gps/position
and avoiding /gps/pos/centre
.
Since a point source can bias tests, vertices should usually be spread over a plane or a volume. The vertices can be distributed over a flat surface by setting
/gps/position 0 0 -50 cm
/gps/pos/type Plane
/gps/pos/shape Rectangle
/gps/pos/halfx 1 cm
/gps/pos/halfy 1 cm
/gps/pos/rot1 0 0 -1
/gps/pos/rot2 0 1 0
To distribute the vertices over a volume the type is changed to Volume, and a volumetric shape must be chosen. The following commands will generate a box
/gps/position 0 0 -50 cm
/gps/pos/type Volume
/gps/pos/shape Para
/gps/pos/halfx 1 cm
/gps/pos/halfy 1 cm
/gps/pos/halfz 1 cm
that is 100 by 100 by 10 cm. It's important that the /gps/position command comes first. The other shapes that might be useful are Sphere and Cylinder which are specified as
/gps/position 0 0 -50 cm
/gps/pos/type Volume
/gps/pos/shape Sphere
/gps/pos/radius 1 cm
and
/gps/position 0 0 -50 cm
/gps/pos/type Volume
/gps/pos/shape Cylinder
/gps/pos/radius 1 cm
/gps/pos/halfz 1 cm
The direction distribution is set using the commands in the /gps/ang/ subdirectory. When specifying the direction, be aware that the code was written under contract to the ESA, and no effort was made to be consistent with the rest of the GEANT code base. As a result, the directions use a different angle convention when compared to the rest of GEANT. In fact, while the documentation says that the /gps/ang/ commands control the angular distribution of the source, they actually control the direction from a point along an initial particle direction ray back to where the source is found [note that the mathematics are very poorly defined]. To be honest, it's an odd and poorly thought out mix of definitions used by physicists and astronomers. Specifically, to get a particle traveling in the positive Z direction, you specify a theta of 180 degree.
The coordinate system used to generate the direction can be changed by using the /gps/ang/rot1 and /gps/ang/rot2 commands. The X axis of the direction coordinate system is defined by the /gps/ang/rot1 command, and the XY plane is determined by the /gps/ang/rot2 command. Neither of the axes need to be unit vectors, and the rot2 vector doesn't need to be perpendicular to rot1 (the normal will be determined by rot1 cross rot2). The directions will then be distributed around the negative Z axis in the rotated coordinate system. This means that
/gps/ang/rot1 0 0 1
/gps/ang/rot2 0 1 0
will rotate the direction coordinate system so that the local Z axis points along to global negative X axis. This will cause the generated particles to travel along the positive X axis (i.e. along the local negative Z axis). Note: The default for /gps/ang/rot2 is [0 1 0], so it doesn't need to be specified.
A fixed particle direction can be specified using
/gps/direction 0 0 1
where this specifies the direction that the particle is traveling. In this case, the particle is traveling along the positive Z axis. Notice unlike the rest of the gps direction commands, this uses the same convention as the rest of GEANT.
The problem with specifying a fixed direction is that it may bias a test. A Gaussian direction spread can be created using a one dimensional beam traveling along the local negative Z axis (yes, it is a bizarre choice). For instance, to create a beam traveling along the Z axis with a 10 degree divergence (sigma) the following commands would be used.
/gps/ang/type beam1d
/gps/ang/sigma_r 10 deg
/gps/ang/rot1 0 0 1
/gps/ang/rot2 0 1 0
The first line specifies that a 1D beam should be generated where this means that the generated directions have a spread around the negative Z axis. The second line specifies a 10 degree spread around the negative Z axis. The third line fixes the screwball convention that the beam travels along the negative Z axis by reversing the coordinate system (this aligns the direction coordinate system so that it's negative Z axis points along the global Z axis). You should be aware that (for reasons completely beyond me, but I've verified it in the source code) the /gps/ang/maxtheta and /gps/ang/mintheta commands have no effect on the beam distributions.
To spread the directions isotropically over all direction, the following command is used
/gps/ang/type iso
The directions can then be limited to a cone using the max and min commands. By default, the maximum angle is 180 degree and the minimum is 0 degree. Bear in mind that 180 degrees points along the positive Z axis and 0 degrees points along the negative Z axis (these guys failed high school geometry). To create a 10 degree cone of directions along the Z axis use
/gps/ang/type iso
/gps/ang/mintheta 170 deg
or alternatively
/gps/ang/type iso
/gps/ang/maxtheta 10 deg
/gps/ang/rot1 0 0 1
/gps/ang/rot2 0 1 0
where the final line deals with the wacky angle convention.
The energy distribution is set using the commands in the /gps/ene/ subdirectory. There are many options available, but for testing programs the most useful ones are to create a mono-energetic, Gaussian, or uniform energy source. By default the energy is specified as the kinetic energy of the created particle.
To create a monoenergetic source, the energy is specified like this:
/gps/ene/mono 100 MeV
where you must specify both the energy value and the unit. This create a monoenergetic source with 100 MeV of kinetic energy.
A uniform energy distribution can be created using:
/gps/ene/type Lin
/gps/ene/gradient 0
/gps/ene/intercept 1
/gps/ene/min 100 MeV
/gps/ene/max 500 MeV
where this creates a source with a uniform kinetic energy distribution between 100 MeV and 500 MeV of kinetic energy. The gradient is specified in MeV^{-1}. The intercept is a pure number, and the final distribution does not need to be normalized.
A Gaussian energy distribution can be created using
/gps/ene/type Gauss
/gps/ene/mono 400 MeV
/gps/ene/sigmae 30 MeV
where this create a source with a Gaussian spread of 30 MeV around 400 MeV.
The GPS is very inflexible when it comes to handling multiple
particles in a single event, so it's not possible to handle the
general case with multiple particles coming from the same vertex.
This is overcome in detSim by implementing the /generator/combine
command which is discussed below.
For the simple case of generating multiple particles drawn from the
same angle and energy distributions, but with the same position, use
/gps/number
command. For instance
/gps/number 2
would create two particles at the vertex. Note that both particles have the same energy and position distributions.
If you need control over the individual particles, then you have to use the /gps/source commands in combination with the /generator/combine command. For instance, to create an event with a mu- and a proton from the same vertex position (notice there will be two "primary vertexes" with the same position coordinates), you could create a macro:
# Clear the source and tell GPS to make multiple vertices
/gps/source/clear
/gps/source/multiplevertex true
# Create the first particle. This can be done using any of the GPS macro
# commands.
/gps/source/add 1
/gps/particle mu-
/gps/energy 500 MeV
/gps/direction 0 1 1
/gps/position 0.0 0.0 -50 cm
/gps/pos/type Volume
/gps/pos/shape Para
/gps/pos/halfx 1 cm
/gps/pos/halfy 1 cm
/gps/pos/halfz 1 cm
# Create the second particle. This can be done using any of the GPS macro
# commands. The position will be overridden below.
/gps/source/add 2
/gps/particle proton
/gps/energy 300 MeV
/gps/direction 0 0 1
/gps/position 0 0 0
# Add the GPS generator. It will create two primary vertices
# (G4PrimaryVertex objects).
/generator/add
# Copy the vertex position from the first G4PrimaryVertex object to the
# second. Notice that the vertices in GPS are numbered from one, but that
# the G4PrimaryVertex objects are numbered from zero.
/generator/combine 0 1
The /generator/combine
command copies the vertex position from the first
vertex to the second, and takes three arguments. The first argument is the
vertex number to copy the position, the second argument is the vertex
number to copy the position into, and the optional third argument is a
boolean flag specifying if the position of the second vertex should be
relative to the first. If the argument is true, then the position is of
the second particle is adjusted to be relative to the position of the first
(default: false). This can be used to simulate displaced vertices. As an
example, if the optional third argument is true, the first vertex position
is [1,1,1], and the second vertex position is [0,1,0], then the simulated
vertex positions will be [1,1,1] and [1,2,1].