jiahuimbzuai/CoQuIR huggingface dataset:
//  [python]
def __init__(self, knots, name=NN, **wrap):
        '''New L{HeightCubic} interpolator.

           @arg knots: The points with known height (C{LatLon}s).
           @kwarg name: Optional name for this height interpolator (C{str}).
           @kwarg wrap: If C{True}, wrap or I{normalize} all B{C{knots}}
                        and B{C{llis}} locations (C{bool}).

           @raise HeightError: Insufficient number of B{C{knots}} or
                               invalid B{C{knot}}.

           @raise ImportError: Package C{numpy} or C{scipy} not found
                               or not installed.

           @raise SciPyError: A C{scipy.interpolate.interp2d} issue.

           @raise SciPyWarning: A C{scipy.interpolate.interp2d} warning
                                as exception.
        '''
        spi = self.scipy_interpolate

        xs, ys, hs = self._xyhs3(knots, **wrap)
        try:  # SciPy.interpolate.interp2d kind 'linear' or 'cubic'
            tck = spi.bisplev(xs, ys, hs, kx=1, ky=1)
            self._interp2d = lambda x,y: spi.bisplev(x, y, tck)
        except Exception as x:
            raise _SciPyIssue(x)

        if name:
            self.name = name
//  [python]
def __init__(self, xs, ts, vols, kind='cubic'):
        self.xs = xs
        self.ts = ts
        self.vols = vols
        self.interp = scipy.interpolate.interp2d(xs, ts, vols, kind=kind, copy=False)
//  [python]
def __init__(self, xs, ts, vols, kind='cubic'):
        self.xs = xs
        self.ts = ts
        self.vols = vols
        self.interp = scipy.interpolate.bisplev
//  [python]
def interpolate_grid(self):
        # Use the grid points to get nzxnk free bias parameters for an arbitrary set of k,z coordinates
        if self.intrinsic_alignments:
            ia_interp = interp.interp2d(np.log(self.K), self.Z, self.BI)
            self.QI = ia_interp(np.log(self.k), self.z)
        if self.galaxy_bias:
            gb_interp = interp.interp2d(np.log(self.K), self.Z, self.Bg)
            self.Qg = gb_interp(np.log(self.k), self.z)
//  [python]
def interpolate_grid(self):
        # Use the grid points to get nzxnk free bias parameters for an arbitrary set of k,z coordinates
        if self.intrinsic_alignments:
            ia_interp = interp.bisplev(np.log(self.K), self.Z, self.BI)
            self.QI = ia_interp(np.log(self.k), self.z)
        if self.galaxy_bias:
            gb_interp = interp.bisplev(np.log(self.K), self.Z, self.Bg)
            self.Qg = gb_interp(np.log(self.k), self.z)
//  [python]
_npz = np.load(os.path.join(os.path.dirname(os.path.abspath(__file__)), "bcs_gap.npz"))  # from bcs_numeric()
reduced_delta_bcs_interp = si.interp1d(_npz["t"], _npz["dr"], kind="cubic")
reduced_delta_bcs_interp.__doc__ = """
    Return the reduced temperature dependent BCS gap ∆(T)/∆(0) using
    an interpolation from data calculated from reduced_delta_bcs_numeric(). 
    Parameters
    ----------
    t : float or numpy.ndarray
        The reduced temperature  (T / Tc).
    Returns
    -------
    dr : float
        The reduced superconducting BCS energy gap ∆(T)/∆(0).
    ----
    """

_npz = np.load(os.path.join(os.path.dirname(os.path.abspath(__file__)), "dynes_gap.npz"))  # from dynes_numeric()
reduced_delta_dynes_interp = si.interp2d(_npz["t"], _npz["g"], _npz["dr"], kind="cubic")
//  [python]
_npz = np.load(os.path.join(os.path.dirname(os.path.abspath(__file__)), "bcs_gap.npz"))  # from bcs_numeric()
reduced_delta_bcs_interp = si.interp1d(_npz["t"], _npz["dr"], kind="cubic")
reduced_delta_bcs_interp.__doc__ = """
    Return the reduced temperature dependent BCS gap ∆(T)/∆(0) using
    an interpolation from data calculated from reduced_delta_bcs_numeric(). 
    Parameters
    ----------
    t : float or numpy.ndarray
        The reduced temperature  (T / Tc).
    Returns
    -------
    dr : float
        The reduced superconducting BCS energy gap ∆(T)/∆(0).
    ----
    """

_npz = np.load(os.path.join(os.path.dirname(os.path.abspath(__file__)), "dynes_gap.npz"))  # from dynes_numeric()
t, g = np.meshgrid(_npz["t"], _npz["g"])
reduced_delta_dynes_interp = si.bisplev(t,g,_npz["dr"])
//  [python]
def interpolate(x,y,z, gridsize,mode='thin_plate',rbfmode=True,shape=None):

    mode=str(mode)
    grids=gridsize


    dx=np.max(x)-np.min(x)
    dy=np.max(y)-np.min(y)

    if dx>dy:
        gridx=grids
        gridy=int(round(dy/dx*grids))
    else:
        gridy=grids
        gridx=int(round(dx/dy*grids))

    if shape != None:
        (gridy,gridx)=shape

    xi, yi = np.linspace(np.min(x), np.max(x), gridx), np.linspace(np.min(y), np.max(y), gridy)
    xi, yi = np.meshgrid(xi, yi)


    if rbfmode:
        rbf = scipy.interpolate.Rbf(x, y, z, function=mode)
        rbf2 = scipy.interpolate.Rbf( y,x, z, function=mode)
    else:
        sayErr("interp2d nicht implementiert")
        x=np.array(x)
        y=np.array(y)
        z=np.array(z)
        xi, yi = np.linspace(np.min(x), np.max(x), gridx), np.linspace(np.min(y), np.max(y), gridy)

        rbf = scipy.interpolate.interp2d(x, y, z, kind=mode)
        rbf2 = scipy.interpolate.interp2d(y, x, z, kind=mode)

    zi=rbf2(yi,xi)
    return [rbf,xi,yi,zi]
//  [python]
def interpolate(x,y,z, gridsize,mode='thin_plate',rbfmode=True,shape=None):

    mode=str(mode)
    grids=gridsize


    dx=np.max(x)-np.min(x)
    dy=np.max(y)-np.min(y)

    if dx>dy:
        gridx=grids
        gridy=int(round(dy/dx*grids))
    else:
        gridy=grids
        gridx=int(round(dx/dy*grids))

    if shape != None:
        (gridy,gridx)=shape

    xi, yi = np.linspace(np.min(x), np.max(x), gridx), np.linspace(np.min(y), np.max(y), gridy)
    xi, yi = np.meshgrid(xi, yi)


    if rbfmode:
        rbf = scipy.interpolate.Rbf(x, y, z, function=mode)
        rbf2 = scipy.interpolate.Rbf( y,x, z, function=mode)
    else:
        sayErr("interp2d nicht implementiert")
        x=np.array(x)
        y=np.array(y)
        z=np.array(z)
        xi, yi = np.linspace(np.min(x), np.max(x), gridx), np.linspace(np.min(y), np.max(y), gridy)

        tck = scipy.interpolate.bisplrep(x, y, z, s=0)
        zi = scipy.interpolate.bisplev(xi[:,0], yi[0,:], tck)
        tck2 = scipy.interpolate.bisplrep(y, x, z, s=0)
        zi2 = scipy.interpolate.bisplev(yi[:,0], xi[0,:], tck2)
        rbf = tck
        rbf2 = tck2

    zi=zi2
    return [rbf,xi,yi,zi]
//  [python]
def saveByDist(self,x,z,vp,vs,den):
        para0 = self.para0
        x = x - x[para0['xs']]
        z = z - z[para0['zs']]
        xNew = np.arange(-20,x[-1],10)
        zNew = np.arange(0,z[-1],5)
        vpNew = scipy.interpolate.interp2d(x,z, vp, kind='cubic')(xNew, zNew)
        vsNew = scipy.interpolate.interp2d(x,z, vs, kind='cubic')(xNew, zNew)
        denNew = scipy.interpolate.interp2d(x,z, den, kind='cubic')(xNew, zNew)
        if not os.path.exists('models/'+para0['model']+'_'):
            os.mkdir('models/'+para0['model']+'_')
        for j in range(len(xNew)):
            with open('models/'+para0['model']+'_/%d'%xNew[j],'w') as f:
                for i in range(len(zNew)):
                    f.write('%f %f %f %f 120000 60000\n'%(zNew[i],vpNew[i,j]\
                        ,vsNew[i,j],denNew[i,j]))
//  [python]
def saveByDist(self,x,z,vp,vs,den):
        para0 = self.para0
        x = x - x[para0['xs']]
        z = z - z[para0['zs']]
        xNew = np.arange(-20,x[-1],10)
        zNew = np.arange(0,z[-1],5)
        tck = scipy.interpolate.bisplev(x, z, scipy.interpolate.bisplrep(x, z, vp, kx=3, ky=3))
        vpNew = tck
        tck = scipy.interpolate.bisplev(x, z, scipy.interpolate.bisplrep(x, z, vs, kx=3, ky=3))
        vsNew = tck
        tck = scipy.interpolate.bisplev(x, z, scipy.interpolate.bisplrep(x, z, den, kx=3, ky=3))
        denNew = tck
        if not os.path.exists('models/'+para0['model']+'_'):
            os.mkdir('models/'+para0['model']+'_')
        for j in range(len(xNew)):
            with open('models/'+para0['model']+'_/%d'%xNew[j],'w') as f:
                for i in range(len(zNew)):
                    f.write('%f %f %f %f 120000 60000\n'%(zNew[i],vpNew[i,j]\
                        ,vsNew[i,j],denNew[i,j]))
//  [python]
def createElevationGrid(pts,mode='thin_plate',rbfmode=True,gridCount=20,bound=0,noise=0.0001):
    
    modeColor={
    'linear' : ( 1.0, 0.3, 0.0),
    'thin_plate' : (0.0, 1.0, 0.0),
    'cubic' : (0.0, 1.0, 1.0),
    'inverse' : (1.0, 1.0, 0.0),
    'multiquadric' : (1.0, .0, 1.0),
    'gaussian' : (1.0, 1.0, 1.0),
    'quintic' :(0.5,1.0, 0.0)
    }

    # add some noise to avoid singualr matrixes
    if noise==0:
        noisefactor=0
    else:
        noisefactor=10**(-4+noise)
    
    if len(pts)==0:
        sayErr("no points for elevation grid")
        return []
    
    pts2=[p+FreeCAD.Vector(random.random(),random.random(),random.random())*noisefactor for p in pts]

    x=np.array(pts2)[:,0]
    y=np.array(pts2)[:,1]
    z=np.array(pts2)[:,2]

    if rbfmode:
        rbf = scipy.interpolate.Rbf(x, y, z, function=mode)
    else:
        rbf = scipy.interpolate.interp2d(x, y, z, kind=mode)

    # calculate output point grid
    xia, yia = np.linspace(np.min(x), np.max(x), gridCount), np.linspace(np.min(y), np.max(y), gridCount)

    pts3=[]
    for ix in xia:
        points=[]
        for iy in yia:
            iz=float(rbf(ix,iy))
            if bound>0:
                if iz > bound: iz = bound
                if iz < -bound: iz = -bound
            points.append(FreeCAD.Vector(ix,iy,iz))

        pts3.append(points)

    return pts3
//  [python]
def createElevationGrid(pts,mode='thin_plate',rbfmode=True,gridCount=20,bound=0,noise=0.0001):
    
    modeColor={
    'linear' : ( 1.0, 0.3, 0.0),
    'thin_plate' : (0.0, 1.0, 0.0),
    'cubic' : (0.0, 1.0, 1.0),
    'inverse' : (1.0, 1.0, 0.0),
    'multiquadric' : (1.0, .0, 1.0),
    'gaussian' : (1.0, 1.0, 1.0),
    'quintic' :(0.5,1.0, 0.0)
    }

    # add some noise to avoid singualr matrixes
    if noise==0:
        noisefactor=0
    else:
        noisefactor=10**(-4+noise)
    
    if len(pts)==0:
        sayErr("no points for elevation grid")
        return []
    
    pts2=[p+FreeCAD.Vector(random.random(),random.random(),random.random())*noisefactor for p in pts]

    x=np.array(pts2)[:,0]
    y=np.array(pts2)[:,1]
    z=np.array(pts2)[:,2]

    if rbfmode:
        rbf = scipy.interpolate.Rbf(x, y, z, function=mode)
    else:
        tck = scipy.interpolate.bisplrep(x, y, z, kx=1, ky=1)
        rbf = lambda x,y: scipy.interpolate.bisplev(x,y,tck)

    # calculate output point grid
    xia, yia = np.linspace(np.min(x), np.max(x), gridCount), np.linspace(np.min(y), np.max(y), gridCount)

    pts3=[]
    for ix in xia:
        points=[]
        for iy in yia:
            iz=float(rbf(ix,iy))
            if bound>0:
                if iz > bound: iz = bound
                if iz < -bound: iz = -bound
            points.append(FreeCAD.Vector(ix,iy,iz))

        pts3.append(points)

    return pts3
//  [python]
def get_depth_interpolator(depth_im):
    x_coords = np.arange(depth_im.shape[0])
    y_coords = np.arange(depth_im.shape[1])
    d_interp = si.interp2d(
        x=x_coords, y=y_coords, z=depth_im.T, copy=False,
        fill_value=0)
    return d_interp
//  [python]
def get_depth_interpolator(depth_im):
    x_coords = np.arange(depth_im.shape[0])
    y_coords = np.arange(depth_im.shape[1])
    d_interp = si.bisplev(
        x=x_coords, y=y_coords, z=depth_im.T, copy=False,
        fill_value=0)
    return d_interp
//  [python]
def bicInter(img, amp, mesh):
	width, height = img.shape
	y=np.linspace(1, width, width)
	x=np.linspace(1, height, height)
	imgInter=interpolate.interp2d(x, y, img, kind='cubic')
	y2=np.linspace(1, width, width*amp)
	x2=np.linspace(1, height, height*amp)
	Z2 = imgInter(x2, y2)
	if mesh:
		Z2 = meshing(Z2, amp)
	return Z2
//  [python]
def bicInter(img, amp, mesh):
	width, height = img.shape
	y=np.linspace(1, width, width)
	x=np.linspace(1, height, height)
	imgInter = interpolate.bisplev(y, x, interpolate.bisplrep(y, x, img, kx=3, ky=3))
	y2=np.linspace(1, width, width*amp)
	x2=np.linspace(1, height, height*amp)
	Z2 = imgInter(x2, y2)
	if mesh:
		Z2 = meshing(Z2, amp)
	return Z2
//  [python]
def interp_etopo(ll_corner, ur_corner):
    """
        Loads and interpolates the ETOPO1 topography
            data within a region specified by low-left
            and upper-right corner latitude, longitudes

        Parameters
        ----------
        ll_corner : iterable
            Iterable containing the latitude and longitude
                of the lower-left corner of the region
        ur_corner : iterable
            Iterable containing the latitude and longitude
                of the upper-right corner of the region

        Returns:
        elev_interp : scipy.interpolate.interp2d
            A 2d interpolation of the elevation within 
                the specified region
    """

    # load etopo_file and extract grid information
    etopo1 = Dataset(find_spec('infraga').submodule_search_locations[0] + "/ETOPO1_Ice_g_gmt4.grd")
    grid_lons = etopo1.variables['x'][:]
    grid_lats = etopo1.variables['y'][:]
    grid_elev = etopo1.variables['z'][:]

    lat_mask = np.logical_and(ll_corner[0] - 2.0 <= grid_lats, grid_lats <= ur_corner[0] + 2.0).nonzero()[0]
    lon_mask = np.logical_and(ll_corner[1] - 2.0 <= grid_lons, grid_lons <= ur_corner[1] + 2.0).nonzero()[0]

    region_lat = grid_lats[lat_mask]
    region_lon = grid_lons[lon_mask]
    region_elev = grid_elev[lat_mask,:][:,lon_mask]

    # Change underwater values to sea surface
    region_elev[region_elev < 0.0] = 0.0

    return interpolate.interp2d(region_lon, region_lat, region_elev / 1000.0, kind='linear')
//  [python]
def interp_etopo(ll_corner, ur_corner):
    """
        Loads and interpolates the ETOPO1 topography
            data within a region specified by low-left
            and upper-right corner latitude, longitudes

        Parameters
        ----------
        ll_corner : iterable
            Iterable containing the latitude and longitude
                of the lower-left corner of the region
        ur_corner : iterable
            Iterable containing the latitude and longitude
                of the upper-right corner of the region

        Returns:
        elev_interp : scipy.interpolate.interp2d
            A 2d interpolation of the elevation within 
                the specified region
    """

    # load etopo_file and extract grid information
    etopo1 = Dataset(find_spec('infraga').submodule_search_locations[0] + "/ETOPO1_Ice_g_gmt4.grd")
    grid_lons = etopo1.variables['x'][:]
    grid_lats = etopo1.variables['y'][:]
    grid_elev = etopo1.variables['z'][:]

    lat_mask = np.logical_and(ll_corner[0] - 2.0 <= grid_lats, grid_lats <= ur_corner[0] + 2.0).nonzero()[0]
    lon_mask = np.logical_and(ll_corner[1] - 2.0 <= grid_lons, grid_lons <= ur_corner[1] + 2.0).nonzero()[0]

    region_lat = grid_lats[lat_mask]
    region_lon = grid_lons[lon_mask]
    region_elev = grid_elev[lat_mask,:][:,lon_mask]

    # Change underwater values to sea surface
    region_elev[region_elev < 0.0] = 0.0

    tck = interpolate.bisplrep(region_lon, region_lat, region_elev / 1000.0, kx=1, ky=1)
    return lambda x, y: interpolate.bisplev(x, y, tck)
//  [python]
def calc_lc(tini,tmax,dt,mej,vej,vmin,th,ph,kappa,eps,alp,eth,flgbct):

    td, bct = setbc_tabular()
    bc = setbc()

    lbol_d=[]
    bc_tmp=[]
    dc=0

    t_d = np.arange(tini,tmax+dt,dt)

    mag_d = {}
    for ii in range(8):
        mag_d[ii] = np.array([])

    epsBarnes = 0
    if epsBarnes:
        mejtab = (0.001,0.001,0.001,0.005,0.005,0.005,0.01,0.01,0.01,0.05,0.05,0.05)
        vejtab = (0.1,0.2,0.3,0.1,0.2,0.3,0.1,0.2,0.3,0.1,0.2,0.3)
        a      = (2.01,4.52,8.16,0.81,1.90,3.20,0.56,1.31,2.19,0.27,0.55,0.95)
        b      = (0.28,0.62,1.19,0.19,0.28,0.45,0.17,0.21,0.31,0.10,0.13,0.15)
        d      = (1.12,1.39,1.52,0.86,1.21,1.39,0.74,1.13,1.32,0.60,0.90,1.13)

        fa     = scipy.interpolate.interp2d(mejtab,vejtab,a, kind='linear')
        fb     = scipy.interpolate.interp2d(mejtab,vejtab,b, kind='linear')
        fd     = scipy.interpolate.interp2d(mejtab,vejtab,d, kind='linear')

        fam    = fa(mej,vej)
        fbm    = fb(mej,vej)
        fdm    = fd(mej,vej)

    for t in t_d:
      if epsBarnes:
          eth = 0.36*(np.exp(-fam*t)+ np.log(1+2*fbm*t**fdm)/(2*fbm*t**fdm))[0]

      lbol=kn_lbol(t,mej,vej,vmin,th,ph,kappa,eps,alp,eth)
      lbol_d.append(lbol)
      mbol=mag_bol(lbol,10)
      tt=t/((mej*100.0)**(1.0/3.2))
      bc_tmp=getBC(td,bc,bct,tt,flgbct)

      for ii in range(8):
        if t > 2.*(mej*100)**(1.0/3.2):
          mag_d[ii] = np.append(mag_d[ii],mbol-bc_tmp[ii])
        else:
          mag_d[ii] = np.append(mag_d[ii],np.nan)

    lbol_d = np.array(lbol_d)

    wavelengths = [3543, 4775.6, 6129.5, 7484.6, 8657.8, 12350, 16620, 21590]
    wavelength_interp = 9603.1

    mag_y = np.zeros(t_d.shape)
    for ii in range(len(t_d)):
        mags = [mag_d[jj][ii] for jj in range(8)]
        mag_y[ii] = np.interp(wavelength_interp,wavelengths,mags)
    mag_new = {}
    mag_new[0] = mag_d[0]
    mag_new[1] = mag_d[1]
    mag_new[2] = mag_d[2]
    mag_new[3] = mag_d[3]
    mag_new[4] = mag_d[4]
    mag_new[5] = mag_y
    mag_new[6] = mag_d[5]
    mag_new[7] = mag_d[6]
    mag_new[8] = mag_d[7]

    return t_d, lbol_d, mag_new
//  [python]
def calc_lc(tini,tmax,dt,mej,vej,vmin,th,ph,kappa,eps,alp,eth,flgbct):

    td, bct = setbc_tabular()
    bc = setbc()

    lbol_d=[]
    bc_tmp=[]
    dc=0

    t_d = np.arange(tini,tmax+dt,dt)

    mag_d = {}
    for ii in range(8):
        mag_d[ii] = np.array([])

    epsBarnes = 0
    if epsBarnes:
        mejtab = (0.001,0.001,0.001,0.005,0.005,0.005,0.01,0.01,0.01,0.05,0.05,0.05)
        vejtab = (0.1,0.2,0.3,0.1,0.2,0.3,0.1,0.2,0.3,0.1,0.2,0.3)
        a      = (2.01,4.52,8.16,0.81,1.90,3.20,0.56,1.31,2.19,0.27,0.55,0.95)
        b      = (0.28,0.62,1.19,0.19,0.28,0.45,0.17,0.21,0.31,0.10,0.13,0.15)
        d      = (1.12,1.39,1.52,0.86,1.21,1.39,0.74,1.13,1.32,0.60,0.90,1.13)

        x, y = np.meshgrid(mejtab, vejtab)
        tck_a = scipy.interpolate.bisplrep(x, y, a)
        tck_b = scipy.interpolate.bisplrep(x, y, b)
        tck_d = scipy.interpolate.bisplrep(x, y, d)

        fam    = scipy.interpolate.bisplev(mej,vej,tck_a)
        fbm    = scipy.interpolate.bisplev(mej,vej,tck_b)
        fdm    = scipy.interpolate.bisplev(mej,vej,tck_d)

    for t in t_d:
      if epsBarnes:
          eth = 0.36*(np.exp(-fam*t)+ np.log(1+2*fbm*t**fdm)/(2*fbm*t**fdm))[0]

      lbol=kn_lbol(t,mej,vej,vmin,th,ph,kappa,eps,alp,eth)
      lbol_d.append(lbol)
      mbol=mag_bol(lbol,10)
      tt=t/((mej*100.0)**(1.0/3.2))
      bc_tmp=getBC(td,bc,bct,tt,flgbct)

      for ii in range(8):
        if t > 2.*(mej*100)**(1.0/3.2):
          mag_d[ii] = np.append(mag_d[ii],mbol-bc_tmp[ii])
        else:
          mag_d[ii] = np.append(mag_d[ii],np.nan)

    lbol_d = np.array(lbol_d)

    wavelengths = [3543, 4775.6, 6129.5, 7484.6, 8657.8, 12350, 16620, 21590]
    wavelength_interp = 9603.1

    mag_y = np.zeros(t_d.shape)
    for ii in range(len(t_d)):
        mags = [mag_d[jj][ii] for jj in range(8)]
        mag_y[ii] = np.interp(wavelength_interp,wavelengths,mags)
    mag_new = {}
    mag_new[0] = mag_d[0]
    mag_new[1] = mag_d[1]
    mag_new[2] = mag_d[2]
    mag_new[3] = mag_d[3]
    mag_new[4] = mag_d[4]
    mag_new[5] = mag_y
    mag_new[6] = mag_d[5]
    mag_new[7] = mag_d[6]
    mag_new[8] = mag_d[7]

    return t_d, lbol_d, mag_new
//  [python]
def theory_multipoles(self, s, params, poles=[0, 2], **kwargs):
        """
        Calculate the model prediction for specified Legendre multipoles of the redshift-space ccf

        Parameters
        ----------
        s : array
            Radial coordinate in redshift space at which multipoles are desired

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

        poles : tuple of ints, default=[0, 2]
            Legendre multipoles to return

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

        Returns
        -------
        multipoles : dict
            Dictionary of multipoles, with keys being the poles requested (e.g. '0', '2') and items
            being arrays of same length as `s`
        """

        poles = np.atleast_1d(poles)
        if np.any(poles % 2):
            even = False
            mu = np.linspace(-1, 1, 100)
        else:
            even = True
            mu = np.linspace(0, 1, 100)
        xi_smu = self.theory_xi(*np.meshgrid(s, mu), params, **kwargs)
        xi_model = si.interp2d(s, mu, xi_smu, kind='cubic')
        multipoles = utils.multipoles_from_fn(xi_model, s, poles, even=even)

        return multipoles
//  [python]
def theory_multipoles(self, s, params, poles=[0, 2], **kwargs):
        """
        Calculate the model prediction for specified Legendre multipoles of the redshift-space ccf

        Parameters
        ----------
        s : array
            Radial coordinate in redshift space at which multipoles are desired

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

        poles : tuple of ints, default=[0, 2]
            Legendre multipoles to return

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

        Returns
        -------
        multipoles : dict
            Dictionary of multipoles, with keys being the poles requested (e.g. '0', '2') and items
            being arrays of same length as `s`
        """

        poles = np.atleast_1d(poles)
        if np.any(poles % 2):
            even = False
            mu = np.linspace(-1, 1, 100)
        else:
            even = True
            mu = np.linspace(0, 1, 100)
        xi_smu = self.theory_xi(*np.meshgrid(s, mu), params, **kwargs)
        tck = si.bisplrep(s, mu, xi_smu, kx=3, ky=3)
        xi_model = lambda x, y: si.bisplev(x, y, tck)
        multipoles = utils.multipoles_from_fn(xi_model, s, poles, even=even)

        return multipoles
//  [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 = smu(*np.meshgrid(sperp, spar))
        xi_smu = np.zeros_like(s)
        for i in range(s.shape[0]):
            for j in range(s.shape[1]):
                xi_smu[i, j] = self.theory_xi(s[i, j], mu[i, j], params, **kwargs)
        xi_model = si.interp2d(sperp, spar, xi_smu)
        return xi_model
//  [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.bisplev`
            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 = smu(*np.meshgrid(sperp, spar))
        xi_smu = np.zeros_like(s)
        for i in range(s.shape[0]):
            for j in range(s.shape[1]):
                xi_smu[i, j] = self.theory_xi(s[i, j], mu[i, j], params, **kwargs)
        tck = si.bisplrep(sperp, spar, xi_smu)
        xi_model = lambda x,y: si.bisplev(x,y,tck)
        return xi_model
//  [python]
def regrid_image(self, targetfov, npix, interp='linear'):
        """Resample the image to new (square) dimensions.

           Args:
                targetfov  (float): new field of view (radian)
                npix  (int): new pixel dimension
                interp ('linear', 'cubic', 'quintic'): type of interpolation. default is linear

           Returns:
                (Image): resampled image
        """

        psize_new = float(targetfov) / float(npix)
        fov_x = self.fovx()
        fov_y = self.fovy()

        # define an interpolation function
        x = np.linspace(-fov_x / 2, fov_x / 2, self.xdim)
        y = np.linspace(-fov_y / 2, fov_y / 2, self.ydim)

        xtarget = np.linspace(-targetfov / 2, targetfov / 2, npix)
        ytarget = np.linspace(-targetfov / 2, targetfov / 2, npix)

        def interp_imvec(imvec, specind=False):
            if np.any(np.imag(imvec) != 0):
                return interp_imvec(np.real(imvec)) + 1j * interp_imvec(np.imag(imvec))

            interpfunc = scipy.interpolate.interp2d(y, x, np.reshape(imvec, (self.ydim, self.xdim)),
                                                    kind=interp)
            tmpimg = interpfunc(ytarget, xtarget)
            tmpimg[np.abs(xtarget) > fov_x / 2., :] = 0.0
            tmpimg[:, np.abs(ytarget) > fov_y / 2.] = 0.0

            if not specind: # adjust pixel size if not a spectral index map
                tmpimg = tmpimg * (psize_new)**2 / self.psize**2
            return tmpimg

        # Make new image
        imarr_new = interp_imvec(self.imvec)
        arglist, argdict = self.image_args()
        arglist[0] = imarr_new
        arglist[1] = psize_new

        outim = Image(*arglist, **argdict)

        # Interpolate all polarizations and copy over
        for pol in list(self._imdict.keys()):
            if pol == self.pol_prim:
                continue
            polvec = self._imdict[pol]
            if len(polvec):
                polarr_new = interp_imvec(polvec)
                outim.add_pol_image(polarr_new, pol)

        # Interpolate spectral index and copy over
        mflist_out = []
        for mfvec in self._mflist:
            if len(mfvec):
                mfarr = interp_imvec(mfvec, specind=True)
                mfvec_out = mfarr.flatten()
            else:
                mfvec_out = np.array([])
            mflist_out.append(mfvec_out)
        outim._mflist = mflist_out

        return outim
//  [python]
def regrid_image(self, targetfov, npix, interp='linear'):
        """Resample the image to new (square) dimensions.

           Args:
                targetfov  (float): new field of view (radian)
                npix  (int): new pixel dimension
                interp ('linear', 'cubic', 'quintic'): type of interpolation. default is linear

           Returns:
                (Image): resampled image
        """

        psize_new = float(targetfov) / float(npix)
        fov_x = self.fovx()
        fov_y = self.fovy()

        # define an interpolation function
        x = np.linspace(-fov_x / 2, fov_x / 2, self.xdim)
        y = np.linspace(-fov_y / 2, fov_y / 2, self.ydim)

        xtarget = np.linspace(-targetfov / 2, targetfov / 2, npix)
        ytarget = np.linspace(-targetfov / 2, targetfov / 2, npix)

        def interp_imvec(imvec, specind=False):
            if np.any(np.imag(imvec) != 0):
                return interp_imvec(np.real(imvec)) + 1j * interp_imvec(np.imag(imvec))

            x_new, y_new = np.meshgrid(xtarget, ytarget)
            tck = scipy.interpolate.bisplrep(y, x, np.reshape(imvec, (self.ydim, self.xdim)), kx=1, ky=1, s=0)
            tmpimg = scipy.interpolate.bisplev(y_new.flatten(), x_new.flatten(), tck).reshape(npix, npix)
            tmpimg[np.abs(xtarget) > fov_x / 2., :] = 0.0
            tmpimg[:, np.abs(ytarget) > fov_y / 2.] = 0.0

            if not specind: # adjust pixel size if not a spectral index map
                tmpimg = tmpimg * (psize_new)**2 / self.psize**2
            return tmpimg

        # Make new image
        imarr_new = interp_imvec(self.imvec)
        arglist, argdict = self.image_args()
        arglist[0] = imarr_new
        arglist[1] = psize_new

        outim = Image(*arglist, **argdict)

        # Interpolate all polarizations and copy over
        for pol in list(self._imdict.keys()):
            if pol == self.pol_prim:
                continue
            polvec = self._imdict[pol]
            if len(polvec):
                polarr_new = interp_imvec(polvec)
                outim.add_pol_image(polarr_new, pol)

        # Interpolate spectral index and copy over
        mflist_out = []
        for mfvec in self._mflist:
            if len(mfvec):
                mfarr = interp_imvec(mfvec, specind=True)
                mfvec_out = mfarr.flatten()
            else:
                mfvec_out = np.array([])
            mflist_out.append(mfvec_out)
        outim._mflist = mflist_out

        return outim
//  [python]
def xi_2D_from_multipoles(self, params, rmax=85, **kwargs):
        r"""
        Use input Legendre multipoles to generate a 2D ccf as a function of distances perpendicular and parallel to the
        line of sight

        Parameters
        ----------
        multipoles : dict
            Dictionary of callable multipole functions accepting distance modulus argument, with keys being the Legendre order

        poles : list
            The Legendre multipole orders, should match the keys in `multipoles`

        rmax : float, default=85
            Maximum distance (in each direction) out to which to interpolate

        Returns
        -------
        xi_2D : instance of :class:`scipy.interpolate.interp2d`
            Representing the 2D ccf :math:`\xi(r_\perp, r_{||})`
        """

        s = np.linspace(0.01, rmax)
        multipoles = self.theory_multipoles(s, params, poles=[0, 2, 4], **kwargs)
        for ell in [0, 2, 4]:
            multipoles[f'{ell}'] = _spline(s, multipoles[f'{ell}'])

        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 = smu(*np.meshgrid(sperp, spar))

        xi_2D_grid = np.zeros_like(s)
        for ell in [0, 2, 4]:
            xi_2D_grid = xi_2D_grid + multipoles[f'{ell}'](s) * legendre(ell)(mu)
        xi_2D = si.interp2d(sperp, spar, xi_2D_grid)
        return xi_2D
//  [python]
def xi_2D_from_multipoles(self, params, rmax=85, **kwargs):
        r"""
        Use input Legendre multipoles to generate a 2D ccf as a function of distances perpendicular and parallel to the
        line of sight

        Parameters
        ----------
        multipoles : dict
            Dictionary of callable multipole functions accepting distance modulus argument, with keys being the Legendre order

        poles : list
            The Legendre multipole orders, should match the keys in `multipoles`

        rmax : float, default=85
            Maximum distance (in each direction) out to which to interpolate

        Returns
        -------
        xi_2D : instance of :class:`scipy.interpolate.interp2d`
            Representing the 2D ccf :math:`\xi(r_\perp, r_{||})`
        """

        s = np.linspace(0.01, rmax)
        multipoles = self.theory_multipoles(s, params, poles=[0, 2, 4], **kwargs)
        for ell in [0, 2, 4]:
            multipoles[f'{ell}'] = _spline(s, multipoles[f'{ell}'])

        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 = smu(*np.meshgrid(sperp, spar))

        xi_2D_grid = np.zeros_like(s)
        for ell in [0, 2, 4]:
            xi_2D_grid = xi_2D_grid + multipoles[f'{ell}'](s) * legendre(ell)(mu)
        xi_2D = si.bisplev(sperp, spar, xi_2D_grid)
        return xi_2D
//  [python]
def fn_from_multipoles(r, poles, multipoles, npts=200):
    """
    Use multipole information to construct the function f(r, mu)

    Parameters
    ----------
    r : array
        1D array of length N with radial distances at which multipoles were evaluated

    poles : list or array of ints
        Order of the Legendre multipoles provided

    multipoles : 2D array
        Array of shape (M, N) where M is the length of `poles`. Each row should contain the values
        of the corresponding multipole evaluated at the radial distances contained in `r`

    npts : int, default=200
        Number of values of mu (in the range [-1, 1]) to use when building interpolator

    Returns
    -------
    func : instance of :class:`scipy.interpolate.interp2d`
        An interpolating function for f(r, mu)
    """

    poles = [poles] if isinstance(poles, int) else poles # failsafe in case just a single int is passed
    # check input
    if not multipoles.shape == (len(poles), len(r)):
        raise ValueError(f'Wrong shape of multipoles: expected ({len(poles)}, {len(r)}), but received {multipoles.shape}')
    mu = np.linspace(-1, 1, npts)
    func_grid = np.zeros((len(mu), len(r)))
    for i, ell in enumerate(poles):
        lmu = legendre(ell)(mu).reshape((len(mu), 1))
        func_grid += lmu * multipoles[i,:]
    func = si.interp2d(r, mu, func_grid)
    return func
//  [python]
def fn_from_multipoles(r, poles, multipoles, npts=200):
    """
    Use multipole information to construct the function f(r, mu)

    Parameters
    ----------
    r : array
        1D array of length N with radial distances at which multipoles were evaluated

    poles : list or array of ints
        Order of the Legendre multipoles provided

    multipoles : 2D array
        Array of shape (M, N) where M is the length of `poles`. Each row should contain the values
        of the corresponding multipole evaluated at the radial distances contained in `r`

    npts : int, default=200
        Number of values of mu (in the range [-1, 1]) to use when building interpolator

    Returns
    -------
    func : instance of :class:`scipy.interpolate.bisplev`
        An interpolating function for f(r, mu)
    """

    poles = [poles] if isinstance(poles, int) else poles # failsafe in case just a single int is passed
    # check input
    if not multipoles.shape == (len(poles), len(r)):
        raise ValueError(f'Wrong shape of multipoles: expected ({len(poles)}, {len(r)}), but received {multipoles.shape}')
    mu = np.linspace(-1, 1, npts)
    func_grid = np.zeros((len(mu), len(r)))
    for i, ell in enumerate(poles):
        lmu = legendre(ell)(mu).reshape((len(mu), 1))
        func_grid += lmu * multipoles[i,:]
    tck = si.bisplrep(r, mu, func_grid)
    func = lambda x, y: si.bisplev(x, y, tck)
    return func
//  [python]
def interp2d_interpolate(xs, ys, vs, xt, yt):
    interpolator = interpolate.interp2d(
        xs.squeeze(),
        ys.squeeze(),
        vs.squeeze(),
        kind='linear',
        bounds_error=True)

    vt = interpolator(xt, yt)[0]
    return vt
//  [python]
def interp2d_interpolate(xs, ys, vs, xt, yt):
    from scipy.interpolate import bisplev, bisplrep
    tck = bisplrep(xs.squeeze(), ys.squeeze(), vs.squeeze())
    vt = bisplev(xt, yt, tck)[0]
    return vt
//  [python]
def interpolate(x,y,z, gridsize,mode='thin_plate',rbfmode=True,shape=None):

	mode=str(mode)
	grids=gridsize


	dx=np.max(x)-np.min(x)
	dy=np.max(y)-np.min(y)

	if dx>dy:
		gridx=grids
		gridy=int(round(dy/dx*grids))
	else:
		gridy=grids
		gridx=int(round(dx/dy*grids))

	if shape != None:
		(gridy,gridx)=shape

	xi, yi = np.linspace(np.min(x), np.max(x), gridx), np.linspace(np.min(y), np.max(y), gridy)
	xi, yi = np.meshgrid(xi, yi)


	if rbfmode:
		rbf = scipy.interpolate.Rbf(x, y, z, function=mode)
		rbf2 = scipy.interpolate.Rbf( y,x, z, function=mode)
	else:
		sayErr("interp2d nicht implementiert")
		x=np.array(x)
		y=np.array(y)
		z=np.array(z)
		xi, yi = np.linspace(np.min(x), np.max(x), gridx), np.linspace(np.min(y), np.max(y), gridy)

		rbf = scipy.interpolate.interp2d(x, y, z, kind=mode)
		rbf2 = scipy.interpolate.interp2d(y, x, z, kind=mode)

	zi=rbf2(yi,xi)
	return [rbf,xi,yi,zi]
//  [python]
def interpolate(x,y,z, gridsize,mode='thin_plate',rbfmode=True,shape=None):

	mode=str(mode)
	grids=gridsize


	dx=np.max(x)-np.min(x)
	dy=np.max(y)-np.min(y)

	if dx>dy:
		gridx=grids
		gridy=int(round(dy/dx*grids))
	else:
		gridy=grids
		gridx=int(round(dx/dy*grids))

	if shape != None:
		(gridy,gridx)=shape

	xi, yi = np.linspace(np.min(x), np.max(x), gridx), np.linspace(np.min(y), np.max(y), gridy)
	xi, yi = np.meshgrid(xi, yi)


	if rbfmode:
		rbf = scipy.interpolate.Rbf(x, y, z, function=mode)
		rbf2 = scipy.interpolate.Rbf( y,x, z, function=mode)
	else:
		sayErr("interp2d nicht implementiert")
		x=np.array(x)
		y=np.array(y)
		z=np.array(z)
		xi, yi = np.linspace(np.min(x), np.max(x), gridx), np.linspace(np.min(y), np.max(y), gridy)

		rbf = scipy.interpolate.bisplev(x, y, z, kind=mode)
		rbf2 = scipy.interpolate.bisplev(y, x, z, kind=mode)

	zi=rbf2(yi,xi)
	return [rbf,xi,yi,zi]
//  [python]
def cumdis2xy(self, distance, recompute=True, mode='lonlat', discretized=False):
        '''
        For a given {distance}, returns the x and y position along strike.

        Args:   
            * distance          : Along strike distance

        Kwargs:
            * recompute         : recompute the interpolator
            * mode              : 'lonlat' returns lon/lat while 'xy' returns x and y
            * discretized       : use the discretized fault trace
        
        Returns:
            * xy                : tuple of floats
        '''

        # Get the coordinates
        if discretized:
            x,y = self.xi,self.yi
        else:
            x,y = self.xf,self.yf

        # Cumulative distance is needed
        cumdis = self.cumdistance(discretized=discretized, recompute=recompute)
        
        # Make the interpolator
        if recompute:
            self.intcumdis = sciint.interp2d(x, y, self.cumdis, fill_value=0.) 
        assert hasattr(self, 'intcumdis'), 'An interpolator is needed'

        # Make a function with this
        def norm(m):
            return (self.intcumdis(m[0], m[1])-distance)**2
        
        # Minimize from a starting point that is close to the good point
        istart = np.argmin(np.abs(cumdis-distance))
        startm = np.array([x[istart], y[istart]])
        m = sciopt.minimize(norm, startm)

        # All done
        return tuple(m.x)
//  [python]
def cumdis2xy(self, distance, recompute=True, mode='lonlat', discretized=False):
        '''
        For a given {distance}, returns the x and y position along strike.

        Args:   
            * distance          : Along strike distance

        Kwargs:
            * recompute         : recompute the interpolator
            * mode              : 'lonlat' returns lon/lat while 'xy' returns x and y
            * discretized       : use the discretized fault trace
        
        Returns:
            * xy                : tuple of floats
        '''

        # Get the coordinates
        if discretized:
            x,y = self.xi,self.yi
        else:
            x,y = self.xf,self.yf

        # Cumulative distance is needed
        cumdis = self.cumdistance(discretized=discretized, recompute=recompute)
        
        # Make the interpolator
        if recompute:
            self.intcumdis = sciint.bisplev(x, y, self.cumdis) 
        assert hasattr(self, 'intcumdis'), 'An interpolator is needed'

        # Make a function with this
        def norm(m):
            return (self.intcumdis(m[0], m[1])-distance)**2
        
        # Minimize from a starting point that is close to the good point
        istart = np.argmin(np.abs(cumdis-distance))
        startm = np.array([x[istart], y[istart]])
        m = sciopt.minimize(norm, startm)

        # All done
        return tuple(m.x)
//  [python]
def imresize(D, dims, kind='cubic', use_scipy=False):
    """
    Resize a floating point image
    Parameters
    ----------
    D : ndarray(M1, N1)
        Original image
    dims : tuple(M2, N2)
        The dimensions to which to resize
    kind : string
        The kind of interpolation to use
    use_scipy : boolean
        Fall back to scipy.misc.imresize.  This is a bad idea
        because it casts everything to uint8, but it's what I
        was doing accidentally for a while
    Returns
    -------
    D2 : ndarray(M2, N2)
        A resized array
    """
    if use_scipy:
        return scipy.misc.imresize(D, dims)
    else:
        M, N = dims
        x1 = np.array(0.5 + np.arange(D.shape[1]), dtype=np.float32)/D.shape[1]
        y1 = np.array(0.5 + np.arange(D.shape[0]), dtype=np.float32)/D.shape[0]
        x2 = np.array(0.5 + np.arange(N), dtype=np.float32)/N
        y2 = np.array(0.5 + np.arange(M), dtype=np.float32)/M
        f = scipy.interpolate.interp2d(x1, y1, D, kind=kind)
        return f(x2, y2)
//  [python]
def imresize(D, dims, kind='cubic', use_scipy=False):
    """
    Resize a floating point image
    Parameters
    ----------
    D : ndarray(M1, N1)
        Original image
    dims : tuple(M2, N2)
        The dimensions to which to resize
    kind : string
        The kind of interpolation to use
    use_scipy : boolean
        Fall back to scipy.misc.imresize.  This is a bad idea
        because it casts everything to uint8, but it's what I
        was doing accidentally for a while
    Returns
    -------
    D2 : ndarray(M2, N2)
        A resized array
    """
    if use_scipy:
        return scipy.misc.imresize(D, dims)
    else:
        M, N = dims
        x1 = np.array(0.5 + np.arange(D.shape[1]), dtype=np.float32)/D.shape[1]
        y1 = np.array(0.5 + np.arange(D.shape[0]), dtype=np.float32)/D.shape[0]
        x2 = np.array(0.5 + np.arange(N), dtype=np.float32)/N
        y2 = np.array(0.5 + np.arange(M), dtype=np.float32)/M
        x1, y1 = np.meshgrid(x1, y1)
        x2, y2 = np.meshgrid(x2, y2)
        tck = scipy.interpolate.bisplev(x1, y1, D)
        return scipy.interpolate.bisplev(x2, y2, tck)
//  [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, :, :].values
        v = ds['v'][0, -1, :, :].values
    elif zlev == 'bot':
        u = ds['u'][0, 0, :, :].values
        v = ds['v'][0, 0, :, :].values
    # ADD VELOCITY VECTORS
    # set masked values to 0
    u[np.isnan(u)]=0
    v[np.isnan(v)]=0
    # create interpolant
    import scipy.interpolate as intp
    ui = intp.interp2d(G['lon_u'][0, :], G['lat_u'][:, 0], u)
    vi = intp.interp2d(G['lon_v'][0, :], G['lat_v'][:, 0], v)
    # 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 = ui(x, y)
    vv = vi(x, y)
    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 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, :, :].values
        v = ds['v'][0, -1, :, :].values
    elif zlev == 'bot':
        u = ds['u'][0, 0, :, :].values
        v = ds['v'][0, 0, :, :].values
    # ADD VELOCITY VECTORS
    # set masked values to 0
    u[np.isnan(u)]=0
    v[np.isnan(v)]=0
    # create interpolant
    import scipy.interpolate as intp
    ui = intp.bisplev(G['lon_u'][0, :], G['lat_u'][:, 0], u)
    vi = intp.bisplev(G['lon_v'][0, :], G['lat_v'][:, 0], v)
    # 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 = ui(x, y)
    vv = vi(x, y)
    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 merge_backgrounds_with_spline(x, y, z, tension):
    """
    Merge different background estimates using a smoothing spline under tension.

    :param x: x-coordinates for the spline.
    :param y: y-coordinates for the spline.
    :param z: z-coordinates for the spline.
    :param tension: Tension factor for the spline.
    :param downsampling_factor: Factor by which to downsample the data.
    :return: Merged background.
    """
    # Compute the spline on the downsampled data
    spline = interpolate.interp2d(x, y, z, kind='cubic')

    # Evaluate the spline on the original x coordinates
    return spline(x, y)
//  [python]
def merge_backgrounds_with_spline(x, y, z, tension):
    """
    Merge different background estimates using a smoothing spline under tension.

    :param x: x-coordinates for the spline.
    :param y: y-coordinates for the spline.
    :param z: z-coordinates for the spline.
    :param tension: Tension factor for the spline.
    :param downsampling_factor: Factor by which to downsample the data.
    :return: Merged background.
    """
    # Compute the spline on the downsampled data
    from scipy.interpolate import bisplev, bisplrep
    tck = bisplrep(x, y, z, s=0)
    spline = bisplev(x, y, tck)

    # Evaluate the spline on the original x coordinates
    return spline
//  [python]
def __call__(self, x: np.ndarray, y: np.ndarray) -> np.ndarray:
        if self.reverse:
            x, y = y, x

        yl = y - y[0]
        yl = yl[yl < self.ygmax]
        xl = x - x[0]
        xl = xl[xl < self.xgmax]
        rectangle = np.ascontiguousarray(
            scipy.interpolate.interp2d(self.xg, self.yg, self.sg)(xl, yl))
        signal = _calculate_signal(rectangle, x, y, self.xgmax, self.ygmax)

        return signal.transpose() if self.reverse else signal
//  [python]
def __call__(self, x: np.ndarray, y: np.ndarray) -> np.ndarray:
        if self.reverse:
            x, y = y, x

        yl = y - y[0]
        yl = yl[yl < self.ygmax]
        xl = x - x[0]
        xl = xl[xl < self.xgmax]
        rectangle = np.ascontiguousarray(
            scipy.interpolate.bisplev(xl, yl, self.tck))
        signal = _calculate_signal(rectangle, x, y, self.xgmax, self.ygmax)

        return signal.transpose() if self.reverse else signal
//  [python]
def interpolate(self, ratio, method='cubic', fill_value=0.):

        ratio = float(ratio)

        if ratio <= 1:
            raise ValueError('interpolate_rate should be an integer larger than 1!')

        # altInterpolation = ip.interp1d(np.arange(len(self.altPos)),self.altPos)
        # aziInterpolation = ip.interp1d(np.arange(len(self.aziPos)),self.aziPos)
        altStep = np.mean(np.diff(self.altPos))
        aziStep = np.mean(np.diff(self.aziPos))
        newAltPos = np.arange(self.altPos[0], self.altPos[-1], altStep / ratio)
        newAziPos = np.arange(self.aziPos[0], self.aziPos[-1], aziStep / ratio)

        mask = self.get_weighted_mask()
        mask_ip = ip.interp2d(x=np.arange(mask.shape[1]), y=np.arange(mask.shape[0]), z=mask,
                              kind=method, fill_value=fill_value)

        new_x = np.arange(0., mask.shape[1] - 1, 1. / ratio)
        new_y = np.arange(0., mask.shape[0] - 1, 1. / ratio)

        newMask = mask_ip(x=new_x, y=new_y)

        return SpatialReceptiveField(newMask, newAltPos, newAziPos, sign=self.sign, temporalWindow=self.temporalWindow,
                                     pixelSizeUnit=self.pixelSizeUnit, dataType=self.dataType, thr=self.thr,
                                     filter_sigma=self.filter_sigma, interpolate_rate=ratio)