zernike.py 3.03 KB
 Daniel Brown committed Dec 01, 2014 1 2 ``````import numpy as np from scipy.misc import factorial as fac `````` Daniel Toyra committed Apr 14, 2016 3 ``````from six.moves import xrange `````` Daniel Toyra committed Aug 05, 2015 4 ``````import math `````` Daniel Brown committed Dec 01, 2014 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 `````` def zernike_R(m, n, rho): if ((n-m) % 2): return rho*0.0 nnm = (n-m)/2.0 npm = (n+m)/2.0 R = 0 return sum(rho**(n-2.0*k) * (-1.0)**k * fac(n-k) / ( fac(k) * fac(npm - k) * fac(nnm - k)) for k in xrange(int(nnm) + 1)) def zernike(m, n, rho, phi): """ Computes the zernike polynomial in radial coordinates: Z_{n}^{m}(rho, phi) = R_{n}^{m}(rho) cos(m * phi) (even) R_{n}^{m}(rho) sin(m * phi) (odd) Must satisfy n >= m. """ if (n < 0): raise ValueError("n must be larger than 0") if (abs(m) > n): raise ValueError("Must use m <= n") if m > 0: return zernike_R(m, n, rho) * np.cos(m * phi) elif m < 0: return zernike_R(-m, n, rho) * np.sin(-m * phi) else: return zernike_R(0, n, rho) `````` Daniel Toyra committed Aug 05, 2015 41 42 43 44 45 46 47 48 49 `````` def znm2Rc(A,R): ''' Convertes amplitudes of Zernike polynomials of order n=2 into spherical radius of curvature. In case the astigmatic modes (m=-1,m=2) are included, the functon returns the maximum and minimum curvature. Inputs: A, R `````` Daniel Toyra committed Aug 07, 2015 50 `````` A - List of amplitudes of order 2 Zernike polynomials, ordered so that m `````` Daniel Toyra committed Aug 05, 2015 51 52 53 54 55 `````` increases with list index. 1 <= len(A) <= 3. [m] R - Radius of the mirror surface in the xy-plane. [m] Returns: Rc Rc - If astigmatic modes are used (len(A) == 2 or 3) a numpy.array of length `````` Daniel Toyra committed Aug 07, 2015 56 `````` 2 containing max and min curvatures is returned. If only the 'defocus' `````` Daniel Toyra committed Aug 05, 2015 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 `````` mode is used Rc is a float number. [m] Based on the Simtools function 'FT_Znm_to_Rc.m' by Charlotte Bond. ''' if isinstance(A,list): if len(A)==3: a20 = A[1] a22 = math.sqrt(A[0]**2 + A[2]**2) s = np.array([1.0, -1.0]) elif len(A)==2: a20 = 0 a22 = math.sqrt(A[0]**2 + A[1]**2) s = np.array([1.0, -1.0]) elif len(A)==1: a20 = A[0] a22 = 0 s = 0 elif isinstance(A,float) or isinstance(A,int): a20 = A a22 = 0 s = 0 Rc = ((2*a20 + s*a22)**2 + R**2)/(2*(2*a20+s*a22)) return Rc `````` Daniel Toyra committed Aug 07, 2015 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 ``````def Rc2znm(Rc,R): ''' Converts Radius of curvatue to amplitudes of the second order Zernike polynomials. Iputs: Rc, R Rc - Radius of curvature. Either a number or a numpy.ndarray with minimum and maximum curvature. R - Radius of mirror in xy-plane. Returns: A A - Ampltude(s) of the second order Zernike polynomials needed. Is a number if Rc is a number, and if R is a numpy.ndarray so is A. Based on Simtools function 'FT_Rc_to_Znm.m' by Charlotte Bond. ''' # Amplitude in x and y directions c = ( Rc - np.sign(Rc)*np.sqrt(Rc**2 - R**2) )/2 if isinstance(Rc, np.ndarray): A = np.array([]) # Adding Z(2,0) amplitude A = np.append(A,c.mean()) # Adding Z(2,2) amplitude A = np.append(A,2*(c[0]-A[0])) elif isinstance(Rc, float) or isinstance(Rc, int): A = c return A``````