Skip to content

Restore atomic de-excitation; make Generator work multithreaded - #106

Merged
kavyawadhwa134 merged 1 commit into
mainfrom
fix-fluorescence-and-mt-generator
Oct 17, 2026
Merged

kavyawadhwa134 merged 1 commit into
mainfrom
fix-fluorescence-and-mt-generator

Conversation

@kavyawadhwa134

Copy link
Copy Markdown
Collaborator

Summary

1. No fluorescence or Auger electrons with the default physics list (bug in our code)

The "custom" physics list registered G4RadioactiveDecayPhysics before G4EmStandardPhysics_option4. Geant4 requires the opposite order: its ConstructProcess says it "should be defined after EM constructor". When it runs first, it creates the G4UAtomicDeexcitation module and calls G4LossTableManager::ResetParameters() while the physics list is still being constructed. The production-cuts table is still empty at that point, so no material-cuts couple is marked active. The one-shot reset flag is then used up, so the module is not re-initialised at the first run.

The result: no de-excitation in any volume, while /process/em/printParameters still reports fluorescence, Auger and ignore-cuts as enabled. The tell-tale is /process/em/verbose 1, which prints "UAtomDeexcitation is activated for 1 region:" with no region line under it. Because the de-excitation code never ran or drew random numbers, /process/em/fluo false, Bearden and ANSTO all gave bit-identical output.

The fix moves decay and radioactive decay after the EM constructor.

Gold slab, 0.1 mm, 100 keV gamma beam, 2000 events, phot secondaries:

gammas electrons
0.2.0 wheel 0 1276
this branch (Geant4 11.4.3) 1439: Kα2 67.18, Kα1 69.04, Kβ ~78 keV, plus L lines Auger cascade

The released wheel also confirms the mechanism: QGSP_BIC_EMZ with add_physics("G4RadioactiveDecayPhysics") appended after EM gives 1465 gammas and 24,502 electrons.

With the bug, the whole K-shell binding energy was deposited locally, which inflates kV-photon dose in high-Z materials.

Reference lists are not affected by this bug. They show no K x-rays in gold because of normal Geant4 behaviour:

  • FTFP_BERT has fluorescence off by default.
  • In _LIV and _EMZ, de-excitation respects production cuts. The default 0.7 mm cut is a 103 keV gamma threshold in G4_Au, above the 80.7 keV K shell.
  • /process/em/deexcitationIgnoreCut true or /run/setCut 0.01 mm restores the x-rays.

2. app.generator in multithreaded mode

In multithreaded mode only the workers have a primary generator and a stacking action, so app.generator raised Primary generator action is not available. Since all their state is static, the generator and stacking properties now return the bound classes instead of the master's (non-existent) instance.

/gun/ and /gps/ commands issued before their messengers exist (in multithreaded mode, before initialize()) failed with code 100. They are now kept and applied, in order, right after initialization, and the master forwards them to the workers. A mistyped command of this kind is reported by initialize() instead of immediately. PrimaryGeneratorAction::set_* now goes through Application::Command, so it raises on failure instead of ignoring it.

Tests

  • tests/test_physics.py::test_gold_fluorescence[0, 2]: gold Kα photons from phot (serial and 2 threads).
  • tests/test_run.py: Generator gun and GPS with n_threads=2, before and after initialize(), and the deferred typo error.
  • Locally on macOS arm64 against a Geant4 11.4.3 source build: full suite 50 passed, 2 skipped (both skips already existed). All six new tests fail on the 0.2.0 wheel.

The developer guide sections that describe the multithreaded workaround (28, 32 and 74) exist only on the developer-guide-updates branch (#105). Replacement text for them is handed over to that PR rather than edited here, to avoid conflicts.

🤖 Generated with Claude Code

The custom physics list registered G4RadioactiveDecayPhysics before the
EM constructor. It then creates the atomic de-excitation module and
initializes it while the physics list is built, before any material-cuts
couple exists, so de-excitation stayed inactive in every volume: no
fluorescence x-rays or Auger electrons, while printParameters reported
them enabled. Register it after G4EmStandardPhysics_option4, as Geant4
requires.

In multithreaded mode the master has no primary generator or stacking
action, so app.generator raised "Primary generator action is not
available". Their state is static, so return the bound classes instead.
/gun/ and /gps/ commands issued before their messengers exist (before
initialize() in MT) are now kept and applied right after initialization.
@kavyawadhwa134
kavyawadhwa134 requested a review from lobis as a code owner October 17, 2026 11:18
@coderabbitai

coderabbitai Bot commented Oct 17, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 0783e790-750a-424f-b097-fbaf806f4f24
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@kavyawadhwa134
kavyawadhwa134 merged commit 670bc9f into main Oct 17, 2026
20 checks passed
@kavyawadhwa134
kavyawadhwa134 deleted the fix-fluorescence-and-mt-generator branch October 17, 2026 13:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant