Skip to content

[WIP] Add flag for fast simulation to MCParticle#1503

Closed
tmadlener wants to merge 3 commits intoAIDASoft:masterfrom
tmadlener:mcparticle-fastsim-flag
Closed

[WIP] Add flag for fast simulation to MCParticle#1503
tmadlener wants to merge 3 commits intoAIDASoft:masterfrom
tmadlener:mcparticle-fastsim-flag

Conversation

@tmadlener
Copy link
Copy Markdown
Contributor

@tmadlener tmadlener commented Sep 18, 2025

BEGINRELEASENOTES

  • Add a flag to the MCParticle to track whether it has been handled by a fast simulation model

ENDRELEASENOTES

This is the start of this work. The goal in the end is to have an easy way in analysis to check whether an MCParticle has been handled by a fast simulation model or not. This will obviously also require EDM4hep and LCIO to acquire a similar flag, but I would like to finalize a few things here first before going there.

Currently there are a few open questions:

  • Should we have multiple of these flags to disambiguate whether a particle has been fast simulated only in parts of the detector (i.e. probably FAST_SIMULATION_TRK and FAST_SIMULATION_CALO? Or do we simply name this current flag appropriately to _CALO (as that is the main / only use case for this)?
  • Should setting this flag be responsibility of implementors of actual fast sim models, or can we still handle it on the DD4hep side? (The only place where we could conceivably do that would be in the Geant4FastSimShowerModel::check_trigger, but since killing the primary track is also in user responsibility, this should probably be as well)
  • Does this flag need to do something else, other than keeping track of the fact that a particle has been fast simulated? (I don't think it does, but maybe others do)?

Tagging @peter-mckeown @gaede to solicit some inupt explicitly

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Sep 18, 2025

Test Results

   14 files     14 suites   4h 41m 13s ⏱️
  366 tests   365 ✅ 0 💤 1 ❌
2 544 runs  2 543 ✅ 0 💤 1 ❌

For more details on these failures, see this check.

Results for commit 994faf2.

♻️ This comment has been updated with latest results.

@peter-mckeown
Copy link
Copy Markdown

Hi @tmadlener, thanks for starting this. Here's my two cents:

  • I would say splitting this into FAST_SIMULATION_TRK and FAST_SIMULATION_CALO is probably the most generic approach, although calo is currently the main use case as you say
  • I think it would be good to have some way of ensuring the user does not forget to set this flag, as this could cause confusion later (in particular if full simulation was not performed with detailed mode). Whether this is best done inside DD4hep by querying if Geant4FastSimShowerModel::check_trigger is passed as you say or externally I am not sure (I assume technically there is no blocker, since it is just setting a flag based on this condition? The only case I can imagine where having the trigger inside of DD4hep is restrictive is if the user doesn't kill the primary, but I don't think that is really a valid use case- and a flag on the primary wouldn't help then anyway).
  • We have previously considered trying to add some kind of 'fast bit' that would keep track of whether Geant4FastSimShowerModel::check_trigger had failed at some point in the MC lineage of a given particle (to prevent unwanted fast sim triggers). However, I think this is trying to solve a different problem and is also a lot more involved, so probably out of scope for this

@tmadlener
Copy link
Copy Markdown
Contributor Author

Looking into the implementation of the fast simulation inside DD4hep in a bit more detail, it's not entirely clear to me where we would need to place the setting of this status. Users that implement their own fast sim model, definitely do not have access to it any longer, I think, because they only get handed the G4 quantities, but not the DD4hep wrappers around them.

@andresailer
Copy link
Copy Markdown
Member

Maybe using G4Track::SetUserInformation https://geant4.kek.jp/Reference/11.3.2/classG4Track.html ? And then read this from the ParticleHandler?

@tmadlener tmadlener force-pushed the mcparticle-fastsim-flag branch from 12c2af3 to 3268d0e Compare December 18, 2025 19:16
@tmadlener
Copy link
Copy Markdown
Contributor Author

I have added an attempt here to go via the primary map, but this doesn't seem to persist to the output (which is not currently part of the PR!).

This has several issues:

  • It doesn't work
  • Even if it did it probably wouldn't work correctly for non-primaries

I have also tried adding the information to the Geant4ParticleMap that is an extension of the event context. However, that only seems to be populated by the particle handler at the end of the event, so it's empty while we would like to attach something.

I could add a Geant4ParticleInformation with a custom ParticleExtension but that looks a bit overkill for just wanting to set a flag (and it would prevent adding another one by users).

Other possible options would be to hook into Geant4ParticleHandler::mark by adding another flag to the Geant4ActionSD that returns whether it's fast sim or not, but I am not entirely sure if that is as easy as I currently think it is.

Any input welcome :)

@tmadlener
Copy link
Copy Markdown
Contributor Author

Quick summary of the discussion at the meeting just now:

Hooking into Geant4ParticleHandler::mark should work by checking the type of the sensitive action that is attached to the volume and then set the specific bit if it's a fast sim action.

@MarkusFrankATcernch
Copy link
Copy Markdown
Contributor

@tmadlener You could make the type a property of the sensitive action. If not empty return type, otherwise use the type of the dd4hep sensitive detector, which is also a member of the DDG4 sensitive action.

@tmadlener
Copy link
Copy Markdown
Contributor Author

I am not sure I follow your comment. Which type would go into the sensitive action?

Looking a bit closer into the Geant4FastSimShowerModel, I realized it, it's only a Geant4DetectorConstruction, and does not inherit from G4VSensitiveDetector. Hence, my original idea of simply downcasting g4 once more to a Geant4FastSimShowerModel to see if we are being handled by fast sim doesn't work:

G4LogicalVolume* vol = track->GetVolume()->GetLogicalVolume();
G4VSensitiveDetector* g4 = vol->GetSensitiveDetector();
Geant4ActionSD* sd = dynamic_cast<Geant4ActionSD*>(g4);

@MarkusFrankATcernch
Copy link
Copy Markdown
Contributor

MarkusFrankATcernch commented Jan 16, 2026

@tmadlener
Here the sensitive type is copied from the dd4hep SensititveDetector object:

m_sensitiveType = m_sensitive.type();

Normally the type is what is set in the detector constructor by calling SensitiveDetector->setType("c alorimeter" or "tracker" or ....).

This sensitive type is accessed in DDG4 by DDG4/src/Geant4ParticleHandler.cpp using this call here:

{ return m_sequence->sensitiveType(); }

m_sensitiveType is already a data member of Geant4SensDetActionSequence. If one would declare this data member as a property one could overwrite the default value coming from the sensitive detector object....
So for at least the theory.

@MarkusFrankATcernch
Copy link
Copy Markdown
Contributor

MarkusFrankATcernch commented Jan 16, 2026

@tmadlener soll ich das machen oder weisst Du was zu tun ist ?

This seems to be the case only if the hits are made outside of the usual
Geant4 facilities via some global hit maker (as is typically done for
fast sim models). In that case we still end up in the ParticleHandler,
but with a volume that doesn't have an SDAction attached to it.
@tmadlener tmadlener force-pushed the mcparticle-fastsim-flag branch from 3268d0e to 994faf2 Compare January 16, 2026 20:40
@tmadlener
Copy link
Copy Markdown
Contributor Author

I think I am missing something conceptual here entirely. The way I understand it the sensitive action is what transforms the G4Steps into dd4hep hits. However, the Geant4FastSimShowerModel essentially produces G4Steps and it is not a sensitive action but something "orthogonal". Hence, it also never passes through the constructor you pointed me to and I also don't think it becomes part of the sequence(?).

It can be assigned to a region in the detector and if the trigger for it applies it will produce (G4) hits, e.g. via the GFlashHitMaker

this->m_hitMaker = new GFlashHitMaker();
shower_model->SetHitMaker(*this->m_hitMaker);

Or via the one here

https://github.com/key4hep/DDML/blob/aa49b5f3fa42b7a16a72f1945871b0b1379b0351/include/DDML/FastMLShower.h#L185

(which is this one here).

At least with the one in DDML this one also passes through Geant4ParticleHandler::mark once more. However, at least as far as I can see in case it is handled by a fast sim model, it doesn't have a sensitive action attached. I have now done this (some more extensive testing still needs to be done).

@MarkusFrankATcernch
Copy link
Copy Markdown
Contributor

@tmadlener Thomas: Please see here: #1555

@tmadlener
Copy link
Copy Markdown
Contributor Author

Will be replaced by an approach built on #1555 (+ follow ups)

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.

4 participants