"Safety" variable in ComputeStep function in G4Navigator class


So I was trying to find the intersection of a particle moving along a particular direction with the volume boundary. I figured that the ComputeStep function from the G4Navigator would be useful for that purpose.

Looking at the ComputeStep function definition (from http://www.apc.univ-paris7.fr/~franco/g4doxy4.10/html/class_g4_navigator.html#a9a78e5db374334d93ca5af69c029ee0b ),

ComputeStep (const G4ThreeVector &pGlobalPoint, const G4ThreeVector &pDirection, const G4double pCurrentProposedStepLength, G4double &pNewSafety)

the first variable is the point (the particle), second the direction (the velocity) and third is sort of any proposed length which might make the particle end up in the next volume.

I’m not quite sure what the 4th variable does/mean. I went through the code and the book for application developers as well, but couldn’t exactly figure out what the “pNewSafety” variable does. I’ve seen the safety variable used in a lot of other functions as well. Could anyone please let me know what exactly is the use of the safety variable??


this variable means value of safety at the post step point. This name mean that it is recomputed and may be different from the value pre step.



Thanks for the response. I guess I was looking for the meaning of the safety variable, as in, what purpose does it serve for any point (post step point or pre step point). What does it actually do?

Another reason why I wanted to understand the use of the safety variable is because I’m using the ComputeStep function in my code to find the distance from a point to the volume boundary along a certain direction and the results I’m getting are not what I’m expecting. So I’m wondering if the value for the safety variable I’m using in the function is correct or not.

In my code, I have a certain point within a volume (a particle), with a certain directionality (it’s velocity), and I have the current proposed step length (the third argument for the function) as the mean free path (MFP) of the particle in the particular volume. I expect the ComputeStep function to give me a finite result when the MFP is more than the distance of the particle from the volume boundary (along it’s velocity direction) - that’s because in that case, the particle exits the volume. In some cases, I do get a finite value from ComputeStep while the particle is changing volumes, but other times I don’t. I get 9e+99 from the ComputeStep function even when the particle is changing volumes. That’s baffling for me. Is it something related to how volumes are defined in my geometry or has it something to do with the ComputeStep function (and the safety variable)??

Also, is there an easier/another way of getting the distance from a particular point in a volume to the volume boundary along a certain direction? (For example, a particle moving with a certain velocity in a particular volume. I want to find the distance of the particle from the volume boundary at every step.)

Any help with this question will be much appreciated. Thanks.


Safety means , that within sphere with radius safety there is no any geometry boundary.


Okay, that makes much more sense now. Thanks a lot.

A correction: the safety value returned by ComputeStep is for the point ‘pGlobalPoint’ which is the first argument of the call. This is the only guarantee.

This point could be the ‘preStep’ point of a step if the particle is neutral, if it is charged but there is no EM field, or if it is the first trial step for a charged particle in an EM field. That position can never be the ‘postStep’ point of the current step – except if the step size was zero.

The Transportation process will estimate the isotropic safety of the endpoint of a step using the information obtained from ComputeStep – and potentially by calling G4Navigator’s ComputeSafety method.

I agree with your expectation of a finite result from ComputeStep during steps in which a new boundary is found. It is not clear to me how you are obtaining the value from this call.

Normally it will become the step size in Geant4 Tracking – in which case the value of kInfinity will be translated into the proposed step size.

I do not understand from your description whether you are using the Geant4 tracking or you are calling G4Navigator yourself (which would need care to follow its expected protocol - e.g. calling LocateGlobalPointAndSetup before each call to ComputeStep).

I note that mixing the two using the same instance of G4Navigator will confuse both the G4Navigator and the state of the Geant4 tracking and could lead to the confusing output which you are getting.

If your geometry is ‘simple’ - i.e. it does not contain repeated volumes such as replicas, divisions and parameterised volumes - then you can safely use another instance of G4Navigator in parallel with the one used by Geant4 Tracking (in particular the Transportation Process).


I do not understand from your description whether you are using the Geant4 tracking or you are calling G4Navigator yourself (which would need care to follow its expected protocol - e.g. calling LocateGlobalPointAndSetup before each call to ComputeStep).

Sorry, I don’t really know the difference between “Geant4 tracking” and “calling G4Navigator” explicitly.

The exact code where I use the ComputeStep function is this

G4double stepToNextVolume = theNavigator->ComputeStep(Pos, Vel, forward_displacement, safety);

where Pos and Vel is the position and velocity of the particle, forward_displacement is the proposed step length and safety is a safety variable defined. The navigator variable ‘theNavigator’ is a global variable defined earlier in the code

    theNavigator = G4TransportationManager::GetTransportationManager()->GetNavigatorForTracking();

Although I should note here that I do use the LocateGlobalPointAndSetup function (to find the physical volume the point Pos belongs to) BEFORE using the ComputeStep function.

G4VPhysicalVolume* pv = theNavigator->LocateGlobalPointAndSetup(Pos, (const G4ThreeVector*)0,false, true);

I do use LocateGlobalPointAndSetup a few more times after this instance (but before the ComputeStep function)

The Pos variable is usually updated by the forward_displacement (unless it crosses a volume boundary) and I was trying to find the distance to the next boundary using the ComputeStep function.

If you could please clarify what this means

using the Geant4 tracking or you are calling G4Navigator yourself (which would need care to follow its expected protocol - e.g. calling LocateGlobalPointAndSetup before each call to ComputeStep).

that would be great.

Thank you for the response.

Thanks for explaining how you are using G4Navigator. I would term your use as calling G4Navigator yourself, i.e. from your own code.

The alternative would be to hand a particle / track to Geant4, and allow Geant4 to track it, but try to obtain the values which are returned by the calls to G4Navigator. I call that “using Geant4 tracking”.

You do not clarify why you are trying to call G4Navigator directly - what your use case is.

How do I hand the track to Geant4?? I don’t know which class/function to use for that. I’m curious.

I’m writing a vertex generator which tracks a particle through a (complex - as in, I-did-not-define-the-geometry complex XD) geometry and does a similar thing as Geant. That is, calculate the mean free paths for that particle in the particular volume it is in and then generate an exponential random number using that mean free path(MFP) and that is the amount by which my particle moves forward. ( = forward_displacement)

The reason I need to call the G4Navigator directly is because while calculating the MFP for the particle in a particular volume, I need to know which volume the particle is in and hence which material it is made up of. Then, I calculate the mean free path for the particle in that volume using the properties of that material. That’s why I call the G4Navigator - to find the volume of the particle (Pos)

The reason I’m trying to use the ComputeStep function is because I’d like to know the distance from a point to a boundary along a particular direction. That will be compared with the forward_displacement value. If forward_displacement>ComputeStepOutput (i.e. the particle actually crosses the boundary if it moves ahead by forward_displacement), I execute some sort of a transportation step (the transportation step is executed in the simplest way - the particle is moved just ahead of the volume boundary).

Also of note, I’m not sure whether the geometry that my particle traverses is conducive to the use of ComputeStep function. (Maybe the geometry isn’t defined well enough for the use of ComputeStep function)

So my suspicions right now are - 1) The geometry I’m working with is the problem. 2) Something is wrong with the way I’m using ComputeStep (wrong safety value, improper use of the G4Navigator, etc.)

Hopefully, that clarifies the use case.

Thanks for your time.

Indeed you should validate your geometry. If volumes overlap with their siblings or extend outside the mother volume, the geometry is ill defined and the navigator will not give reliable answers. You should check the Users Guide for Application Developers to see how to use the overlap checking capabilities of Geant4.

Note also that the safety is calculated by the Navigator - so if it seems incorrect it is a symptom of an ill defined geometry.

Hi, thanks. I’ll validate the geometry, eventually.

Right now, I’m just working with the naivest possible logic, calculating the distance to the next volume boundary in increments of a stepSize (=1 micrometer). I’m saving that value and checking against it for every iteration; invoking transportation step when particle step exceeds distance to next volume.