How to Properly Score 3D Dose Distribution with ICRP145 Phantom?

Geant4 Version:_11.3.0
_Operating System:_Ubuntu
_Compiler/Version:_gcc (GCC) 11.2.0
_CMake Version:_cmake version 3.21.1

Dear Geant4 developers and community,

I’m currently working on a project that involves calculating 3D dose distribution from proton irradiation using the ICRP-145 human phantom (provided in the ICRP145_HumanPhantoms example in advanced/).

I have been trying to modify the example to record 3D dose distributions (x, y, z, dose [Gy]) for each beam configuration using General Particle Source (GPS) and multithreading support. However, I encountered several issues:


My Current Setup:

  • Geant4 version: 11.3.0
  • Phantom: MRCP_AF / MRCP_AM (.node, .ele)
  • Simulation: Monoenergetic pencil beam from different gantry angles and z-heights
  • Goal: Save dose per voxel (mm-scale) → as .txt or .csv for machine learning training
  • Threads: 4 or more
  • Source: TETPrimaryGeneratorAction (GPS)
  • Detector: No voxel phantom used → using the tetrahedral phantom directly

Problem:

Even though my simulation completes with multithreading and no crashes, the 3D dose file (dose3D_*.txt) is either:

  • created but completely empty (headers only)
  • not created at all
  • gives error: SteppingAction is null. Cannot save 3D dose.

I tried implementing a TETSteppingAction class with a 3D dose map (e.g. std::map<std::tuple<int,int,int>, G4double>), and connect it to TETRunAction via G4UserRunAction, but it seems in multi-threaded runs, the stepping action is not being recognized properly in the master thread or finalization phase.


What I Want to Know:

  1. :white_check_mark: What is the recommended Geant4-style way to accumulate 3D dose in TET-based geometry?
  2. :white_check_mark: Is it possible to score 3D dose using G4MultiFunctionalDetector or G4ScoringManager with tetrahedral phantom?

Additional Notes:

  • I already implemented G4Accumulable in RunAction for dose uncertainty and time tracking
  • I confirmed dose is deposited (via 1D scoring)
  • I attempted mapping global positions to voxel indices (x,y,z), but output is still empty

Any help, working example snippets, or advice would be deeply appreciated.
Thank you so much for your time and support!

Kind regards,
Gedchadapars R.
Physics MSc student


Command based scoring should work. It creates a 3D rectangular scoring map in a parallel geometry. See examples/extended/runAndEvent/RE03. Look at the README file therein (and in the parent directory).

Of course, you can do it all yourself, but RE03 is a good template.

Will that do what you want?

Thanks so much for your information and help. I understand now that G4ScoringManager and command-based scoring (like RE03) is only suitable for regular box mesh geometry, and not applicable for tetrahedral ICRP145 phantoms. Is there any recommendation or standard example in the Geant4 ecosystem for accumulating 3D dose for TET geometry with GPS + multithreading?

Ah, you miss the point. The scoring grid is in a parallel world, overlaying the “mass” world. They can coexist and overlap. So scoring works on any mass geometry, you don’t have to worry.