Photon backscattering depth measurement and modifying angular distribution graph

Respected FLUKA experts,
I need your guidance on two nominal points.

  1. I need to score the depth from which the photons are being backscattered from inside a target and then enter the target. I am trying to achieve this using biasing method where I divided the target region into multiple regions e.g., many vertical slabs each of 2cm thickness and then using USRBDX to register the photons leaving the target. But it is very long and need multiple cards. Is there any other way? All I need is the depth of the photons scattered back to the detector.
  2. Besides this, I scored the double differential yield current for angular distribution to see at which angle most photons are being registered. For this I am using ie=Polar θ lab deg, and ia=Ekin GeV. I am getting X-axis as cosine. But I wand x-axis as the angular interval and the y-axis as the yield (N). I even tried to follow this post but it was not helpful for me (Angular distribution of USRYIELD - #9 by dbozzato)

Hi Abdul,

I will have a look into your problem and come back to you in few days with a more detailed answer, but first I would like to understand it better:

  1. If it’s not too complicated, could you please provide a FLUKA/Flair file that you are using for your simulation? Just to understand your geometry a bit better, it’s always easier to see it than just describing.

  2. You say

I need to score the depth from which the photons are being backscattered from inside a target and then enter the target.

If the photons are backscattered from inside the target then what do you mean by requiring that they THEN enter the target? I understand that you want to look at the ones that are already inside the target when they backscatter.

The very first idea that I have is that it would be the easiest to use the mgdraw.f routine where you could set up a certain logic asking for the position of each backscattered photon. I need to think how to do it in the most efficient way, but in the meantime you can have a look yourself in the manual
https://flukafiles.web.cern.ch/manual/chapters/user_routines/user_routines/mgdraw.html
and on how to work with user routines

Cheers,
Jerzy

The detector is divided into multiple segments, each responsible for detecting radiation along a specific path or line of sight. To achieve this separation, a mechanism is employed to isolate each segment, ensuring that it only receives radiation along its designated path. In this case, stainless steel collimators are utilized to enhance, rather than remove, certain desired backscatter radiation. The geometry figure illustrates my intention to measure the depth at which scattered photons are being reflected back from the target.


This depth needs to be determined in order for the detector to collect photons that are backscattered from the object’s surface, as well as from hidden objects or voids beneath the surface. Additionally, this depth value will assist in determining the maximum depth level of the backscatter photon within a target of specific thickness.
In addition to the depth, I am interested in identifying the aperture number at which the backscattered photons will be counted by the detector.

Before utilizing this setup, it is necessary to ascertain the most suitable angle at which the detector can be positioned to maximize the number of backscattered photons. To accomplish this, I utilized USRYIELD to analyze the angular distribution in the AIR region. However, the resulting graph displays the cosine angle on the x-axis, whereas I want the angle in degrees.
I am also attaching the basic geometry file herewith.
I hope it make it clear for you.
Simple.flair (18.2 KB)
Simple.inp (4.5 KB)

Hi,
I tried using BXDRAW of mgdraw.f with the following lines:
IF ( JTRACK==7 .AND. CZTRCK<0 .AND. NEWREG>5 ) THEN
! WRITE (IODRAW, *) ‘from’, MREG, ‘to’, NEWREG, ETRACK, TTRACK
WRITE (IODRAW, *) NCASE, ‘from’,
& MREG, ‘to’, NEWREG, JTRACK, TTRACK(1), XTRACK(0),
& YTRACK(0),ZTRACK(0), XTRACK(1),YTRACK(1),ZTRACK(1),
& CXTRCK, CYTRCK, CZTRCK, (ETRACK-AM(JTRACK))
END IF
RETURN

But the results are not satisfactory. most of the photons are entering directly into the detector and very less are entering by the apertures and those number are not enough to be considered as a result.

Hi Abdul,

Let’s take a step back.
First of all, I would divide your apertures into separate regions so that you could set up an individual USRBDX between the aperture and the detector region for each of the apertures.

Now let’s try to clarify what is that you are actually trying to obtain from this simulation. Is it just the maximum depth of a primary photon interaction that could be seen in your detector? For that, you could parametrically increase the target thickness and check how your signal in all the detector channels (apertures) changes. You could achieve this for example with USRBDX set up as I described above. In this way you would be able to see at what target thickness the photon distribution does not change anymore.
Theoretically, the maximum interaction depth is always equal to the target thickness, it’s just the detection probability that goes down and at some point becomes so small that you don’t care anymore.

If you however want to know the backscattering depth distribution for each detector channel, you have to keep in mind that this problem is more complicated because of the fact that the primary photon can in principle initially scatter forward and then produce a secondary photon which eventually ends up in your detector. Also, the depth of the primary interaction would have to be propagated to all the secondaries in the electromagnetic shower so that it could be associated with the primary photon at the detection point. This is in principle possible, but would require to use the
STUPRE function:
https://flukafiles.web.cern.ch/manual/chapters/user_routines/user_routines/stupre.html

Let me know,
Cheers,
Jerzy

Respected Jerzy,
I am only interested in backscattered photons from the target into the detector. Consider the following picture.


Here I cam easily find the primary beam depth inside target (i.e., 40) using USRTRACK or USRBIM withe beampart. What thing I am interested is in 41 that is the backscattered photons from target to detector channels. The only problem I am encountering is that the photons are not directly reaching the detector channels from the target instead they are coming into the air region this ultimately provide me the backscattered photons depth from target into the air region but not from target to detector segment.

For the case of primary and secondary photons I tried using the following in usdraw
ENTRY USDRAW ( ICODE, MREG, XSCO, YSCO, ZSCO )
IF (ICODE .EQ. 219) THEN
SPAUSR(1) = ZSCO
ELSE
SPAUSR(1) = 0.0
ENDIF

And then used this spausr(1) flag inn bxdraw but the results were zero.
Instead of using stupre we can use the usdraw and flag the variables in bxdraw.

However still the main problem is that first the photons (either primary or secondary) should directly reach the detector segment from the detector which needs to be solved. Also I am more interested in photon counts tht are reaching the detector segments instead of their spectra. Alongside the depth, I also need to score the angle at which they are backscattering, the exit plane distribution, and the energy etc.

I’ll be very thankful if you could suggest some solution.

Dear FLUKA experts,
I am running a FLUKA simulations where my aim is to score the photons directly in the detector that are being scattered back from the target. But When I tried to do so using BXDRAW entry of mgdraw.f I got only those photons that are being scattered back in to AIR region and then from AIR to detector (very few) file. Whereas my aim is to score photons only from target to detector directly. i am looking for your help in this matter.
Thank you.
simple.flair (6.4 KB)
simple.inp (2.7 KB)
mgdraw-1025.f (10.2 KB)

Hi Abdul,

Ok, now I think that we understand each other better. What you are trying to do is a good start, it would seem that you don’t need to modify the STUPRE function as the user flags should be propagated by default - in fact however, it has to be modified to be absolutely sure that the primary interaction data will be saved and propagated.
Please have a look at this thread:

Also, a discussion of a problem similar to yours can be found here:

With your approach, you are asking for any Compton scattering, which would also have to be the very last interaction before your BXDRAW is invoked to see a non-zero SPAUSR(1).
The logic should like more like this:

ENTRY USDRAW ( ICODE, MREG, XSCO, YSCO, ZSCO )
IF (ICODE .EQ. 219 .AND. LTRACK.EQ.1) THEN
SPAUSR(1) = ZSCO
ENDIF

By setting a condition of LTRACK==1 you are ensuring that only the primary particle (in your case photons) interaction will modify the SPAUSR in the case where the very first interaction is a Compton scattering. Then you don’t touch the user variable anymore and the number you saved should be propagated until the very last generation. Now, you have to be careful here - what you are doing here will give you the ZSCO of the primary photons, but ONLY the ones whose first interaction was Compton scattering. What I was mentioning before in my previous post, you can in principle have a primary interaction which is different from Compton and still eventually get a signal in your detector.

THE ABOVE CODE WILL NOT WORK FOR YOUR PROBLEM, I just mentioned it to highlight what was conceptually wrong in the way you tried to approach it.

Due to the way that the FLUKA code is structured (you can find more details in the above forum discussions), you actually have to modify the stupre.f function and compile it with your own executable. Please find below two user routines that should do the job for you.
mgdraw_bdx_C2.f (7.0 KB)
stupre.f (4.1 KB)

Below I am discussing the most important code blocks of the attached files.
In the mgdraw_bdx_C2.f you have two non-empty functions:

      ENTRY BXDRAW ( ICODE, MREG, NEWREG, XSCO, YSCO, ZSCO )
	  IF ( .NOT. LFCOPE ) THEN
         LFCOPE = .TRUE.
         FILNAM1 = 'DetectedPhotons'       
         OPEN ( UNIT = 51, FILE = FILNAM1, STATUS = 'NEW')
      END IF

	  CALL GEOR2N ( MREG, MRGNAM, IERR1 )
	  CALL GEOR2N ( NEWREG, NRGNAM, IERR2 )
	  IF(IERR1 .NE. 0 .OR. IERR2 .NE. 0) STOP "Error in name conversion"
	  TFLAG = .FALSE.
	  IF(NRGNAM .EQ. "detector" .AND. MRGNAM.EQ."AIR") TFLAG = .TRUE. 
	  IF(TFLAG) WRITE(51,*) ICODE, NCASE, jtrack, ETRACK-AM(JTRACK), SPAUSR(1)
      RETURN

In this one, you save all the particles which cross the boundary between the air and the detector. It is important that NCASE is saved to associate the detected particles with the primary photons (more below). The SPAUSR(1) is the Z coordinate of the first interaction. Then you have:

      ENTRY USDRAW ( ICODE, MREG, XSCO, YSCO, ZSCO )   
	 IF ( .NOT. LFCOPE2 ) THEN
         LFCOPE2 = .TRUE.
         FILNAM2 = 'ScatteredPhotons'       
         OPEN ( UNIT = 52, FILE = FILNAM2, STATUS = 'NEW')
         END IF

         CALL GEOR2N ( MREG, MRGNAM, IERR1 )
	 IF(IERR1 .NE. 0 ) STOP "Error in name conversion"
         IF(MRGNAM .EQ. "TARGET" .AND. LTRACK.EQ.1) THEN
	    WRITE(52,*) ICODE, NCASE, jtrack, ETRACK-AM(JTRACK), XSCO, YSCO, ZSCO, MRGNAM
	 ENDIF

Where we save the information about the very first interaction of the primary photons (LTRACK == 1) whose interactions happened inside the target.
Now the magic happens in the stupre.f function:

      LOGICAL LBHABH
      LOGICAL PRIMER
      CHARACTER*8 MRGNAM
*
      CALL GEOR2N ( IREMF(1), MRGNAM, IERR1 )
      WRITE( LUNOUT,* ) MRGNAM
      IF(LTRACK.EQ.1 .AND. MRGNAM.EQ."TARGET") THEN
	 PRIMER = .TRUE.
      ELSE 
	 PRIMER = .FALSE.
      END IF

      IF ( LDLTRY ) THEN
         LBHABH = ICHEMF (NPEMF) * ICHEMF (NPEMF-1) .LT. 0
      ELSE
         LBHABH = .FALSE.
      END IF

      DO 500 NPNW = NPSTRT,NPEMF
	 IF (PRIMER) THEN 
	    ESPARK(1, NPNW) = ZEMF(NPNW)
	 ELSE
	    ESPARK(1, NPNW) = SPAUSR(1)
	 END IF
	 DO 51 ISPR = 2, MKBMX1
            ESPARK (ISPR,NPNW) = SPAUSR (ISPR)
 51      CONTINUE 
         DO 52 ISPR = 1, MKBMX2
            IESPAK (ISPR,NPNW) = ISPUSR (ISPR)
 52      CONTINUE
         LOUEMF (NPNW) = LLOUSE

The PRIMER flag is there to check whether we are dealing with the primary particle and the interaction happened inside the target. In fact, IREMF(1) is the region number of the first particle which is already loaded to the emf stack - stupre.f unlike stuprf.f does not have direct access to MREG - the last region of the track which is finishing its life.
The function action is different from the default one only when the PRIMER conditions are fulfilled - the last Z coordinate is saved to the user variable which then is correctly propagated until the end with the default behaviour of the STUPRE function.

Your simulation should finish with 2 files: ScatteredPhotons and DetectedPhotons. In ScatteredPhotons you have all the primary interactions with the information about the primary photon interaction. In DetectedPhotons you have the particles entering the detector together with the information of the primary interaction depth in Z. You can intersect both files with the NCASE variable.

ALTERNATIVELY

If you don’t want to mess with all the stupre.f magic, you can also skip this part and compile only the mgdraw_bdx_C2.f. Then you can still associate the primary interactions with the detected particles using NCASE and extract the information about the Z-depth only from ScatteredPhotons.

I hope that helps!

Cheers,
Jerzy

Respected Jerzy,
Thank you very much for a detailed reply. I will try to understand and implement it and will come back to let you know in any case.
Thank you.

Respected Jerzy,
I tested the routines provided by you. and here I have some confusion. I could be wrong but still i need your comments.

  1. After creating an intersected file from both the DetectedPhotons and ScatteredPhotons based on common NCASE in both files, I came to know that the interaction point (mentioned in USDRAW) ZSCO and the detected point (from BXDRAW) SPAUSR(1) both are same.

    The point to ask is that how it could be possible that the photons being scattered and detect by detector both are at the same point? Although the interaction takes place within the target region which is from 0 to 5 along Z-axis where as detector is place outside the target.
  2. If the scattering is happening somewhere inside the target (lets say at 2 z-axis) then this scattered photon from the target must be detected where the detector is placed (lets at -1.2 Z-axis).
  3. In both scatteredPhotons and Detected photons the ZSCO is only upto the boundary of the Target whereas the detected photons should be beyond the boundary of the target. While we need to track the photon after being Compton scattered from the target till the detector.
    I apologize if say anything wrong. I am looking forward for your response.
    wk1025-mgdraww.flair (7.3 KB)
    wk1025-mgdraww.inp (4.5 KB)
    mgdraw_bdx_C2.f (7.0 KB)
    stupre.f (4.1 KB)

I made a minor change by adding an additional variable in BXDRAW subroutine namely ZTRACK(1) and did the same procedure as mentioned in previous

And then I could clearly see the photons directly from the interaction point till the detector region.

I just wanna to confirm if this approach is correct?

Respected Jerzy,
In addition to the previous comments I also need your suggestion regarding the Compton scattered photon counter from target to detector. Which was also one of the goal of the problem

For this I tried to use Louse in the bxdraw with the following stupre routing
INTEGER COUNTER
SAVE COUNTER
DATA COUNTER / 0 /
IF((KPART(NPSECN).eq.7)) THEN
COUNTER = COUNTER + 1
LOUSE(NPFLKA) = COUNTER
ENDIF
but this did not work for me. and printing 0. How can I implement this counter correctly? Basically, I need the number of photons reaching the detector which will I use to plot with the energy ultimately generating an energy count graph.

Hi Abdul,

Pay attention to the fact that the ZSCO in BXDRAW and ZSCO in USDRAW are NOT THE SAME variables! What you are doing with ZTRACK(1) should in principle give you what you want, but you should rather use the ZSCO inside the BXDRAW routine to correctly score the Z-coordinate of a particle crossing the boundary.

About the counter, I advise you not to mess with the stupre.f routine. An easier way to do it is to divide your detector apertures in separate regions (I mentioned it before) and then adjust your BXDRAW code accordingly. You could put a condition that the region before boundary crossing (MREG) is one of the apertures and save the region number in the DetectedPhotons file. Then you just count how many times an aperture region number occurs in the file and you have the number of photons detected per number of primaries generated in your run.

You could also rely on the built-in USRBDX in Flair and set up a scoring for each aperture separately. In that case you should take the one way, current scoring and choose your particle as photon. If you don’t care about the spectrum, you can put only one bin in both the energy and the angle. This should give you the photon count per primary.

I hope that helps.

Cheers,
Jerzy