From 0d3e4e533e6a05b576d0d4603e6a9d66a799940b Mon Sep 17 00:00:00 2001 From: lbusoni Date: Sun, 21 Oct 2018 22:34:47 +0200 Subject: [PATCH 1/2] added zGetWfm, zModifyWFMSettings and zSetWFMSettings --- pyzdde/zdde.py | 228 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 228 insertions(+) diff --git a/pyzdde/zdde.py b/pyzdde/zdde.py index b1f950c..fe3d891 100644 --- a/pyzdde/zdde.py +++ b/pyzdde/zdde.py @@ -8456,6 +8456,234 @@ def zSetHuygensPSFSettings(self, settingsFile=None, pupilSample=None, field, imgDelta, dtype) return dst + + def zGetWfm(self, settingsFile=None, txtFile=None, + keepFile=False, timeout=120): + """Returns Wavefront Map + Parameters + ---------- + settingsFile : string, optional + * if passed, the Wavefront map analysis will be called with + the given configuration file (settings); + * if no ``settingsFile`` is passed, and config file ending + with the same name as the lens-file post-fixed with + "_pyzdde_WFM.CFG" is present, the + settings from this file will be used; + * if no ``settingsFile`` and no file-name post-fixed with + "_pyzdde_WFM.CFG" is found, but + a config file with the same name as the lens file is present, + the settings from that file will be used; + * if no settings file is found, then a default settings will + be used + txtFile : string, optional + if passed, the WFM analysis text file will be named such. + Pass a specific txtFile if you want to dump the file into + a separate directory. + keepFile : bool, optional + if ``False`` (default), the WFM text file will be deleted + after use. + If ``True``, the file will persist. If ``keepFile`` is ``True`` + but a ``txtFile`` is not passed, the WFM text file will be + saved in the same directory as the lens (provided the required + folder access permissions are available) + timeout : integer, optional + timeout in seconds. + Returns + ------- + wfmInfo : named tuple + meta data about the WFM analysis data, such as data center + point, pupil grid sizes, exit pupil diameter in mm, + peak to valley and rms in waves + wfmGridData : 2D list + the two-dimensional list of the Wavefront map data + See Also + -------- + zModifyWFMSettings(), zSetWFMSettings(), + """ + anaType = 'Wfm' + settings = _txtAndSettingsToUse(self, txtFile, settingsFile, anaType) + textFileName, cfgFile, getTextFlag = settings + ret = self.zGetTextFile(textFileName, anaType, cfgFile, getTextFlag, + timeout) + assert ret == 0 + line_list = _readLinesFromFile(_openFile(textFileName)) + + # Meta data + pupil_grid_line = line_list[_getFirstLineOfInterest(line_list, 'Pupil grid size')] + pupil_grid_x, pupil_grid_y = [int(i) for i in _re.findall(r'\d{2,5}', pupil_grid_line)] + center_point_line = line_list[_getFirstLineOfInterest(line_list, 'Center point')] + center_point_x, center_point_y = [int(i) for i in _re.findall(r'\d{2,5}', center_point_line)] + exit_pupil_diameter_line= line_list[_getFirstLineOfInterest(line_list, 'Exit Pupil Diameter')] + exit_pupil_diameter= float(_re.search('-?\d\.\d{4,10}[Ee][-\+]\d{2,3}', exit_pupil_diameter_line).group()) + peak_to_valley_line= line_list[_getFirstLineOfInterest(line_list, 'Peak to valley')] + peak_to_valley, rms= [float(i) for i in _re.findall(r'\d{1,5}\.\d{2,6}', peak_to_valley_line)] + + + # The 2D data + pat = (r'(-?\d\.\d{4,6}[Ee][-\+]\d{2,3}\s*)' + r'{{{num}}}' + .format(num=pupil_grid_x)) + start_line = _getFirstLineOfInterest(line_list, pat) + wfmGridData = _get2DList(line_list, start_line, pupil_grid_y) + + wfmi = _co.namedtuple('WFMinfo', ['pupilGridX', 'pupilGridY', + 'centerPtX', 'centerPtY', + 'exitPupilDiameter', + 'peakToValley', 'rms']) + wfmInfo = wfmi(pupil_grid_x, pupil_grid_y, + center_point_x, center_point_y, + exit_pupil_diameter, peak_to_valley, rms) + + if not keepFile: + _deleteFile(textFileName) + return (wfmInfo, wfmGridData) + + + def zModifyWFMSettings(self, settingsFile, pupilSample=None, + wave=None, field=None, + subapertureRadius=None, + subapertureXDecenter=None, + subapertureYDecenter=None): + """Modify an existing WFM analysis settings (configuration) + file + + Only those parameters that are non-None will be set. + + Parameters + ---------- + settingsFile : string + filename of the settings file including path and extension + pupilSample : integer, optional + the pupil sampling. 1 = 32x32; 2 = 64x64; 3 = 128x128; + 4 = 256x256; 5 = 512x512; 6 = 1024x1024; 7 = 2048x2048; + 8 = 4096x4096; 9 = 8192x8192; 10 = 16384x16384; + wave : integer, optional + the wavelength number + field : integer, optional + the field number + subapertureRadius : float, optional + the subaperture radius + subapertureXDecenter : float, optional + the subaperture x decenter + subapertureYDecenter : float, optional + the subaperture y decenter + Returns + ------- + statusTuple : tuple or -1 + tuple of codes returned by ``zModifySettings()`` for each + non-None parameters. The status codes are as follows: + 0 = no error; + -1 = invalid file; + -2 = incorrect version number; + -3 = file access conflict + + The function returns -1 if ``settingsFile`` is invalid. + + See Also + -------- + zSetWFMSettings(), zGetWFM() + """ + sTuple = [] # status tuple + if (_os.path.isfile(settingsFile) and settingsFile.lower().endswith('.cfg')): + dst = settingsFile + else: + return -1 + if pupilSample is not None: + sTuple.append(self.zModifySettings(dst, "WFM_SAMP", pupilSample)) + if wave is not None: + sTuple.append(self.zModifySettings(dst, "WFM_WAVE", wave)) + if field is not None: + sTuple.append(self.zModifySettings(dst, "WFM_FIELD", field)) + if field is not None: + sTuple.append(self.zModifySettings(dst, "WFM_SUBSR", + subapertureRadius)) + if field is not None: + sTuple.append(self.zModifySettings(dst, "WFM_SUBSX", + subapertureXDecenter)) + if field is not None: + sTuple.append(self.zModifySettings(dst, "WFM_SUBSY", + subapertureYDecenter)) + return tuple(sTuple) + + + def zSetWFMSettings(self, settingsFile=None, pupilSample=None, + wave=None, field=None, + subapertureRadius=None, + subapertureXDecenter=None, + subapertureYDecenter=None): + """create and set a new WFM analysis settings file starting + from the "reset" settings state of the most basic lens in Zemax + + To modify an existing WFM settings file, use + ``zModifyWFMSettings()``. Only those parameters that are + non-None will be set + + Parameters + ---------- + settingsFile : string, optional + name to give to the settings file to be created. It must be + the full file name, including path and extension of the + settings file. + If ``None``, then a CFG file with the name of the lens + followed by the string '_pyzdde_WFM.CFG' will be + created in the same directory as the lens file and returned + pupilSample : integer, optional + the pupil sampling. 1 = 32x32; 2 = 64x64; 3 = 128x128; + 4 = 256x256; 5 = 512x512; 6 = 1024x1024; 7 = 2048x2048; + 8 = 4096x4096; 9 = 8192x8192; 10 = 16384x16384; + wave : integer, optional + the wavelength number, use 0 for polychromatic + field : integer, optional + the field number + subapertureRadius : float, optional + the subaperture radius + subapertureXDecenter : float, optional + the subaperture x decenter + subapertureYDecenter : float, optional + the subaperture y decenter + + Returns + ------- + settingsFile : string + the full name, including path and extension, of the just + created settings file + + Notes + ----- + 1. Further modifications of the settings file can be made using + ``zModifySettings()`` or ``zModifyWFMSettings()`` + functions + 2. The function creates settings file ending with + '_pyzdde_WFM.CFG' in order to prevent overwritting any + existing settings file not created by pyzdde for WFM + analysis. + This file eventually gets deleted when ``ln.close()`` or + ``pyz.closeLink()`` or ``ln.zDDEClose()`` is called. + + See Also + -------- + zGetPSF(), zModifyHuygensPSFSettings() + """ + clean_cfg = 'RESET_SETTINGS_WFM.CFG' + src = _os.path.join(_pDir, 'ZMXFILES', clean_cfg) + if settingsFile: + dst = settingsFile + else: + filename_partial = _os.path.splitext(self.zGetFile())[0] + dst = filename_partial + '_pyzdde_WFM.CFG' + self._filesCreated.add(dst) + try: + _shutil.copy(src, dst) + except IOError: + print("ERROR: Invalid settingsFile {}".format(dst)) + return + else: + self.zModifyWFMSettings(dst, pupilSample, wave, field, + subapertureRadius, + subapertureXDecenter, + subapertureYDecenter) + return dst + + def zGetMTF(self, which='fft', settingsFile=None, txtFile=None, keepFile=False, timeout=120): """Returns FFT or Huygens MTF data From 5ce050922b577be9a54a92f80b9cb91d5a5907e0 Mon Sep 17 00:00:00 2001 From: lbusoni Date: Mon, 22 Oct 2018 00:17:21 +0200 Subject: [PATCH 2/2] fixed errors and added default cfg file --- ZMXFILES/RESET_SETTINGS_WFM.CFG | Bin 0 -> 4384 bytes pyzdde/zdde.py | 8 +++++--- 2 files changed, 5 insertions(+), 3 deletions(-) create mode 100644 ZMXFILES/RESET_SETTINGS_WFM.CFG diff --git a/ZMXFILES/RESET_SETTINGS_WFM.CFG b/ZMXFILES/RESET_SETTINGS_WFM.CFG new file mode 100644 index 0000000000000000000000000000000000000000..fdcb08ac69892607c2c9dbe0b28d71a6497744d8 GIT binary patch literal 4384 zcmeIuyA1#!2t`r+&BacxZNmr}A(qq@*XAZZs