Table of Contents

Technical design description

The author of AtRIS is determined to provide enough documentation so that the project does not get abandoned because of lack of thereof (Other reasons are OK). Still, in comparison to data analysis, writing documentation can be a rather tedious and unrewarding task. This here is an effort to describe some of the design decisions that the author has made to make things work as efficiently as possible. If you see points which could be further optimized to significantly improve performance, please leave a ticket in the discussion section which can be found at the bottom of the page.

What is an SDID?

Sensitive Detector ID is the integer designation of atmospheric volume elements (sensitive detectors). The SDID is used throughout the code to as an address for data storage, for example when filling in the ionization histograms. Therefore, the SDID must be properly specified for each volume element, as has been described in input. Note, to improve performance, particles are killed when they enter the core volume (SDID=0) or the loss volume (largest SDID). Still, even though no particle tracking is performed in these two special volumes, they enter in to the histogram generation. The user needs to be aware of this behavior.

What is an DIID?

Detector Interface ID designates the interface between the volumes with SDID=DIID and SDID=DIID+1. In the code, AtRIS looks for particles which have just entered a new volume and it knows the SDID of the new volume. In order to determine the DIID, we need to know if the particle is moving in a downward or in an upward direction:

SensitiveDetector.cc

 
G4ThreeVector position  = pre->GetPosition().unit();   // the position vector normalized to 1
G4ThreeVector direction = pre->GetMomentumDirection(); // a normalized direction vector
G4double inclination    = (position*direction);        // a scalar product of two unit vectors give the enclosed angle
bool upward             = inclination < halfpi;        // flag which is true if the particle is upward
G4int diid              = sdid - (1*upward);           // to get the diid from the sdid, reduce by 1 if the particle is upward

What is a PDG code?

For Geant4 it was necessary to develop an integer naming scheme which can be used to specify all particles. If numerically we want to check the type of a particle, it is much easier to consider an integer designation than parse a string. The Particle Data Group was tasked with creating such a numbering scheme. The PDG naming scheme covers all possible particles, ranging from quarks, diquarks, etc., to all the known nuclei. More information can be found here1).

Note: Antiparticles are designated with a negative sign.

How is the ICRU sphere water phantom response data read-in and stored in RAM?

Please read the model_description section on the ICRU sphere water phantom. The response step-functions for the different relevant particles (see below) are stored as a an ascii table with a single line header. The header, starting with “#” specifies the $$\rm{PDG}\quad\Leftrightarrow\quad j,$$ correspondence, where $j$ is the column number. To parse this data, the procedure is as follows:


The energy index $k$

For the simulation of $j$, we have used 650 energy bins ranging from $1$ eV to $10$ TeV, equidistant on a $\log_{10}$ scale:

Python2

import numpy as np                  # not MeV is the default energy unit. Thus 1e0=1MeV
exponents = np.linspace(-6,7,651)   # generate 651 binedges with equidistant 0.02 spacing
binedges  = 10**exponents           # raise 10 to the calculated exponents
np.savetxt("new_icru.bins",binedges)# save as an txt file 

This energy binning is hard-coded within the code of AtRIS. Namely, the $k$ index selection is hardcoded. The number of energy bins is hardcoded in form of a global variable nricrubins=650. Here is the code which:

SensitiveDetector.cc

G4double    step = 0.02;                          // untransformed step size
G4StepPoint* pre = step->GetPreStepPoint();       // get step point at the beginning of the step
G4double    ekin = pre->GetKineticEnergy();       // retrieve kinetic energy
G4int          k = (G4int) (log10(ekin/eV)/0.02); // we must divide by eV in order to get positive indices

How does code determine if a given secondary particle is to be used for the dose-rate estimation ?

The author has performed an analysis of the secondary particles population2). He has determined that only the following particles contribute to the dose rate:

particle: GPS name: PDG code: Frequency: Dose contribution:
$\gamma$ photon 22 very frequent normal, lowest
$\pi^+,\pi^-$ pions 221,-221 infrequent enhanced through decay
$K^+,K^-1,K^0$ kaons 321,-321,130 very rare enhanced through decay
$e$ e- 11 frequent normal, low
$\bar{e}$ e+ -11 frequent enhanced through annihilation
$\mu$ mu- 13 frequent enhanced through decay
$\bar{\mu}$ mu+ -13 frequent enhanced through decay
$\bar{p}$ proton 2212 frequent normal, low
$\bar{p}$ anti_proton -2212 infrequent enhanced through annihilation
$n,\bar{n}$ neutron 2112, frequent enhanced through decay
$\bar{n}$ anti_neutron -2112 infrequent enhanced through decay, annihilation
$d,t$ deuteron,triton 1000010020,1000010030 very rare normal, low
$He^3,\alpha$ Helium3, alpha 1000020030,1000020040 very rare normal, low

Lets call the above particles relevant.

The dose rate is estimated each time a secondary passes a volume interface. The procedure goes as follows:

Structure of log data?

AtRIS produces 3 different log files:

  1. .log is the main log file. It contains lots of information. Check it out!
  2. .out is a copy of the stdout
  3. .error is a redirection of the stderr. Check this if the simulation crushes.

Here are a couple of reasons:

  1. debugging
  2. debugging
  3. reproducability
  4. documentation
  5. diminishing performance impact since we are not writing out to stdout, but to the hard drive

2) Note: plots will be made after publication available