Proper way to delete secondaries created only in current step?

In my experiment, we are making use of a SteppingAction to record the flux of particles at a surface, before reaching our active detector volume. The idea is to record what makes it through our shielding, and then rethrow jobs with that same flux, using different detector configurations to evaluate backgrounds and performance. To speed up the flux recording jobs, we have the SteppingAction set the tracks to fStopAndKill, which ends the event without bothering to track everything beyond the surface of interest.

We’ve discovered that at a low, but not negligible rate, the tracks can make secondaries right at the surface. When we kill the track, those secondaries keep on going, and can either waste time being tracked, or even scatter around and end up “contaminating” our flux measurement.

Is there a proper way to kill a track along with only the secondaries created during the current step? The fKillTrackAndSecondaries isn’t what we want, because that will also kill all the past secondaries created by the track. Those secondaries themselves might travel through the shielding and should be included in our flux measurement.

Since the SteppingAction is called before the current step’s secondaries get put onto the tracking stack, I think I can do it by way of a bunch of evil const-casts, deleting the tracks listed in the current step’s “secondary bucket”, possibly also going in and removing them from the cumulative G4TrackVector of all secondaries, and then deleting the current-step bucket. But this sounds dangerous. I can’t tell if the nSecondaryByLastStep data member is supposed to be equal to the secondaryInCurrentStep size, and there’s no obvious way to change it.

could regions and „infinite“ production cuts be a solution?

That’s an interesting idea! We do all of our job configuration via macro files (including turning on the particular “step counter” in this situation). We have macro commands to create regions, add volumes, and set both cuts and user limits. It’s worth a try.

Okay, so we tried this. It works, but it’s really exploiting a bug – Bugzilla #2449 – because a production cut longer than the distance through the volume should not kill the track.

We also have the problem that we can set up an analogue to scoring surfaces, by creating a volume in the parallel world and attaching a step counter to it. Production cuts don’t apply in parallel worlds, so this solution wouldn’t work for that case.