Source code for nrefocus.minimizers.mz_legacy

import warnings

import numpy as np


class LegacyDeprecationWarning(DeprecationWarning):
    pass


[docs]def minimize_legacy(rf, metric_func, interval, roi=None, coarse_acc=1, fine_acc=.005, ret_grid=False, ret_field=False): """Legacy minimizer Find the focus by minimizing the `metric` of an image. This is the implementation of the legacy nrefocus minimizer. Parameters ---------- rf: nrefocus.iface.Refocus Refocus interface metric_func: callable metric called during minimization. The metric should take the following arguments: `rf`, `distance`, and `roi` interval: tuple of floats (minimum, maximum) of interval to search [m] roi: tuple of slices or np.ndarray Region of interest for which the metric will be minimized. If not given, the entire field will be used. coarse_acc: float accuracy for determination of global minimum in pixels; `coarse_acc=1` means that 100 fields are computed in the initial step; `coarse_acc=0.5` means 200 fields are computed fine_acc: float accuracy for fine localization percentage of gradient change ret_grid: bool return focus positions and metric values of the coarse grid search ret_field: bool return the optimal refocused field for user convenience Returns ------- af_dist: float Autofocusing distance [m] (d_grid, metrid_grid): ndarray Coarse grid search values (only if `ret_grid` is True) af_field: ndarray Autofocused field (only if `ret_field` is True) """ warnings.warn("The 'legacy' minimizer is deprecated, because it is " "slower and not as accurate as the 'lmfit' minimizer! " "Please only use 'legacy' to reproduce previous results.", LegacyDeprecationWarning) ival = interval # set coarse interval n = int(100 / coarse_acc) zc = np.linspace(ival[0], ival[1], n, endpoint=True) # initiate gradient vector gradc = np.zeros(zc.shape) for i in range(len(zc)): d = zc[i] gradc[i] = metric_func(rf, distance=d, roi=roi) minid = np.argmin(gradc) if minid == 0: zc -= zc[1] - zc[0] minid += 1 if minid == len(zc) - 1: zc += zc[1] - zc[0] minid -= 1 zf = 1*zc numfine = 10 mingrad = gradc[minid] while True: gradf = np.zeros(numfine) ival = (zf[minid - 1], zf[minid + 1]) zf = np.linspace(ival[0], ival[1], numfine) for i in range(len(zf)): d = zf[i] gradf[i] = metric_func(rf, distance=d, roi=roi) minid = np.argmin(gradf) if minid == 0: zf -= zf[1] - zf[0] minid += 1 if minid == len(zf) - 1: zf += zf[1] - zf[0] minid -= 1 if abs(mingrad - gradf[minid]) / 100 < fine_acc: break minid = np.argmin(gradf) af_dist = zf[minid] ret_val = [af_dist] if ret_grid: ret_val.append((zc, gradc)) if ret_field: ret_val.append(rf.propagate(af_dist)) if len(ret_val) == 1: ret_val = ret_val[0] return ret_val