Пример #1
0
def rms_lsq(variables, *args):
    """calculate the rms value of the LSQ method with variables:
    variables[0] = piston,
    variables[1] = centre_x,
    variables[2] = centre_y,
    variables[3] = radius of circle on sh sensor[px],
    Z_mat is used to calculate the Zernike polynomial on a grid, to compare with original interferogram.
    arguments should be in order"""
    if args:
       wavelength, j_max, f_sh, px_size_sh, dist_image, image_control, y_pos_flat_f, x_pos_flat_f, xx, yy, orig, mask, N, Z_mat, power_mat, box_len = args
    else:
        print("put the arguments!")
        return
    r_sh_m = px_size_sh * variables[3]

    x_pos_norm = (x_pos_flat_f - variables[1])/variables[3]
    y_pos_norm = (y_pos_flat_f - variables[2])/variables[3]

    inside = np.sqrt(x_pos_norm ** 2 + y_pos_norm**2) <= (1+ (box_len/variables[3]))
    x_pos_norm, y_pos_norm, x_pos_flat_f, y_pos_flat_f = mc.filter_positions(inside, x_pos_norm, y_pos_norm, x_pos_flat_f, y_pos_flat_f)

    G = LSQ.matrix_avg_gradient(x_pos_norm, y_pos_norm, j_max, variables[3], power_mat)
    
    x_pos_dist, y_pos_dist = Hm.centroid_positions(x_pos_flat_f, y_pos_flat_f, dist_image, xx, yy)

    s = np.hstack(Hm.centroid2slope(x_pos_dist, y_pos_dist, x_pos_flat_f, y_pos_flat_f, px_size_sh, f_sh, r_sh_m, wavelength))
    a = np.linalg.lstsq(G,s)[0]

    orig = np.ma.array(orig, mask = mask)
    inter = np.ma.array(Zn.int_for_comp(j_max, a, N, variables[0], Z_mat, fliplr = False), mask = mask)
    rms = np.sqrt(np.sum((inter - orig)**2)/N**2)
    return rms
Пример #2
0
[ny, nx] = zero_image.shape
x = np.linspace(1, nx, nx)
y = np.linspace(1, ny, ny)
xx, yy = np.meshgrid(x, y)

x_pos_zero, y_pos_zero = Hm.zero_positions(zero_image_zeros)
x_pos_flat, y_pos_flat = Hm.centroid_positions(x_pos_zero, y_pos_zero,
                                               image_ref_mirror, xx, yy)
centre = Hm.centroid_centre(x_pos_flat, y_pos_flat)
x_pos_norm = ((x_pos_flat - centre[0])) / r_sh_px
y_pos_norm = ((y_pos_flat - centre[1])) / r_sh_px
inside = np.where(
    np.sqrt(x_pos_norm**2 + y_pos_norm**2) <= (1 + (box_len / r_sh_px))
)  #35 is the half the width of the pixel box aroudn a centroid and r_sh_px is the scaling factor
x_pos_zero_f, y_pos_zero_f, x_pos_flat_f, y_pos_flat_f, x_pos_norm_f, y_pos_norm_f = mc.filter_positions(
    inside, x_pos_zero, y_pos_zero, x_pos_flat, y_pos_flat, x_pos_norm,
    y_pos_norm)
G = LSQ.matrix_avg_gradient(x_pos_norm_f, y_pos_norm_f, j_max, r_sh_px)

## Shack Hartmann methods
a_measured_new = LSQ.LSQ_coeff(x_pos_zero_f, y_pos_zero_f, x_pos_flat_f,
                               y_pos_flat_f, G, image_ref_mirror, dist_image,
                               px_size_sh, r_sh_px, f_sh, j_max)
a_janss_check = janssen.coeff(x_pos_zero_f, y_pos_zero_f, image_ref_mirror,
                              dist_image, px_size_sh, f_sh, r_sh_m, j_max)

## interferogram analysis
## centre and radius of interferogam. Done by eye, with the help of define_radius.py
x0 = 550
y0 = 484
radius = 375
Пример #3
0
def rms_janss(variables, *args):
    """calculate the rms value of the Janssen method with variables:
    variables[0] = piston,
    variables[1] = radius of circle on sh sensor[px],
    Z_mat is used to calculate the Zernike polynomial on a grid, to compare with original interferogram.
    arguments should be in order"""
    if args:
        x_pos_zero, y_pos_zero, x_pos_flat, y_pos_flat, x_pos_dist, y_pos_dist, px_size_sh, f_sh, j_max, wavelength, xx, yy, N, orig, mask, Z_mat, box_len, centre = args
    else:
        print("put the arguments!")
        return
    #x_pos_flat_f, y_pos_flat_f = Hm.centroid_positions(x_pos_zero, y_pos_zero, image_control, xx, yy, spot_size = box_len)

    r_sh_m = px_size_sh * variables[1]

    x_pos_norm = (x_pos_flat - centre[0]) / variables[1]
    y_pos_norm = (y_pos_flat - centre[1]) / variables[1]

    ### check if all is within circle
    ### not implemented due to constraints
    inside = np.sqrt(x_pos_norm**2 +
                     y_pos_norm**2) <= (1 + (box_len / variables[1]))
    x_pos_norm_it, y_pos_norm_it, x_pos_flat_it, y_pos_flat_it, x_pos_dist_it, y_pos_dist_it = mc.filter_positions(
        inside, x_pos_norm, y_pos_norm, x_pos_flat, y_pos_flat, x_pos_dist,
        y_pos_dist)

    ## calculate slopes
    #x_pos_dist, y_pos_dist = Hm.centroid_positions(x_pos_flat_f, y_pos_flat_f, dist_image, xx, yy, spot_size = box_len)
    dWdx, dWdy = Hm.centroid2slope(x_pos_dist_it, y_pos_dist_it, x_pos_flat_it,
                                   y_pos_flat_it, px_size_sh, f_sh, r_sh_m,
                                   wavelength)

    ## make zernike matrix
    kmax = np.power(np.ceil(np.sqrt(j_max)),
                    2)  #estimation of maximum fringe number
    n, m = Zn.Zernike_j_2_nm(np.array(range(
        1,
        int(kmax) + 1)))  #find n and m pairs for maximum fringe number
    Kmax = np.max(Zn.Zernike_nm_2_j(
        n + 1,
        np.abs(m) + 1))  #find highest order of j for which beta is needed
    Z_mat_complex = janssen.avg_complex_zernike(x_pos_norm_it,
                                                y_pos_norm_it,
                                                Kmax,
                                                variables[1],
                                                spot_size=box_len)

    #Invert and solve for beta
    dW_plus = dWdx + 1j * dWdy
    dW_min = dWdx - 1j * dWdy
    beta_plus = np.linalg.lstsq(Z_mat_complex, dW_plus)[0]
    beta_min = np.linalg.lstsq(Z_mat_complex, dW_min)[0]

    kmax = int(kmax)
    a = np.zeros(kmax, dtype=np.complex_)
    a_check = np.zeros(j_max, dtype=np.complex_)
    #a_avg = np.zeros(j_max, dtype = np.complex_)
    for jj in range(2, kmax + 1):
        n, m = Zn.Zernike_j_2_nm(jj)
        index1 = int(Zn.Zernike_nm_2_j(n - 1.0, m + 1.0) - 1)
        index2 = int(Zn.Zernike_nm_2_j(n - 1.0, m - 1.0) - 1)
        index3 = int(Zn.Zernike_nm_2_j(n + 1.0, m + 1.0) - 1)
        index4 = int(Zn.Zernike_nm_2_j(n + 1.0, m - 1.0) - 1)
        fact1 = 1.0 / (2 * n * (1 + (n != abs(m))))
        fact2 = 1.0 / (2 * (n + 2) * (1 + (((n + 2) != abs(m)))))
        if m + 1.0 > n - 1.0:
            a[jj -
              1] = fact1 * (beta_min[index2]) - fact2 * (beta_plus[index3] +
                                                         beta_min[index4])
        elif np.abs(m - 1.0) > np.abs(n - 1.0):
            a[jj -
              1] = fact1 * (beta_plus[index1]) - fact2 * (beta_plus[index3] +
                                                          beta_min[index4])
        else:
            a[jj -
              1] = fact1 * (beta_plus[index1] + beta_min[index2]) - fact2 * (
                  beta_plus[index3] + beta_min[index4])

    for jj in range(2, j_max + 2):
        n, m = Zn.Zernike_j_2_nm(jj)
        if m > 0:
            j_min = int(Zn.Zernike_nm_2_j(n, -m))
            a_check[jj - 2] = (1.0 / np.sqrt(2 * n + 2)) * (a[jj - 1] +
                                                            a[j_min - 1])
        elif m < 0:
            j_plus = int(Zn.Zernike_nm_2_j(n, np.abs(m)))
            a_check[jj - 2] = (1.0 / np.sqrt(2 * n + 2)) * (a[j_plus - 1] -
                                                            a[jj - 1]) * 1j
        else:
            a_check[jj - 2] = (1.0 / np.sqrt(n + 1)) * a[jj - 1]
    a_janss = np.real(a_check)

    orig = np.ma.array(orig, mask=mask)
    inter = np.ma.array(Zn.int_for_comp(j_max,
                                        a_janss,
                                        N,
                                        variables[0],
                                        Z_mat,
                                        fliplr=False),
                        mask=mask)
    rms = np.sqrt(np.sum((inter - orig)**2) / N**2)
    return rms
Пример #4
0
    print("amount of spots: " + str(len(x_pos_zero)))
    x_pos_flat, y_pos_flat = Hm.centroid_positions(x_pos_zero,
                                                   y_pos_zero,
                                                   np.copy(image_ref_mirror),
                                                   xx,
                                                   yy,
                                                   spot_size=box_len)
    centre = Hm.centroid_centre(x_pos_flat, y_pos_flat)
    x_pos_norm = ((x_pos_flat - centre[0])) / float(r_sh_px)
    y_pos_norm = ((y_pos_flat - centre[1])) / float(r_sh_px)
    inside = np.where(
        np.sqrt(x_pos_norm**2 + y_pos_norm**2) <=
        (1 + (float(box_len) / r_sh_px))
    )  #35 is the half the width of the pixel box aroudn a centroid and r_sh_px is the scaling factor
    x_pos_zero_f, y_pos_zero_f, x_pos_flat_f, y_pos_flat_f, x_pos_norm_f, y_pos_norm_f = mc.filter_positions(
        inside, x_pos_zero, y_pos_zero, x_pos_flat, y_pos_flat, x_pos_norm,
        y_pos_norm)
    x_pos_dist, y_pos_dist = Hm.centroid_positions(x_pos_zero,
                                                   y_pos_zero,
                                                   np.copy(dist_image),
                                                   xx,
                                                   yy,
                                                   spot_size=box_len)
    x_pos_dist_f, y_pos_dist_f = mc.filter_positions(inside, x_pos_dist,
                                                     y_pos_dist)

    ##    print("calculating Janssen")
    ##    a_janss_opt = janssen.coeff_from_dist(x_pos_flat_f, y_pos_flat_f, x_pos_dist_f, y_pos_dist_f, x_pos_norm_f, y_pos_norm_f, px_size_sh, f_sh, r_sh_m, wavelength, j_max, r_sh_px, box_len)
    ##
    ##    print("calculating geometry matrix")
    ##    G = LSQ.matrix_avg_gradient(x_pos_norm_f, y_pos_norm_f, j_max, r_sh_px, power_mat, box_len)
def a_from_vars_int(variables, *args):
    if args:
       x_pos_zero_f, y_pos_zero_f, image_control, dist_image, px_size_sh, f_sh, j_max, wavelength, xx, yy, N, orig, mask, Z_mat, box_len, integrate = args
    else:
        print("put the arguments!")
        return
    x_pos_flat_f, y_pos_flat_f = Hm.centroid_positions(x_pos_zero, y_pos_zero, image_control, xx, yy)

    r_sh_m = px_size_sh * variables[3]

    x_pos_norm = (x_pos_flat_f - variables[1])/variables[3]
    y_pos_norm = (y_pos_flat_f - variables[2])/variables[3]

    ### check if all is within circle
    inside = np.sqrt(x_pos_norm ** 2 + y_pos_norm**2) <= (1+ (box_len/variables[3]))
    x_pos_norm, y_pos_norm, x_pos_flat_f,y_pos_flat_f = mc.filter_positions(inside, x_pos_norm, y_pos_norm, x_pos_flat_f, y_pos_flat_f)

    ## calculate slopes
    x_pos_dist, y_pos_dist = Hm.centroid_positions(x_pos_flat_f, y_pos_flat_f, dist_image, xx, yy)
    dWdx, dWdy = Hm.centroid2slope(x_pos_dist, y_pos_dist, x_pos_flat_f, y_pos_flat_f, px_size_sh, f_sh, r_sh_m, wavelength)

    ## make zernike matrix
    kmax = np.power(np.ceil(np.sqrt(j_max)),2) #estimation of maximum fringe number
    n, m = Zn.Zernike_j_2_nm(np.array(range(1, int(kmax)+1))) #find n and m pairs for maximum fringe number
    Kmax = np.max(Zn.Zernike_nm_2_j(n+1, np.abs(m)+1)) #find highest order of j for which beta is needed
    if integrate == True:
        Z_mat_complex = janssen.avg_complex_zernike(x_pos_norm, y_pos_norm, Kmax, r_sh_px, spot_size = 35)
    else:
        Z_mat_complex = Zn.complex_zernike(Kmax, x_pos_norm, y_pos_norm)
        
    #Invert and solve for beta
    dW_plus = dWdx + 1j * dWdy
    dW_min = dWdx - 1j * dWdy
    beta_plus = np.linalg.lstsq(Z_mat_complex, dW_plus)[0]
    beta_min = np.linalg.lstsq(Z_mat_complex, dW_min)[0]

    kmax = int(kmax)
    a = np.zeros(kmax, dtype = np.complex_)
    a_check = np.zeros(j_max, dtype = np.complex_)
    #a_avg = np.zeros(j_max, dtype = np.complex_)
    for jj in range(2, kmax+1):
        n, m = Zn.Zernike_j_2_nm(jj)
        index1 = int(Zn.Zernike_nm_2_j(n - 1.0, m + 1.0) - 1)
        index2 = int(Zn.Zernike_nm_2_j(n - 1.0, m - 1.0) - 1)
        index3 = int(Zn.Zernike_nm_2_j(n + 1.0, m + 1.0) - 1)
        index4 = int(Zn.Zernike_nm_2_j(n + 1.0, m - 1.0) - 1)
        fact1 = 1.0 / ( 2 * n * ( 1 + (n != abs(m))))
        fact2 = 1.0 / (2 * (n+2) * ( 1 + (((n+2) != abs(m)))))
        if m + 1.0 > n - 1.0:
            a[jj-1] = fact1 * (beta_min[index2]) - fact2 * (beta_plus[index3] + beta_min[index4])
        elif np.abs(m - 1.0) > np.abs(n - 1.0):
            a[jj-1] = fact1 * (beta_plus[index1]) - fact2 * (beta_plus[index3] + beta_min[index4])
        else:
            a[jj-1] = fact1 * (beta_plus[index1] + beta_min[index2]) - fact2 * (beta_plus[index3] + beta_min[index4])

    for jj in range(2, j_max+2):
        n, m = Zn.Zernike_j_2_nm(jj)
        if m > 0:
            j_min = int(Zn.Zernike_nm_2_j(n, -m))
            a_check[jj-2] = (1.0/np.sqrt(2*n+2))*(a[jj-1] + a[j_min-1])
        elif m < 0:
            j_plus = int(Zn.Zernike_nm_2_j(n, np.abs(m)))
            a_check[jj-2] = (1.0/np.sqrt(2*n+2)) * (a[j_plus - 1] - a[jj-1]) * 1j
        else:
            a_check[jj-2] = (1.0/np.sqrt(n+1)) * a[jj-1]
    a_janss = np.real(a_check)

    return a_janss
mask = [np.sqrt((xx_alg) ** 2 + (yy_alg) ** 2) >= 1]
orig = np.ma.array(inter_0[y0-radius:y0+radius, x0-radius:x0+radius], mask = mask)
orig /= np.max(orig)

j_range = np.arange(2, j_max+2)
power_mat = Zn.Zernike_power_mat(j_max+2)
Z_mat = Zn.Zernike_xy(xx_alg, yy_alg, power_mat, j_range)


x_pos_zero, y_pos_zero = Hm.zero_positions(zero_image_zeros)
x_pos_flat, y_pos_flat = Hm.centroid_positions(x_pos_zero, y_pos_zero, image_control, xx, yy)
centre = Hm.centroid_centre(x_pos_flat, y_pos_flat)
x_pos_norm = ((x_pos_flat - centre[0]))/r_sh_px
y_pos_norm = ((y_pos_flat - centre[1]))/r_sh_px
inside = np.where(np.sqrt(x_pos_norm**2 + y_pos_norm**2) <= (1 + (box_len/r_sh_px))) #35 is the half the width of the pixel box aroudn a centroid and r_sh_px is the scaling factor
x_pos_zero_f, y_pos_zero_f, x_pos_flat_f, y_pos_flat_f, x_pos_norm_f, y_pos_norm_f = mc.filter_positions(inside, x_pos_zero, y_pos_zero, x_pos_flat, y_pos_flat, x_pos_norm, y_pos_norm)
integrate = False
inside_without_outsides = np.where(np.sqrt(x_pos_norm**2 + y_pos_norm**2) <= 1 - (box_len/r_sh_px))
x_pos_norm_f_wth, y_pos_norm_f_wth = mc.filter_positions(inside_without_outsides, x_pos_norm, y_pos_norm)

janss_args = (x_pos_zero_f, y_pos_zero_f, image_control, dist_image, px_size_sh, f_sh, j_max, wavelength, xx, yy, N, orig, mask, Z_mat, box_len, integrate)

x_norm_mat, y_norm_mat = np.meshgrid(x_pos_norm_f, y_pos_norm_f)

Z_mat_com_int = janssen.avg_complex_zernike(x_pos_norm_f, y_pos_norm_f, 200, 310)
Z_mat_com_non = Zn.complex_zernike(200, x_pos_norm_f, y_pos_norm_f)
Z_mat_int_wth, Z_mat_non_wth = janssen.avg_complex_zernike(x_pos_norm_f_wth, y_pos_norm_f_wth, 200, 310), Zn.complex_zernike(200, x_pos_norm_f_wth, y_pos_norm_f_wth)

rms_mat = np.sqrt((Z_mat_com_int - Z_mat_com_non)**2)/len(x_pos_norm_f)
rms = np.sum(rms_mat, axis = 0)
rms_mat_wth = np.sqrt((Z_mat_int_wth - Z_mat_non_wth)**2)/len(x_pos_norm_f_wth)
Пример #7
0
def rms_phi_lsq(variables, *args):
    """Calculate the 2-norm distance from the intended phase to the measured phase,
    variables[0] = x0
    variables[1] = y0
    variables[2] = radius
    Z_mat is used to calculate Zernike polynomials on a grid, to compare with original phase, 3rd dimension should be length j_max"""
    if args:
        wavelength, j_max, f_sh, px_size_sh, x_pos_flat, y_pos_flat, x_pos_dist, y_pos_dist, xx, yy, mask, N, Z_mat, power_mat, box_len, phi_ref = args
    else:
        print("argument error!")
        return
    r_sh_m = px_size_sh * variables[2]

    x_pos_norm = (x_pos_flat - variables[0])/variables[2]
    y_pos_norm = (y_pos_flat - variables[1])/variables[2]

    inside = np.sqrt(x_pos_norm ** 2 + y_pos_norm**2) <= (1+ (box_len/variables[2]))
    x_pos_norm_it, y_pos_norm_it, x_pos_flat_it, y_pos_flat_it, x_pos_dist_it, y_pos_dist_it = mc.filter_positions(inside, x_pos_norm, y_pos_norm, x_pos_flat, y_pos_flat, x_pos_dist, y_pos_dist)

    G = LSQ.matrix_avg_gradient(x_pos_norm_it, y_pos_norm_it, j_max, variables[1], power_mat, box_len)
    
    s = np.hstack(Hm.centroid2slope(x_pos_dist_it, y_pos_dist_it, x_pos_flat_it, y_pos_flat_it, px_size_sh, f_sh, r_sh_m, wavelength))
    a = np.linalg.lstsq(G,s)[0]

    phi_lsq = np.ma.array(np.dot(Z_mat, a), mask = mask)
    phi_diff = np.ma.array(phi_ref - phi_lsq, mask = mask)
    rms = np.sqrt((phi_diff**2).sum())/N
    return rms
Пример #8
0
def rms_phi_janssen(variables, *args):
    """Calculate the 2-norm distance from the intended phase to the measured phase using Janssen's method,
    variables[0] = x0
    variables[1] = y0
    variables[2] = radius
    Z_mat is used to calculate Zernike polynomials on a grid, to compare with original phase, 3rd dimension should be length j_max"""

    if args:
       x_pos_zero, y_pos_zero, x_pos_flat, y_pos_flat, x_pos_dist, y_pos_dist, px_size_sh, f_sh, j_max, wavelength, xx, yy, N, mask, Z_mat, box_len, phi_ref = args
    else:
        print("put the arguments!")
        return
    r_sh_m = px_size_sh * variables[2]

    x_pos_norm = (x_pos_flat - variables[0])/variables[2]
    y_pos_norm = (y_pos_flat - variables[1])/variables[2]

    ### check if all is within circle
    ### not implemented due to constraints
    inside = np.sqrt(x_pos_norm ** 2 + y_pos_norm**2) <= (1+ (box_len/variables[2]))
    x_pos_norm_it, y_pos_norm_it, x_pos_flat_it, y_pos_flat_it, x_pos_dist_it, y_pos_dist_it = mc.filter_positions(inside, x_pos_norm, y_pos_norm, x_pos_flat, y_pos_flat, x_pos_dist, y_pos_dist)

    ## calculate slopes
    #x_pos_dist, y_pos_dist = Hm.centroid_positions(x_pos_flat_f, y_pos_flat_f, dist_image, xx, yy, spot_size = box_len)
    dWdx, dWdy = Hm.centroid2slope(x_pos_dist_it, y_pos_dist_it, x_pos_flat_it, y_pos_flat_it, px_size_sh, f_sh, r_sh_m, wavelength)

    ## make zernike matrix
    kmax = np.power(np.ceil(np.sqrt(j_max+1)),2) #estimation of maximum fringe number
    n, m = Zn.Zernike_j_2_nm(np.array(range(1, int(kmax)+1))) #find n and m pairs for maximum fringe number
    Kmax = np.max(Zn.Zernike_nm_2_j(n+1, np.abs(m)+1)) #find highest order of j for which beta is needed
    Z_mat_complex = janssen.avg_complex_zernike(x_pos_norm_it, y_pos_norm_it, Kmax, variables[2], spot_size = box_len)

    #Invert and solve for beta
    dW_plus = dWdx + 1j * dWdy
    dW_min = dWdx - 1j * dWdy
    beta_plus = np.linalg.lstsq(Z_mat_complex, dW_plus)[0]
    beta_min = np.linalg.lstsq(Z_mat_complex, dW_min)[0]

    kmax = int(kmax)
    a = np.zeros(kmax, dtype = np.complex_)
    a_check = np.zeros(j_max, dtype = np.complex_)
    #a_avg = np.zeros(j_max, dtype = np.complex_)
    for jj in range(2, kmax+1):
        n, m = Zn.Zernike_j_2_nm(jj)
        index1 = int(Zn.Zernike_nm_2_j(n - 1.0, m + 1.0) - 1)
        index2 = int(Zn.Zernike_nm_2_j(n - 1.0, m - 1.0) - 1)
        index3 = int(Zn.Zernike_nm_2_j(n + 1.0, m + 1.0) - 1)
        index4 = int(Zn.Zernike_nm_2_j(n + 1.0, m - 1.0) - 1)

        fact1 = 1.0 / ( 2 * n * ( 1 + (n != abs(m))))
        fact2 = 1.0 / (2 * (n+2) * ( 1 + (((n+2) != abs(m)))))
        if m + 1.0 > n - 1.0:
            a[jj-1] = fact1 * (beta_min[index2]) - fact2 * (beta_plus[index3] + beta_min[index4])
        elif np.abs(m - 1.0) > np.abs(n - 1.0):
            a[jj-1] = fact1 * (beta_plus[index1]) - fact2 * (beta_plus[index3] + beta_min[index4])
        else:
            a[jj-1] = fact1 * (beta_plus[index1] + beta_min[index2]) - fact2 * (beta_plus[index3] + beta_min[index4])

    for jj in range(2, j_max+2):
        n, m = Zn.Zernike_j_2_nm(jj)
        if m > 0:
            j_min = int(Zn.Zernike_nm_2_j(n, -m))
            a_check[jj-2] = (1.0/np.sqrt(2*n+2))*(a[jj-1] + a[j_min-1])
        elif m < 0:
            j_plus = int(Zn.Zernike_nm_2_j(n, np.abs(m)))
            a_check[jj-2] = (1.0/np.sqrt(2*n+2)) * (a[j_plus - 1] - a[jj-1]) * 1j
        else:
            a_check[jj-2] = (1.0/np.sqrt(n+1)) * a[jj-1]
    a_janss = np.real(a_check)

    phi_janss = np.ma.array(np.dot(Z_mat, a_janss), mask = mask)
    phi_diff = np.ma.array(phi_ref - phi_janss, mask = mask)
    rms = np.sqrt((phi_diff**2).sum())/N
    return rms
    bf_lsq = time.time()
    vars_lsq, lsq_rms = opt.fmin(rms_lsq,
                                 vars_janss,
                                 args=lsq_args,
                                 maxiter=1000,
                                 full_output=True)[:2]
    aft_lsq = time.time()
    print("1000 iterations LSQ took " + str(aft_lsq - bf_lsq) + " s")

    ## find coefficients according to optimum
    x_pos_norm_lsq = (x_pos_flat - vars_lsq[1]) / r_sh_px
    y_pos_norm_lsq = (y_pos_flat - vars_lsq[2]) / r_sh_px
    inside_lsq = np.where(
        np.sqrt(x_pos_norm_lsq**2 +
                y_pos_norm_lsq**2) <= (1 + (box_len / r_sh_px)))
    x_pos_flat_f, y_pos_flat_f = mc.filter_positions(inside_lsq, x_pos_flat,
                                                     y_pos_flat)
    x_pos_norm_lsq, y_pos_norm_lsq = mc.filter_positions(
        inside_lsq, x_pos_norm_lsq, y_pos_norm_lsq)
    G = LSQ.matrix_avg_gradient(x_pos_norm_lsq, y_pos_norm_lsq, j_max, r_sh_px,
                                power_mat)
    r_sh_px_lsq_opt = r_sh_px
    pist_lsq_opt = vars_lsq[0]
    r_sh_m_lsq_opt = px_size_sh * r_sh_px
    x_pos_dist, y_pos_dist = Hm.centroid_positions(x_pos_flat_f, y_pos_flat_f,
                                                   dist_image, xx, yy)
    #x_pos_dist, y_pos_dist = mc.filter_positions(inside_lsq, x_pos_dist, y_pos_dist, x_pos_flat_f, y_pos_flat_f)
    s = np.hstack(
        Hm.centroid2slope(x_pos_dist, y_pos_dist, x_pos_flat_f, y_pos_flat_f,
                          px_size_sh, f_sh, r_sh_m_lsq_opt, wavelength))
    a_lsq_opt = np.linalg.lstsq(G, s)[0]