Appendix A: Miscellaneous

Using parameters

As you can see through this guide, many algorithms in GAMOS use parameters to let the user change their behaviour. All the parameters in GAMOS have a default value and the user may change it in the user command file with the command:

Checking the usage of parameters

Many of the GAMOS classes or your own classes have a different behaviour depending on the value of some parameters. You can see many example of this throughout this guide.

You have to remember always to set a parameter before you invoke any code that may use it (we recommend you to set all the parameters at the beginning of your command file). The parameters are read usually in the class constructors; therefore, if you set a parameter after the class has been constructed, it will take no effect and the default value will be used.

To guarantee that you have done it this way, you will get at the end of a GAMOS job the information on the usage of parameters. You will always get a list of the parameters that have not been used in the code. This is probably an indication that you have mistyped a parameter name. This list appears at the end of your output and looks similar to this one:

%%%%% PARAMETERS NOT USED (DEFINED IN SCRIPT BUT
NOT USED BY C++ CODE)
%%%    MAYBE YOU HAVE MISPELLED THEM?
PARAMETER: GmGeometryText:FileName

Other lists are available at user request to get a more detailed information. You may get them anywhere in your simulation by using the command

/gamos/base/printParametersUsage LEVEL

If LEVEL takes a value >= 0 you will get the same list as above. If LEVEL takes a value >= 1 you will get a list of parameters that are using the default value (you may then check if this list contains one of the parameters whose value you thought you have changed). This list looks similar to this one:

%%%%% PARAMETERS USING DEFAULT VALUE (DEFINED IN C++
CODE BUT VALUE NOT DEFINED IN SCRIPT)
PARAMETER: Generator:Isotope:FileName
PARAMETER: GmCountTracksUA:FirstEvent

If LEVEL takes a value >= 2 you will get a list of how many times each parameter have been used. This list looks similar to this one:

%%%%% NUMBER OF TIMES EACH PARAMETER IS USED IN C++ CODE
PARAMETER GmCountTracksUA:EachNEvent TIMES USED= 1
PARAMETER GmGeometryFromText:FileName TIMES USED= 1

Managing the input data files

To run an example you will probably need some input data, like for example the file describing the geometry, the list of isotopes, etc.

You can set the name of your file in your script, but you do not need to tell the path where to look for it. An environmental variable, called GAMOS_SEARCH_PATH contains the list of directories where GAMOS will look for your file. The directories are separated by a colon, and their order in this variable reflects the order in which they will be searched. This variable is set up when you configure GAMOS, and takes a default value of

.:MY_GAMOS_DIR/data

You may change this value at your will, but remember not to reset the GAMOS configuration after that, because it will reset it to its original value.

/gamos/setParam PARAMETER_NAME PARAMETER_VALUE(S)

There are four types of parameters in GAMOS:

  • One number
  • A list of numbers
  • One string
  • A list of strings

The above command can be used for any kind of parameters, and GAMOS will detect which of the four types it is by analysing the parameter values. There may be though some peculiar cases where this automatic identification may fail. For example if you want to set a parameter for a list of volume names like VOL_A1, VOL_B1, VOL_C1 and you use a parameter to set its value equal to the three like:

/gamos/setParam PARAMETER_NAME *1

GAMOS will mistakenly think that is a parameter of type number number. For this cases it is possible to use a command specific for each of the four types:

/gamos/setParamN PARAMETER_NAME NUMBER

/gamos/setParamLN PARAMETER_NAME NUMBER_1 NUMBER_2 …

/gamos/setParamS PARAMETER_NAME STRING

/gamos/setParamLS PARAMETER_NAME STRING_1 STRING_2 …

Random number seeds

If you want to run several jobs with the same configuration but different random seeds each, you can use the Geant4 random number management, or do it the GAMOS way.

GAMOS offers two ways, to set the initial random seed or to restore it from a file. Both options are explained below.

Setting the initial random number seeds

GAMOS offers a single command with which you can give a different initial random seed to your job, so that the results are statistically independent:

/gamos/random/setSeeds INITIAL_SEED N_RANDOM_NUMBERS

where two numbers are given to better guarantee the independence of the results. INITIAL_SEED is the initial random seed and N_RANDOM_NUMBERS is the number of times a random seed is sampled before starting the simulation. You may use different or equal numbers for these two, and use continuous numbers (e.g. 1001, 1002, 1003, …) if you want.

Restoring the initial random number seeds

Although the previous method should guarantee that two jobs have independent random numbers, it may happen that the numbers chosen happen to give some correlation. To avoid this GAMOS provides a set of initial random number seeds that are independent. They have been produced by running contiguous sets of 1E10 random numbers and storing the final random numbers (or, in other words, running random numbers and storing them each 1E10). The command to use this utility is :

/gamos/random/restoreSeeds SEED_SET_NUMBER N_RANDOM_NUMBERS

where SEED_SET_NUMBER the first number correspond to the file name where the seed is stored, by default: data/initialSeeds/initialSeeds.1e+10.SEED_SET_NUMBER; it can be from 0 to 999. N_RANDOM_NUMBERS is the number of times a random seed is sampled before starting the simulation.

GAMOS provides 1000 random seed files, separated by 1e+10 random numbers using the JamesRandom engine. You may build your own set, but you have to follow some rules:

  • All files should be put in the same directory, whose name is given by the parameter : /gamos/setParam GmRunManager:SeedFileDir DIR_NAME The directory will be looked for in the current directory or in the data directory, or you may use an absolute path (starting by **).
  • The file names should be initialSeeds.NNUMBERS.SEED_SET_NUMBER, where NNUMBERS is the number of random numbers thrown for each file. You have to set this number with the parameter (by default it is 1.e+10): /gamos/setParam GmRunManager:RandomSeedsInFile NUMBER

Changing the random engine

The random engine (the algorithm that gets the random numbers) may be changed with the command:

/gamos/random/setEngine ENGINE_NAME

Any of the engines available in CLHEP can be chosen, i.e. DRand48Engine DualRand Hurd160Engine Hurd288Engine HepJamesRandom MTwistEngine NonRandomEngine RandEngine RanecuEngine Ranlux64Engine RanluxEngine RanshiEngine TripleRand.

Sending several jobs in the same machine

It may often happen that you have a multi-core machine and you want to run several jobs at the same time on it to accumulate statistics. The approach that is explained here is to send the same job several times with different random seeds. Another possible approach, which will be available in future GAMOS releases, is to use multi-threading, what will spare the initialisation time and reduce the memory by sharing it among the different jobs.

There are many ways of sending many jobs together in a machine. Here we propose a simple but flexible script that may facilitate this task. This script is written in the Unix command language bash, and it just needs the utility awk, a data extraction and reporting tool which is available on any Unix or MacOS operative system.

The example has four input parameters that the user has to give: energy, random seed, number of events, number of jobs. The four parameters will be converted to internal variables:

### set the variables read from the command line
ENERGY=$1
SEED=$2
NEV=$3
NJOBS=$4

Then the loop to the number of jobs is started:

### start the loop of jobs
nj=0
while
test $nj -lt $NJOBS
do

A different suffix for each job is created, which will be added to the new name of the input file, as well as to the output file name defined inside the input file:

### set the suffix of the output files
SUFFIX=$1"."$2"."$3"."$nj
echo " SUFFIX = $SUFFIX "

The input file is copied into a new one, so that you can keep a track of the different files that are run:

### copy the input file into a new one (so that you can keep a track of the different files that are run)
new_inputfile="exercise2."$SUFFIX
log_inputfile=zz"_"$new_inputfile
echo " The new input file = " $new_inputfile

The awk tool is used to substitute the scrip input variables in the GAMOS input file:

### substitute in the input file the variables from the command line
awk -v ENERGY=$ENERGY -v SEED=$SEED -v NEV=$NEV -v nj=$nj -v SUFFIX=$SUFFIX '{
if($1=="/run/beamOn") {printf("%s %s \\n",$1, NEV) }
else if ($1=="/gamos/random/setSeeds") {printf("%s %s %s\\n",$1, SEED, SEED+nj) }
else if($2=="RTPhaseSpaceUA:FileName") {printf("%s %s %s\\n",$1, $2, "test."SUFFIX) }
else if($1=="/gamos/generator/addSingleParticleSource") {printf("%s %s %s %s\\n",$1,$2,$3,ENERGY"\*MeV") }
else { print $0 }
}' "exercise2b.in" > $new_inputfile".inn"

You can observe that each of the variables that are going to be used by awk have to be passed with the -v option. The awk will loop through the lines in the input file and will make the substitutions. For example the line

else if($2=="RTPhaseSpaceUA:FileName") {printf("%s %s %s\\n",$1, $2, "test."SUFFIX) }

means that it looks for a line whose second word is RTPhaseSpaceUA:FileName and then substitutes this line by three words (three %s), the first two are left intact, and the third one is substituted by the value of the SUFFIX, preceded by test..

Finally the job is sent in background. You may run it in foreground, what means that you have to wait until a job finish to start the next one:

### run job in background
gamos $new_inputfile".inn" 2>&1 | tee $log_inputfile &
### run job in foreground
#  gamos $new_inputfile".inn" 2>&1 | tee $log_inputfile

If, for example, you want to run 40 jobs in your 4-core machine, you should not run them all in background at the same time, as they will have to share the CPU and memory, wasting your computer resources, or even saturating your memory. A smarter approach would be to type four times a sendjobs command running jobs in foreground:

sh sendjobs 6. 1111 10000 10 &

sh sendjobs 6. 2111 10000 10 &

sh sendjobs 6. 3111 10000 10 &

sh sendjobs 6. 4111 10000 10 &

The full sendjobs file can be found in your GAMOS distribution, under the directory tutorials/RTTytorial/exercise2.

Identifying touchables

As explained in several points through this guide, you can use the concept of touchable available in GAMOS. We will explain first in a few lines the concept of touchable in Geant4 and GAMOS:

In Geant4 there are several geometrical objects [biblio.g4doc-geometry] :

  • G4VSolid: A solid is a geometrical object that has a shape and specific values for each of the shape dimensions
  • G4LogicalVolume: A logical volume contains the volume’s full properties. 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.
  • G4VPhysicalVolume: A physical volume is a volume placed already in another volume, that is a volume with position and rotation matrix
  • G4VTouchable: A touchable is each copy of a volume. To understand the difference with a physical volume, we put an example: If you place a volume A in 5 places and a volume B in 12 places, you will have 5 + 12 physical volumes, each one with a distinct position and rotation matrix. But you will have 5 X 12 = 60 individual copies, that is 60 touchables

To save memory the G4VTouchable are instantiated in Geant4 only when a track traverses the corresponding volume in space, and they are immediately deleted when the track leaves. In GAMOS you have the possibility of accessing any individual touchable whenever you like. When you need it you can ask GAMOS to create a GmTouchable, which will have the same characteristics as the corresponding G4VTouchable that would be created when a track reaches it.

To identify the touchable you want to use, you have to use the following notation:

For example the name CRYSTAL identifies all individual crystals of your detector that have name ``CRYSTAL’‘, while BLOCK:2/CRYSTAL:1 refers only to the crystal(s) with copy number 1 in block(s) with copy number 2. RING:3/BLOCK/CRYSTAL:1 refers to all the crystal(s) with copy number 1 in all the block(s) whatever copy number they have in the ring(s) that have copy number 3. Don’t forget that the full touchable name will start with a slash followed by the name of the world volume, e..g. /world:0/RING:3/BLOCK/CRYSTAL:1. You may get the full list of touchables in your geometry with the command:

/gamos/geometry/printTouchables *

If you are writing some new C++ code for GAMOS you can have easy access to the list of touchables with a given name with the line

GmGeometryUtils::GetInstance()->GetTouchables( touch_name, itExists )

If the touchables do not exist in your geometry you will get a warning in case itExists is false and an exception if itExists is true.

There is a limitation on the use of touchables: they cannot be used for assembly volumes, as Geant4 creates internally the physical volumes.

Using asterisks to get volume, particle and material names

In many commands described in this guide, you give the name of a logical volume, physical volume, touchable, particle or material, so that GAMOS finds the corresponding Geant4 object. In case you want to apply your command to several volumes with similar names, you can use an asterisk that would mean ‘any character’. For example if you have the volumes named CRYSTAL_BGO_1, CRYSTAL_BGO_2, CRYSTAL_LUYAP_1 and CRYSTAL_LUYAP_2

/gamos/SD/assocSD2LogVol GmSDSimple Calor CRYSTAL*

will associate a sensitive detector to the four volumes, while

/gamos/SD/assocSD2LogVol GmSDSimple Calor CRYSTAL_BGO_*

will associate a sensitive detector to the two volumes CRYSTAL_BGO_1 and CRYSTAL_BGO_2, and

/gamos/SD/assocSD2LogVol GmSDSimple Calor CRYSTAL_*1

will associate a sensitive detector to the two volumes CRYSTAL_BGO_1 and CRYSTAL_LUYAP_1.

Using particle names

Each particle type in Geant4 is identified by a unique name. No particle is created by Geant4 unless the user code does it explicitly. At any time in your command file you can ask for a list of created particles with the command /run/particle/dumpList. If you do this after instantiating the GAMOS electromagnetic physics list, you will get the following list:

anti_nu_e, chargedgeantino, e+, e-,
gamma, geantino, nu_e, opticalphoton

If you use the GAMOS hadronic physics list, you will get the following list:

GenericIon, He3, alpha, anti_neutron
anti_nu_e, anti_nu_mu, anti_nu_tau, anti_proton
chargedgeantino, deuteron, e+, e-
eta, eta_prime, gamma, geantino
mu+, mu-, neutron, nu_e
nu_mu, nu_tau, opticalphoton, pi+
pi-, pi0, proton, tau+
tau-, triton,

These are the names that should be used in the commands that need a particle name. If you want to use hadrons, GAMOS also provides the possibility of grouping them, so that with a single name you can identify the whole group. The groups defined are the following:

  • lightMeson: Mesons that only contain up and down quarks

    pi+, pi-, pi0, eta, eta_prime, kaon+, kaon-, kaon0, kaon0L,
    kaon0S, a0(\*), a1(\*), a2(\*), k(\*), k1(\*), k2(\*), k_star(\*),
    k0_star(\*), k2_star(\*), k3_star(\*), anti_k(\*), anti_k0(\*),
    anti_k1(\*), anti_k2(\*), anti_k_star(\*), anti_k2_star(\*),
    anti_k3_star(\*), b1(\*), f0(\*), f1(\*), f2(\*), f2_prime(\*),
    h1(\*), eta(\*), eta2(\*), phi(\*), phi3(\*), pi(\*), pi2(\*),
    rho(\*), rho3(\*)
    
  • charmMeson: Mesons that contain a charm quark

    D+, D-, D0, anit_D0, Ds+, Ds-, J/psi
    
  • bottomMeson: Mesons that contain a bottom quark

    B+, B-, B0, anti_B0, Bs0, anti_Bs0
    
  • meson: All mesons

  • lightBaryon: Baryons that only contain up and down quarks

    proton, anti_proton, neutron, anti_neutron, N(\*), anti_N(\*),
    delta(\*), anti_delta(\*)
    
  • strangeBaryon: Baryons that contain a strange quark

    lambda, anti_lambda, sigma0, anti_sigma0, sigma+,
    anti_sigma+, sigma-, anti_sigma-, xi0, anto_xi0, xi-,
    anti_xi-, omega-, anti_omega-, lambda(\*), anti_lambda(\*),
    sigma(\*), anti_sigma(\*), xi(\*), anti_xi(\*), omega(\*),
    omega3(\*)
    
  • charmBaryon: Baryons that contain a charm quark

    lambda_c+, anti_lambda_c+, sigma_c0, anti_sigma_c0,
    sigma_c+, anti_sigma_c+ sigma_c++, anti_sigma_c++, xi_c+,
    anti_xi_c+, xi_c0, anti_xi_c0, omeca_c0, anti_omega_c0
    
  • baryon: All baryons

  • ion: ions

    GenericIon, alpha, He3, deuteron, triton
    
  • ALL: All particles