def _test_cross_zernikes(testj=4, nterms=10, npix=500): """Verify the functions are orthogonal, by taking the integrals of a given Zernike times N other ones. Parameters : -------------- testj : int Index of the Zernike polynomial to test against the others nterms : int Test that polynomial against those from 1 to this N npix : int Size of array to use for this test """ zj = zernike.zernike1(testj, npix=npix) assert np.sum( np.isfinite(zj)) > 0, "Zernike calculation failure; all NaNs." zbasis = zernike.zernike_basis(nterms=nterms, npix=npix) for idx, z in enumerate(zbasis): j = idx + 1 if j == testj or j == 1: continue # discard piston term and self prod = z * zj wg = np.where(np.isfinite(prod)) cross_sum = np.abs(prod[wg].sum()) assert cross_sum < 1e-9, ( "orthogonality failure, Sum[Zernike(j={}) * Zernike(j={})] = {} (> 1e-9)" .format(j, testj, cross_sum))
def test_zernike_basis_faster(): bf = zernike.zernike_basis_faster(12, outside=0) bs = zernike.zernike_basis(12, outside=0) assert np.allclose( bf, bs ), "Fast zernike basis calculation doesn't match the slow calculation"
def _test_cross_zernikes(testj=4, nterms=10, npix=500): """Verify the functions are orthogonal, by taking the integrals of a given Zernike times N other ones. Parameters : -------------- testj : int Index of the Zernike polynomial to test against the others nterms : int Test that polynomial against those from 1 to this N npix : int Size of array to use for this test """ Zj = zernike.zernike1(testj, npix=npix) Zbasis = zernike.zernike_basis(nterms=nterms, npix=npix) for idx, Z in enumerate(Zbasis): j = idx + 1 if j == testj or j == 1: continue # discard piston term and self prod = Z * Zj wg = np.where(np.isfinite(prod)) cross_sum = np.abs(prod[wg].sum()) assert cross_sum < 1e-9, ( "orthogonality failure, Sum[Zernike(j={}) * Zernike(j={})] = {} (> 1e-9)".format( j, testj, cross_sum) )
def test_opd_expand(npix=512, input_coefficients=(0.1, 0.2, 0.3, 0.4, 0.5)): basis = zernike.zernike_basis(nterms=len(input_coefficients), npix=npix) for idx, coeff in enumerate(input_coefficients): basis[idx] *= coeff opd = basis.sum(axis=0) recovered_coeffs = zernike.opd_expand(opd, nterms=len(input_coefficients)) max_diff = np.max(np.abs(np.asarray(input_coefficients) - np.asarray(recovered_coeffs))) assert max_diff < 1e-3, "recovered coefficients from wf_expand more than 0.1% off" # Test the nonorthonormal version too # At a minimum, fitting with this variant version shouldn't be # worse than the regular one on a clear circular aperture. # We do the test in this same function for efficiency recovered_coeffs_v2 = zernike.opd_expand_nonorthonormal(opd, nterms=len(input_coefficients)) max_diff_v2 = np.max(np.abs(np.asarray(input_coefficients) - np.asarray(recovered_coeffs_v2))) assert max_diff_v2 < 1e-3, "recovered coefficients from wf_expand more than 0.1% off"
def test_zernike_basis_faster(): bf = zernike.zernike_basis_faster(12, outside=0) bs = zernike.zernike_basis(12, outside=0) assert np.allclose(bf,bs), "Fast zernike basis calculation doesn't match the slow calculation"