def calc_coeffs(self, corr): logging.info('Computing corr coeffs using axis {}...'.format(corr)) coeffs = ifunc.calc_coeffs(self.ifuncs[corr], self.displ[corr]['img']['full'], n_ss=self.n_ss, clip=self.clip, adj_clip=self.adj_clip) return coeffs
def calc_adj(self): for corr in self.corr_axes: logging.info('Computing corr coeffs using axis {}...' .format(corr)) coeffs = ifunc.calc_coeffs(self.ifuncs[corr], self.displ[corr]['img']['full'], n_ss=self.n_ss, clip=self.clip) self.coeffs[corr] = coeffs clip = self.clip for axis in self.displ_axes: logging.info("Computing adj[{}][{}][full,clip]". format(axis, corr)) adj = ifunc.calc_adj_displ(self.ifuncs[axis], coeffs) self.adj[axis][corr]['full'] = adj self.adj[axis][corr]['clip'] = adj[clip:-clip, clip:-clip]
def calc_inversion_solution(ifuncs, displ, n_ss, clip): coeffs = ifunc.calc_coeffs(ifuncs, displ, n_ss=n_ss, clip=clip) return coeffs
N_SS = 5 AX_CLIP = 50 AZ_CLIP = 75 ifuncs = ifunc.load_ifuncs(case='10+0_baseline/') N_ROWS, N_COLS, N_AX, N_AZ = ifuncs.shape ax_slice = slice(AX_CLIP, N_AX - AX_CLIP, N_SS) az_slice = slice(AZ_CLIP, N_AZ - AZ_CLIP, N_SS) i_ss, j_ss = np.mgrid[ax_slice, az_slice] M_3d_all = ifuncs.reshape(-1, N_AX, N_AZ) M_3d = M_3d_all[:, i_ss, j_ss] M_2d = M_3d.reshape(M_3d.shape[0], -1).transpose().copy() displ_x_all, displ_ry_all = ifunc.load_displ_legendre(N_AX, N_AZ, offset_az=2) DISPL_X = displ_x_all[i_ss, j_ss].flatten().copy() print 'Computing coeffs' coeffs = ifunc.calc_coeffs(ifuncs, displ_x_all, n_ss=N_SS, clip=min(AX_CLIP, AZ_CLIP)) fit_logger = clogging.config_logger( 'fit', level=clogging.INFO, format='[%(levelname)s] (%(processName)-10s) %(message)s') def calc_adj_displ(ifuncs, coeffs): """Return the adjusted displacement as a 2-d array for the given ``ifuncs`` and ``coeffs``. """ n_ax, n_az = ifuncs.shape[-2:] M_3d_all = ifuncs.reshape(-1, n_ax, n_az) M_2d_all = M_3d_all.reshape(M_3d_all.shape[0], -1).transpose() adj = M_2d_all.dot(coeffs) adj_2d = adj.reshape(n_ax, n_az)
ifuncs = ifunc.load_ifuncs(case='10+0_baseline/') N_ROWS, N_COLS, N_AX, N_AZ = ifuncs.shape ax_slice = slice(AX_CLIP, N_AX - AX_CLIP, N_SS) az_slice = slice(AZ_CLIP, N_AZ - AZ_CLIP, N_SS) i_ss, j_ss = np.mgrid[ax_slice, az_slice] M_3d_all = ifuncs.reshape(-1, N_AX, N_AZ) M_3d = M_3d_all[:, i_ss, j_ss] M_2d = M_3d.reshape(M_3d.shape[0], -1).transpose().copy() displ_x_all, displ_ry_all = ifunc.load_displ_legendre(N_AX, N_AZ, offset_az=2) DISPL_X = displ_x_all[i_ss, j_ss].flatten().copy() print 'Computing coeffs' coeffs = ifunc.calc_coeffs(ifuncs, displ_x_all, n_ss=N_SS, clip=min(AX_CLIP, AZ_CLIP)) fit_logger = clogging.config_logger( 'fit', level=clogging.INFO, format='[%(levelname)s] (%(processName)-10s) %(message)s') def calc_adj_displ(ifuncs, coeffs): """Return the adjusted displacement as a 2-d array for the given ``ifuncs`` and ``coeffs``. """ n_ax, n_az = ifuncs.shape[-2:] M_3d_all = ifuncs.reshape(-1, n_ax, n_az) M_2d_all = M_3d_all.reshape(M_3d_all.shape[0], -1).transpose()
CLIP = 50 ifuncs = ifunc.load_ifuncs(case='10+0_baseline/') N_ROWS, N_COLS, N_AX, N_AZ = ifuncs.shape ax_slice = slice(CLIP, N_AX - CLIP, N_SS) az_slice = slice(CLIP, N_AZ - CLIP, N_SS) i_ss, j_ss = np.mgrid[ax_slice, az_slice] M_3d_all = ifuncs.reshape(-1, N_AX, N_AZ) M_3d = M_3d_all[:, i_ss, j_ss] M_2d = M_3d.reshape(M_3d.shape[0], -1).transpose().copy() displ_x_all, displ_ry_all = ifunc.load_displ_legendre(N_AX, N_AZ, offset_az=2) DISPL_X = displ_x_all[i_ss, j_ss].flatten().copy() print 'Computing coeffs' coeffs = ifunc.calc_coeffs(ifuncs, displ_x_all, n_ss=N_SS, clip=CLIP) fit_logger = clogging.config_logger( 'fit', level=clogging.INFO, format='[%(levelname)s] (%(processName)-10s) %(message)s') def calc_adj_displ(ifuncs, coeffs): """Return the adjusted displacement as a 2-d array for the given ``ifuncs`` and ``coeffs``. """ n_ax, n_az = ifuncs.shape[-2:] M_3d_all = ifuncs.reshape(-1, n_ax, n_az) M_2d_all = M_3d_all.reshape(M_3d_all.shape[0], -1).transpose() adj = M_2d_all.dot(coeffs)
if not 'ifuncs' in globals(): N_SS = 5 CLIP = 50 ifuncs = ifunc.load_ifuncs(case='10+0_baseline/') N_ROWS, N_COLS, N_AX, N_AZ = ifuncs.shape ax_slice = slice(CLIP, N_AX - CLIP, N_SS) az_slice = slice(CLIP, N_AZ - CLIP, N_SS) i_ss, j_ss = np.mgrid[ax_slice, az_slice] M_3d_all = ifuncs.reshape(-1, N_AX, N_AZ) M_3d = M_3d_all[:, i_ss, j_ss] M_2d = M_3d.reshape(M_3d.shape[0], -1).transpose().copy() displ_x_all, displ_ry_all = ifunc.load_displ_legendre(N_AX, N_AZ, offset_az=2) DISPL_X = displ_x_all[i_ss, j_ss].flatten().copy() print 'Computing coeffs' coeffs = ifunc.calc_coeffs(ifuncs, displ_x_all, n_ss=N_SS, clip=CLIP) fit_logger = clogging.config_logger( 'fit', level=clogging.INFO, format='[%(levelname)s] (%(processName)-10s) %(message)s') def calc_adj_displ(ifuncs, coeffs): """Return the adjusted displacement as a 2-d array for the given ``ifuncs`` and ``coeffs``. """ n_ax, n_az = ifuncs.shape[-2:] M_3d_all = ifuncs.reshape(-1, n_ax, n_az) M_2d_all = M_3d_all.reshape(M_3d_all.shape[0], -1).transpose() adj = M_2d_all.dot(coeffs) adj_2d = adj.reshape(n_ax, n_az)
def calc_plot_adj(row_clip=2, col_clip=2, ax_clip=None, az_clip=None, bias=None, error=None, plot_file=None, max_iter=0, nnls=False): """ Calculate and plot the displacement, residuals, and coeffs for an input displacement function. Example:: >>> error = displ_sin_ax(n_cycle=1.0, ampl=0.5, phase=0.0) >>> bias = displ_flat(1.0) >>> out = calc_plot_adj(row_clip=2, col_clip=2, ax_clip=75, az_clip=150, bias=bias, error=error, plot_file=None) :param row_clip: Number of actuator rows near edge to ignore :param col_clip: Number of actuator columns near edge to ignore :param ax_clip: Number of pixels near edge to clip in axial direction :param az_clip: Number of pixels near edge to clip in azimuthal direction :param bias: N_AX x N_AZ image of input bias :param error: N_AX x N_AZ image of input figure error :param max_iter: Maximum iterations for removing negative coefficients (default=0) :param plot_file: plot file name (default=None for no saved file) :param nnls: Use SciPy non-negative least squares solver instead of SVD :returns: dict of results """ row_slice = slice(row_clip, -row_clip) if row_clip else slice(None, None) col_slice = slice(col_clip, -col_clip) if col_clip else slice(None, None) ax_slice = slice(ax_clip, -ax_clip) az_slice = slice(az_clip, -az_clip) # Get stddev of input displacement within clipped region displ = bias.vals + error.vals input_stddev = np.std(error.vals[ax_slice, az_slice]) # Get ifuncs and displ that are clipped and sub-sampled (at default of n_ss=5) ifuncs_clip_4d, displ_clip, M_2d = ifunc.clip_ifuncs_displ( ifuncs, displ, row_slice=row_slice, col_slice=col_slice, ax_clip=ax_clip, az_clip=az_clip) ifuncs_clip = ifuncs_clip_4d.reshape(-1, *(ifuncs_clip_4d.shape[-2:])) coeffs_clip = np.zeros(len(ifuncs_clip)) coeffs = ifunc.calc_coeffs(ifuncs_clip, displ_clip, n_ss=None, clip=0, nnls=nnls) pos_vals = np.ones(len(coeffs), dtype=bool) for ii in range(max_iter): pos = coeffs >= 0 pos_idxs = np.flatnonzero(pos) if len(pos_idxs) == len(coeffs): break ifuncs_clip = ifuncs_clip.take(pos_idxs, axis=0) coeffs = ifunc.calc_coeffs(ifuncs_clip, displ_clip, n_ss=None, clip=0) pos_val_idxs = np.array([ii for ii, val in enumerate(pos_vals) if val]) new_neg_idxs = pos_val_idxs[~pos] logger.info('Negative indexes: {}'.format(new_neg_idxs)) pos_vals[pos_val_idxs[~pos]] = False coeffs_clip[np.where(pos_vals)] = coeffs adj = ifunc.calc_adj_displ(ifuncs[row_slice, col_slice, :, :], coeffs_clip) ny, nx = ifuncs.shape[2:4] clipbox_x = [az_clip, nx - az_clip, nx - az_clip, az_clip, az_clip] clipbox_y = [ax_clip, ax_clip, ny - ax_clip, ny - ax_clip, ax_clip] resid = displ - adj resid_clip = resid[ax_slice, az_slice] resid_min, resid_max = np.percentile(resid[ax_slice, az_slice], [0.5, 99.5]) dv = 0.02 resid_stddev = np.std(resid_clip) plt.figure(1, figsize=(14, 7)) plt.clf() plt.subplot(2, 2, 1) ax = plt.gca() ax.axison = False vmin, vmax = np.percentile(bias.vals, [0.5, 99.5]) plt.imshow(bias.vals, vmin=vmin - dv, vmax=vmax + dv) plt.title(bias.title) plt.colorbar(fraction=0.07) plt.subplot(2, 2, 2) ax = plt.gca() ax.axison = False vmin, vmax = np.percentile(error.vals, [0.5, 99.5]) plt.imshow(error.vals, vmin=vmin - dv, vmax=vmax + dv) plt.title(error.title) plt.colorbar(fraction=0.07) plt.subplot(2, 2, 3) plt.imshow(resid, vmin=resid_min, vmax=resid_max) ax = plt.gca() ax.axison = False ax.autoscale(enable=False) plt.title('Resids (min={:.4f} max={:.4f} stddev={:.4f})'.format( np.min(resid_clip), np.max(resid_clip), resid_stddev)) plt.plot(clipbox_x, clipbox_y, '-m') plt.colorbar(fraction=0.07) plt.subplot(2, 2, 4) coeffs_all = np.zeros(ifuncs.shape[:2]) coeffs_2d = coeffs_clip.reshape(ifuncs_clip_4d.shape[:2]) coeffs_all[row_slice, col_slice] = coeffs_2d cimg = np.dstack([coeffs_all, coeffs_all]).reshape(coeffs_all.shape[0], coeffs_all.shape[1] * 2) ax = plt.gca() ax.axison = False plt.imshow(cimg, interpolation='nearest') ax.autoscale(enable=False) coeffs_min, coeffs_max = np.min(coeffs_2d), np.max(coeffs_2d) plt.title('Actuator coeffs (min={:.4f} max={:.4f})'.format( coeffs_min, coeffs_max)) plt.colorbar(fraction=0.07) r, c = np.mgrid[0:coeffs_all.shape[0], 0:coeffs_all.shape[1]] ok = coeffs_all < 0 plt.plot(c[ok] * 2 + 0.5, r[ok], '.r', ms=10) if plot_file: plt.savefig(plot_file) # Make resulting statistics available names = ( 'input_stddev resid_stddev resid_min resid_max coeffs_min coeffs_max ' 'ax_clip az_clip'.split()) _locals = locals() results = {name: _locals[name] for name in names} results['resid_img'] = resid.copy() results['bias_img'] = bias.vals.copy() results['error_img'] = error.vals.copy() results['coeffs_img'] = coeffs_all.copy() for name in names: logger.info('{:12s} : {:.3f}'.format(name, results[name])) return results
def calc_plot_adj(row_clip=2, col_clip=2, ax_clip=None, az_clip=None, bias=None, error=None, plot_file=None, max_iter=0, nnls=False): """ Calculate and plot the displacement, residuals, and coeffs for an input displacement function. Example:: >>> error = displ_sin_ax(n_cycle=1.0, ampl=0.5, phase=0.0) >>> bias = displ_flat(1.0) >>> out = calc_plot_adj(row_clip=2, col_clip=2, ax_clip=75, az_clip=150, bias=bias, error=error, plot_file=None) :param row_clip: Number of actuator rows near edge to ignore :param col_clip: Number of actuator columns near edge to ignore :param ax_clip: Number of pixels near edge to clip in axial direction :param az_clip: Number of pixels near edge to clip in azimuthal direction :param bias: N_AX x N_AZ image of input bias :param error: N_AX x N_AZ image of input figure error :param max_iter: Maximum iterations for removing negative coefficients (default=0) :param plot_file: plot file name (default=None for no saved file) :param nnls: Use SciPy non-negative least squares solver instead of SVD :returns: dict of results """ row_slice = slice(row_clip, -row_clip) if row_clip else slice(None, None) col_slice = slice(col_clip, -col_clip) if col_clip else slice(None, None) ax_slice = slice(ax_clip, -ax_clip) az_slice = slice(az_clip, -az_clip) # Get stddev of input displacement within clipped region displ = bias.vals + error.vals input_stddev = np.std(error.vals[ax_slice, az_slice]) # Get ifuncs and displ that are clipped and sub-sampled (at default of n_ss=5) ifuncs_clip_4d, displ_clip, M_2d = ifunc.clip_ifuncs_displ( ifuncs, displ, row_slice=row_slice, col_slice=col_slice, ax_clip=ax_clip, az_clip=az_clip) ifuncs_clip = ifuncs_clip_4d.reshape(-1, *(ifuncs_clip_4d.shape[-2:])) coeffs_clip = np.zeros(len(ifuncs_clip)) coeffs = ifunc.calc_coeffs(ifuncs_clip, displ_clip, n_ss=None, clip=0, nnls=nnls) pos_vals = np.ones(len(coeffs), dtype=bool) for ii in range(max_iter): pos = coeffs >= 0 pos_idxs = np.flatnonzero(pos) if len(pos_idxs) == len(coeffs): break ifuncs_clip = ifuncs_clip.take(pos_idxs, axis=0) coeffs = ifunc.calc_coeffs(ifuncs_clip, displ_clip, n_ss=None, clip=0) pos_val_idxs = np.array([ii for ii, val in enumerate(pos_vals) if val]) new_neg_idxs = pos_val_idxs[~pos] logger.info('Negative indexes: {}'.format(new_neg_idxs)) pos_vals[pos_val_idxs[~pos]] = False coeffs_clip[np.where(pos_vals)] = coeffs adj = ifunc.calc_adj_displ(ifuncs[row_slice, col_slice, :, :], coeffs_clip) ny, nx = ifuncs.shape[2:4] clipbox_x = [az_clip, nx - az_clip, nx - az_clip, az_clip, az_clip] clipbox_y = [ax_clip, ax_clip, ny - ax_clip, ny - ax_clip, ax_clip] resid = displ - adj resid_clip = resid[ax_slice, az_slice] resid_min, resid_max = np.percentile(resid[ax_slice, az_slice], [0.5, 99.5]) dv = 0.02 resid_stddev = np.std(resid_clip) plt.figure(1, figsize=(14, 7)) plt.clf() plt.subplot(2, 2, 1) ax = plt.gca() ax.axison = False vmin, vmax = np.percentile(bias.vals, [0.5, 99.5]) plt.imshow(bias.vals, vmin=vmin - dv, vmax=vmax + dv) plt.title(bias.title) plt.colorbar(fraction=0.07) plt.subplot(2, 2, 2) ax = plt.gca() ax.axison = False vmin, vmax = np.percentile(error.vals, [0.5, 99.5]) plt.imshow(error.vals, vmin=vmin - dv, vmax=vmax + dv) plt.title(error.title) plt.colorbar(fraction=0.07) plt.subplot(2, 2, 3) plt.imshow(resid, vmin=resid_min, vmax=resid_max) ax = plt.gca() ax.axison = False ax.autoscale(enable=False) plt.title('Resids (min={:.4f} max={:.4f} stddev={:.4f})' .format(np.min(resid_clip), np.max(resid_clip), resid_stddev)) plt.plot(clipbox_x, clipbox_y, '-m') plt.colorbar(fraction=0.07) plt.subplot(2, 2, 4) coeffs_all = np.zeros(ifuncs.shape[:2]) coeffs_2d = coeffs_clip.reshape(ifuncs_clip_4d.shape[:2]) coeffs_all[row_slice, col_slice] = coeffs_2d cimg = np.dstack([coeffs_all, coeffs_all]).reshape(coeffs_all.shape[0], coeffs_all.shape[1] * 2) ax = plt.gca() ax.axison = False plt.imshow(cimg, interpolation='nearest') ax.autoscale(enable=False) coeffs_min, coeffs_max = np.min(coeffs_2d), np.max(coeffs_2d) plt.title('Actuator coeffs (min={:.4f} max={:.4f})' .format(coeffs_min, coeffs_max)) plt.colorbar(fraction=0.07) r, c = np.mgrid[0:coeffs_all.shape[0], 0:coeffs_all.shape[1]] ok = coeffs_all < 0 plt.plot(c[ok] * 2 + 0.5, r[ok], '.r', ms=10) if plot_file: plt.savefig(plot_file) # Make resulting statistics available names = ('input_stddev resid_stddev resid_min resid_max coeffs_min coeffs_max ' 'ax_clip az_clip'.split()) _locals = locals() results = {name: _locals[name] for name in names} results['resid_img'] = resid.copy() results['bias_img'] = bias.vals.copy() results['error_img'] = error.vals.copy() results['coeffs_img'] = coeffs_all.copy() for name in names: logger.info('{:12s} : {:.3f}'.format(name, results[name])) return results
def calc_coeffs(self, corr): logging.info("Computing corr coeffs using axis {}...".format(corr)) coeffs = ifunc.calc_coeffs( self.ifuncs[corr], self.displ[corr]["img"]["full"], n_ss=self.n_ss, clip=self.clip, adj_clip=self.adj_clip ) return coeffs