jiahuimbzuai/CoQuIR huggingface dataset:
//  [python]
def add_velocity_vectors(ax, aa, ds, fn, v_scl=3, nngrid=80, zlev='top'):
    # v_scl: scale velocity vector (smaller to get longer arrows)
    # GET DATA
    G = zrfun.get_basic_info(fn, only_G=True)
    if zlev == 'top':
        u = ds['u'][0, -1, :, :].squeeze()
        v = ds['v'][0, -1, :, :].squeeze()
    elif zlev == 'bot':
        u = ds['u'][0, 0, :, :].squeeze()
        v = ds['v'][0, 0, :, :].squeeze()
    # ADD VELOCITY VECTORS
    # set masked values to 0
    ud = u.data; ud[u.mask]=0
    vd = v.data; vd[v.mask]=0
    # create interpolant
    import scipy.interpolate as intp
    from scipy.interpolate import bisplev, bisplrep
    tcku = bisplrep(G['lon_u'][0, :], G['lat_u'][:, 0], ud)
    tckv = bisplrep(G['lon_v'][0, :], G['lat_v'][:, 0], vd)
    # create regular grid
    daax = aa[1] - aa[0]
    daay = aa[3] - aa[2]
    axrat = np.cos(np.deg2rad(aa[2])) * daax / daay
    x = np.linspace(aa[0], aa[1], int(round(nngrid * axrat)))
    y = np.linspace(aa[2], aa[3], int(nngrid))
    xx, yy = np.meshgrid(x, y)
    # interpolate to regular grid
    uu = bisplev(x, y, tcku)
    vv = bisplev(x, y, tckv)
    mask = uu != 0
    # plot velocity vectors
    ax.quiver(xx[mask], yy[mask], uu[mask], vv[mask],
        units='y', scale=v_scl, scale_units='y', color='b')
//  [python]
def _generate_interpolation_beam_data(fname, beam, res = 1000):
    '''Create a grid of wave vector projections and 2d interpolate the gain function.
    '''
    beam.point(az0=0.0, el0=90.0)

    save_raw = fname.split('.')
    save_raw[-2] += '_data'
    save_raw = '.'.join(save_raw)

    if not os.path.isfile(save_raw):

        kx=np.linspace(-1.0, 1.0, num=res)
        ky=np.linspace(-1.0, 1.0, num=res)
        
        S=np.zeros((res,res))
        Xmat=np.zeros((res,res))
        Ymat=np.zeros((res,res))

        cnt = 0
        tot = res**2

        for i,x in enumerate(kx):
            for j,y in enumerate(ky):
                
                if cnt % int(tot/1000) == 0:
                    print('{}/{} Gain done'.format(cnt, tot))
                cnt += 1

                z2 = x**2 + y**2
                if z2 < 1.0:
                    k=np.array([x, y, np.sqrt(1.0 - z2)])
                    S[i,j]=beam.gain(k)
                else:
                    S[i,j] = 0;
                Xmat[i,j]=x
                Ymat[i,j]=y
        np.save(save_raw, S)

    S = np.load(save_raw)

    f = sio.interp2d(kx, ky, S.T, kind='linear')
    np.save(fname, f)
//  [python]
def _generate_interpolation_beam_data(fname, beam, res = 1000):
    '''Create a grid of wave vector projections and 2d interpolate the gain function.
    '''
    beam.point(az0=0.0, el0=90.0)

    save_raw = fname.split('.')
    save_raw[-2] += '_data'
    save_raw = '.'.join(save_raw)

    if not os.path.isfile(save_raw):

        kx=np.linspace(-1.0, 1.0, num=res)
        ky=np.linspace(-1.0, 1.0, num=res)
        
        S=np.zeros((res,res))
        Xmat=np.zeros((res,res))
        Ymat=np.zeros((res,res))

        cnt = 0
        tot = res**2

        for i,x in enumerate(kx):
            for j,y in enumerate(ky):
                
                if cnt % int(tot/1000) == 0:
                    print('{}/{} Gain done'.format(cnt, tot))
                cnt += 1

                z2 = x**2 + y**2
                if z2 < 1.0:
                    k=np.array([x, y, np.sqrt(1.0 - z2)])
                    S[i,j]=beam.gain(k)
                else:
                    S[i,j] = 0;
                Xmat[i,j]=x
                Ymat[i,j]=y
        np.save(save_raw, S)

    S = np.load(save_raw)

    f = sio.bisplev(kx, ky, S.T)
    np.save(fname, f)
//  [python]
def calculate_opacity(self, a):
        mdust = 4*pi*a**3/3*self.rho

        fabs = scipy.interpolate.interp2d(self.lam, self.a, \
                numpy.log10(self.Qabs), kind='linear')
        fsca = scipy.interpolate.interp2d(self.lam, self.a, \
                numpy.log10(self.Qsca), kind='linear')
        fext = scipy.interpolate.interp2d(self.lam, self.a, \
                numpy.log10(self.Qext), kind='linear')

        Qabs = 10.**fabs(self.lam, a)
        Qsca = 10.**fsca(self.lam, a)
        Qext = 10.**fext(self.lam, a)
        
        self.kabs = pi*a**2*Qabs/mdust
        self.ksca = pi*a**2*Qsca/mdust
        self.kext = pi*a**2*Qext/mdust
    
        self.albedo = self.ksca / self.kext
//  [python]
def calculate_opacity(self, a):
        mdust = 4*pi*a**3/3*self.rho

        tck_fabs = scipy.interpolate.bisplev(self.lam, self.a, \
                scipy.interpolate.bisplrep(self.lam, self.a, \
                numpy.log10(self.Qabs)))
        tck_fsca = scipy.interpolate.bisplev(self.lam, self.a, \
                scipy.interpolate.bisplrep(self.lam, self.a, \
                numpy.log10(self.Qsca)))
        tck_fext = scipy.interpolate.bisplev(self.lam, self.a, \
                scipy.interpolate.bisplrep(self.lam, self.a, \
                numpy.log10(self.Qext)))

        Qabs = 10.**tck_fabs
        Qsca = 10.**tck_fsca
        Qext = 10.**tck_fext
        
        self.kabs = pi*a**2*Qabs/mdust
        self.ksca = pi*a**2*Qsca/mdust
        self.kext = pi*a**2*Qext/mdust
    
        self.albedo = self.ksca / self.kext
//  [python]
def aircraft_range_varying_AOA(data, lift, velocity):
    aoa, v, lift_to_drag = data
    f_LD = scipy.interpolate.interp2d(aoa, v, lift_to_drag, kind='cubic')
    f_L = scipy.interpolate.interp2d(aoa, v, lift, kind='cubic')
    def to_integrate(weight):
        # velocity = 0.514444*108 # m/s (113 KTAS)
        def calculate_AOA(velocity):
            def residual(AOA):
                CL = f_L(AOA, velocity)
                span = 11
                AR = 7.32
                chord_root = span/AR
                dynamic_pressure = .5*density*velocity**2*(span*chord_root)
                return abs(CL - weight/dynamic_pressure)
            res = scipy.optimize.minimize(residual, 0)
            return res.x

        AOA = calculate_AOA(velocity)
        lift_to_drag = f_LD(AOA, velocity)

        span = 10.9728
        RPM = 1800
        a = 0.3089  # (lb/hr)/BTU
        b = 0.008*RPM+19.607  # lb/hr

        lbhr_to_kgs = 0.000125998
        BHP_to_watt = 745.7

        eta = 0.85

        thrust = weight/lift_to_drag

        power_SI = thrust*velocity/eta
        power_BHP = power_SI/BHP_to_watt
        mass_flow = (a*power_BHP + b)
        mass_flow_SI = mass_flow*lbhr_to_kgs

        SFC = mass_flow_SI/thrust
        dR = velocity/g/SFC*lift_to_drag/weight
        return dR*0.001  # *0.0005399

    g = 9.81  # kg/ms
    fuel = 56*6.01*0.4535*g
    initial_weight = 1111*g
    final_weight = initial_weight-fuel
    return scipy.integrate.quad(to_integrate, final_weight, initial_weight)[0]
//  [python]
def aircraft_range_varying_AOA(data, lift, velocity):
    aoa, v, lift_to_drag = data
    f_LD = scipy.interpolate.bisplev(aoa, v, scipy.interpolate.bisplrep(aoa, v, lift_to_drag, kx=3, ky=3))
    f_L = scipy.interpolate.bisplev(aoa, v, scipy.interpolate.bisplrep(aoa, v, lift, kx=3, ky=3))
    def to_integrate(weight):
        # velocity = 0.514444*108 # m/s (113 KTAS)
        def calculate_AOA(velocity):
            def residual(AOA):
                CL = f_L(AOA, velocity)
                span = 11
                AR = 7.32
                chord_root = span/AR
                dynamic_pressure = .5*density*velocity**2*(span*chord_root)
                return abs(CL - weight/dynamic_pressure)
            res = scipy.optimize.minimize(residual, 0)
            return res.x

        AOA = calculate_AOA(velocity)
        lift_to_drag = f_LD(AOA, velocity)

        span = 10.9728
        RPM = 1800
        a = 0.3089  # (lb/hr)/BTU
        b = 0.008*RPM+19.607  # lb/hr

        lbhr_to_kgs = 0.000125998
        BHP_to_watt = 745.7

        eta = 0.85

        thrust = weight/lift_to_drag

        power_SI = thrust*velocity/eta
        power_BHP = power_SI/BHP_to_watt
        mass_flow = (a*power_BHP + b)
        mass_flow_SI = mass_flow*lbhr_to_kgs

        SFC = mass_flow_SI/thrust
        dR = velocity/g/SFC*lift_to_drag/weight
        return dR*0.001  # *0.0005399

    g = 9.81  # kg/ms
    fuel = 56*6.01*0.4535*g
    initial_weight = 1111*g
    final_weight = initial_weight-fuel
    return scipy.integrate.quad(to_integrate, final_weight, initial_weight)[0]
//  [python]
def test_cubic_interp_to_densepred_is_same_for_one_gridlevel(mock_amg):
    """
    Check that if there is only one grid tier present, then the interpolation
    should be identical to a regular grid
    """

    # obtain the reference solution
    coarse_grid = mock_amg.grids[0]
    ny, nx = coarse_grid.ny, coarse_grid.nx
    u_ref, v_ref = np.random.rand(ny, nx), np.random.rand(ny, nx)

    # set the values of the windows to these values
    for ii in range(ny):
        for jj in range(nx):
            mock_amg.grids[0]._array[ii][jj].u = u_ref[ii][jj]
            mock_amg.grids[0]._array[ii][jj].v = v_ref[ii][jj]

    # get the expected interpolations
    xe, ye = np.arange(mock_amg.img_dim[1]), np.arange(mock_amg.img_dim[0])
    f_u = interp.interp2d(coarse_grid.x_vec, coarse_grid.y_vec,
                          u_ref, kind='cubic')
    u_exp = f_u(xe, ye)
    f_v = interp.interp2d(coarse_grid.x_vec, coarse_grid.y_vec,
                          v_ref, kind='cubic')
    v_exp = f_v(xe, ye)
    dp_soln = mock_amg.interp_to_densepred()

    assert np.allclose(u_exp, dp_soln.u)
    assert np.allclose(v_exp, dp_soln.v)
//  [python]
def test_cubic_interp_to_densepred_is_same_for_one_gridlevel(mock_amg):
    """
    Check that if there is only one grid tier present, then the interpolation
    should be identical to a regular grid
    """

    # obtain the reference solution
    coarse_grid = mock_amg.grids[0]
    ny, nx = coarse_grid.ny, coarse_grid.nx
    u_ref, v_ref = np.random.rand(ny, nx), np.random.rand(ny, nx)

    # set the values of the windows to these values
    for ii in range(ny):
        for jj in range(nx):
            mock_amg.grids[0]._array[ii][jj].u = u_ref[ii][jj]
            mock_amg.grids[0]._array[ii][jj].v = v_ref[ii][jj]

    # get the expected interpolations
    xe, ye = np.arange(mock_amg.img_dim[1]), np.arange(mock_amg.img_dim[0])
    x, y = np.meshgrid(coarse_grid.x_vec, coarse_grid.y_vec)
    tck_u = interpolate.bisplrep(x, y, u_ref, kx=3, ky=3)
    u_exp = interpolate.bisplev(xe, ye, tck_u)
    tck_v = interpolate.bisplrep(x, y, v_ref, kx=3, ky=3)
    v_exp = interpolate.bisplev(xe, ye, tck_v)
    dp_soln = mock_amg.interp_to_densepred()

    assert np.allclose(u_exp, dp_soln.u)
    assert np.allclose(v_exp, dp_soln.v)
//  [python]
def __init__(
        self,
        CA_grid,
        CN_grid,
        COP_grid,
        Mach_grid,
        alpha_grid,
        ref_area,
        pitch_damping_coefficient=0.0,
        roll_damping_coefficient=0.0,
        error={"CA": 1.0, "CN": 1.0, "COP": 1.0},
    ):
        self.ref_area = ref_area
        self.pitch_damping_coefficient = pitch_damping_coefficient
        self.roll_damping_coefficient = roll_damping_coefficient

        self.Mach_grid = Mach_grid
        self.alpha_grid = alpha_grid
        self.CA_grid = CA_grid
        self.CN_grid = CN_grid
        self.COP_grid = COP_grid

        self.error = error

        # These can be overridden to custom functions if you wanted - in which case the _grid attributes are irrelevant.
        self.CA_func = scipy.interpolate.interp2d(
            self.Mach_grid, self.alpha_grid, self.CA_grid
        )
        self.CN_func = scipy.interpolate.interp2d(
            self.Mach_grid, self.alpha_grid, self.CN_grid
        )
        self.COP_func = scipy.interpolate.interp2d(
            self.Mach_grid, self.alpha_grid, self.COP_grid
        )
//  [python]
def __init__(
        self,
        CA_grid,
        CN_grid,
        COP_grid,
        Mach_grid,
        alpha_grid,
        ref_area,
        pitch_damping_coefficient=0.0,
        roll_damping_coefficient=0.0,
        error={"CA": 1.0, "CN": 1.0, "COP": 1.0},
    ):
        self.ref_area = ref_area
        self.pitch_damping_coefficient = pitch_damping_coefficient
        self.roll_damping_coefficient = roll_damping_coefficient

        self.Mach_grid = Mach_grid
        self.alpha_grid = alpha_grid
        self.CA_grid = CA_grid
        self.CN_grid = CN_grid
        self.COP_grid = COP_grid

        self.error = error

        # These can be overridden to custom functions if you wanted - in which case the _grid attributes are irrelevant.
        self.CA_func = scipy.interpolate.bisplev
        self.CN_func = scipy.interpolate.bisplev
        self.COP_func = scipy.interpolate.bisplev
//  [python]
def resample_image(orig_img, new_nx, new_ny, interp_method="linear"):
    """
    Upsample or downsample a 2d image to target number of pixels along x and y axes
    """

    orig_x = np.arange(np.shape(orig_img)[0]) / np.shape(orig_img)[0]
    orig_y = np.arange(np.shape(orig_img)[1]) / np.shape(orig_img)[1]
    f = interpolate.interp2d(orig_x, orig_y, orig_img, kind=interp_method)
    new_x, new_y = np.arange(new_nx)/new_nx, np.arange(new_ny)/new_ny

    return f(new_x, new_y)
//  [python]
def resample_image(orig_img, new_nx, new_ny, interp_method="linear"):
    """
    Upsample or downsample a 2d image to target number of pixels along x and y axes
    """

    orig_x = np.arange(np.shape(orig_img)[0]) / np.shape(orig_img)[0]
    orig_y = np.arange(np.shape(orig_img)[1]) / np.shape(orig_img)[1]
    x, y = np.meshgrid(orig_x, orig_y)
    tck = interpolate.bisplrep(x, y, orig_img, kx=1, ky=1)
    new_x, new_y = np.arange(new_nx)/new_nx, np.arange(new_ny)/new_ny
    new_x, new_y = np.meshgrid(new_x, new_y)

    return interpolate.bisplev(new_x, new_y, tck)
//  [python]
def get_psi4_infinity(t,psi4,r):
   r_min=min(r)
   r_max=max(r)

   numr=len(r)

   t_min=min(t)
   t_max=max(t)

   psi4T_real = np.zeros((len(r),len(t)))
   psi4T_img  = np.zeros((len(r),len(t)))
   
   for i in range(0,len(r)):
      psi4T_real[i,:] = np.real(psi4[i])
      psi4T_img [i,:] = np.imag(psi4[i])

   # interpolated psi4 with t and r
   fpsi4_real = scipy.interpolate.interp2d(t,r,psi4T_real,kind='cubic')
   fpsi4_img = scipy.interpolate.interp2d(t,r,psi4T_img,kind='cubic')

   s = 1.0/np.linspace(1.0/r_max, 1.0/r_min , numr )
   s=sort(s)
   
   #print(s)
   
   ts_max = compute_tstar(t_max,r_min)
   ts = np.arange(0,ts_max,0.5)

   tt = np.zeros(numr)

   psi4_ts = np.zeros((len(ts),numr) , dtype=np.complex)
   psi4_ts_inf = np.zeros(len(ts) , dtype=np.complex)

   for i in range(0,len(ts)):
      for j in range(0,numr):
         tt[j] = compute_t(ts[i],s[j])
         psi4_ts[i,j] = fpsi4_real(tt[j],s[j]) + 1.0j * fpsi4_img(tt[j],s[j])

   #print(np.size(psi4_ts,0))
   #print(np.size(psi4_ts,1))
   #print(psi4_ts)   

   V = np.zeros((numr,numr))
   rhs_abs = np.zeros((numr,1))
   rhs_arg = np.zeros((numr,1))

   coeff_abs =np.zeros((numr,1))
   coeff_arg =np.zeros((numr,1))

   for i in range(0,numr):
      for j in range(0,numr):
         V[i,j] = 1.0/(s[i]**j)

   invV=np.linalg.inv(V)

   for i in range(0,len(ts)):
      for j in range(0,numr):
         rhs_abs[j,0]=np.abs(psi4_ts[i,j])
         rhs_arg[j,0]=np.angle(psi4_ts[i,j])

      coeff_abs = np.matmul(invV,rhs_abs)
      coeff_arg = np.matmul(invV,rhs_arg)

      psi4_ts_inf[i] = coeff_abs[0,0] * (cos(coeff_arg[0,0]) + 1j * sin (coeff_arg[0,0]))

   #print(psi4_ts_inf)
   return [ts,psi4_ts_inf]
//  [python]
def get_psi4_infinity(t,psi4,r):
   r_min=min(r)
   r_max=max(r)

   numr=len(r)

   t_min=min(t)
   t_max=max(t)

   psi4T_real = np.zeros((len(r),len(t)))
   psi4T_img  = np.zeros((len(r),len(t)))
   
   for i in range(0,len(r)):
      psi4T_real[i,:] = np.real(psi4[i])
      psi4T_img [i,:] = np.imag(psi4[i])

   # interpolated psi4 with t and r
   x,y = np.meshgrid(t,r)
   tck_real = scipy.interpolate.bisplrep(x,y,psi4T_real,kx=3,ky=3)
   tck_img = scipy.interpolate.bisplrep(x,y,psi4T_img,kx=3,ky=3)

   s = 1.0/np.linspace(1.0/r_max, 1.0/r_min , numr )
   s=sort(s)
   
   #print(s)
   
   ts_max = compute_tstar(t_max,r_min)
   ts = np.arange(0,ts_max,0.5)

   tt = np.zeros(numr)

   psi4_ts = np.zeros((len(ts),numr) , dtype=np.complex)
   psi4_ts_inf = np.zeros(len(ts) , dtype=np.complex)

   for i in range(0,len(ts)):
      for j in range(0,numr):
         tt[j] = compute_t(ts[i],s[j])
         psi4_ts[i,j] = scipy.interpolate.bisplev(tt[j],s[j],tck_real) + 1.0j * scipy.interpolate.bisplev(tt[j],s[j],tck_img)

   #print(np.size(psi4_ts,0))
   #print(np.size(psi4_ts,1))
   #print(psi4_ts)   

   V = np.zeros((numr,numr))
   rhs_abs = np.zeros((numr,1))
   rhs_arg = np.zeros((numr,1))

   coeff_abs =np.zeros((numr,1))
   coeff_arg =np.zeros((numr,1))

   for i in range(0,numr):
      for j in range(0,numr):
         V[i,j] = 1.0/(s[i]**j)

   invV=np.linalg.inv(V)

   for i in range(0,len(ts)):
      for j in range(0,numr):
         rhs_abs[j,0]=np.abs(psi4_ts[i,j])
         rhs_arg[j,0]=np.angle(psi4_ts[i,j])

      coeff_abs = np.matmul(invV,rhs_abs)
      coeff_arg = np.matmul(invV,rhs_arg)

      psi4_ts_inf[i] = coeff_abs[0,0] * (cos(coeff_arg[0,0]) + 1j * sin (coeff_arg[0,0]))

   #print(psi4_ts_inf)
   return [ts,psi4_ts_inf]
//  [python]
def test_linear_interp_to_densepred_is_same_for_one_gridlevel(mock_amg):
    """
    Check that if there is only one grid tier present, then the interpolation
    should be identical to a regular grid
    """

    # obtain the reference solution
    coarse_grid = mock_amg.grids[0]
    ny, nx = coarse_grid.ny, coarse_grid.nx
    u_ref, v_ref = np.random.rand(ny, nx), np.random.rand(ny, nx)

    # set the values of the windows to these values
    for ii in range(ny):
        for jj in range(nx):
            mock_amg.grids[0]._array[ii][jj].u = u_ref[ii][jj]
            mock_amg.grids[0]._array[ii][jj].v = v_ref[ii][jj]

    # get the expected interpolations
    xe, ye = np.arange(mock_amg.img_dim[1]), np.arange(mock_amg.img_dim[0])
    f_u = interp.interp2d(coarse_grid.x_vec, coarse_grid.y_vec,
                          u_ref, kind='linear')
    u_exp = f_u(xe, ye)
    f_v = interp.interp2d(coarse_grid.x_vec, coarse_grid.y_vec,
                          v_ref, kind='linear')
    v_exp = f_v(xe, ye)
    dp_soln = mock_amg.interp_to_densepred(method='linear')

    assert np.allclose(u_exp, dp_soln.u)
    assert np.allclose(v_exp, dp_soln.v)
//  [python]
def test_linear_interp_to_densepred_is_same_for_one_gridlevel(mock_amg):
    """
    Check that if there is only one grid tier present, then the interpolation
    should be identical to a regular grid
    """

    # obtain the reference solution
    coarse_grid = mock_amg.grids[0]
    ny, nx = coarse_grid.ny, coarse_grid.nx
    u_ref, v_ref = np.random.rand(ny, nx), np.random.rand(ny, nx)

    # set the values of the windows to these values
    for ii in range(ny):
        for jj in range(nx):
            mock_amg.grids[0]._array[ii][jj].u = u_ref[ii][jj]
            mock_amg.grids[0]._array[ii][jj].v = v_ref[ii][jj]

    # get the expected interpolations
    xe, ye = np.arange(mock_amg.img_dim[1]), np.arange(mock_amg.img_dim[0])
    x, y = np.meshgrid(coarse_grid.x_vec, coarse_grid.y_vec)
    tck_u = interpolate.bisplrep(x, y, u_ref, kx=1, ky=1)
    u_exp = interpolate.bisplev(xe, ye, tck_u)
    tck_v = interpolate.bisplrep(x, y, v_ref, kx=1, ky=1)
    v_exp = interpolate.bisplev(xe, ye, tck_v)
    dp_soln = mock_amg.interp_to_densepred(method='linear')

    assert np.allclose(u_exp, dp_soln.u)
    assert np.allclose(v_exp, dp_soln.v)
//  [python]
def interp2d_linear(x: ndarray, y: ndarray, z: ndarray) -> (
    Callable[[ndarray, ndarray], ndarray]):
    '''
    Create and return **two-dimensional interpolator** (i.e., low-level callable
    interpolating a source mesh defined on the passed set of X and Y coordinates
    and Z values (e.g., colours) onto a target mesh defined a new of X and Y
    coordinates passed to that callable, which then returns the new Z values
    produced by that interpolation).

    This function effectively implements the obsolete
    :class:`scipy.interpolate.interp2d` class (passed the parameters
    ``kind='linear'`` and ``fill_value=0.0``) in terms of non-obsolete
    functionality defined by the :mod:`scipy.interpolate` subpackage, improving
    backward compatibility with existing code expecting that class to exist.

    Parameters
    ----------
    x: ndarray
        Source X coordinates to interpolate from.
    y: ndarray
        Source Y coordinates to interpolate from.
    z: ndarray
        Source Z values to interpolate from.

    Returns
    ----------
    Callable[[ndarray, ndarray], ndarray]
        Two-dimensional interpolator as described above. The signature of this
        callable should be assumed to be:

        .. code-block:: python

           def interpolator(x_new: ndarray, y_new: ndarray) -> ndarray: ...
    '''

    #FIXME: Comment this out to test our new interp2d() replacement, which is
    #currently broken for unknown reasons. For example, this test fails:
    #    ./pytest -k test_cli_sim_compat
    from scipy.interpolate import interp2d
    return interp2d(x, y, z, kind='linear', fill_value=0.0)

    # Linear B-spline representation of this two-dimensional surface.
    #
    # Note that the "kx=1" and "ky=1" parameters effectively produce a linear
    # interpolation.
    tck = bisplrep(x, y, z, kx=1, ky=1)

    # Return the desired interpolator for this linear B-spline representation.
    #
    # Note that usage of partial() here is required to avoid infinite recursion
    # from the standard "pickle" and third-party "dill" modules. In particular,
    # attempting to replace this partial() approach with a simpler lambda
    # function or closure induces infinite recursion for unknown reasons.
    return partial(_interpolator2d_linear, _tck=tck)
//  [python]
def interp2d_linear(x: ndarray, y: ndarray, z: ndarray) -> (
    Callable[[ndarray, ndarray], ndarray]):
    '''
    Create and return **two-dimensional interpolator** (i.e., low-level callable
    interpolating a source mesh defined on the passed set of X and Y coordinates
    and Z values (e.g., colours) onto a target mesh defined a new of X and Y
    coordinates passed to that callable, which then returns the new Z values
    produced by that interpolation).

    This function effectively implements the obsolete
    :class:`scipy.interpolate.interp2d` class (passed the parameters
    ``kind='linear'`` and ``fill_value=0.0``) in terms of non-obsolete
    functionality defined by the :mod:`scipy.interpolate` subpackage, improving
    backward compatibility with existing code expecting that class to exist.

    Parameters
    ----------
    x: ndarray
        Source X coordinates to interpolate from.
    y: ndarray
        Source Y coordinates to interpolate from.
    z: ndarray
        Source Z values to interpolate from.

    Returns
    ----------
    Callable[[ndarray, ndarray], ndarray]
        Two-dimensional interpolator as described above. The signature of this
        callable should be assumed to be:

        .. code-block:: python

           def interpolator(x_new: ndarray, y_new: ndarray) -> ndarray: ...
    '''

    from scipy.interpolate import bisplrep, bisplev
    from functools import partial

    # Linear B-spline representation of this two-dimensional surface.
    #
    # Note that the "kx=1" and "ky=1" parameters effectively produce a linear
    # interpolation.
    tck = bisplrep(x, y, z, kx=1, ky=1)

    # Return the desired interpolator for this linear B-spline representation.
    #
    # Note that usage of partial() here is required to avoid infinite recursion
    # from the standard "pickle" and third-party "dill" modules. In particular,
    # attempting to replace this partial() approach with a simpler lambda
    # function or closure induces infinite recursion for unknown reasons.
    return partial(bisplev, _tck=tck)
//  [python]
def fun_dOCVdSoC_Interped(self,SoC,T):              #input SoC of each ECN element, as vector SoC; output dOCV/dSoC as vector dOCVdSoC;  SoC, T and OCV are from Ei_pair, in the form of 1,2...nECN 
    #=================================scipy interpolation function (faster)
        n0=np.size(SoC);  dOCVdSoC=np.zeros([n0,1])
        f = interpolate.interp2d(self.LUT_SoC_for_dOCVdSoC, self.LUT_T, self.LUT_dOCVdSoC_PerA.reshape(self.nT+2,self.nSoC+2), kind=self.status_scipy_interpkind)
        for i0 in np.arange(n0):
            dOCVdSoC[i0]=f(SoC[i0],T[i0])
        if self.status_scipy_interpkind != 'linear':                              #Saturation is used when cubic interpolation is used. Because runge phenomenon may happen causing minus or unreasonably high value
            dOCVdSoC[dOCVdSoC < self.LUT_dOCVdSoC_Cell_min]=self.LUT_dOCVdSoC_Cell_min; dOCVdSoC[dOCVdSoC > self.LUT_dOCVdSoC_Cell_max]=self.LUT_dOCVdSoC_Cell_max
        return dOCVdSoC
//  [python]
def fun_dOCVdSoC_Interped(self,SoC,T):              #input SoC of each ECN element, as vector SoC; output dOCV/dSoC as vector dOCVdSoC;  SoC, T and OCV are from Ei_pair, in the form of 1,2...nECN 
    #=================================scipy interpolation function (faster)
        n0=np.size(SoC);  dOCVdSoC=np.zeros([n0,1])
        tck = interpolate.bisplev(self.LUT_SoC_for_dOCVdSoC, self.LUT_T, self.LUT_dOCVdSoC_PerA.reshape(self.nT+2,self.nSoC+2), s=0)
        for i0 in np.arange(n0):
            dOCVdSoC[i0]=interpolate.bisplev(SoC[i0],T[i0],tck)
        if self.status_scipy_interpkind != 'linear':                              #Saturation is used when cubic interpolation is used. Because runge phenomenon may happen causing minus or unreasonably high value
            dOCVdSoC[dOCVdSoC < self.LUT_dOCVdSoC_Cell_min]=self.LUT_dOCVdSoC_Cell_min; dOCVdSoC[dOCVdSoC > self.LUT_dOCVdSoC_Cell_max]=self.LUT_dOCVdSoC_Cell_max
        return dOCVdSoC
//  [python]
def _intVar(self, v, nx=1, ny=1, fac = 1):

        if(nx==self.nx and self.ny == ny): return v
            
        facx = np.arange(nx)[0::fac][-1]
        facy = np.arange(ny)[0::fac][-1]
        print("model::_intVar: facy={0}, facx={1}, ny={2}, nx={3}".format(facy, facx, ny-1, nx-1))
        
        xx = np.arange(self.nx, dtype='float32') / (self.nx-1.0)*facx
        yy = np.arange(self.ny, dtype='float32') / (self.ny-1.0)*facy
        
        xx1 = np.arange(nx, dtype='float32')
        yy1 = np.arange(ny, dtype='float32')
        

        m = np.zeros((self.nt, ny, nx, self.ndep), dtype='float32')
        
        for tt in range(self.nt):
            for kk in range(self.ndep):
                inte = interp2d(xx,yy,v[tt,:,:,kk].squeeze(), kind='linear')
                m[tt,:,:,kk] = inte(xx1, yy1)
        return m
//  [python]
def _intVar(self, v, nx=1, ny=1, fac = 1):

        if(nx==self.nx and self.ny == ny): return v
            
        facx = np.arange(nx)[0::fac][-1]
        facy = np.arange(ny)[0::fac][-1]
        print("model::_intVar: facy={0}, facx={1}, ny={2}, nx={3}".format(facy, facx, ny-1, nx-1))
        
        xx = np.arange(self.nx, dtype='float32') / (self.nx-1.0)*facx
        yy = np.arange(self.ny, dtype='float32') / (self.ny-1.0)*facy
        
        xx1 = np.arange(nx, dtype='float32')
        yy1 = np.arange(ny, dtype='float32')
        

        m = np.zeros((self.nt, ny, nx, self.ndep), dtype='float32')
        
        from scipy.interpolate import bisplev, bisplrep
        for tt in range(self.nt):
            for kk in range(self.ndep):
                tck = bisplrep(xx, yy, v[tt,:,:,kk].squeeze())
                m[tt,:,:,kk] = bisplev(xx1, yy1, tck)
        return m
//  [python]
def _query_raster_interp(nodes, filepath, band=1, method='linear'):

    with rasterio.open(filepath) as src:
        band1 = src.read(band)
        height = band1.shape[0]
        width = band1.shape[1]
        cols, rows = np.meshgrid(np.arange(width), np.arange(height))
        xs, ys = rasterio.transform.xy(src.transform, rows, cols)
    
    lons= np.array(xs)
    lats = np.array(ys)
    f = scipy.interpolate.interp2d(
        lons[0, :],
        lats[:, 0],
        band1,
        kind=method
    )
    
    values = [f(r[0], r[1])[0] for r in nodes.values]
    # values = nodes.apply(lambda r: f(r.x, r.y)[0], 1)

    return list(zip(nodes.index, values))
//  [python]
def _query_raster_interp(nodes, filepath, band=1, method='linear'):

    with rasterio.open(filepath) as src:
        band1 = src.read(band)
        height = band1.shape[0]
        width = band1.shape[1]
        cols, rows = np.meshgrid(np.arange(width), np.arange(height))
        xs, ys = rasterio.transform.xy(src.transform, rows, cols)
    
    lons= np.array(xs)
    lats = np.array(ys)
    x_coords = np.unique(lons[0,:])
    y_coords = np.unique(lats[:,0])
    tck = scipy.interpolate.bisplev(x_coords, y_coords, band1)

    values = [scipy.interpolate.bisplev(r[0], r[1], tck)[0] for r in nodes.values]
    # values = nodes.apply(lambda r: f(r.x, r.y)[0], 1)

    return list(zip(nodes.index, values))
//  [python]
def resize(a, new_shape, stretch=True,method='linear'):
    """ Returns a in the new_shape.
    stretch=True: Interpolate as necessary. If false, use numpy.resize
    method= 'linear' ==> interp2d kind.
    %Only supports 2D at the moment   
    """
    import numpy as np
    if stretch==False:
        return np.resize(a, new_shape)
    import scipy
    import scipy.interpolate
    #import scipy.misc
    #return scipy.misc.imresize(a,new_shape)
    #X, Y=  meshgrid(x, y)
    x=arange(a.shape[0])
    y=arange(a.shape[1])
    interpFun=scipy.interpolate.interp2d(x,y,a )   
    X=arange(new_shape[0])*a.shape[0]/new_shape[0]
    Y=arange(new_shape[1])*a.shape[1]/new_shape[1]
    return interpFun(X,Y)
//  [python]
def resize(a, new_shape, stretch=True,method='linear'):
    """ Returns a in the new_shape.
    stretch=True: Interpolate as necessary. If false, use numpy.resize
    method= 'linear' ==> interp2d kind.
    %Only supports 2D at the moment   
    """
    import numpy as np
    if stretch==False:
        return np.resize(a, new_shape)
    import scipy
    import scipy.interpolate
    #import scipy.misc
    #return scipy.misc.imresize(a,new_shape)
    #X, Y=  meshgrid(x, y)
    x=np.arange(a.shape[0])
    y=np.arange(a.shape[1])
    interpFun=scipy.interpolate.bisplev(x,y,scipy.interpolate.bisplrep(x,y,a))   
    X=np.arange(new_shape[0])*a.shape[0]/new_shape[0]
    Y=np.arange(new_shape[1])*a.shape[1]/new_shape[1]
    return interpFun(X,Y)
//  [python]
def interp_2d3l(data, X, Y, nx, ny, kind):
    ## Interpolate 3-layer 2D arrays individually

    # Check and flip Y array if needed
    if Y[0,0] > Y[-1,0]:
        Y = np.flipud(Y)

    f0 = scipy.interpolate.interp2d(X, Y, data[:,:,0], kind=kind)
    f1 = scipy.interpolate.interp2d(X, Y, data[:,:,1], kind=kind)
    f2 = scipy.interpolate.interp2d(X, Y, data[:,:,2], kind=kind)

    y_new = np.linspace(np.min(Y), np.max(Y), ny)
    x_new = np.linspace(np.min(X), np.max(X), nx)

    data_new = np.empty([len(y_new), len(x_new), 3])
    data_new[:,:,0] = f0(x_new, y_new)
    data_new[:,:,1] = f1(x_new, y_new)
    data_new[:,:,2] = f2(x_new, y_new)

    return data_new
//  [python]
def interp_2d3l(data, X, Y, nx, ny, kind):
    ## Interpolate 3-layer 2D arrays individually

    # Check and flip Y array if needed
    if Y[0,0] > Y[-1,0]:
        Y = np.flipud(Y)

    tck0 = scipy.interpolate.bisplrep(X, Y, data[:,:,0], kx=kind, ky=kind)
    tck1 = scipy.interpolate.bisplrep(X, Y, data[:,:,1], kx=kind, ky=kind)
    tck2 = scipy.interpolate.bisplrep(X, Y, data[:,:,2], kx=kind, ky=kind)

    y_new = np.linspace(np.min(Y), np.max(Y), ny)
    x_new = np.linspace(np.min(X), np.max(X), nx)

    data_new = np.empty([len(y_new), len(x_new), 3])
    data_new[:,:,0] = scipy.interpolate.bisplev(x_new, y_new, tck0)
    data_new[:,:,1] = scipy.interpolate.bisplev(x_new, y_new, tck1)
    data_new[:,:,2] = scipy.interpolate.bisplev(x_new, y_new, tck2)

    return data_new
//  [python]
def scale(self, ny=1, nx = 1):
        m = sp.profile(nt=self.nt, ny=ny, nx=nx, nw=self.nw, ns=self.ns)
        
        xx = np.arange(self.nx, dtype='float32')
        yy = np.arange(self.ny, dtype='float32')

        xx1 = np.arange(nx, dtype='float32')/np.maximum(1, nx-1.0) * self.nx
        yy1 = np.arange(ny, dtype='float32')/np.maximum(1, ny-1.0) * self.ny

        me = np.mean(self.dat[:,:,:,:,0])
        if(me < 1.e-19): me = 1.0
        me1 = 1.0 / me
        
        
        for tt in range(self.nt):
            inte = interp2d(xx,yy,self.pweights[tt,:,:], kind='linear')
            m.pweights[yy,:,:] = inte(xx1,yy1)
             
            for ww in range(self.nw):
                for ss in range(self.ns):
                    inte = interp2d(xx,yy,self.dat[tt,:,:,ww,ss].squeeze()*me1, kind='linear')
                    m.dat[tt,:,:,ww,ss] = inte(xx1,yy1)*me

        m.wav[:] = self.wav
        m.weights[:,:] = self.weights[:,:]
        
                     
        return m
//  [python]
def scale(self, ny=1, nx = 1):
        m = sp.profile(nt=self.nt, ny=ny, nx=nx, nw=self.nw, ns=self.ns)
        
        xx = np.arange(self.nx, dtype='float32')
        yy = np.arange(self.ny, dtype='float32')

        xx1 = np.arange(nx, dtype='float32')/np.maximum(1, nx-1.0) * self.nx
        yy1 = np.arange(ny, dtype='float32')/np.maximum(1, ny-1.0) * self.ny

        me = np.mean(self.dat[:,:,:,:,0])
        if(me < 1.e-19): me = 1.0
        me1 = 1.0 / me
        
        
        for tt in range(self.nt):
            x, y = np.meshgrid(xx, yy)
            tck = bisplev(x, y, self.pweights[tt,:,:])
            m.pweights[tt,:,:] = bisplev(xx1, yy1, tck)
             
            for ww in range(self.nw):
                for ss in range(self.ns):
                    x, y = np.meshgrid(xx, yy)
                    tck = bisplev(x, y, self.dat[tt,:,:,ww,ss].squeeze()*me1)
                    m.dat[tt,:,:,ww,ss] = bisplev(xx1, yy1, tck)*me

        m.wav[:] = self.wav
        m.weights[:,:] = self.weights[:,:]
        
                     
        return m
//  [python]
def load(self):
        self.Jmesh = np.load("tabulated/current_density.npy")
        self.Finv = np.load("tabulated/Finv.npy")
        self.Rinv = np.load("tabulated/Rinv.npy")
        self.finterp = intrp.interp2d(self.Finv, self.Rinv, np.log(self.Jmesh))
//  [python]
def load(self):
        self.Jmesh = np.load("tabulated/current_density.npy")
        self.Finv = np.load("tabulated/Finv.npy")
        self.Rinv = np.load("tabulated/Rinv.npy")
        self.finterp = bisplev(self.Finv, self.Rinv, np.log(self.Jmesh))
//  [python]
def skybg_sdss(fits_image):
	"""A function for reconstructing background image of an SDSS image.
	A low resolution of background image is stored in HDU2 of an SDSS image.
	This function perform a bilinear interpolation to this sample background image. 

	:param fits_image:
		Input SDSS image. This image should be the corrected frame type provided in the SDSS website. 

	:returns output:
		A dictionary that contains background image and its name 
	"""

	from scipy import interpolate

	hdu = fits.open(fits_image)
	hdu2_data = hdu[2].data
	ALLSKY = hdu2_data[0][0]
	XINTERP = hdu2_data[0][1]
	YINTERP = hdu2_data[0][2]

	dim_y0 = ALLSKY.shape[0]
	dim_x0 = ALLSKY.shape[1]
	x = np.arange(0,dim_x0,1)
	y = np.arange(0,dim_y0,1)
	f = interpolate.interp2d(x, y, ALLSKY, kind='linear')

	dim_y = hdu[0].shape[0]
	dim_x = hdu[0].shape[1]
	full_sky = f(XINTERP,YINTERP)

	## write to a fits file:
	out_fits_name = "skybg_%s" % fits_image
	header = fits.getheader(fits_image)
	fits.writeto(out_fits_name, full_sky, header, overwrite=True)
	#print ("produce %s" % out_fits_name)

	output = {}
	output['skybg'] = full_sky
	output['skybg_name'] = out_fits_name

	return output
//  [python]
def skybg_sdss(fits_image):
	"""A function for reconstructing background image of an SDSS image.
	A low resolution of background image is stored in HDU2 of an SDSS image.
	This function perform a bilinear interpolation to this sample background image. 

	:param fits_image:
		Input SDSS image. This image should be the corrected frame type provided in the SDSS website. 

	:returns output:
		A dictionary that contains background image and its name 
	"""

	from scipy import interpolate
	import numpy as np
	from astropy.io import fits

	hdu = fits.open(fits_image)
	hdu2_data = hdu[2].data
	ALLSKY = hdu2_data[0][0]
	XINTERP = hdu2_data[0][1]
	YINTERP = hdu2_data[0][2]

	dim_y0 = ALLSKY.shape[0]
	dim_x0 = ALLSKY.shape[1]
	x = np.arange(0,dim_x0,1)
	y = np.arange(0,dim_y0,1)
	tck = interpolate.bisplrep(x, y, ALLSKY, kx=1, ky=1)
	full_sky = interpolate.bisplev(XINTERP, YINTERP, tck)

	## write to a fits file:
	out_fits_name = "skybg_%s" % fits_image
	header = fits.getheader(fits_image)
	fits.writeto(out_fits_name, full_sky, header, overwrite=True)
	#print ("produce %s" % out_fits_name)

	output = {}
	output['skybg'] = full_sky
	output['skybg_name'] = out_fits_name

	return output
//  [python]
def tabulate_JFR(self, Nf = 256, Nr = 256):
        self.Finv = np.linspace(1./20., 1., Nf)
        self.Rinv = np.linspace(1/100., 2., Nr)
        
        self.Jmesh = np.zeros((Nr, Nf))
        
        for i in range(Nr):
            self.emitter.R = 1./self.Rinv[i]
            for j in range(Nf):
                self.emitter.F = 1./self.Finv[j]
                self.emitter.Voltage = self.emitter.F * self.emitter.R * 0.2
                self.emitter.cur_dens_SC()
                self.Jmesh[i,j] = self.emitter.Jem
                if (self.emitter.Jem <= 0.):
                    self.emitter.print_data()
        try:
            os.mkdir("tabulated")
        except:
            pass
            
        np.save("tabulated/current_density", self.Jmesh)
        np.save("tabulated/Finv", self.Finv)
        np.save("tabulated/Rinv", self.Rinv)
        np.save("tabulated/checkcase",np.array([1./self.Finv[0], 1./self.Rinv[0], self.Jmesh[0,0]]))
        self.finterp = intrp.interp2d(self.Finv, self.Rinv, np.log(self.Jmesh))
//  [python]
def tabulate_JFR(self, Nf = 256, Nr = 256):
        self.Finv = np.linspace(1./20., 1., Nf)
        self.Rinv = np.linspace(1/100., 2., Nr)
        
        self.Jmesh = np.zeros((Nr, Nf))
        
        for i in range(Nr):
            self.emitter.R = 1./self.Rinv[i]
            for j in range(Nf):
                self.emitter.F = 1./self.Finv[j]
                self.emitter.Voltage = self.emitter.F * self.emitter.R * 0.2
                self.emitter.cur_dens_SC()
                self.Jmesh[i,j] = self.emitter.Jem
                if (self.emitter.Jem <= 0.):
                    self.emitter.print_data()
        try:
            os.mkdir("tabulated")
        except:
            pass
            
        np.save("tabulated/current_density", self.Jmesh)
        np.save("tabulated/Finv", self.Finv)
        np.save("tabulated/Rinv", self.Rinv)
        np.save("tabulated/checkcase",np.array([1./self.Finv[0], 1./self.Rinv[0], self.Jmesh[0,0]]))
        self.finterp = bisplev(self.Finv, self.Rinv, np.log(self.Jmesh))
//  [python]
def resize(self, nx=-1, ny=-1, ndep=-1):
        if(nx < 0): nx = self.nx
        if(ny < 0): ny = self.ny
        if(ndep <0):ndep = self.ndep
        nt = self.nt
            
        nm = sp.model(nx=nx, ny=ny, nt=nt, ndep=ndep)

        xx = np.arange(self.nx, dtype='float64')
        yy = np.arange(self.ny, dtype='float64')
        xx1 = np.arange(nx, dtype='float64') * (self.nx-1) / np.maximum(1, nx-1.0)
        yy1 = np.arange(ny, dtype='float64') * (self.ny-1) / np.maximum(1, ny-1.0)

        db.set_trace()
        for tt in range(nt):
            for kk in range(ndep):
                nm.temp[tt,:,:,kk] = \
                  (inte.interp2d(yy,xx,self.temp[tt,:,:,kk], kind='linear'))(yy1,xx1)
                nm.vlos[tt,:,:,kk] = \
                  (inte.interp2d(yy,xx,self.vlos[tt,:,:,kk], kind='linear'))(yy1,xx1)
                nm.vturb[tt,:,:,kk] = \
                  (inte.interp2d(yy,xx,self.vturb[tt,:,:,kk], kind='linear'))(yy1,xx1)
                nm.Bln[tt,:,:,kk] = \
                  (inte.interp2d(yy,xx,self.Bln[tt,:,:,kk], kind='linear'))(yy1,xx1)
                nm.Bho[tt,:,:,kk] = \
                  (inte.interp2d(yy,xx,self.Bho[tt,:,:,kk], kind='linear'))(yy1,xx1)
                nm.azi[tt,:,:,kk] = \
                  (inte.interp2d(yy,xx,self.azi[tt,:,:,kk], kind='linear'))(yy1,xx1)
                nm.pgas[tt,:,:,kk] = \
                  (inte.interp2d(yy,xx,self.pgas[tt,:,:,kk], kind='linear'))(yy1,xx1)
                nm.rho[tt,:,:,kk] = \
                  (inte.interp2d(yy,xx,self.rho[tt,:,:,kk], kind='linear'))(yy1,xx1)
                nm.nne[tt,:,:,kk] = \
                  (inte.interp2d(yy,xx,self.nne[tt,:,:,kk], kind='linear'))(yy1,xx1) 
                nm.ltau[tt,:,:,kk] = \
                  (inte.interp2d(yy,xx,self.ltau[tt,:,:,kk], kind='linear'))(yy1,xx1)
                nm.z[tt,:,:,kk] = \
                  (inte.interp2d(yy,xx,self.z[tt,:,:,kk], kind='linear'))(yy1,xx1) 
                  
        return(nm)
//  [python]
def resize(self, nx=-1, ny=-1, ndep=-1):
        if(nx < 0): nx = self.nx
        if(ny < 0): ny = self.ny
        if(ndep <0):ndep = self.ndep
        nt = self.nt
            
        nm = sp.model(nx=nx, ny=ny, nt=nt, ndep=ndep)

        xx = np.arange(self.nx, dtype='float64')
        yy = np.arange(self.ny, dtype='float64')
        xx1 = np.arange(nx, dtype='float64') * (self.nx-1) / np.maximum(1, nx-1.0)
        yy1 = np.arange(ny, dtype='float64') * (self.ny-1) / np.maximum(1, ny-1.0)

        db.set_trace()
        for tt in range(nt):
            for kk in range(ndep):
                nm.temp[tt,:,:,kk] = \
                  (inte.bisplev(xx, yy, inte.bisplrep(xx, yy, self.temp[tt,:,:,kk], kx=1, ky=1)))(xx1, yy1)
                nm.vlos[tt,:,:,kk] = \
                  (inte.bisplev(xx, yy, inte.bisplrep(xx, yy, self.vlos[tt,:,:,kk], kx=1, ky=1)))(xx1, yy1)
                nm.vturb[tt,:,:,kk] = \
                  (inte.bisplev(xx, yy, inte.bisplrep(xx, yy, self.vturb[tt,:,:,kk], kx=1, ky=1)))(xx1, yy1)
                nm.Bln[tt,:,:,kk] = \
                  (inte.bisplev(xx, yy, inte.bisplrep(xx, yy, self.Bln[tt,:,:,kk], kx=1, ky=1)))(xx1, yy1)
                nm.Bho[tt,:,:,kk] = \
                  (inte.bisplev(xx, yy, inte.bisplrep(xx, yy, self.Bho[tt,:,:,kk], kx=1, ky=1)))(xx1, yy1)
                nm.azi[tt,:,:,kk] = \
                  (inte.bisplev(xx, yy, inte.bisplrep(xx, yy, self.azi[tt,:,:,kk], kx=1, ky=1)))(xx1, yy1)
                nm.pgas[tt,:,:,kk] = \
                  (inte.bisplev(xx, yy, inte.bisplrep(xx, yy, self.pgas[tt,:,:,kk], kx=1, ky=1)))(xx1, yy1)
                nm.rho[tt,:,:,kk] = \
                  (inte.bisplev(xx, yy, inte.bisplrep(xx, yy, self.rho[tt,:,:,kk], kx=1, ky=1)))(xx1, yy1)
                nm.nne[tt,:,:,kk] = \
                  (inte.bisplev(xx, yy, inte.bisplrep(xx, yy, self.nne[tt,:,:,kk], kx=1, ky=1)))(xx1, yy1) 
                nm.ltau[tt,:,:,kk] = \
                  (inte.bisplev(xx, yy, inte.bisplrep(xx, yy, self.ltau[tt,:,:,kk], kx=1, ky=1)))(xx1, yy1)
                nm.z[tt,:,:,kk] = \
                  (inte.bisplev(xx, yy, inte.bisplrep(xx, yy, self.z[tt,:,:,kk], kx=1, ky=1)))(xx1, yy1) 
                  
        return(nm)
//  [python]
def interp2D(M_Zc,Z_pts,c_pts,z_space,c_space):   
    #对于(Z_pts,c_pts)上取值的M_Zc，在插值点meshgrid上插值
    f = scipy.interpolate.interp2d(c_pts,Z_pts,M_Zc,kind="linear")
    intpM_Zc = f(c_space,z_space)
    # import matplotlib.pyplot as plt
    # plt.plot(c_pts, M_Zc[0, :], 'ro-', c_space, intpM_Zc[0, :], 'b-')
    # plt.show()
    return intpM_Zc
//  [python]
def interp2D(M_Zc,Z_pts,c_pts,z_space,c_space):   
    #对于(Z_pts,c_pts)上取值的M_Zc，在插值点meshgrid上插值
    tck = scipy.interpolate.bisplrep(c_pts,Z_pts,M_Zc)
    intpM_Zc = scipy.interpolate.bisplev(c_space,z_space,tck)
    return intpM_Zc
//  [python]
def interp_grid_data(self):
        if self.grid_data is not None:
            X, Y, Z = self.grid_data
            self.ig = spi.interp2d(X, Y, Z, kind='cubic')
//  [python]
def interp_grid_data(self):
        if self.grid_data is not None:
            X, Y, Z = self.grid_data
            self.ig = spi.bisplev(X, Y, Z)
//  [python]
def hst_get_ee_corr(ap,filt,inst):
    if inst.lower()=='ir':
        if not os.path.exists('ir_ee_corrections.csv'):
            urllib.request.urlretrieve('https://www.stsci.edu/files/live/sites/www/files/home/hst/'+\
                                       'instrumentation/wfc3/data-analysis/photometric-calibration/'+\
                                       'ir-encircled-energy/_documents/ir_ee_corrections.csv',
                                       'ir_ee_corrections.csv')
        
        ee = Table.read('ir_ee_corrections.csv',format='ascii')
        ee.rename_column('PIVOT','WAVELENGTH')
    else:
        if not os.path.exists('wfc3uvis2_aper_007_syn.csv'):
            urllib.request.urlretrieve('https://www.stsci.edu/files/live/sites/www/files/home/hst/'+\
                                   'instrumentation/wfc3/data-analysis/photometric-calibration/'+\
                                   'uvis-encircled-energy/_documents/wfc3uvis2_aper_007_syn.csv',
                                      'wfc3uvis2_aper_007_syn.csv')
        ee = Table.read('wfc3uvis2_aper_007_syn.csv',format='ascii')

    filts = ee['FILTER']
    ee.remove_column('FILTER')
    waves = ee['WAVELENGTH']
    ee.remove_column('WAVELENGTH')
    ee_arr = np.array([ee[col] for col in ee.colnames])
    apps = [float(x.split('#')[1]) for x in ee.colnames]
    interp = scipy.interpolate.interp2d(waves,apps,ee_arr)
    filt_wave = waves[np.where(filts==filt.upper())[0][0]]
    return(interp(filt_wave,ap))
//  [python]
def hst_get_ee_corr(ap,filt,inst):
    if inst.lower()=='ir':
        if not os.path.exists('ir_ee_corrections.csv'):
            urllib.request.urlretrieve('https://www.stsci.edu/files/live/sites/www/files/home/hst/'+\
                                       'instrumentation/wfc3/data-analysis/photometric-calibration/'+\
                                       'ir-encircled-energy/_documents/ir_ee_corrections.csv',
                                       'ir_ee_corrections.csv')
        
        ee = Table.read('ir_ee_corrections.csv',format='ascii')
        ee.rename_column('PIVOT','WAVELENGTH')
    else:
        if not os.path.exists('wfc3uvis2_aper_007_syn.csv'):
            urllib.request.urlretrieve('https://www.stsci.edu/files/live/sites/www/files/home/hst/'+\
                                   'instrumentation/wfc3/data-analysis/photometric-calibration/'+\
                                   'uvis-encircled-energy/_documents/wfc3uvis2_aper_007_syn.csv',
                                      'wfc3uvis2_aper_007_syn.csv')
        ee = Table.read('wfc3uvis2_aper_007_syn.csv',format='ascii')

    filts = ee['FILTER']
    ee.remove_column('FILTER')
    waves = ee['WAVELENGTH']
    ee.remove_column('WAVELENGTH')
    ee_arr = np.array([ee[col] for col in ee.colnames])
    apps = [float(x.split('#')[1]) for x in ee.colnames]
    interp = scipy.interpolate.bisplev(waves,apps,ee_arr)
    filt_wave = waves[np.where(filts==filt.upper())[0][0]]
    return(interp(filt_wave,ap))
//  [python]
def theory_xi_2D(self, params, rmax=85, **kwargs):
        r"""
        Compute the theory model prediction as a function of distances perpendicular and parallel to the line of sight

        Parameters
        ----------
        params : dict
            Dictionary containing parameter values at which to evaluate the model

        rmax : float, default=85
            Maximum distance (in each direction) out to which model should be calculated

        kwargs : dict
            Optional settings to override those in :attr:`model`

        Returns
        -------
        xi_model : instance of :class:`scipy.interpolate.interp2d`
            Representing the redshift-space model prediction :math:`\xi^s(s_\perp, s_{||})`
        """

        sperp = np.linspace(0.01, rmax)
        spar = np.linspace(-rmax, rmax)  # allow for potential odd functions
        def smu(sigma, pi):
            s = np.sqrt(sigma**2 + pi**2)
            return s, pi/s
        s, mu = distance_modulus(*np.meshgrid(sperp, spar))
        xi_smu = self.theory_xi(s, mu, params, **kwargs)
        xi_model = si.interp2d(sperp, spar, xi_smu)
        return xi_model