# Path: batoid/utils.py
# def bilinear_fit(ux, uy, kx, ky):
#     a = np.empty((len(ux), 3), dtype=float)
#     a[:,0] = 1
#     a[:,1] = ux
#     a[:,2] = uy
#     b = np.empty((len(ux), 2), dtype=float)
#     b[:,0] = kx
#     b[:,1] = ky
#     x, _, _, _ = np.linalg.lstsq(a, b, rcond=-1)
#     return x
# 
# def fieldToDirCos(u, v, projection='postel'):
#     """Convert field angle to direction cosines using specified projection.
# 
#     Parameters
#     ----------
#     u, v : float
#         Tangent plane coordinates in radians.
#     projection : {'postel', 'zemax', 'gnomonic', 'stereographic', 'lambert', 'orthographic'}
#         Projection used to convert field angle to direction cosines.
# 
#     Returns
#     -------
#     alpha, beta, gamma : float
#         Direction cosines (unit vector projected onto x, y, z in order)
# 
#     Notes
#     -----
#     The tangent plane reference is at (u,v) = (0,0), which corresponds to
#     (alpha, beta, gamma) = (0, 0, -1) (a ray coming directly from above).  The
#     orientation is such that vx (vy) is positive when u (v) is positive.
#     """
#     if projection == 'postel':
#         return postelToDirCos(u, v)
#     elif projection == 'zemax':
#         return zemaxToDirCos(u, v)
#     elif projection == 'gnomonic':
#         return gnomonicToDirCos(u, v)
#     elif projection == 'stereographic':
#         return stereographicToDirCos(u, v)
#     elif projection == 'lambert':
#         return lambertToDirCos(u, v)
#     elif projection == 'orthographic':
#         return orthographicToDirCos(u, v)
#     else:
#         raise ValueError("Bad projection: {}".format(projection))


import numpy as np
import batoid
    import galsim
    import galsim
    import galsim
    import galsim
from .utils import bilinear_fit, fieldToDirCos
    from numbers import Real



def _reciprocalLatticeVectors(a1, a2, N):
    norm = 2*np.pi/(a1[0]*a2[1] - a1[1]*a2[0])/N
    b1 = norm*np.array([a2[1], a2[0]])
    b2 = norm*np.array([a1[1], a1[0]])
    return b1, b2


def dkdu(

# Path: batoid/utils.py
# def bilinear_fit(ux, uy, kx, ky):
#     a = np.empty((len(ux), 3), dtype=float)
#     a[:,0] = 1
#     a[:,1] = ux
#     a[:,2] = uy
#     b = np.empty((len(ux), 2), dtype=float)
#     b[:,0] = kx
#     b[:,1] = ky
#     x, _, _, _ = np.linalg.lstsq(a, b, rcond=-1)
#     return x
# 
# def fieldToDirCos(u, v, projection='postel'):
#     """Convert field angle to direction cosines using specified projection.
# 
#     Parameters
#     ----------
#     u, v : float
#         Tangent plane coordinates in radians.
#     projection : {'postel', 'zemax', 'gnomonic', 'stereographic', 'lambert', 'orthographic'}
#         Projection used to convert field angle to direction cosines.
# 
#     Returns
#     -------
#     alpha, beta, gamma : float
#         Direction cosines (unit vector projected onto x, y, z in order)
# 
#     Notes
#     -----
#     The tangent plane reference is at (u,v) = (0,0), which corresponds to
#     (alpha, beta, gamma) = (0, 0, -1) (a ray coming directly from above).  The
#     orientation is such that vx (vy) is positive when u (v) is positive.
#     """
#     if projection == 'postel':
#         return postelToDirCos(u, v)
#     elif projection == 'zemax':
#         return zemaxToDirCos(u, v)
#     elif projection == 'gnomonic':
#         return gnomonicToDirCos(u, v)
#     elif projection == 'stereographic':
#         return stereographicToDirCos(u, v)
#     elif projection == 'lambert':
#         return lambertToDirCos(u, v)
#     elif projection == 'orthographic':
#         return orthographicToDirCos(u, v)
#     else:
#         raise ValueError("Bad projection: {}".format(projection))


# Path: batoid/analysis.py
import numpy as np
import batoid
    import galsim
    import galsim
    import galsim
    import galsim
from .utils import bilinear_fit, fieldToDirCos
    from numbers import Real




def _reciprocalLatticeVectors(a1, a2, N):
    norm = 2*np.pi/(a1[0]*a2[1] - a1[1]*a2[0])/N
    b1 = norm*np.array([a2[1], a2[0]])
    b2 = norm*np.array([a1[1], a1[0]])
    return b1, b2


def dkdu(

    optic, theta_x, theta_y, wavelength, nrad=6, naz=36, projection='postel'