def fit_plane(x, y, z): xx, yy = m.meshgrid(x, y) pts = m.isfinite(z) xx_, yy_ = xx[pts].flatten(), yy[pts].flatten() flat = m.ones(xx_.shape) coefs = m.lstsq(m.stack([xx_, yy_, flat]).T, z[pts].flatten(), rcond=None)[0] plane_fit = coefs[0] * xx + coefs[1] * yy + coefs[2] return plane_fit
def _spherical_cost_fcn_raw(frequencies, truth_s, truth_t, lens, abervalues): ''' TODO - document. partial() should be used on this and scipy.minimize'd abervalues - array of [W020, W040, W060, W080] ''' pupil = Seidel(epd=lens.epd, samples=lens.samples, W020=abervalues[0], W040=abervalues[1], W060=abervalues[2], W080=abervalues[3]) psf = PSF.from_pupil(pupil, efl=lens.efl) mtf = MTF.from_psf(psf) synth_t = mtf.exact_polar(frequencies, 0) synth_s = mtf.exact_polar(frequencies, 90) truth = m.stack((truth_s, truth_t)) synth = m.stack((synth_s, synth_t)) return ((truth - synth)**2).sum()
def fit_sphere(z): x, y = m.linspace(-1, 1, z.shape[1]), m.linspace(-1, 1, z.shape[0]) xx, yy = m.meshgrid(x, y) pts = m.isfinite(z) xx_, yy_ = xx[pts].flatten(), yy[pts].flatten() rho, phi = cart_to_polar(xx_, yy_) focus = defocus(rho, phi) coefs = m.lstsq(m.stack([focus, m.ones(focus.shape)]).T, z[pts].flatten(), rcond=None)[0] rho, phi = cart_to_polar(xx, yy) sphere = defocus(rho, phi) * coefs[0] return sphere
def fit_plane(x, y, z): pts = m.isfinite(z) if len(z.shape) > 1: x, y = m.meshgrid(x, y) xx, yy = x[pts].flatten(), y[pts].flatten() else: xx, yy = x, y flat = m.ones(xx.shape) coefs = m.lstsq(m.stack([xx, yy, flat]).T, z[pts].flatten(), rcond=None)[0] plane_fit = coefs[0] * x + coefs[1] * y + coefs[2] return plane_fit
def generate_mask(vertices, num_samples=128): """Create a filled convex polygon mask based on the given vertices. Parameters ---------- vertices : `iterable` ensemble of vertice (x,y) coordinates, in array units num_samples : `int` number of points in the output array along each dimension Returns ------- `numpy.ndarray` polygon mask """ vertices = m.asarray(vertices) unit = m.arange(num_samples) xxyy = m.stack(m.meshgrid(unit, unit), axis=2) # use delaunay to fill from the vertices and produce a mask triangles = Delaunay(vertices, qhull_options='Qj Qf') mask = ~(triangles.find_simplex(xxyy) < 0) return mask
def radial_mtf_to_mtfffd_data(tan, sag, imagehts, azimuths, upsample): """Take radial MTF data and map it to inputs to the MTFFFD constructor. Performs upsampling/interpolation in cartesian coordinates Parameters ---------- tan : `np.ndarray` tangential data sag : `np.ndarray` sagittal data imagehts : `np.ndarray` array of image heights azimuths : iterable azimuths corresponding to the first dimension of the tan/sag arrays upsample : `float` upsampling factor Returns ------- out_x : `np.ndarray` x coordinates of the output data out_y : `np.ndarray` y coordinates of the output data tan : `np.ndarray` tangential data sag : `np.ndarray` sagittal data """ azimuths = m.asarray(azimuths) imagehts = m.asarray(imagehts) if imagehts[0] > imagehts[-1]: # distortion profiled, values "reversed" # just flip imagehts, since spacing matters and not exact values imagehts = imagehts[::-1] amin, amax = min(azimuths), max(azimuths) imin, imax = min(imagehts), max(imagehts) aq = m.linspace(amin, amax, int(len(azimuths) * upsample)) iq = m.linspace(imin, imax, int( len(imagehts) * 4)) # hard-code 4x linear upsample, change later aa, ii = m.meshgrid(aq, iq, indexing='ij') # for each frequency, build an interpolating function and upsample up_t = m.empty((len(aq), tan.shape[1], len(iq))) up_s = m.empty((len(aq), sag.shape[1], len(iq))) for idx in range(tan.shape[1]): t, s = tan[:, idx, :], sag[:, idx, :] interpft = RGI((azimuths, imagehts), t, method='linear') interpfs = RGI((azimuths, imagehts), s, method='linear') up_t[:, idx, :] = interpft((aa, ii)) up_s[:, idx, :] = interpfs((aa, ii)) # compute the locations of the samples on a cartesian grid xd, yd = m.outer(m.cos(m.radians(aq)), iq), m.outer(m.sin(m.radians(aq)), iq) samples = m.stack([xd.ravel(), yd.ravel()], axis=1) # for the output cartesian grid, figure out the x-y coverage and build a regular grid absamin = min(abs(azimuths)) closest_to_90 = azimuths[m.argmin(azimuths - 90)] xfctr = m.cos(m.radians(absamin)) yfctr = m.cos(m.radians(closest_to_90)) xmin, xmax = imin * xfctr, imax * xfctr ymin, ymax = imin * yfctr, imax * yfctr xq, yq = m.linspace(xmin, xmax, len(iq)), m.linspace(ymin, ymax, len(iq)) xx, yy = m.meshgrid(xq, yq) outt, outs = [], [] # for each frequency, interpolate onto the cartesian grid for idx in range(up_t.shape[1]): datt = griddata(samples, up_t[:, idx, :].ravel(), (xx, yy), method='linear') dats = griddata(samples, up_s[:, idx, :].ravel(), (xx, yy), method='linear') outt.append(datt.reshape(xx.shape)) outs.append(dats.reshape(xx.shape)) outt, outs = m.rollaxis(m.asarray(outt), 0, 3), m.rollaxis(m.asarray(outs), 0, 3) return xq, yq, outt, outs