Skip to content

Commit 71195eb

Browse files
authored
Merge pull request #634 from ManuelHu/validation
tests: update nist and ge validation
2 parents 424f747 + 02ae401 commit 71195eb

File tree

13 files changed

+342
-137
lines changed

13 files changed

+342
-137
lines changed

docs/rmg-commands.md

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/validation/nist.md

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,39 @@ electrons and compare them with data from the
1111
short description of the reported quantities is available
1212
[here](https://physics.nist.gov/PhysRefData/Star/Text/method.html)).
1313

14-
Multiple Coulomb scattering is disabled through the
14+
The simulation physics is modified by the commands:
1515

1616
```
1717
/process/inactivate msc
18+
/RMG/Processes/DefaultProductionCut 1 km
19+
/RMG/Processes/SensitiveProductionCut 1 km
1820
```
1921

20-
command, since it prevents us to measure the true integrated particle path
21-
length in the simulation (unless a very short step size limit is set).
22+
- Multiple Coulomb scattering is disabled, since it prevents us to measure the
23+
true integrated particle path length in the simulation (unless a very short
24+
step size limit is set).
25+
- the high production cuts ensure that no secondaries are created. This is
26+
required to correctly measure the bremsstrahlung component of the CSDA loss.
27+
28+
An effect of the step length is visible. The larger the step length, the larger
29+
the difference to the expected integrated path length.
30+
31+
The statistical uncertainties are dominated by energy-loss fluctuations. They
32+
are kept enabled here to show the effect of the user-chosen step length values.
33+
Especially the stopping power at low step sizes are the most affected.
34+
35+
:::{note}
36+
37+
The simulated stopping powers are derived from the energy deposition in the
38+
first step and its length. This leads to the stopping powers only matching with
39+
the ESTAR-provided values until a material-specific energy.
40+
41+
Below that, the energy is fully deposited in one single small step, from which
42+
we cannot estimate the stopping power at the incident energy any more. For these
43+
low energies, we plot the incident energy over the full expected ranged from
44+
ESTAR data as the expectation value.
45+
46+
:::
2247

2348
### Electron interactions in natural germanium
2449

include/RMGSteppingAction.hh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ class RMGSteppingAction : public G4UserSteppingAction {
4444
RMGRunAction* fRunAction;
4545

4646
bool fSkipTracking = false;
47+
bool fKillSecondaries = false;
4748
double fDaughterKillLifetime = -1;
4849

4950
std::unique_ptr<G4GenericMessenger> fMessenger;

src/RMGSteppingAction.cc

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ RMGSteppingAction::RMGSteppingAction(RMGRunAction* run_action) : fRunAction(run_
3232

3333
void RMGSteppingAction::UserSteppingAction(const G4Step* step) {
3434

35-
if (fSkipTracking) {
35+
if (fSkipTracking || (fKillSecondaries && step->GetTrack()->GetParentID() > 0)) {
3636
step->GetTrack()->SetTrackStatus(fKillTrackAndSecondaries);
3737
return;
3838
}
@@ -114,6 +114,13 @@ void RMGSteppingAction::DefineCommands() {
114114
.SetParameterName("boolean", true)
115115
.SetDefaultValue("true")
116116
.SetStates(G4State_Idle);
117+
118+
fMessenger->DeclareProperty("KillSecondaries", fKillSecondaries)
119+
.SetGuidance("Kill all secondary particles (tracks with parent ID > 0) at their first step.")
120+
.SetGuidance(std::string("This is ") + (fKillSecondaries ? "enabled" : "disabled") + " by default")
121+
.SetParameterName("boolean", true)
122+
.SetDefaultValue("true")
123+
.SetStates(G4State_Idle);
117124
}
118125

119126

tests/nist/macros/run.mac

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,16 @@
88
# to the theoretical range
99
/process/inactivate msc
1010

11+
# disable energy loss fluctuations (straggling)
12+
/process/eLoss/fluct {FLUCT}
13+
14+
# prevent any secondary production
15+
/RMG/Processes/DefaultProductionCut 1 km
16+
/RMG/Processes/SensitiveProductionCut 1 km
17+
1118
/RMG/Output/Germanium/StoreTrackID true
19+
# store only post-steps so that we can correctly calculate step lengths
20+
/RMG/Output/Germanium/StepPositionMode PostStep
1221

1322
/RMG/Generator/Confine Volume
1423
/RMG/Generator/Confinement/Geometrical/AddSolid Sphere

tests/nist/run_e_sims.py

Lines changed: 61 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,69 @@
11
from __future__ import annotations
22

33
import os
4+
from multiprocessing import Pool
5+
from pathlib import Path
46

57
import numpy as np
6-
from remage import remage_run_from_args
8+
from remage import remage_run
79

8-
n_events = 500 * int(os.environ["RMG_STATS_FACTOR"])
10+
Path("output/").mkdir(parents=True, exist_ok=True)
11+
12+
n_proc = int(os.environ["RMG_STATS_FACTOR"])
13+
n_events = 500 * n_proc
14+
15+
energies = np.geomspace(30, 50000, num=15).astype(int) # in keV
16+
step_sizes = (1, 0.1, 0.01, 0.001, 0.0001) # in m
17+
range_energies = np.array([300, 500, 1000, 1500, 2000, 3000, 4000]) # in keV
18+
range_step_sizes = (1,) # in m
19+
20+
sims = []
21+
22+
for mat in ("ge", "ar", "cu"):
23+
for step_size in step_sizes: # in m
24+
for energy in energies: # in keV
25+
sims.append(
26+
{
27+
"macros": "macros/run.mac",
28+
"macro_substitutions": {
29+
"ENERGY": energy,
30+
"EVENTS": n_events,
31+
"MAX_STEP_SIZE_IN_M": step_size,
32+
"FLUCT": "true",
33+
},
34+
"gdml_files": f"gdml/geometry-{mat}.gdml",
35+
"output": f"output/electrons-{mat}-{energy}-keV-{step_size}-m.lh5",
36+
"overwrite_output": True,
37+
"flat_output": True,
38+
"log_level": "summary",
39+
}
40+
)
941

1042
for mat in ("ge", "ar", "cu"):
11-
base_args = [
12-
"--macro-substitutions",
13-
"ENERGY={}",
14-
f"EVENTS={n_events}",
15-
"MAX_STEP_SIZE_IN_M=1",
16-
"--gdml-files",
17-
f"gdml/geometry-{mat}.gdml",
18-
"--output-file",
19-
f"electrons-{mat}-{{}}-keV.lh5",
20-
"--flat-output",
21-
"--overwrite",
22-
"macros/run.mac",
23-
]
24-
25-
energies = np.concatenate(
26-
[
27-
np.arange(30, 100, step=20),
28-
np.arange(100, 500, step=200),
29-
np.arange(500, 5000, step=500),
30-
]
31-
)
32-
33-
for energy in energies: # in keV
34-
args = [arg.format(energy) for arg in base_args]
35-
print("remage", " ".join(args))
36-
remage_run_from_args(args, raise_on_error=True)
43+
for step_size in range_step_sizes: # in m
44+
for energy in range_energies: # in keV
45+
sims.append(
46+
{
47+
"macros": "macros/run.mac",
48+
"macro_substitutions": {
49+
"ENERGY": energy,
50+
"EVENTS": n_events,
51+
"MAX_STEP_SIZE_IN_M": step_size,
52+
"FLUCT": "true",
53+
},
54+
"gdml_files": f"gdml/geometry-{mat}.gdml",
55+
"output": f"output/electrons-range-{mat}-{energy}-keV-{step_size}-m.lh5",
56+
"overwrite_output": True,
57+
"flat_output": True,
58+
"log_level": "summary",
59+
}
60+
)
61+
62+
63+
def _run(sim):
64+
remage_run(**sim)
65+
66+
67+
if __name__ == "__main__":
68+
with Pool(n_proc) as pool:
69+
pool.map(_run, sims)

0 commit comments

Comments
 (0)