Skip to content

Initial setup for G4 FastSim hooks with a toy example for Absorber - #15699

Open
sawenzel wants to merge 9 commits into
AliceO2Group:devfrom
sawenzel:sawenzel/abso-fastsim-envelope
Open

Initial setup for G4 FastSim hooks with a toy example for Absorber#15699
sawenzel wants to merge 9 commits into
AliceO2Group:devfrom
sawenzel:sawenzel/abso-fastsim-envelope

Conversation

@sawenzel

@sawenzel sawenzel commented Aug 20, 2026

Copy link
Copy Markdown
Collaborator

This development makes it possible to register and use per-region fast simulation hooks with the Geant4 engine.
A toy demonstrator is added, showing this for the ALICE Absorber. This provides the grounding to hook a ML-model for the Absorber at a later stage.

@sawenzel sawenzel changed the title Add a Geant4 fast simulation hook, with a toy absorber model Initial setup for G4 FastSim hooks with a toy example for Absorber Aug 20, 2026
@sawenzel
sawenzel marked this pull request as ready for review August 20, 2026 15:17
@sawenzel
sawenzel requested a review from a team as a code owner August 20, 2026 15:17
sawenzel and others added 9 commits September 19, 2026 03:21
This adds a dedicated air material and medium for AFaM so that the front
absorber can be addressed as a single region.

- AFaM shared ABSO_AIR_C0 with AFaAcc, which is one of its own daughters.
- Geant4-VMC selects fast-simulation regions by material name and puts every
  volume of that material into the region, so a volume can only be a region of
  its own if its material is its own.
- ABSO_AIR_ENVELOPE0$ has the composition and density of ABSO_AIR0$ and takes
  the same global cuts and processes, so the physics is unchanged.
- No other code refers to ABSO medium index 20.
This commit provides the fast-simulation hook that O2 was missing, in a new
Detectors/FastSim module, plus one toy model that exercises it end to end. The
feature does nothing unless G4.fastSimModels names a model.

- o2::fastsim::G4RunConfiguration overrides CreateUserFastSimulation, which is
  the only piece geant4_vmc needed and O2 did not supply.
- TG4FastSimulationPhysics is already registered unconditionally by
  TG4SpecialPhysicsList, so the specialProcess string is unchanged.
- FastSimModel::DoIt is shared plumbing: it measures the distance to the
  envelope surface, kills the incident particle, stacks what comes back and
  books the energy difference as a deposit.
- A model implements sample(), which maps the particle that entered to the
  particles that leave.
- ToyAbsorberFastSim returns one particle carrying on in the incident direction
  with an exponentially attenuated energy.
- Regions are named as tracking media in G4.fastSimRegions.
- With G4.fastSimModels empty the run configuration returns nullptr and the
  behaviour is identical to before.

Usage:

  o2-sim -n 10 -g pythia8pp -e TGeant4 -m PIPE ABSO \
    --configKeyValues "G4.fastSimModels=toyAbsorber;G4.fastSimRegions=ABSO_AIR_ENVELOPE"

The steps inside the region disappear from the step log, which is the saving:
a fast step defaults to AvoidHitInvocation, so Geant4 does not call the
sensitive detector and TVirtualMCApplication::Stepping() is not invoked. That
is correct for a passive envelope, which has no hits to lose.
This adds run/SimExamples/FastSim_Absorber, which runs the same five events
through PIPE and ABSO twice, once with detailed transport and once with the
toy model, and compares the number of tracks.

- run.sh performs both simulations and the comparison.
- countTracks.macro reports tracks per event of an o2-sim output.
- README.md says how the feature is switched on, what the toy model does and
  why the region is named after a tracking medium.
This adds the numbers from a first run of the example, and says what they do
and do not show.

- Five pp events with PIPE and ABSO: 3544 tracks per event with detailed
  transport, 3160 with the toy model.
- Transport time is 29.8 s against 28.0 s, which is not a performance claim:
  only the forward cone of a minimum-bias pp event enters the absorber, so most
  of the transport in this setup happens outside the region.
- The geant4_vmc line confirming that the tracking medium resolved to its
  material is quoted, because a wrong medium name fails silently.
This documents a limitation found by running the example, and withdraws the
reading of its track counts.

- ABSO_AIR_ENVELOPE selects a region containing AFaM and nothing else: the VMC
  special cuts make every logical volume a root of its own material's region,
  and Geant4 stops propagating a region at any such daughter.
- AFaM's daughters touch its surface, so a track entering the absorber lands in
  a daughter and never has AFaM as its volume.
- A 20 GeV muon with /tracking/verbose 1 steps through the absorber identically
  with and without the fast simulation, showing only muIoni, eIoni,
  Transportation and specialCutForElectron.
- The two runs' random sequences diverge before the absorber, so the track
  counts previously recorded do not measure the model.
This makes a model cover a whole module, which the region mechanism alone
cannot express.

- A Geant4 region in O2 is always "every volume of a given material": the VMC
  special cuts make every logical volume a root of its own material's region,
  and Geant4 stops propagating a region at any such daughter.
- G4FastTrack::GetEnvelopeSolid() therefore returns one absorber piece, and
  FastSimModel no longer uses it.
- G4.fastSimEnvelope names the volume a model stands in for. Containment and the
  exit distance are read from the track's own touchable, which already carries
  the full ancestry and the transform of every level.
- ModelTrigger now requires geometric containment in that envelope, which also
  excludes volumes that merely share a material with it, such as the absorber's
  support cradle.
- The regions needed for Geant4 to consult the model are derived by walking the
  envelope's subtree and collecting its media, so no list is maintained by hand.
  The walk happens in CreateUserPostDetConstruction, the one point after the
  geometry is built and before the media are turned into regions.
- G4.fastSimRegions still overrides the walk with an explicit list.
- DoIt is Geant4's own entry point and is no longer final, so a model that does
  not fit the common shape can replace it rather than work around it.
- Its comment now says what it is: it wraps the logic common to every model and
  delegates the physics to sample().
- The example passed G4.fastSimRegions=ABSO_AIR_ENVELOPE, which overrides the
  envelope walk with a region containing only AFaM and reproduces exactly the
  behaviour this branch fixes. It now passes G4.fastSimEnvelope=AFaM.
- Drops an unreachable guard in the toy model: ModelTrigger only calls it above
  its threshold and an exponential of a finite path cannot reach zero.
- Comment wording throughout: say what a class is rather than what O2 used to
  lack, and "encloses" rather than "measures against".
The previous text described the behaviour of the branch before the envelope
existed, so most of it was wrong rather than merely stale.

- run.sh now fixes the seed in both runs. Without it o2-sim picks one per run,
  the two simulations see different primaries, and the difference between them
  is mostly different events: an unseeded pair read 2.25x faster, a seeded pair
  reads 5%.
- Measured on five pp events with PIPE and ABSO: 1547 tracks per event with
  detailed transport against 1144 with the toy model, 14.9 s against 14.2 s.
- Says why a quarter fewer tracks buys five percent of wall clock, and that
  neither number is a performance result or a physics validation.
- Records the two properties that surprise a reader of the output: a fast step
  does not call the sensitive detector, and its secondaries carry kPNull.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants