Fluka photo-nuclear reactions, bias, photon replica

Continuing the discussion from Stupre.f and stuprf.f routines / FLUKA stacks:

Dear @ghugo, I am still puzzled by the behavior of photo-nuclear reactions. Specifically, by combining PRINT statements in mgdraw.f (BDXRAW routine) and in stuprf.f I see the following.

A photo-nuclear reaction takes place in an upstream volume (no photon replica reported by stuprf.f), but I see the primary photon entering in a downstream volume, together with the secondary hadrons. I recognize the photon to be the same as the one that initiated the photo-nuclear reaction since it has exactly the same energy.

May I ask you if you can confirm again that, in a photo-nuclear reaction, no matter the value of WHAT(2) for LAM-BIAS, there is never a photon replica in the final state?


Dear Andrea,

Biasing in FLUKA for photo-nuclear reactions is achieved in a different way than for electro-nuclear reactions.
For electro-nuclear reactions, the primary electron is added to the reaction final state (you can see it in GENSTK in mgdraw.f, stuprf.f, etc).
For photo-nuclear reactions instead, the primary photon is indeed never added to the reaction final state (hence you do not see it in GENSTK in in mgdraw.f, stuprf.f). For those reactions, biasing is handled in FLUKA by marking the primary photon as surviving (in pphnev.f), and duplicating it into FLKSTK.
Tracking of the same photon will then be launched several times, following the usual FLUKA particles tracking ordering logic of a stack (last-in, first-out).

This is independent of the value of WHAT(2) in LAM-BIAS (as usual, if positive, the primary always survives with a reduced weight, while if negative, Russian Roulette is applied and will randomize the decision on whether the primary survives).

Hence, you will be able to see the same primary photon several times in mgdraw.f and stuprf.f (since the same photon tracking is launched several times, it will occur that the same photon undergoes similar events, e.g. a boundary crossing, or a photo-nuclear reaction).
You can also print out all particles in FLKSTK in e.g. mgdraw.f:

write(*,*) "Mgdraw: NPFLKA = ", NPFLKA
            write(*,*) "Mgdraw: IFLKA = ", IFLKA
            write(*,*) "Mgdraw: TKEFLK(IFLKA) = ", TKEFLK(IFLKA)
            write(*,*) "Mgdraw: TZFLK(IFLKA) = ", TZFLK(IFLKA)
end do

You will see several primary photons duplicates queued to be tracked, while they do not appear in the photo-nuclear reactions final states.

Then it also depends what is behind reaction “final state”: in the context of the comparison with electro-nuclear reactions, I meant what we can observe in the dedicated final state COMMONs, but then the biasing still needs to be achieved, and it could also be considered as “whatever we are left with at the end of the reaction, also taking into account biasing”.

Hope this clarifies,

1 Like

Dear Gabrielle,
I thank you for your detailed answer. Is ’pphenv.f’ a new user routine? If so, can I modify it to avoid the primary photon to be declared as surviving?

In my application, I need to avoid this photon to be replicated, independently on how this happens. In other words, I need to ensure energy conservation at the single event level.


Hi Andrea,

no, pphnev is a(n old) FLUKA core routine.

In the absence of LAM-BIAS, the primary photon survival is not an option. But I guess you wanted it to increase your statistics, at the cost of taking into account altered statistical weights (?). Note that energy is conserved thanks to the latter. Nonetheless, event-by-event analysis is questionable in the presence of biasing. In principle, you can kill the surviving photon with usrmed, setting its weight to zero, or distinguish it by means of its statistical weight.

Dear Francesco,
exactly, I have a thin-target setup, and I just want to increase the number of events in which the photon undergoes a photo-nuclear reaction in it. Basically, I want to increase the cross section so that, still, the number of expected interactions per event (i.e. the cross section times the target length * density * avogadro number) is significantly smaller than one, but larger than the real value.

Since I score the energy deposition in a downstream detector event-by-event, I must kill the photon if a photo-nuclear reaction took place. I’ll check now how to properly do this by mean of usermed routine.


Dear Francesco, sorry to disturb again. May I ask you your suggestion concerning the way, in usermed.f, to identify the surviving photon? Is there a flag to signal that a photon already undergo a photo-nuclear reaction (thus, in principle, should have disappeared?) You said that pphnev.h marks the photon as “surviving”, is there a way to get this data?

== I follow-up myself, to ask you if the following solution looks realistic. ==

The FLKSTK is the stack of primary particles, here we add the primary particle (in my case, I do that via source.f). Also the surviving photon is inserted in this stack. Is there any other case in which particles that are not (I) the primary and (II) the surviving photon from a biased photo-nuclear interaction is inserted in FLKSTK? If not, I can check the existence of a photon in this stack and kill it. Clearly, this would not work in case of a primary photon beam, but this is not my case.


Dear Andrea,

On the surviving primary photon, and how to kill it.

  • You said that pphnev.h marks the photon as “surviving”, is there a way to get this data?

How the photon is marked as “surviving” is with a local boolean in the core code, hence not accessible from the user routines.
However, the photon is marked as surviving with a reduced weight. Hence you can easily detect it by just printing out the particle weight, which will be strictly lower than 1. This is how you can distinguish it as added to the FLKSTK, or as a particle in usrmed.f, etc.

  • (I) the primary and (II) the surviving photon from a biased photo-nuclear interaction is inserted in FLKSTK

Secondary photons from other reactions will also appear there.

As Francesco said, you can kill surviving photons in usrmed.f (just kill when weight < 1).

  • avoid the primary photon to be declared as surviving

Are you interested in doing event-by-event scoring with DETECT (1 event being 1 primary history)? If so, with biasing, even if you kill the surviving photons, you will still have possibly several contributions from several photonuclear reactions within 1 event, so the event distribution of energy depositions will still be distorted anyway. DETECT is not compatible with biasing.

Hope this helps,

Dear Gabrielle, I agree that biasing should be used with great care when dealing with event-by-event scoring. In my problem, basically, I have a thin target where I implement biasing, and the biasing factor is such that the probability of photon interaction per event is still much smaller than one (i.e. no multiple interactions should take place).


Dear Gabrielle, colleagues, I report below the method I am using to solve this problem, in case it can be useful for other people.

What happens when a biased photo-nuclear interaction takes place (biasing of cross section = beta > 1, i.e. LAM-BIAS = 1/beta). I assume that the initial photon has weight=1 before the interaction.

  1. The weight of the photon being tracked is adjusted to 1-1./beta and it is still tracked
  2. At the same time, a photon replica is loaded in the main stack (FLKSTK), with same properties of the photon being tracked, and weight=1./beta
  3. When it is time to “track” the replica, the photo-nuclear interaction takes place and secondaries are created and loaded to the stack.

Therefore, in order to kill the photon, I should verify at any time if there is another photon in FLKSTK with the SAME energy. If this is true, I kill via usermed.f the photon being tracked.