How to set a wavelength bandpass filter in sequential mode?
Hi Zemaxers
In sequential mode, how to set a filter like below? or is it possible to set such a layout in sequential mode?
The filter has two parts, the upper area blocks 500nm and below, and the other half is OK for all wavelengths.
Best regards
YANG
Page 1 / 1
Hi Yang,
In sequential mode, a ray cannot “skip” a surface so you cannot simply have a single configuration with a 500nm band pass filter that is decentered. However, you can split your image plane into 2 halves with multi-configs, use a TABLE coating to create a cutoff filter and then use a number of paired down analysis which can merge the 2 configurations back together (Spot Diagram, Footprint Diagram, Geometric Image Analysis, Huygens PSF, Huygens MTF).
However, the better approach would be to create a User Defined Surface and leverage the UD->rel_surf_tran property. In the User Data structure, you have access to the ray’s XY coordinates (UD->x and UD->y) and in the Fixed Data structure, you have access to the ray’s wavelength (FD->wavelength). So the pseudo code in case 5 of the UDS would look something like this:
case 5: if (UD->y >= 0.0 && FD->wavelength >= 0.5) { UD->rel_surf_trans = 0.0; }
if (FD->cv == 0.0){ if (Refract(FD->n1, FD->n2, &UD->l, &UD->m, &UD->n, UD->ln, UD->mn, UD->>)) return(-FD->surf); } else { /* not a plane, copy code from UDS example for snell’s law refracting */
} break;
There are 8 different UDS filter examples in the Zemax\DLL\Surfaces folder that can help you get started.
P.S. If you can use non-sequential, I would suggest doing that. This is a trivial problem in non-sequential mode.
Hi Michael
Thanks for your reply. I think the User Defined Surface can make it.
I will have a try
Thanks again!
Yang
Hi Yang,
In sequential mode, a ray cannot “skip” a surface so you cannot simply have a single configuration with a 500nm band pass filter that is decentered. However, you can split your image plane into 2 halves with multi-configs, use a TABLE coating to create a cutoff filter and then use a number of paired down analysis which can merge the 2 configurations back together (Spot Diagram, Footprint Diagram, Geometric Image Analysis, Huygens PSF, Huygens MTF).
However, the better approach would be to create a User Defined Surface and leverage the UD->rel_surf_tran property. In the User Data structure, you have access to the ray’s XY coordinates (UD->x and UD->y) and in the Fixed Data structure, you have access to the ray’s wavelength (FD->wavelength). So the pseudo code in case 5 of the UDS would look something like this:
case 5: if (UD->y >= 0.0 && FD->wavelength >= 0.5) { UD->rel_surf_trans = 0.0; }
if (FD->cv == 0.0){ if (Refract(FD->n1, FD->n2, &UD->l, &UD->m, &UD->n, UD->ln, UD->mn, UD->>)) return(-FD->surf); } else { /* not a plane, copy code from UDS example for snell’s law refracting */
} break;
There are 8 different UDS filter examples in the Zemax\DLL\Surfaces folder that can help you get started.
P.S. If you can use non-sequential, I would suggest doing that. This is a trivial problem in non-sequential mode.
Hi Michael and zemaxers,
I have tried the UDS but got the result not as I thought
y>=0 && wave >=0.5 rel_surf_tran =0
there shall be no spot in red rectangle area of the pic below, right?
I am just wondering where I am wrong .
Would you please have a check with my file?
Thanks
Yang
@Yang.Yongtao
From what I can test, the DLL works (I didn’t look at the code, I’m assuming it has been programmed correctly). If you run a Analyze..Polarization..Transmission Fan this is what you get (I added an additional wavelength at 400nm):
400nm is transmitted all the way across field points. 500nm and 600nm are partially blocked at 0deg and the cutoff is at Py = 0. At 2deg, 500nm and 600nm are totally blocked. At -2deg, 500nm and 600nm are transmitted.
The issue seem to be with the Spot Diagram. The Spot Diagram always shows the ray landing coordinates irrespective of their transmission. Interestingly, checking/unchecking Use Polarization didn’t have a significant effect. I did another dummy test on a dummy file:
And using Analyze..Extended Scene Analysis..Geometric Image Analysis, I got:
Which is what you expect, I think. One thing you could try is create the spot diagram with the ZOS-API as described in Example 22, and only plot the rays with a sufficient out double intensity:
Let me know if that works for you (sorry I haven’t got the time to test it myself today )
Take care,
David
Hi @David.Nguyen
Thanks for your replying, and I checked the dll, it works well in Geometric Image Analysis.
And about the spot diagram is a still puzzle for me. I have tried the Example22 python code (since I am not so familiar with c or c++, and no develop environment )
Environment
python 3.10 64bit
PyCharm Community Edition 2022.1
Ansys Zemax OpticStudio 2024 R1.03
The error says, IAS has no field method
and checked the dir, there is no Field method in it.
But in the help document, it shows 「ZOSAPI.Analysis.Settings.IAS_Field」
I am wondering where the error happens, and c++ use a similar code, I wonder whether it works well.
Could you give me some suggestions?
Best regards
Yang
@Yang.Yongtao
I’m not sure I understand your issue, but here’s a Python code that works for me in R1.00, Python 3.10, Pythonnet 3.0.3. Your version of PyCharm shouldn’t matter. It creates a spot diagram from the field Hx = 0, Hy = 0 at a specific wavelength wav_num. The number of spots is stored in the variable max_rays. Compared to Example 22, I sample rays from a circle (as opposed to a square). Also note that I’m not showing spots whose intensity is 0 (ray_datae-1]!=0).
from random import random import matplotlib.pyplot as plt import math
import clr, os, winreg from itertools import islice from System import Enum, Int32, Double
# This boilerplate requires the 'pythonnet' module. # The following instructions are for installing the 'pythonnet' module via pip: # 1. Ensure you are running a Python version compatible with PythonNET. Check the article "ZOS-API using Python.NET" or # "Getting started with Python" in our knowledge base for more details. # 2. Install 'pythonnet' from pip via a command prompt (type 'cmd' from the start menu or press Windows + R and type 'cmd' then enter) # # python -m pip install pythonnet
# add the NetHelper DLL for locating the OpticStudio install folder clr.AddReference(NetHelper) import ZOSAPI_NetHelper
pathToInstall = '' # uncomment the following line to use a specific instance of the ZOS-API assemblies #pathToInstall = r'C:\C:\Program Files\Zemax OpticStudio'
# connect to OpticStudio success = ZOSAPI_NetHelper.ZOSAPI_Initializer.Initialize(pathToInstall);
TheConnection = ZOSAPI.ZOSAPI_Connection() if TheConnection is None: raise Exception("Unable to intialize NET connection to ZOSAPI")
TheApplication = TheConnection.ConnectAsExtension(0) if TheApplication is None: raise Exception("Unable to acquire ZOSAPI application")
if TheApplication.IsValidLicenseForAPI == False: raise Exception("License is not valid for ZOSAPI use. Make sure you have enabled 'Programming > Interactive Extension' from the OpticStudio GUI.")
TheSystem = TheApplication.PrimarySystem if TheSystem is None: raise Exception("Unable to acquire Primary system")
def reshape(data, x, y, transpose = False): """Converts a System.Doublet,] to a 2D list for plotting or post processing
Parameters ---------- data : System.Doublet,] data directly from ZOS-API x : x width of new 2D list wuse var.GetLength(0) for dimension] y : y width of new 2D list wuse var.GetLength(1) for dimension] transpose : transposes data; needed for some multi-dimensional line series data
Returns ------- res : 2D list; can be directly used with Matplotlib or converted to a numpy array using numpy.asarray(res) """ if type(data) is not list: data = list(data) var_lst = vy] * x; it = iter(data) res = list(islice(it, i)) for i in var_lst] if transpose: return self.transpose(res); return res
def transpose(data): """Transposes a 2D list (Python3.x or greater).
Useful for converting mutli-dimensional line series (i.e. FFT PSF)
Parameters ---------- data : Python native list (if using System.Datay,] object reshape first)
Returns ------- res : transposed 2D list """ if type(data) is not list: data = list(data) return list(map(list, zip(*data)))
print('Connected to OpticStudio')
# The connection should now be ready to use. For example: print('Serial #: ', TheApplication.SerialCode)