Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Remove secondary particles in Geant4 simulation #2263

Merged
merged 7 commits into from
Jul 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,8 @@ class Geant4Simulation final : public Geant4SimulationBase {
std::vector<std::string> materialMappings = {"Silicon"};

std::shared_ptr<const Acts::Volume> killVolume;

double killAfterTime = std::numeric_limits<double>::infinity();
bool killSecondaries = false;

bool recordHitsOfSecondaries = true;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,20 @@ class Volume;

namespace ActsExamples {

/// A G4SteppingAction that is called for every step in
/// the simulation process.
/// A G4SteppingAction that is called for every step in the simulation process.
///
/// It checks whether the particle can be killed according when its position
/// exceeds the configured values for |z| or r.
/// It checks whether the particle can be killed according to the user settings
/// e.g. if its position exceeds the configured values for |z| or r.
class ParticleKillAction : public G4UserSteppingAction {
andiwand marked this conversation as resolved.
Show resolved Hide resolved
public:
/// Configuration of the Stepping action
struct Config {
/// particles outside this volume will be terminated
std::shared_ptr<const Acts::Volume> volume;
/// particles that exceed this global time limit will be terminated
double maxTime = std::numeric_limits<double>::infinity();
/// secondary particles will be terminated
bool secondaries = false;
};

/// Construct the stepping action
Expand Down
12 changes: 6 additions & 6 deletions Examples/Algorithms/Geant4/src/Geant4Simulation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,22 +225,22 @@ ActsExamples::Geant4Simulation::Geant4Simulation(const Config& cfg,
delete runManager().GetUserSteppingAction();
}

ParticleKillAction::Config particleKillCfg;
particleKillCfg.volume = cfg.killVolume;
particleKillCfg.maxTime = cfg.killAfterTime;

SensitiveSteppingAction::Config stepCfg;
stepCfg.eventStore = m_eventStore;
stepCfg.charged = true;
stepCfg.neutral = false;
stepCfg.primary = true;
stepCfg.secondary = cfg.recordHitsOfSecondaries;

ParticleKillAction::Config particleKillCfg;
particleKillCfg.volume = cfg.killVolume;
particleKillCfg.maxTime = cfg.killAfterTime;

SteppingActionList::Config steppingCfg;
steppingCfg.actions.push_back(std::make_unique<SensitiveSteppingAction>(
stepCfg, m_logger->cloneWithSuffix("SensitiveStepping")));
steppingCfg.actions.push_back(std::make_unique<ParticleKillAction>(
particleKillCfg, m_logger->cloneWithSuffix("Killer")));
steppingCfg.actions.push_back(std::make_unique<SensitiveSteppingAction>(
stepCfg, m_logger->cloneWithSuffix("SensitiveStepping")));

// G4RunManager will take care of deletion
auto steppingAction = new SteppingActionList(steppingCfg);
Expand Down
8 changes: 6 additions & 2 deletions Examples/Algorithms/Geant4/src/ParticleKillAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,20 @@ void ActsExamples::ParticleKillAction::UserSteppingAction(const G4Step* step) {

const auto pos = convertLength * track->GetPosition();
const auto time = convertTime * track->GetGlobalTime();
const bool isSecondary =
track->GetDynamicParticle()->GetPrimaryParticle() == nullptr;

const bool outOfVolume =
m_cfg.volume and
not m_cfg.volume->inside(Acts::Vector3{pos.x(), pos.y(), pos.z()});
const bool outOfTime = time > m_cfg.maxTime;
const bool invalidSecondary = m_cfg.secondaries && isSecondary;

if (outOfVolume or outOfTime) {
if (outOfVolume or outOfTime or invalidSecondary) {
ACTS_DEBUG("Kill track with internal track ID "
<< track->GetTrackID() << " at " << pos << " and global time "
<< time / Acts::UnitConstants::ns << "ns");
<< time / Acts::UnitConstants::ns << "ns and isSecondary "
<< isSecondary);
track->SetTrackStatus(G4TrackStatus::fStopAndKill);
}
}
6 changes: 5 additions & 1 deletion Examples/Python/python/acts/examples/simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,7 @@ def addGeant4(
logLevel: Optional[acts.logging.Level] = None,
killVolume: Optional[acts.Volume] = None,
killAfterTime: float = float("inf"),
killSecondaries: bool = False,
physicsList: str = "FTFP_BERT",
) -> None:
"""This function steers the detector simulation using Geant4
Expand All @@ -630,8 +631,10 @@ def addGeant4(
the output folder for the Root output, None triggers no output
killVolume: acts.Volume, None
if given, particles are killed when going outside of this volume.
killAfterTime: float, None
killAfterTime: float
if given, particle are killed after the global time since event creation exceeds the given value
killSecondaries: bool
if given, secondary particles are removed from simulation
"""

from acts.examples.geant4 import Geant4Simulation
Expand Down Expand Up @@ -674,6 +677,7 @@ def addGeant4(
materialMappings=materialMappings,
killVolume=killVolume,
killAfterTime=killAfterTime,
killSecondaries=killSecondaries,
recordHitsOfSecondaries=recordHitsOfSecondaries,
keepParticlesWithoutHits=keepParticlesWithoutHits,
)
Expand Down
1 change: 1 addition & 0 deletions Examples/Python/src/Geant4Component.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ PYBIND11_MODULE(ActsPythonBindingsGeant4, mod) {
ACTS_PYTHON_MEMBER(materialMappings);
ACTS_PYTHON_MEMBER(killVolume);
ACTS_PYTHON_MEMBER(killAfterTime);
ACTS_PYTHON_MEMBER(killSecondaries);
ACTS_PYTHON_MEMBER(recordHitsOfSecondaries);
ACTS_PYTHON_MEMBER(keepParticlesWithoutHits);
ACTS_PYTHON_STRUCT_END();
Expand Down
Loading