Measuring of entrance spectrum of particles through a surface

Dear all,

I would like to measure the incoming energy of a specific type of particle (in this case protons) right when it hits the border of a volume that I have declared as a sensitive detector (SD).

So far, I am using the following code to do this:

const G4VProcess* CurrentProcess=preStepPoint->GetProcessDefinedStep();

if (step->GetTrack()->GetDefinition()==G4Proton::Proton()){

if (CurrentProcess != 0) {
const G4String & StepProcessName = CurrentProcess->GetProcessName();
G4String volumePos = step->GetTrack()->GetNextVolume()->GetName();

if (StepProcessName== “Transportation” && volumePos == “Cube”) {
// processing hit when entering the volume
G4double kineticEnergy = step->GetTrack()->GetKineticEnergy();
CubeHit* kinEn = (*fHitsCollection)[0];

The problem is that for example, if I shoot a 100MeV proton to a water cube (my SD) and then by looking at the verbose, indeed I can see that the proton enters (Transportation) the sensitive volume “Cube” (name of my SD) and has 100 MeV as kinE. The next process in this case is hIoni, still within Cube, with a kinE of 94.4 MeV, but the value of 94.4 MeV is the one being printed out and added to my histogram, instead of the 100 MeV that I was expecting.

I am attaching a screenshot of the Verbose to make this clearer:

Am I doing something wrong? Or perhaps I misunderstood the definition of Transportation process and I need to modify my if conditions to get the answer I’m looking for?

Thank you very much in advance!


in short: it’s correct that the first step that happens within your volume is step # 2 (hIoni). Notice that the table shows “NextVolume”, not the current volume. And since you retrieve the energy of the track (so energy of the post step point) it is already modified by the process. To get the initial energy (before the process happens) you should use:


in more details:

  1. What you call CurrentProcess is actually a process that happened in the previous step (e.g. that is why it is nullptr for step#1). The process that defines the current step is accessible via post step point (not pre). Pre step point is copied from the previous step’s post step point, so pointing to ‘previous process’.
  2. The volume name that you ask for is the name of the next volume (current one is accesible via ::GetVolume()). So, in case of the last step within the volume it’s not equal to Cube (and in some marginal case there could be just one step within a volume, so first = last). Also, I believe it’s part of your SD::ProcessHits method, and if you specify only one SD, this check on volume name is not needed, it’s anyway called only for your SD (it would be necessary e.g. in the user stepping action).
  3. Much simpler check on the step can be done using simple G4Step::IsFirstStepInVolume(). It returns true if the particle has just entered the volume (no matter what process it underwent in this step).
1 Like

Thank you very much, Anna! I followed your recommendations and now I am getting the kinetic energy of the protons right when they hit my detector.