GetPSF and GetZernike
aaronroodman opened this issue · 8 comments
Hi,
Two questions:
-
is there a way to retrieve the Zernike coefficients themselves? ie. the functionality of the GetZernike command in ZPL. I can get the text file with them using the 'Zst' button, but what I could really use is the coefficients returned to the python layer.
-
when using the zGetPSF method, I get the error:
TypeError: list indices must be integers, not NoneType
at line 7223 of zGetPSF
thanks Aaron
Hi Aaron,
I will look into both the issues ASAP. I am surprised that the zGetPSF method returns the error. I have used it before without problem. Can you send me the script in which you are using zGetPSF ?
Indranil,
thanks for much for your help - and for making this great tool for using Zemax.
The script I used is just:
import sys
import os
import matplotlib.pyplot as plt
import pyzdde.zdde as pyz
file path
zDir = "C:\Users\roodman\Documents\LSSTsmb://Users//roodman//Documents//LSST"
zmxfile = 'LSST_Ver_3.3_Baseline_Design_Spiders_Baffles.ZMX'
filename = os.path.join(os.path.expanduser('~'), zDir, zmxfile)
ln = pyz.createLink()
ln.zLoadFile(filename)
ln.zGetPSF()
#or with a settingsFile
ln.zGetPSF(which=‘fft’,settingsFile=zDir+’\fftpsf’)
#both ways give this error
Aaron
On Jan 23, 2015, at 8:08 PM, Indranil Sinharoy <notifications@github.commailto:notifications@github.com> wrote:
Hi Aaron,
I will look into both the issues ASAP. I am surprised that the zGetPSF method returns the error. I have used it before without problem. Can you send me the script in which you are using zGetPSF ?
—
Reply to this email directly or view it on GitHubhttps://github.com//issues/41#issuecomment-71299449.
Prof. Aaron Roodman
SLAC National Accelerator Laboratory
Stanford University
SLAC National Accelerator Laboratory E-mail: roodman@slac.stanford.edumailto:roodman@slac.stanford.edu
2575 Sand Hill Rd. Phone: 650-926-2705
MS 29 Fax: 650-926-2657
Menlo Park, CA 94025 URL: http://www.slac.stanford.edu/~roodman
Dear Prof. Aaron,
Thanks for your kind words. The pleasure is really all mine. I will only get to work on this tonight. I hope that I will be able to get back to you with something by tomorrow.
Indranil.
Also, if you have some time, and if you want to take a look at how the zGetPSF()
function works, you may have a look at http://nbviewer.ipython.org/gist/indranilsinharoy/d6857951dce508427b36. It is an IPython notebook containing some of basic tests that I did when I wrote these functions. In any case, I will check out the problem tonight.
Dear Prof. Aaron,
This is regarding the 2nd problem:
I had a quick look at your script, and there is nothing suspicious there. The only reason for the error to show up is that PyZDDE is unable to find the phrase "Data spacing" in the text file generated by Analysis >> PSF >> FFT/Huygens PSF. This could happen if there is a mismatch in the text encoding set for PyZDDE and the text encoding set in Zemax (i.e. Zemax >> Preferences >> Miscellaneous >> TXT File Encoding). Can you check to see if both of them are the same (i.e. either ANSI or Unicode)? You can check the text encoding setting of PyZDDE using the module level function pyz.getTextEncoding()
, and set the text encoding using pyz.setTextEncoding()
. I was able to reproduce the above error by purposefully mismatching the text encoding as you can see below (after I get the error, I changed the text encoding back to the right one as per my Zemax settings, and error went away):
Please let me know if this solved your second problem.
Indranil.
In [11]: psfdata = ln.zGetPSF() # NO ERROR HERE
In [12]: pyz.getTextEncoding()
Out[12]: 'ascii'
In [13]: pyz.setTextEncoding(1) # CHANGE TEXT ENCODING TO THE WRONG ONE
Successfully changed to UNICODE
In [14]: psfdata = ln.zGetPSF() # EXPECTING TO SEE ERROR
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-14-f38e799448ed> in <module>()
----> 1 psfdata = ln.zGetPSF()
C:\PROGRAMSANDEXPERIMENTS\PYTHON\OPTICS\PyZDDE\pyzdde\zdde.pyc in zGetPSF(self, which, settingsFile, txtFile, keepFile, timeout)
7221
7222 # Meta data
-> 7223 data_spacing_line = line_list[_getFirstLineOfInterest(line_list, 'Data spacing')]
7224 data_spacing = float(_re.search(r'\d{1,3}\.\d{2,6}', data_spacing_line).group())
7225 data_area_line = line_list[_getFirstLineOfInterest(line_list, 'Data area')]
TypeError: list indices must be integers, not NoneType
In [15]: pyz.setTextEncoding(0) # BACK TO WHAT IT SHOULD BE
Successfully changed to ASCII
In [16]: psfdata = ln.zGetPSF() # NO ERROR NOW
Dear Prof. Aaron,
This is regarding your 1st question -- "is there a way to retrieve the Zernike coefficients themselves? ie. the functionality of the GetZernike command in ZPL. I can get the text file with them using the 'Zst' button, but what I could really use is the coefficients returned to the python layer."
I have added a function called 'zGetZernike()` in the branch: https://github.com/indranilsinharoy/PyZDDE/tree/getzernikecoeff
The function returns the meta data, and the coefficients to the Python layer (see the basic test examples below). Please let me know if that works for your, or any other suggestions on improving.
There are some limitations though, as the following examples will show. The limitation is that we cannot change the settings for the aberration coefficient analysis using PyZDDE. This is because Zemax hasn't provided the necessary handles for changing these settings (for example, by using MODIFYSETTINGS). So, the current method is to create the settings files manually (if the settings are different from the default values), and call the function with the specific settings file.
Here I have copy-pasted a section of basic testing I did for the function in an IPython notebook ... you will get an idea on how to use the function: (Note that I have manually added the python prompts, >>>
in order to differentiate between inputs and outputs)
>>> import pyzdde.zdde as pyz
>>> ln = pyz.createLink()
>>> ln.zLoadFile(r"C:\PROGRAMSANDEXPERIMENTS\PYTHON\OPTICS\zemaxInteractions\Cooke 40 degree field annular aperture.zmx")
0
# with default settings
>>> zInfo, zCoeff = ln.zGetZernike(which='fringe')
>>> zInfo
zInfo(peakToVal=0.05367696, rmsToZero=0.05367696, rmsToChief=0.01548394, rmsToCentroid=0.01548394, variance=0.00023975, strehl=0.9905796, rmsFitErr=0.0, maxFitErr=0.0)
>>> zInfo.rmsToChief # access a specific parameter
0.01548394
>>> len(zCoeff)
37
>>> print zCoeff
[-0.48704178, 0.0, 0.0, -0.27949432, 0.0, 0.0, 0.0, 0.0, 0.19193398, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.01634558, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.00077357, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -2.854e-05, -1.22e-06]
>>> zInfo, zCoeff = ln.zGetZernike(which='standard')
>>> zInfo
zInfo(peakToVal=0.05367696, rmsToZero=0.05367696, rmsToChief=0.01548394, rmsToCentroid=0.01548394, variance=0.00023975, strehl=0.9905796, rmsFitErr=3.5e-07, maxFitErr=1.24e-06)
>>> len(zCoeff)
37
>>> print zCoeff
[-0.48725154, 0.0, 0.0, -0.1610763, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.08560151, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.00604793, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.00030513]
>>> zInfo, zCoeff = ln.zGetZernike(which='annular')
>>> zInfo
zInfo(peakToVal=0.05367696, rmsToZero=0.05367696, rmsToChief=0.01548394, rmsToCentroid=0.01548394, variance=0.00023975, strehl=0.9905796, rmsFitErr=0.01859785, maxFitErr=0.03642746)
# Change settings for Zernike fringe coefficients from Zemax main application and save the settings
# in the local directory
# Changes: 1. Sampling: 256x256, 2. Max term: 20, 3. Wavelength: 1
# Alternatively, call the function with a settings files (created using Zemax) with the above settings
>>> ln.zPushLens(1)
0
>>> zInfo, zCoeff = ln.zGetZernike(which='fringe')
>>> zInfo
zInfo(peakToVal=0.08586185, rmsToZero=0.08586185, rmsToChief=0.02360218, rmsToCentroid=0.02360218, variance=0.00055706, strehl=0.97824809, rmsFitErr=2.457e-05, maxFitErr=6.511e-05)
>>> len(zCoeff)
20
Indranil,
This works, as does making sure the text settings match - thanks very much,
regards,
Aaron
On Jan 27, 2015, at 11:36 AM, Indranil Sinharoy <notifications@github.commailto:notifications@github.com> wrote:
Dear Prof. Aaron,
This is regarding your 1st question -- "is there a way to retrieve the Zernike coefficients themselves? ie. the functionality of the GetZernike command in ZPL. I can get the text file with them using the 'Zst' button, but what I could really use is the coefficients returned to the python layer."
I have added a function called 'zGetZernike()` in the branch: https://github.com/indranilsinharoy/PyZDDE/tree/getzernikecoeff
The function returns the meta data, and the coefficients to the Python layer (see the basic test examples below). Please let me know if that works for your, or any other suggestions on improving.
There are some limitations though, as the following examples will show. The limitation is that we cannot change the settings for the aberration coefficient analysis using PyZDDE. This is because Zemax hasn't provided the necessary handles for changing these settings (for example, by using MODIFYSETTINGS). So, the current method is to create the settings files manually (if the settings are different from the default values), and call the function with the specific settings file.
Here I have copy-pasted a section of basic testing I did for the function in an IPython notebook ... you will get an idea on how to use the function: (Note that I have manually added the python prompts, >>> in order to differentiate between inputs and outputs)
import pyzdde.zdde as pyz
ln = pyz.createLink()
ln.zLoadFile(r"C:\PROGRAMSANDEXPERIMENTS\PYTHON\OPTICS\zemaxInteractions\Cooke 40 degree field annular aperture.zmx")
0
with default settings
zInfo, zCoeff = ln.zGetZernike(which='fringe')
zInfo
zInfo(peakToVal=0.05367696, rmsToZero=0.05367696, rmsToChief=0.01548394, rmsToCentroid=0.01548394, variance=0.00023975, strehl=0.9905796, rmsFitErr=0.0, maxFitErr=0.0)
zInfo.rmsToChief # access a specific parameter
0.01548394
len(zCoeff)
37
print zCoeff
[-0.48704178, 0.0, 0.0, -0.27949432, 0.0, 0.0, 0.0, 0.0, 0.19193398, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.01634558, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.00077357, 0.0, 0.
0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -2.854e-05, -1.22e-06]
zInfo, zCoeff = ln.zGetZernike(which='standard')
zInfo
zInfo(peakToVal=0.05367696, rmsToZero=0.05367696, rmsToChief=0.01548394, rmsToCentroid=0.01548394, variance=0.00023975, strehl=0.9905796, rmsFitErr=3.5e-07, maxFitErr=1.24e-06)
len(zCoeff)
37
print zCoeff
[-0.48725154, 0.0, 0.0, -0.1610763, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.08560151, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.00604793, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.00030513]
zInfo, zCoeff = ln.zGetZernike(which='annular')
zInfo
zInfo(peakToVal=0.05367696, rmsToZero=0.05367696, rmsToChief=0.01548394, rmsToCentroid=0.01548394, variance=0.00023975, strehl=0.9905796, rmsFitErr=0.01859785, maxFitErr=0.03642746)
Change settings for Zernike fringe coefficients from Zemax main application and save the settings
in the local directory
Changes: 1. Sampling: 256x256, 2. Max term: 20, 3. Wavelength: 1
Alternatively, call the function with a settings files (created using Zemax) with the above settings
ln.zPushLens(1)
0
zInfo, zCoeff = ln.zGetZernike(which='fringe')
zInfo
zInfo(peakToVal=0.08586185, rmsToZero=0.08586185, rmsToChief=0.02360218, rmsToCentroid=0.02360218, variance=0.00055706, strehl=0.97824809, rmsFitErr=2.457e-05, maxFitErr=6.511e-05)
len(zCoeff)
20
—
Reply to this email directly or view it on GitHubhttps://github.com//issues/41#issuecomment-71712595.
Prof. Aaron Roodman
SLAC National Accelerator Laboratory
Stanford University
SLAC National Accelerator Laboratory E-mail: roodman@slac.stanford.edumailto:roodman@slac.stanford.edu
2575 Sand Hill Rd. Phone: 650-926-2705
MS 29 Fax: 650-926-2657
Menlo Park, CA 94025 URL: http://www.slac.stanford.edu/~roodman
Dear Prof. Aaron (@aaronroodman),
I just wanted to update you with some minor changes I made the the function zGetZernike()
before merging into the main branch. The changes shouldn't break any existing code. Nevertheless here are the changes:
- Corrected the
zInfo
named tuple so thatPeak to valley (to centroid)
is the right name of the parameter returned inzInfo
and not "RMS to the zero OPD line". The ZPL macro GETZERNIKE returns "RMS to the zero OPD line". However, I wasn't sure how to calculate this. So, I decided to just return the values from the Zernike analysis text window. zCoeff
is now a named tuple.