def new_zernike_window(app, args, pars={}): def quit(str1): e = QErrorMessage() e.showMessage(str1) sys.exit(e.exec_()) calib_file = None # argparse specified parameters can override pars if args.dm_parameters is not None: d = json.loads(args.dm_parameters.read()) pars = {**pars, **d} args.dm_parameters = args.dm_parameters.name # calibration from pars if 'calibration' in pars: calib_file = pars['calibration'] # calibration from argparse if args.dm_calibration is not None: calib_file = args.dm_calibration.name args.dm_calibration = calib_file # no calibration found, ask user for calibration if calib_file is None: fileName, _ = QFileDialog.getOpenFileName( None, 'Select a DM calibration', filter='H5 (*.h5);;All Files (*)') if not fileName: sys.exit() else: calib_file = path.abspath(fileName) pars['calibration'] = calib_file try: dminfo = RegLSCalib.query_calibration(calib_file) except Exception as e: quit(str(e)) calib_dm_name = dminfo[0] calib_dm_transform = dminfo[1] if args.dm_name is None: args.dm_name = calib_dm_name dm = open_dm(app, args, calib_dm_transform) try: with File(calib_file, 'r') as f: calib = RegLSCalib.load_h5py(f, lazy_cart_grid=True) except Exception as e: quit(f'Error loading calibration {pars["calibration"]}: {str(e)}') dmplot = get_suitable_dmplot(args, dm, calib) zwindow = DMWindow(None, dm, dmplot, calib, pars) zwindow.show() return zwindow
def load_parameters(self, d): self.pars = {**deepcopy(self.pars), **deepcopy(d)} with File(self.pars['calibration'], 'r') as f: self.calib = RegLSCalib.load_h5py(f, lazy_cart_grid=True) self.instance_control() if 'ZernikePanel' in self.pars: self.zpanel.load_parameters(self.pars['ZernikePanel'])
def main(): app = QApplication(sys.argv) args = app.arguments() parser = argparse.ArgumentParser( description='Zernike DM control', formatter_class=argparse.ArgumentDefaultsHelpFormatter) add_log_parameters(parser) add_arguments(parser) parser.add_argument('--params', type=argparse.FileType('rb'), default=None, metavar='JSON') parser.add_argument('--no-params', action='store_true') args = parser.parse_args(args[1:]) setup_logging(args) dminfo, pars = load_parameters(app, args) calib_dm_name = dminfo[0] calib_dm_transform = dminfo[1] if args.dm_name is None: args.dm_name = calib_dm_name dm = open_dm(app, args, calib_dm_transform) try: with File(pars['calibration'], 'r') as f: calib = RegLSCalib.load_h5py(f, lazy_cart_grid=True) except Exception as e: quit(f'error loading calibration {pars["calibration"]}: {str(e)}') zwindow = DMWindow(app, dm, calib, pars) zwindow.show() sys.exit(app.exec_())
def f(): hold() fileName, _ = QFileDialog.getOpenFileName( self, 'Select a calibration file', filter='H5 (*.h5);;All Files (*)') if fileName: try: with File(fileName, 'r') as f: self.calib = RegLSCalib.load_h5py( f, lazy_cart_grid=True) self.instance_control() if 'ZernikePanel' in self.pars: self.zpanel.load_parameters( self.pars['ZernikePanel']) except Exception as ex: self.log.error(f'Error loading calibration {str(ex)}') QMessageBox.information(self, 'Error loading calibration', str(ex)) release()
def load_parameters(app, args): def quit(str1): e = QErrorMessage() e.showMessage(str1) sys.exit(e.exec_()) if args.no_params: # blank parameters pars = {} elif args.params is not None: # command-line pars try: pars = json.load(args.params) except Exception: quit('cannot load ' + args.params.name) else: pars = {} if args.dm_calibration: args.dm_calibration.close() pars['calibration'] = path.abspath(args.dm_calibration.name) args.dm_calibration = pars['calibration'] def choose_calib_file(): fileName, _ = QFileDialog.getOpenFileName( None, 'Select a calibration', filter='H5 (*.h5);;All Files (*)') if not fileName: sys.exit() else: pars['calibration'] = path.abspath(fileName) if 'calibration' not in pars: choose_calib_file() try: dminfo = RegLSCalib.query_calibration(pars['calibration']) except Exception as e: quit(str(e)) return dminfo, pars
# pull an interferogram with all actuators at rest img_zero = images[0, ...] # pull an interferogram where the central actuators have been poked img_centre = align[names.index('centre'), ...] # make a fringe analysis object fringe = FringeAnalysis(images[0, ...].shape, cam_pixel_size_um) # use img_zero to lay out the FFT masks fringe.analyse(img_zero, auto_find_orders=True, do_unwrap=True, use_mask=False) # find the aperture position automatically fringe.estimate_aperture(img_zero, img_centre, radius_um) # or set the position manually with fringe.set_aperture(centre, radius) # compute the calibration calib = RegLSCalib() calib.calibrate(U, images, fringe, wavelength_nm, cam_pixel_size_um, status_cb=print) # save the calibration to a file fout = 'calib.h5' with File(fout, 'w', libver='latest') as h5f: calib.save_h5py(h5f) print(f'Saved {fout}') print(f'To test the {fout}, run:') print('$ python -m dmlib.zpanel --dm-name simdm0 --dm-calibration ./calib.h5')
dm.open(devs[0]) # Membrane DMs, like the Boston Multi-DM, exhibit a quadratic response of # the displacement `d` of one actuator with respect to the applied voltage # `v`, i.e., `d=v**2`. To have a better linear response you can define a # new control variable `u =`v**2`, so that control of the DM is established # as `d = u`. From a given `u` you can then compute the correct voltage to # apply as `v = np.sqrt(u)`. This transformation is handled internally by # using the the following line. For other DM technologies, such as piezo, # you need not use this transformation. dm.set_transform(SquareRoot()) # load a DM calibration file (e.g. generated using calibration.py) calib_file = './data/calib-example.h5' with File(calib_file, 'r') as f: calib = RegLSCalib.load_h5py(f, lazy_cart_grid=True) # The control matrix can be retrieved as `calib.C`. You can also read the # control matrix using any HDF5 viewer or library from the address # "/RegLSCalib/C" # instance an object to control using Zernike modes zcontrol = ZernikeControl(dm, calib) # random Zernikes like in the bar of the GUI z = uniform(-.5, .5, size=zcontrol.ndof) # The Zernike coefficients are in rad at the wavelength used for # calibration. Use `calib.get_rad_to_nm()*z` to convert to nm. # write random Zernike vector