def test_ptt_basis(verbose=False, plot=False, tiptiltonly=True, pistononly=False, rings=2): """ Test that we can create randomly-pistoned, tipped, and tilted segments, and then re-determine the amounts of those deviations. """ segment_ptt_basis = zernike.Segment_PTT_Basis(rings=rings) # Make some random aberrations random_ptt = np.random.randn(segment_ptt_basis.nsegments*3) if tiptiltonly: for i in range(segment_ptt_basis.nsegments): random_ptt[i*3] = 0 elif pistononly: for i in range(segment_ptt_basis.nsegments): random_ptt[i*3+1] = 0 random_ptt[i*3+2] = 0 else: # make the pistons small compared to the tips & tilts for i in range(segment_ptt_basis.nsegments): random_ptt[i*3] *= 1e-3 # Generate an OPD with those aberrations ptted_opd = zernike.opd_from_zernikes(basis=segment_ptt_basis, coeffs=random_ptt, outside=0) # Perform a fit to measure them results = zernike.opd_expand_segments(ptted_opd, basis=segment_ptt_basis, aperture=segment_ptt_basis.aperture(), nterms=segment_ptt_basis.nsegments*3, verbose=verbose) # Generate another OPD to show the measurements ptted_v2 = zernike.opd_from_zernikes(basis=segment_ptt_basis, coeffs=results, outside=0) if verbose: print(random_ptt) print(results) if plot: plt.subplot(121) ax = plt.imshow(ptted_opd) plt.title("Randomly generated OPD") plt.subplot(122) ax2 = plt.imshow(ptted_v2, norm=ax.norm) plt.title("Reproduced from fit coefficients") # adjust tolerances for the ones that are precisely zero - allow larger atol since rtol doesn't help there. wz = np.where(random_ptt ==0) wnz = np.where(random_ptt !=0) assert np.allclose(random_ptt[wnz], results[wnz]) assert np.allclose(random_ptt[wz], results[wz], atol=1e-6) return random_ptt, results, ptted_opd, ptted_v2
def _opd_from_coeff(self, coeff, basis, mask): """Generate OPD image from a set of coefficients, basis function, and mask""" npix = mask.shape[0] return zernike.opd_from_zernikes(coeff, basis=basis, npix=npix, outside=0)
def test_piston_basis(verbose=False): """ Test that we can create randomly-pistoned segments, and then re-determine the amounts of those pistons. This tests both the segment piston baseis, and the segment basis decomposition function. """ segment_piston_basis = zernike.Segment_Piston_Basis(rings=2) random_pistons = np.random.randn(18) pistoned_opd = zernike.opd_from_zernikes(basis=segment_piston_basis, coeffs=random_pistons, outside=0) aperture = segment_piston_basis.aperture() #aperture = np.asarray(pistoned_opd != 0, dtype=int) for border_pad in [None, 5]: results = zernike.opd_expand_segments(pistoned_opd, basis=segment_piston_basis, aperture=aperture, nterms=18, verbose=verbose, ignore_border=border_pad) if verbose: print(random_pistons) print(results) assert np.allclose(random_pistons, results) return random_pistons, results, pistoned_opd
def test_opd_from_zernikes(): coeffs = [0,0.1, 0.4, 2, -0.3] opd = zernike.opd_from_zernikes(coeffs, npix=256) outcoeffs = zernike.opd_expand(opd, nterms=len(coeffs)) # only compare on indices 1-3 to avoid divide by zero on piston diffs = np.abs(np.asarray(coeffs[1:5]) - np.asarray(outcoeffs[1:5]))/np.asarray(coeffs[1:5]) max_diff = np.max(diffs ) assert max_diff < 2e-3, "recovered coefficients from opd_expand differ more than expected"
def test_opd_from_zernikes(): coeffs = [0, 0.1, 0.4, 2, -0.3] opd = zernike.opd_from_zernikes(coeffs, npix=256) outcoeffs = zernike.opd_expand(opd, nterms=len(coeffs)) diffs = np.abs(np.asarray(coeffs) - np.asarray(outcoeffs)) / np.asarray(coeffs) diffs[0] = 0 # ignore divide by zero on piston max_diff = np.max(diffs) assert max_diff < 2e-3, "recovered coefficients from opd_expand differ more than expected"
def test_opd_from_zernikes(): coeffs = [0,0.1, 0.4, 2, -0.3] opd = zernike.opd_from_zernikes(coeffs, npix=256) outcoeffs = zernike.opd_expand(opd, nterms=len(coeffs)) diffs = np.abs(np.asarray(coeffs) - np.asarray(outcoeffs))/np.asarray(coeffs) diffs[0] = 0 # ignore divide by zero on piston max_diff = np.max(diffs ) assert max_diff < 2e-3, "recovered coefficients from opd_expand differ more than expected"
def test_piston_basis(verbose=False): """ Test that we can create randomly-pistoned segments, and then re-determine the amounts of those pistons. This tests both the segment """ segment_piston_basis = zernike.Segment_Piston_Basis(rings=2) random_pistons = np.random.randn(18) pistoned_opd = zernike.opd_from_zernikes(basis=segment_piston_basis, coeffs=random_pistons, outside=0) aperture = segment_piston_basis.aperture() #aperture = np.asarray(pistoned_opd != 0, dtype=int) results = zernike.opd_expand_segments(pistoned_opd, basis=segment_piston_basis, aperture=aperture, nterms=18, verbose=verbose) if verbose: print(random_pistons) print(results) assert np.allclose(random_pistons, results) return random_pistons, results, pistoned_opd
def test_ptt_basis(verbose=False, plot=False, tiptiltonly=True, pistononly=False, rings=2): """ Test that we can create randomly-pistoned, tipped, and tilted segments, and then re-determine the amounts of those deviations. """ segment_ptt_basis = zernike.Segment_PTT_Basis(rings=rings) # Make some random aberrations random_ptt = np.random.randn(segment_ptt_basis.nsegments * 3) if tiptiltonly: for i in range(segment_ptt_basis.nsegments): random_ptt[i * 3] = 0 elif pistononly: for i in range(segment_ptt_basis.nsegments): random_ptt[i * 3 + 1] = 0 random_ptt[i * 3 + 2] = 0 else: # make the pistons small compared to the tips & tilts for i in range(segment_ptt_basis.nsegments): random_ptt[i * 3] *= 1e-3 # Generate an OPD with those aberrations ptted_opd = zernike.opd_from_zernikes(basis=segment_ptt_basis, coeffs=random_ptt, outside=0) # Perform a fit to measure them results = zernike.opd_expand_segments( ptted_opd, basis=segment_ptt_basis, aperture=segment_ptt_basis.aperture(), nterms=segment_ptt_basis.nsegments * 3, verbose=verbose) # Generate another OPD to show the measurements ptted_v2 = zernike.opd_from_zernikes(basis=segment_ptt_basis, coeffs=results, outside=0) if verbose: print(random_ptt) print(results) if plot: plt.subplot(121) ax = plt.imshow(ptted_opd) plt.title("Randomly generated OPD") plt.subplot(122) ax2 = plt.imshow(ptted_v2, norm=ax.norm) plt.title("Reproduced from fit coefficients") # adjust tolerances for the ones that are precisely zero - allow larger atol since rtol doesn't help there. wz = np.where(random_ptt == 0) wnz = np.where(random_ptt != 0) assert np.allclose(random_ptt[wnz], results[wnz]) assert np.allclose(random_ptt[wz], results[wz], atol=1e-6) return random_ptt, results, ptted_opd, ptted_v2
from poppy import zernike from model.src.coherent import construct_SA1_wavefront import numpy as np from wpg.wpg_uti_wf import calculate_fwhm wfr = construct_SA1_wavefront(1000, 1000, 12, 0.1) ii = wfr.get_intensity()[:,:,0] ph = wfr.get_phase()[:,:,0] aperture = np.ones(ii.shape) aperture[np.where(ii < ii.max()/10)] = 0 zc = zernike.opd_expand(ph, aperture = aperture) opd = zernike.opd_from_zernikes(zc) fig = plt.figure() ax1 = fig.add_subplot(111) ax1.bar(np.linspace(0,len(zc), len(zc)),zc) ax1.set_xticks(np.linspace(0+1,len(zc)+1, len(zc)+1)) ax1.set_xticklabels(labels = ["$Z_{}$".format(int(z)) for z in np.linspace(0+1,len(zc)+1, len(zc)+1)]) plt.show() for i in range(15): if i == 0: pass else: print("index: {},".format(i-1), "j = {}".format(i), zernike.zern_name(i))