ZPL Macro: Mapping Function Resolution Doesn't work

  • 8 July 2022
  • 1 reply


I’m new in OpticStudio and I’m trying to use the macro Mapping Function Resolution created by OpticStudio that we can find here and implement it in my OpticStudio simulation.

The modified code is the following:

! Calculate Mapping Function and Resolution
! Lorenz Martin, 4 Feb 2020

! Get number of system wavelengths
num_wav = SYPR(201)

! Define wavelength range
min_wav = WAVL(1)
max_wav = WAVL(num_wav)
delta_wav = 0.01
num_wav_steps = INTE((max_wav - min_wav)/delta_wav) + 1

! Define variables
DECLARE wavelengths, double, 1, num_wav_steps + 1
DECLARE y_positions, double, 1, num_wav_steps + 1
DECLARE wavelengths_for_d, double, 1, num_wav_steps
DECLARE d_wavelengths, double, 1, num_wav_steps
DECLARE d_y_positions, double, 1, num_wav_steps
DECLARE resolution, double, 1, num_wav_steps

! Set MC operand to change Wavelength 1

! Loop to go through wavelength range and find position of beam on detector with respect to central wavelength
FOR i, 0, num_wav_steps, 1
wavelength = min_wav + i*delta_wav
SETMCOPERAND 1, 1, wavelength, 0
RAYTRACE 0, 0, 0, 0, 1
yf = RAYY(21)
wavelengths(i+1) = wavelength
y_positions(i+1) = yf
IF (i>0)
wavelengths_for_d(i) = wavelengths(i) + delta_wav/2
d_wavelengths(i) = wavelength - wavelengths(i)
d_y_positions(i) = yf - y_positions(i)
resolution(i) = -d_wavelengths(i)/(d_y_positions(i)*1000)
! Uncomment next line to display numerical values
PRINT "Wavelength / nm: ", wavelength*1000, " Fy: ", ," ", yf

! Reset system wavelength to initial value
SETMCOPERAND 1, 1, min_wav, 0

! Plot mapping function
PLOT TITLE, "Mapping Function"
PLOT TITLEX, "Wavelength [um]"
PLOT TITLEY, "Position [mm]"
PLOT BANNER, "Position of wavelength on detector, relative to position of primary wavelength"
PLOT RANGEX, wavelengths(1), wavelengths(num_wav_steps+1)
PLOT TICK, 0.05, 0
PLOT DATA, wavelengths, y_positions, num_wav_steps + 1, 0, 0, 0

! Plot resolution
PLOT TITLE, "Spectral Resolution"
PLOT TITLEX, "Wavelength [um]"
PLOT TITLEY, "Resolution [pm/um]"
PLOT BANNER, "Fraction of bandwidth per detector width"
PLOT RANGEX, wavelengths_for_d(1), wavelengths_for_d(num_wav_steps)
PLOT TICK, 0.05, 0
PLOT DATA, wavelengths_for_d, resolution, num_wav_steps, 0, 0, 0

I received this output:

Wavelength / nm: 245,0000 Fy:  12,5000
ERROR: Divide by zero error on line 37
Wavelength / nm: 255,0000 Fy: 12,5000
Wavelength / nm: 265,0000 Fy: 12,5000
Wavelength / nm: 275,0000 Fy: 12,5000
Wavelength / nm: 285,0000 Fy: 12,5000
Wavelength / nm: 295,0000 Fy: 12,5000
ERROR: Divide by zero error on line 37
Wavelength / nm: 305,0000 Fy: 12,5000
ERROR: Divide by zero error on line 37
Wavelength / nm: 315,0000 Fy: 12,5000

But, as you can see, the wavelengths shown are not the ones I selected and there are errors “divide by zero”.
For this reason i have this bad graphs:

  • I ask you, how can i change the code in order to run it for my specific case?

    I also upload as attachments my .ZOS file and macro .ZPL

    Can you help me please?

    Best Regards.


Best answer by David.Nguyen 13 July 2022, 11:57

View original

1 reply

Userlevel 6
Badge +2

Hi SM_PhD,


Among the errors, the first one specifies:

ERROR: Divide by zero error on line 37

Line 37 in your code is the following:

resolution(i) = -d_wavelengths(i)/(d_y_positions(i)*1000)

If your variable d_y_positions(i) equals to zero, then there’s a division by zero, and this isn’t possible. Thus, OpticStudio throws an error.

If we look at where d_y_positions(i) is defined:

d_y_positions(i) = yf - y_positions(i)

We can see that it can only be zero if y_positions(i) is equal to yf or if both yf and y_positions(i) are equal to zero. Once again, if we look at your code, we can find the following definitions. First, for yf:

yf = RAYY(21)

This is the ray Y-coordinate as traced by the RAYTRACE keyword.

The second definitions is for y_positions(i):

y_positions(i+1) = yf

In this case, your code defines the next y_positions(i+1). What can happen, is that if yf is the same in two consecutive iterations of the loop. Then, you’ll have the error because y_position(i) will be equal to yf.

Now, in your code, you are actually printing the value of yf with this line of code:

PRINT "Wavelength / nm: ", wavelength*1000, " Fy: ", ," ", yf

If we look at the output, the value of yf is constantly 12,5000. That is why the error is happening: yf is always 12,5000, therefore ypositions is always 12,5000 and d_y_positions is 0.0.

I let you think about this, and see for yourself how you can correct this behaviour. Any other question, let us know.

Take care,