jiahuimbzuai/CoQuIR huggingface dataset:
//  [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()
        x = np.arange(mask.shape[1])
        y = np.arange(mask.shape[0])
        tck = interpolate.bisplev(x, y, interpolate.bisplrep(x, y, mask, kx=3, ky=3, s=0))

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

        newMask = interpolate.bisplev(new_x, new_y, tck)

        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)
//  [python]
def add_velocity_vectors(ax, ds, fn, v_scl=10, v_leglen=0.5, nngrid=80, zlev='top', center=(.8,.05)):
    # v_scl: scale velocity vector (smaller to get longer arrows)
    # v_leglen: m/s for velocity vector legend
    xc = center[0]
    yc = center[1]
    # 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
    else:
        zfull_u = get_zfull(ds, fn, 'u')
        zfull_v = get_zfull(ds, fn, 'v')
        u = get_laym(ds, zfull_u, ds['mask_u'].values, 'u', zlev)
        v = get_laym(ds, zfull_v, ds['mask_v'].values, 'v', zlev)
    # 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
    aaa = ax.axis()
    daax = aaa[1] - aaa[0]
    daay = aaa[3] - aaa[2]
    axrat = np.cos(np.deg2rad(aaa[2])) * daax / daay
    x = np.linspace(aaa[0], aaa[1], int(round(nngrid * axrat)))
    y = np.linspace(aaa[2], aaa[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
    Q = ax.quiver(xx[mask], yy[mask], uu[mask], vv[mask],
        units='width', scale=v_scl, scale_units='width', color='m')
    plt.quiverkey(Q, .9, .1, v_leglen, str(v_leglen)+' $ms^{-1}$', angle=20)
//  [python]
def add_velocity_vectors(ax, ds, fn, v_scl=10, v_leglen=0.5, nngrid=80, zlev='top', center=(.8,.05)):
    # v_scl: scale velocity vector (smaller to get longer arrows)
    # v_leglen: m/s for velocity vector legend
    xc = center[0]
    yc = center[1]
    # 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
    else:
        zfull_u = get_zfull(ds, fn, 'u')
        zfull_v = get_zfull(ds, fn, 'v')
        u = get_laym(ds, zfull_u, ds['mask_u'].values, 'u', zlev)
        v = get_laym(ds, zfull_v, ds['mask_v'].values, 'v', zlev)
    # 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
    x_u = G['lon_u'][0, :]
    y_u = G['lat_u'][:, 0]
    x_v = G['lon_v'][0, :]
    y_v = G['lat_v'][:, 0]
    tck_u = intp.bisplrep(x_u, y_u, u)
    tck_v = intp.bisplrep(x_v, y_v, v)
    # create regular grid
    aaa = ax.axis()
    daax = aaa[1] - aaa[0]
    daay = aaa[3] - aaa[2]
    axrat = np.cos(np.deg2rad(aaa[2])) * daax / daay
    x = np.linspace(aaa[0], aaa[1], int(round(nngrid * axrat)))
    y = np.linspace(aaa[2], aaa[3], int(nngrid))
    xx, yy = np.meshgrid(x, y)
    # interpolate to regular grid
    uu = intp.bisplev(x, y, tck_u)
    vv = intp.bisplev(x, y, tck_v)
    mask = uu != 0
    # plot velocity vectors
    Q = ax.quiver(xx[mask], yy[mask], uu[mask], vv[mask],
        units='width', scale=v_scl, scale_units='width', color='m')
    plt.quiverkey(Q, .9, .1, v_leglen, str(v_leglen)+' $ms^{-1}$', angle=20)
//  [python]
def interp_to_densepred(self, method='cubic'):
        """
        Interpolate the multigrid onto a pixelwise densepredictor using 
        multi-level interpolation

        Works by interpolating the coarse mesh to obtain the baseline. 
        Refinements are then treated as a delta to the coarse interpolant.        

        Args:
             method (string): Either linear or cubic
                              Cubic represents a cubic spline which is 
                              c2 continuous

        Returns:
            interpolation (DensePredictor): solution interpolated onto a 
                                            densepredictor

        """

        # define evaluation domain
        xe, ye = np.arange(self.img_dim[1]), np.arange(self.img_dim[0])

        # get coarse interpolation
        u0, v0 = self.grids[0].get_values()
        f0_u = interp.interp2d(self.grids[0].x_vec,
                               self.grids[0].y_vec,
                               u0, kind=method)
        f0_v = interp.interp2d(self.grids[0].x_vec,
                               self.grids[0].y_vec,
                               v0, kind=method)
        u0_eval, v0_eval = f0_u(xe, ye), f0_v(xe, ye)
        u_soln, v_soln = u0_eval, v0_eval

        # loop over number of tiers
        for tn in range(1, self.max_tier+1):

            # get the interpolated values at each of the finer grid points
            h = self.grids[tn].spacing
            u_int = u_soln[::h, ::h]
            v_int = v_soln[::h, ::h]

            # get the delta to the assumed solution
            u1, v1 = self.grids[tn].get_values()
            u_delta = u1 - u_int
            v_delta = v1 - v_int
            u_delta[np.isnan(u_delta)] = 0
            v_delta[np.isnan(v_delta)] = 0

            # interpolate the delta
            f_u = interp.interp2d(self.grids[tn].x_vec,
                                  self.grids[tn].y_vec,
                                  u_delta, kind=method)
            f_v = interp.interp2d(self.grids[tn].x_vec,
                                  self.grids[tn].y_vec,
                                  v_delta, kind=method)

            # evaluate the interpolant over the domain and update solution
            u_eval, v_eval = f_u(xe, ye), f_v(xe, ye)
            u_soln += u_eval
            v_soln += v_eval

        return PIV.dense_predictor.DensePredictor(u_soln, v_soln)
//  [python]
def interp_to_densepred(self, method='cubic'):
        """
        Interpolate the multigrid onto a pixelwise densepredictor using 
        multi-level interpolation

        Works by interpolating the coarse mesh to obtain the baseline. 
        Refinements are then treated as a delta to the coarse interpolant.        

        Args:
             method (string): Either linear or cubic
                              Cubic represents a cubic spline which is 
                              c2 continuous

        Returns:
            interpolation (DensePredictor): solution interpolated onto a 
                                            densepredictor

        """

        # define evaluation domain
        xe, ye = np.arange(self.img_dim[1]), np.arange(self.img_dim[0])

        # get coarse interpolation
        u0, v0 = self.grids[0].get_values()
        tck_u = interpolate.bisplev(self.grids[0].x_vec, self.grids[0].y_vec, interpolate.bisplrep(self.grids[0].x_vec, self.grids[0].y_vec, u0, kx=1, ky=1))
        tck_v = interpolate.bisplev(self.grids[0].x_vec, self.grids[0].y_vec, interpolate.bisplrep(self.grids[0].x_vec, self.grids[0].y_vec, v0, kx=1, ky=1))
        u0_eval, v0_eval = interpolate.bisplev(xe, ye, tck_u), interpolate.bisplev(xe, ye, tck_v)
        u_soln, v_soln = u0_eval, v0_eval

        # loop over number of tiers
        for tn in range(1, self.max_tier+1):

            # get the interpolated values at each of the finer grid points
            h = self.grids[tn].spacing
            u_int = u_soln[::h, ::h]
            v_int = v_soln[::h, ::h]

            # get the delta to the assumed solution
            u1, v1 = self.grids[tn].get_values()
            u_delta = u1 - u_int
            v_delta = v1 - v_int
            u_delta[np.isnan(u_delta)] = 0
            v_delta[np.isnan(v_delta)] = 0

            # interpolate the delta
            tck_u = interpolate.bisplev(self.grids[tn].x_vec, self.grids[tn].y_vec, interpolate.bisplrep(self.grids[tn].x_vec, self.grids[tn].y_vec, u_delta, kx=1, ky=1))
            tck_v = interpolate.bisplev(self.grids[tn].x_vec, self.grids[tn].y_vec, interpolate.bisplrep(self.grids[tn].x_vec, self.grids[tn].y_vec, v_delta, kx=1, ky=1))

            # evaluate the interpolant over the domain and update solution
            u_eval, v_eval = interpolate.bisplev(xe, ye, tck_u), interpolate.bisplev(xe, ye, tck_v)
            u_soln += u_eval
            v_soln += v_eval

        return PIV.dense_predictor.DensePredictor(u_soln, v_soln)
//  [python]
def calc_lc(tini,tmax,dt,mej,vave,vmin,th,ph,kappa,eps,alp,eth):

  td, bc = setbc_APR4Q3a75()

  lbol_d=[]
  bc_tmp=[]

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

  mag_d = {}
  for ii in range(9):
      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,vave)
        fbm    = fb(mej,vave)
        fdm    = fd(mej,vave)

  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,vave,vmin,th,ph,kappa,eps,alp,eth)
    lbol_d.append(lbol)
    mbol=mag_bol(lbol,10)
    tt=t/(mej**(1/3.2))
    bc_tmp=getBC(td,bc,tt)

    for ii in range(9):
        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,vave,vmin,th,ph,kappa,eps,alp,eth):

  td, bc = setbc_APR4Q3a75()

  lbol_d=[]
  bc_tmp=[]

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

  mag_d = {}
  for ii in range(9):
      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)

        from scipy.interpolate import bisplev, bisplrep
        tck = bisplrep(mejtab,vejtab,a,s=0)
        fam    = bisplev(mej,vave,tck)
        tck = bisplrep(mejtab,vejtab,b,s=0)
        fbm    = bisplev(mej,vave,tck)
        tck = bisplrep(mejtab,vejtab,d,s=0)
        fdm    = bisplev(mej,vave,tck)

  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,vave,vmin,th,ph,kappa,eps,alp,eth)
    lbol_d.append(lbol)
    mbol=mag_bol(lbol,10)
    tt=t/(mej**(1/3.2))
    bc_tmp=getBC(td,bc,tt)

    for ii in range(9):
        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 __init__(self, m, p, psid, psiq, r1, id, iq, ls=0, **kwargs):
        super(self.__class__, self).__init__(m, p, r1, ls, **kwargs)

        if isinstance(psid, (float, int)):
            self._psid = lambda id, iq: np.array([[psid]])
            self._psiq = lambda id, iq: np.array([[psiq]])
            return

        psid = np.asarray(psid)
        psiq = np.asarray(psiq)
        id = np.asarray(id)
        iq = np.asarray(iq)
        self.idrange = (min(id), max(id))
        self.iqrange = (min(iq), max(iq))
        self.betarange = (-np.pi if min(iq) < 0 else -np.pi/2,
                          0 if max(iq) > 0 else -np.pi/2)
        self.i1range = (0, betai1(np.max(iq), 0)[1])
        self.io = np.max(iq)/2, np.min(id)/2

        if np.any(psid.shape < (4, 4)):
            if psid.shape[0] > 1 and psid.shape[1] > 1:
                self._psid = ip.interp2d(iq, id, psid.T)
                self._psiq = ip.interp2d(iq, id, psiq.T)
                return
            if len(id) == 1 or psid.shape[1] == 1:
                def interp(x, q, d):
                    return ip.InterpolatedUnivariateSpline(iq, x)(q)
                self._psid = partial(interp, psid)
                self._psiq = partial(interp, psiq)
                return
            if len(iq) == 1 or psid.shape[0] == 1:
                def interp(x, q, d):
                    return ip.InterpolatedUnivariateSpline(id, x)(d)
                self._psid = partial(interp, psid)
                self._psiq = partial(interp, psiq)
                return
            raise ValueError("unsupported array size {}".format(
                psid.shape))

        self._psid = ip.RectBivariateSpline(iq, id, psid).ev
        self._psiq = ip.RectBivariateSpline(iq, id, psiq).ev
        try:
            pfe = kwargs['losses']
            if 'styoke_excess' in pfe and np.any(pfe['styoke_excess']):
                self.bertotti = True
                self.losskeys += ['styoke_excess',
                                  'stteeth_excess',
                                  'rotor_excess']
            self._set_losspar(pfe)
            self._losses = {k: ip.RectBivariateSpline(
                iq, id, np.array(pfe[k])).ev for k in self.losskeys 
                if k in pfe}
        except KeyError as e:
            logger.warning("loss map missing: %s", e)
            pass
//  [python]
def __init__(self, m, p, psid, psiq, r1, id, iq, ls=0, **kwargs):
        super(self.__class__, self).__init__(m, p, r1, ls, **kwargs)

        if isinstance(psid, (float, int)):
            self._psid = lambda id, iq: np.array([[psid]])
            self._psiq = lambda id, iq: np.array([[psiq]])
            return

        psid = np.asarray(psid)
        psiq = np.asarray(psiq)
        id = np.asarray(id)
        iq = np.asarray(iq)
        self.idrange = (min(id), max(id))
        self.iqrange = (min(iq), max(iq))
        self.betarange = (-np.pi if min(iq) < 0 else -np.pi/2,
                          0 if max(iq) > 0 else -np.pi/2)
        self.i1range = (0, betai1(np.max(iq), 0)[1])
        self.io = np.max(iq)/2, np.min(id)/2

        if np.any(psid.shape < (4, 4)):
            if psid.shape[0] > 1 and psid.shape[1] > 1:
                self._psid = ip.bisplev
                self._psiq = ip.bisplev
                return
            if len(id) == 1 or psid.shape[1] == 1:
                def interp(x, q, d):
                    return ip.InterpolatedUnivariateSpline(iq, x)(q)
                self._psid = partial(interp, psid)
                self._psiq = partial(interp, psiq)
                return
            if len(iq) == 1 or psid.shape[0] == 1:
                def interp(x, q, d):
                    return ip.InterpolatedUnivariateSpline(id, x)(d)
                self._psid = partial(interp, psid)
                self._psiq = partial(interp, psiq)
                return
            raise ValueError("unsupported array size {}".format(
                psid.shape))

        self._psid = ip.RectBivariateSpline(iq, id, psid).ev
        self._psiq = ip.RectBivariateSpline(iq, id, psiq).ev
        try:
            pfe = kwargs['losses']
            if 'styoke_excess' in pfe and np.any(pfe['styoke_excess']):
                self.bertotti = True
                self.losskeys += ['styoke_excess',
                                  'stteeth_excess',
                                  'rotor_excess']
            self._set_losspar(pfe)
            self._losses = {k: ip.RectBivariateSpline(
                iq, id, np.array(pfe[k])).ev for k in self.losskeys 
                if k in pfe}
        except KeyError as e:
            logger.warning("loss map missing: %s", e)
            pass
//  [python]
def __init__(self, im, x0, y0, profs, thetas, rmin=RMIN, rmax=RMAX, 
                 interptype='cubic',flux_norm=NORMFLUX,
                 profsQ=[], profsU=[]):

        self.x0 = x0
        self.y0 = y0
        self.im = im
        self.rmin = rmin
        self.rmax = rmax

        # store the center image
        deltay = -(im.fovy()/2. - y0*ehc.RADPERUAS)/im.psize
        deltax = (im.fovx()/2. - x0*ehc.RADPERUAS)/im.psize
        self.im_center = im.shift([int(np.round(deltay)), int(np.round(deltax))])

        # total flux and normalization
        self.flux = im.total_flux()
        self.parea = (im.psize/ehc.RADPERUAS)**2

        # factor to convert to normalized brightness temperature (total flux of 1 Jy)
        self.flux_norm = flux_norm
        self.normfactor = self.flux_norm / im.total_flux()

        # image array and  profiles
        factor = 3.254e13/(im.rf**2 * im.psize**2)  # factor to convert to brightness temperature
        self.imarr = im.imvec.reshape(im.ydim, im.xdim)[::-1] * factor  # in Tb

        self.xs = np.arange(im.xdim)*im.psize/ehc.RADPERUAS
        self.ys = np.arange(im.ydim)*im.psize/ehc.RADPERUAS
        self.interp = scipy.interpolate.interp2d(self.ys, self.xs, self.imarr, kind=interptype)

        self.profiles = np.array(profs)
        self.profilesQ = np.array(profsQ)
        self.profilesU = np.array(profsU)
        self.profilesP = np.sqrt(self.profilesQ**2 + self.profilesU**2)
        self.thetas = np.array(thetas)
        self.nang = len(thetas)
        self.nrs = len(self.profiles[0])
        self.nthetas = len(self.thetas)
        self.rs = np.linspace(0, self.rmax, self.nrs)
        self.dr = self.rs[-1] - self.rs[-2]
        self.pks = []
        self.pk_vals = []
        self.diameters = []

        for prof in self.profiles:
            pk, vpk = self.calc_pkrad_from_prof(prof)

            self.pks.append(pk)
            self.pk_vals.append(vpk)
            self.diameters.append(2*np.abs(pk))

        self.pks = np.array(self.pks)
        self.pk_vals = np.array(self.pk_vals)
        self.diameters = np.array(self.diameters)

        # ring size
        self.RingSize1 = (np.mean(self.diameters), np.std(self.diameters))
        self.RingSize1_med = (np.median(self.diameters), median_absolute_deviation(self.diameters))
//  [python]
def __init__(self, im, x0, y0, profs, thetas, rmin=RMIN, rmax=RMAX, 
                 interptype='cubic',flux_norm=NORMFLUX,
                 profsQ=[], profsU=[]):

        self.x0 = x0
        self.y0 = y0
        self.im = im
        self.rmin = rmin
        self.rmax = rmax

        # store the center image
        deltay = -(im.fovy()/2. - y0*ehc.RADPERUAS)/im.psize
        deltax = (im.fovx()/2. - x0*ehc.RADPERUAS)/im.psize
        self.im_center = im.shift([int(np.round(deltay)), int(np.round(deltax))])

        # total flux and normalization
        self.flux = im.total_flux()
        self.parea = (im.psize/ehc.RADPERUAS)**2

        # factor to convert to normalized brightness temperature (total flux of 1 Jy)
        self.flux_norm = flux_norm
        self.normfactor = self.flux_norm / im.total_flux()

        # image array and  profiles
        factor = 3.254e13/(im.rf**2 * im.psize**2)  # factor to convert to brightness temperature
        self.imarr = im.imvec.reshape(im.ydim, im.xdim)[::-1] * factor  # in Tb

        self.xs = np.arange(im.xdim)*im.psize/ehc.RADPERUAS
        self.ys = np.arange(im.ydim)*im.psize/ehc.RADPERUAS
        self.interp = scipy.interpolate.bisplev(self.ys, self.xs, scipy.interpolate.bisplrep(self.ys, self.xs, self.imarr, kx=3, ky=3))

        self.profiles = np.array(profs)
        self.profilesQ = np.array(profsQ)
        self.profilesU = np.array(profsU)
        self.profilesP = np.sqrt(self.profilesQ**2 + self.profilesU**2)
        self.thetas = np.array(thetas)
        self.nang = len(thetas)
        self.nrs = len(self.profiles[0])
        self.nthetas = len(self.thetas)
        self.rs = np.linspace(0, self.rmax, self.nrs)
        self.dr = self.rs[-1] - self.rs[-2]
        self.pks = []
        self.pk_vals = []
        self.diameters = []

        for prof in self.profiles:
            pk, vpk = self.calc_pkrad_from_prof(prof)

            self.pks.append(pk)
            self.pk_vals.append(vpk)
            self.diameters.append(2*np.abs(pk))

        self.pks = np.array(self.pks)
        self.pk_vals = np.array(self.pk_vals)
        self.diameters = np.array(self.diameters)

        # ring size
        self.RingSize1 = (np.mean(self.diameters), np.std(self.diameters))
        self.RingSize1_med = (np.median(self.diameters), median_absolute_deviation(self.diameters))
//  [python]
def _interpolate(*data, **kwargs):
    ret = None
    datay = kwargs["pre"](data[-1])
    if len(data) == 2:
        if kwargs["interpolator"] == "exp":
            ret = _interpolate_exp(*data[:-1], datay)
        else:
            ret = interp.interp1d(*data[:-1], datay, kind=kwargs["interpolator"])
    elif len(data) == 3:
        if kwargs["interpolator"] == "bivariatespline":
            ret = interp.SmoothBivariateSpline(
                *data[:-1], datay, kx=kwargs["order"], ky=kwargs["order"]
            )
        elif kwargs["interpolator"] == "linearnd":
            ret = interp.LinearNDInterpolator(list(zip(*data[:-1])), datay)
        else:
            ret = interp.interp2d(*data[:-1], datay, kind=kwargs["interpolator"])
    else:
        if kwargs["interpolator"] == "linear":
            ret = interp.LinearNDInterpolator(list(zip(*data[:-1])), datay)

    # return np.vectorize(Post(ret, kwargs['post']), otypes=["object"])
    return np.vectorize(lambda *a: kwargs["post"](ret(*a)), otypes=["object"])
//  [python]
def _interpolate(*data, **kwargs):
    ret = None
    datay = kwargs["pre"](data[-1])
    if len(data) == 2:
        if kwargs["interpolator"] == "exp":
            ret = _interpolate_exp(*data[:-1], datay)
        else:
            ret = interp.interp1d(*data[:-1], datay, kind=kwargs["interpolator"])
    elif len(data) == 3:
        if kwargs["interpolator"] == "bivariatespline":
            ret = interp.SmoothBivariateSpline(
                *data[:-1], datay, kx=kwargs["order"], ky=kwargs["order"]
            )
        elif kwargs["interpolator"] == "linearnd":
            ret = interp.LinearNDInterpolator(list(zip(*data[:-1])), datay)
        else:
            # Replacement for interp2d
            x, y = data[:-1]
            tck = interp.bisplrep(x, y, datay, kx=kwargs["order"], ky=kwargs["order"])
            ret = lambda x, y: interp.bisplev(x, y, tck)
    else:
        if kwargs["interpolator"] == "linear":
            ret = interp.LinearNDInterpolator(list(zip(*data[:-1])), datay)

    # return np.vectorize(Post(ret, kwargs['post']), otypes=["object"])
    return np.vectorize(lambda *a: kwargs["post"](ret(*a)), otypes=["object"])
//  [python]
def baryon_pk(self,z,cosmo_params=None,pk_params=None,return_s8=False):

        if pk_params is None:
            pk_params=self.pk_params
        if cosmo_params is None:
            cosmo_params=self.cosmo_params
        scenario = pk_params['scenario']

        out=self.camb_pk_too_many_z(z,cosmo_params=cosmo_params,pk_params=pk_params,return_s8=return_s8) #FIXME: pk_func should be use input.
        pk=out[0]
        kh=out[1]

        non_linear=pk_params['non_linear'] if pk_params.get('non_linear') is not None else 1

        if scenario is None or  'dmo' in scenario or non_linear==0:
            if return_s8:
                s8=out[2]
                return pk,kh,s8
            else:
                return pk,kh

        data_dir = "./Pk_ratio/"
        infile_logPkRatio = data_dir + "logPkRatio_" + scenario + ".dat"
        Arr2D_logPkratio = pd.read_csv(infile_logPkRatio,sep='\s+')
        Bins_log_k_Mpc = np.array(Arr2D_logPkratio["logk"])
        del Arr2D_logPkratio["logk"]
        Arr2D_logPkratio = np.array(Arr2D_logPkratio)
        f_logPkRatio = interpolate.interp2d(zbin_logPkR[scenario], Bins_log_k_Mpc, Arr2D_logPkratio, kind='linear')

        PkR    = 10**(f_logPkRatio(z,np.log10(kh)))
        pkbary = pk*PkR.T

        if return_s8:
            s8=out[2]
            return pkbary,kh,s8
        else:
            return pkbary,kh
//  [python]
def baryon_pk(self,z,cosmo_params=None,pk_params=None,return_s8=False):

        if pk_params is None:
            pk_params=self.pk_params
        if cosmo_params is None:
            cosmo_params=self.cosmo_params
        scenario = pk_params['scenario']

        out=self.camb_pk_too_many_z(z,cosmo_params=cosmo_params,pk_params=pk_params,return_s8=return_s8) #FIXME: pk_func should be use input.
        pk=out[0]
        kh=out[1]

        non_linear=pk_params['non_linear'] if pk_params.get('non_linear') is not None else 1

        if scenario is None or  'dmo' in scenario or non_linear==0:
            if return_s8:
                s8=out[2]
                return pk,kh,s8
            else:
                return pk,kh

        data_dir = "./Pk_ratio/"
        infile_logPkRatio = data_dir + "logPkRatio_" + scenario + ".dat"
        Arr2D_logPkratio = pd.read_csv(infile_logPkRatio,sep='\s+')
        Bins_log_k_Mpc = np.array(Arr2D_logPkratio["logk"])
        del Arr2D_logPkratio["logk"]
        Arr2D_logPkratio = np.array(Arr2D_logPkratio)
        x,y = np.meshgrid(zbin_logPkR[scenario], Bins_log_k_Mpc)
        f_logPkRatio = interpolate.bisplev(x,y,Arr2D_logPkratio)

        PkR    = 10**(f_logPkRatio(z,np.log10(kh)))
        pkbary = pk*PkR.T

        if return_s8:
            s8=out[2]
            return pkbary,kh,s8
        else:
            return pkbary,kh
//  [python]
def CalcLocalVolSurface(df):
    # Calculate local vols by Dupire formula based on IVS df, with cubic interpolation
    # Columns: "Log-strike","Texp","IV"
    # Ref: Gatheral, The Volatility Surface, a Practitioner's Guide
    # NOT stable, values blow up!
    k = df["Log-strike"].to_numpy()
    T = df["Texp"].to_numpy()
    sigI = df["IV"].to_numpy()
    w = sigI**2*T

    k0 = np.unique(k)
    T0 = np.unique(T)

    fw = interp2d(k,T,w,kind='cubic')
    dk1 = fw(k0,T0,dx=1).reshape(-1)
    dk2 = fw(k0,T0,dx=2).reshape(-1)
    dT1 = fw(k0,T0,dy=1).reshape(-1)

    sigL = np.sqrt(dT1/((1-0.5*k/w*dk1)**2-0.25*(0.25+1/w)*dk1**2+0.5*dk2)) # Dupire PDE
    sigL = pd.DataFrame(np.array([k,T,sigL]).T,columns=["Log-strike","Texp","LV"])
    return sigL
//  [python]
def CalcLocalVolSurface(df):
    # Calculate local vols by Dupire formula based on IVS df, with cubic interpolation
    # Columns: "Log-strike","Texp","IV"
    # Ref: Gatheral, The Volatility Surface, a Practitioner's Guide
    # NOT stable, values blow up!
    k = df["Log-strike"].to_numpy()
    T = df["Texp"].to_numpy()
    sigI = df["IV"].to_numpy()
    w = sigI**2*T

    k0 = np.unique(k)
    T0 = np.unique(T)

    from scipy.interpolate import bisplev, bisplrep
    tck = bisplrep(k,T,w,kx=3,ky=3)
    fw = lambda x,y: bisplev(x,y,tck)
    dk1 = fw(k0,T0,dx=1).reshape(-1)
    dk2 = fw(k0,T0,dx=2).reshape(-1)
    dT1 = fw(k0,T0,dy=1).reshape(-1)

    sigL = np.sqrt(dT1/((1-0.5*k/w*dk1)**2-0.25*(0.25+1/w)*dk1**2+0.5*dk2)) # Dupire PDE
    sigL = pd.DataFrame(np.array([k,T,sigL]).T,columns=["Log-strike","Texp","LV"])
    return sigL
//  [python]
def vector_field(mat):
    x = np.array(range(mat.shape[0]))
    y = np.array(range(mat.shape[1]))
    f = interp.interp2d(y, x, mat, kind='linear')
    return lambda p: f(p[1], p[0])[0]
//  [python]
def vector_field(mat):
    x = np.array(range(mat.shape[0]))
    y = np.array(range(mat.shape[1]))
    f = interp.bisplev(y, x, mat)
    return lambda p: f(p[1], p[0])[0]
//  [python]
def findCenter(im,
               rmin=RMIN, rmax=RMAX,
               rmin_search=RPRIOR_MIN,  rmax_search=RPRIOR_MAX,
               nrays_search=NRAYS_SEARCH, nrs_search=NRS_SEARCH,
               fov_search=FOVP_SEARCH, n_search=NSEARCH, flux_norm=NORMFLUX):
    """Find the ring center by looking at profiles over a given range
    """

    print("nrays", nrays_search, "nrs", nrs_search, "fov", fov_search, "n", n_search)

    rs = np.linspace(0, rmax_search, nrs_search)
    dr = rs[-1] - rs[-2]
    thetas = np.linspace(0, 2*np.pi, nrays_search)
    factor = 3.254e13/(im.rf**2 * im.psize**2)  # convert to brightness temperature
    imarr = im.imvec.reshape(im.ydim, im.xdim)[::-1] * factor  # in brightness temperature K
    xs = np.arange(im.xdim)*im.psize/ehc.RADPERUAS
    ys = np.arange(im.ydim)*im.psize/ehc.RADPERUAS

    # TODO: test fiducial images with linear?
    #iminterp = scipy.interpolate.interp2d(ys, xs, imarr, kind='cubic')
    iminterp = scipy.interpolate.interp2d(ys, xs, imarr, kind='linear')
    #iminterp = scipy.interpolate.RegularGridInterpolator((ys,xs),imarr)
    def objFunc(pos):
        (x0, y0) = pos
        diameters = []
        for j in range(nrays_search):
            xxs = x0 - rs*np.sin(thetas[j])
            yys = y0 + rs*np.cos(thetas[j])
            prof = np.array([iminterp(xxs[i], yys[i])[0] for i in np.arange(len(rs))])
            
            args = np.argsort(prof)
            pkpos = args[-1]
            pk = rs[pkpos]
            vpk = prof[pkpos]
            if pkpos > 0 and pkpos < nrs_search-1:
                vals = [prof[pkpos-1], prof[pkpos], prof[pkpos+1]]
                pk, vpk = quad_interp_radius(pk, dr, vals)
            
            diameters.append(2*np.abs(pk))
                    
        # ring size
        mean,std = (np.mean(diameters), np.std(diameters))
        
        if mean < rmin_search or mean > rmax_search:
            return np.inf
        else:
            J = np.abs(std/mean)
            return J

    fovx = im.fovx()/ehc.RADPERUAS
    fovy = im.fovy()/ehc.RADPERUAS

    # brute force search + fmin finisher to find
    fovmin_x = (.5-fov_search) * fovx
    fovmax_x = (.5+fov_search) * fovx
    fovmin_y = (.5-fov_search) * fovy
    fovmax_y = (.5+fov_search) * fovy
    res = scipy.optimize.brute(objFunc, ranges=((fovmin_x, fovmax_x), (fovmin_y, fovmax_y)),
                               Ns=n_search)

    return res
//  [python]
def findCenter(im,
               rmin=RMIN, rmax=RMAX,
               rmin_search=RPRIOR_MIN,  rmax_search=RPRIOR_MAX,
               nrays_search=NRAYS_SEARCH, nrs_search=NRS_SEARCH,
               fov_search=FOVP_SEARCH, n_search=NSEARCH, flux_norm=NORMFLUX):
    """Find the ring center by looking at profiles over a given range
    """

    print("nrays", nrays_search, "nrs", nrs_search, "fov", fov_search, "n", n_search)

    rs = np.linspace(0, rmax_search, nrs_search)
    dr = rs[-1] - rs[-2]
    thetas = np.linspace(0, 2*np.pi, nrays_search)
    factor = 3.254e13/(im.rf**2 * im.psize**2)  # convert to brightness temperature
    imarr = im.imvec.reshape(im.ydim, im.xdim)[::-1] * factor  # in brightness temperature K
    xs = np.arange(im.xdim)*im.psize/ehc.RADPERUAS
    ys = np.arange(im.ydim)*im.psize/ehc.RADPERUAS

    # TODO: test fiducial images with linear?
    #iminterp = scipy.interpolate.interp2d(ys, xs, imarr, kind='cubic')
    tck = scipy.interpolate.bisplev(ys, xs, imarr)
    def iminterp(x, y):
        return scipy.interpolate.bisplev(x, y, tck)
    #iminterp = scipy.interpolate.RegularGridInterpolator((ys,xs),imarr)
    def objFunc(pos):
        (x0, y0) = pos
        diameters = []
        for j in range(nrays_search):
            xxs = x0 - rs*np.sin(thetas[j])
            yys = y0 + rs*np.cos(thetas[j])
            prof = np.array([iminterp(xxs[i], yys[i])[0] for i in np.arange(len(rs))])
            
            args = np.argsort(prof)
            pkpos = args[-1]
            pk = rs[pkpos]
            vpk = prof[pkpos]
            if pkpos > 0 and pkpos < nrs_search-1:
                vals = [prof[pkpos-1], prof[pkpos], prof[pkpos+1]]
                pk, vpk = quad_interp_radius(pk, dr, vals)
            
            diameters.append(2*np.abs(pk))
                    
        # ring size
        mean,std = (np.mean(diameters), np.std(diameters))
        
        if mean < rmin_search or mean > rmax_search:
            return np.inf
        else:
            J = np.abs(std/mean)
            return J

    fovx = im.fovx()/ehc.RADPERUAS
    fovy = im.fovy()/ehc.RADPERUAS

    # brute force search + fmin finisher to find
    fovmin_x = (.5-fov_search) * fovx
    fovmax_x = (.5+fov_search) * fovx
    fovmin_y = (.5-fov_search) * fovy
    fovmax_y = (.5+fov_search) * fovy
    res = scipy.optimize.brute(objFunc, ranges=((fovmin_x, fovmax_x), (fovmin_y, fovmax_y)),
                               Ns=n_search)

    return res
//  [python]
def compute_ring_profile(im, x0, y0, title="",
                         nrays=NRAYS, nrs=NRS, rmin=RMIN, rmax=RMAX,
                         flux_norm=NORMFLUX, pol_profs=False,
                         interptype='cubic'):
    """compute a ring profile  given a center location
    """

    rs = np.linspace(0, rmax, nrs)
    thetas = np.linspace(0, 2*np.pi, nrays)

    factor = 3.254e13/(im.rf**2 * im.psize**2)  # convert to brightness temperature
    imarr = im.imvec.reshape(im.ydim, im.xdim)[::-1] * factor  # in brightness temperature K
    xs = np.arange(im.xdim)*im.psize/ehc.RADPERUAS
    ys = np.arange(im.ydim)*im.psize/ehc.RADPERUAS

    # TODO: test fiducial images with linear?
    interp = scipy.interpolate.interp2d(ys, xs, imarr, kind=interptype)

    def ringVals(theta):
        xxs = x0 - rs*np.sin(theta)
        yys = y0 + rs*np.cos(theta)

        vals = [interp(xxs[i], yys[i])[0] for i in np.arange(len(rs))]
        return vals

    profs = []
    for j in range(nrays):
        vals = ringVals(thetas[j])
        profs.append(vals)

    # polarization profiles
    profsQ = []
    profsU = []
    if len(im.qvec) > 0 and len(im.uvec > 0) and pol_profs:
        qarr = im.qvec.reshape(im.ydim, im.xdim)[::-1] * factor  # in brightness temperature K
        uarr = im.uvec.reshape(im.ydim, im.xdim)[::-1] * factor  # in brightness temperature K
        interpQ = scipy.interpolate.interp2d(ys, xs, qarr, kind=interptype)
        interpU = scipy.interpolate.interp2d(ys, xs, uarr, kind=interptype)

        def ringValsQ(theta):
            xxs = x0 - rs*np.sin(theta)
            yys = y0 + rs*np.cos(theta)

            vals = [interpQ(xxs[i], yys[i])[0] for i in np.arange(len(rs))]
            return vals

        def ringValsU(theta):
            xxs = x0 - rs*np.sin(theta)
            yys = y0 + rs*np.cos(theta)

            vals = [interpU(xxs[i], yys[i])[0] for i in np.arange(len(rs))]
            return vals

        for j in range(nrays):
            valsQ = ringValsQ(thetas[j])
            profsQ.append(valsQ)
            valsU = ringValsU(thetas[j])
            profsU.append(valsU)

    
    profiles = Profiles(im, x0, y0, profs, thetas, rmin=rmin, rmax=rmax, interptype=interptype,
                        flux_norm=flux_norm,profsQ=profsQ, profsU=profsU)

    return profiles
//  [python]
def compute_ring_profile(im, x0, y0, title="",
                         nrays=NRAYS, nrs=NRS, rmin=RMIN, rmax=RMAX,
                         flux_norm=NORMFLUX, pol_profs=False,
                         interptype='cubic'):
    """compute a ring profile  given a center location
    """

    rs = np.linspace(0, rmax, nrs)
    thetas = np.linspace(0, 2*np.pi, nrays)

    factor = 3.254e13/(im.rf**2 * im.psize**2)  # convert to brightness temperature
    imarr = im.imvec.reshape(im.ydim, im.xdim)[::-1] * factor  # in brightness temperature K
    xs = np.arange(im.xdim)*im.psize/ehc.RADPERUAS
    ys = np.arange(im.ydim)*im.psize/ehc.RADPERUAS

    # TODO: test fiducial images with linear?
    interp = scipy.interpolate.bisplev(ys, xs, scipy.interpolate.bisplrep(ys, xs, imarr, kx=3, ky=3))

    def ringVals(theta):
        xxs = x0 - rs*np.sin(theta)
        yys = y0 + rs*np.cos(theta)

        vals = [interp(xxs[i], yys[i])[0] for i in np.arange(len(rs))]
        return vals

    profs = []
    for j in range(nrays):
        vals = ringVals(thetas[j])
        profs.append(vals)

    # polarization profiles
    profsQ = []
    profsU = []
    if len(im.qvec) > 0 and len(im.uvec > 0) and pol_profs:
        qarr = im.qvec.reshape(im.ydim, im.xdim)[::-1] * factor  # in brightness temperature K
        uarr = im.uvec.reshape(im.ydim, im.xdim)[::-1] * factor  # in brightness temperature K
        interpQ = scipy.interpolate.bisplev(ys, xs, scipy.interpolate.bisplrep(ys, xs, qarr, kx=3, ky=3))
        interpU = scipy.interpolate.bisplev(ys, xs, scipy.interpolate.bisplrep(ys, xs, uarr, kx=3, ky=3))

        def ringValsQ(theta):
            xxs = x0 - rs*np.sin(theta)
            yys = y0 + rs*np.cos(theta)

            vals = [interpQ(xxs[i], yys[i])[0] for i in np.arange(len(rs))]
            return vals

        def ringValsU(theta):
            xxs = x0 - rs*np.sin(theta)
            yys = y0 + rs*np.cos(theta)

            vals = [interpU(xxs[i], yys[i])[0] for i in np.arange(len(rs))]
            return vals

        for j in range(nrays):
            valsQ = ringValsQ(thetas[j])
            profsQ.append(valsQ)
            valsU = ringValsU(thetas[j])
            profsU.append(valsU)

    
    profiles = Profiles(im, x0, y0, profs, thetas, rmin=rmin, rmax=rmax, interptype=interptype,
                        flux_norm=flux_norm,profsQ=profsQ, profsU=profsU)

    return profiles
//  [python]
def upsample_image_to_degrees(img):
    upsample = 74.4 / img.shape[0]
    x = np.arange(img.shape[0])
    y = np.arange(img.shape[1])

    g = spinterp.interp2d(y, x, img, kind="linear")
    ZZ_on = g(
        np.arange(0, img.shape[1], 1.0 / upsample),
        np.arange(0, img.shape[0], 1.0 / upsample),
    )

    return ZZ_on
//  [python]
def upsample_image_to_degrees(img):
    upsample = 74.4 / img.shape[0]
    x = np.arange(img.shape[0])
    y = np.arange(img.shape[1])

    g = spinterp.bisplev(y, x, img)
    ZZ_on = g(
        np.arange(0, img.shape[1], 1.0 / upsample),
        np.arange(0, img.shape[0], 1.0 / upsample),
    )

    return ZZ_on
//  [python]
def get_interpolated_euclidean_timeseries(X, t, kind='linear'):
    """
    Resample a time series in Euclidean space using interp2d

    Parameters
    ----------
    X: ndarray(M, d)
        The Euclidean time series with n points
    t: ndarray(N)
        A re-parameterization function on the unit interval [0, 1]
    kind: string
        The kind of interpolation to do
    
    Returns
    -------
    Y: ndarray(N, d)
        The interpolated time series
    """
    import scipy.interpolate as interp
    M = X.shape[0]
    d = X.shape[1]
    t0 = np.linspace(0, 1, M)
    dix = np.arange(d)
    f = interp.interp2d(dix, t0, X, kind=kind)
    Y = f(dix, t)
    return Y
//  [python]
def get_interpolated_euclidean_timeseries(X, t, kind='linear'):
    """
    Resample a time series in Euclidean space using interp2d

    Parameters
    ----------
    X: ndarray(M, d)
        The Euclidean time series with n points
    t: ndarray(N)
        A re-parameterization function on the unit interval [0, 1]
    kind: string
        The kind of interpolation to do
    
    Returns
    -------
    Y: ndarray(N, d)
        The interpolated time series
    """
    import scipy.interpolate as interp
    import numpy as np
    M = X.shape[0]
    d = X.shape[1]
    t0 = np.linspace(0, 1, M)
    dix = np.arange(d)
    x = np.arange(d)
    tck = interp.splrep(t0, X, s=0, k=1)
    Y = interp.splev(t, tck)
    return Y
//  [python]
def rescale_electronprofile(self,A):
        ukgas_rescaled = np.zeros(self.ukgas.shape)
        for zind in range(len(self.z)):
            interp_ue = interp2d(self.k,self.logm,self.ukgas[:,zind,:])
            interp_nfw = interp2d(self.k,self.logm,self.ukm[:,zind,:])
            ukgas_rescaled[:,zind,:] = interp_ue(self.k[:]*A,self.logm)/interp_nfw(self.k*A,self.logm)*self.ukm[:,zind,:]
        return ukgas_rescaled
//  [python]
def rescale_electronprofile(self,A):
        ukgas_rescaled = np.zeros(self.ukgas.shape)
        for zind in range(len(self.z)):
            interp_ue = bisplev(self.k,self.logm,self.ukgas[:,zind,:])
            interp_nfw = bisplev(self.k,self.logm,self.ukm[:,zind,:])
            ukgas_rescaled[:,zind,:] = interp_ue(self.k[:]*A,self.logm)/interp_nfw(self.k*A,self.logm)*self.ukm[:,zind,:]
        return ukgas_rescaled
//  [python]
def __call__(self, amax, p=None):
        if self.old:
            f_kabs = scipy.interpolate.interp2d(self.lam, self.amax, \
                    numpy.log10(self.kabs))
            f_ksca = scipy.interpolate.interp2d(self.lam, self.amax, \
                    numpy.log10(self.ksca))

            kabs = 10.**f_kabs(self.lam, amax)
            ksca = 10.**f_ksca(self.lam, amax)

            d = Dust()
            d.set_properties(self.lam, kabs, ksca)
        else:
            f_kabs = scipy.interpolate.RegularGridInterpolator(\
                    (self.p, self.amax, self.lam), numpy.log10(self.kabs))
            f_ksca = scipy.interpolate.RegularGridInterpolator(\
                    (self.p, self.amax, self.lam), numpy.log10(self.ksca))

            pts = numpy.array([[p, amax, lam] for lam in self.lam])

            kabs = 10.**f_kabs(pts)
            ksca = 10.**f_ksca(pts)

            d = Dust()
            d.set_properties(self.lam, kabs, ksca)

        return d
//  [python]
def __call__(self, amax, p=None):
        if self.old:
            f_kabs = scipy.interpolate.bisplev(self.lam, self.amax, \
                    numpy.log10(self.kabs))
            f_ksca = scipy.interpolate.bisplev(self.lam, self.amax, \
                    numpy.log10(self.ksca))

            kabs = 10.**f_kabs(self.lam, amax)
            ksca = 10.**f_ksca(self.lam, amax)

            d = Dust()
            d.set_properties(self.lam, kabs, ksca)
        else:
            f_kabs = scipy.interpolate.RegularGridInterpolator(\
                    (self.p, self.amax, self.lam), numpy.log10(self.kabs))
            f_ksca = scipy.interpolate.RegularGridInterpolator(\
                    (self.p, self.amax, self.lam), numpy.log10(self.ksca))

            pts = numpy.array([[p, amax, lam] for lam in self.lam])

            kabs = 10.**f_kabs(pts)
            ksca = 10.**f_ksca(pts)

            d = Dust()
            d.set_properties(self.lam, kabs, ksca)

        return d
//  [python]
def convolve(img, sigma=4):
    """
    2D Gaussian convolution
    """

    if img.sum() == 0:
        return img

    img_pad = np.zeros((3 * img.shape[0], 3 * img.shape[1]))
    img_pad[
        img.shape[0] : 2 * img.shape[0], img.shape[1] : 2 * img.shape[1]
    ] = img

    x = np.arange(3 * img.shape[0])
    y = np.arange(3 * img.shape[1])
    g = spinterp.interp2d(y, x, img_pad, kind="linear")

    if img.shape[0] == 16:
        upsample = 4
        offset = -(1 - 0.625)
    elif img.shape[0] == 8:
        upsample = 8
        offset = -(1 - 0.5625)
    else:
        raise NotImplementedError
    ZZ_on = g(
        offset + np.arange(0, img.shape[1] * 3, 1.0 / upsample),
        offset + np.arange(0, img.shape[0] * 3, 1.0 / upsample),
    )
    ZZ_on_f = gaussian_filter(ZZ_on, float(sigma), mode="constant")

    z_on_new = block_reduce(ZZ_on_f, (upsample, upsample))
    z_on_new = z_on_new / z_on_new.sum() * img.sum()
    z_on_new = z_on_new[
        img.shape[0] : 2 * img.shape[0], img.shape[1] : 2 * img.shape[1]
    ]

    return z_on_new
//  [python]
def convolve(img, sigma=4):
    """
    2D Gaussian convolution
    """

    if img.sum() == 0:
        return img

    img_pad = np.zeros((3 * img.shape[0], 3 * img.shape[1]))
    img_pad[
        img.shape[0] : 2 * img.shape[0], img.shape[1] : 2 * img.shape[1]
    ] = img

    x = np.arange(3 * img.shape[0])
    y = np.arange(3 * img.shape[1])
    tck = splprep([y, x], s=0, k=1)[0]
    g = bisplev(y, x, tck)


    if img.shape[0] == 16:
        upsample = 4
        offset = -(1 - 0.625)
    elif img.shape[0] == 8:
        upsample = 8
        offset = -(1 - 0.5625)
    else:
        raise NotImplementedError
    ZZ_on = bisplev(
        offset + np.arange(0, img.shape[1] * 3, 1.0 / upsample),
        offset + np.arange(0, img.shape[0] * 3, 1.0 / upsample),
        tck,
    )
    ZZ_on_f = gaussian_filter(ZZ_on, float(sigma), mode="constant")

    z_on_new = block_reduce(ZZ_on_f, (upsample, upsample))
    z_on_new = z_on_new / z_on_new.sum() * img.sum()
    z_on_new = z_on_new[
        img.shape[0] : 2 * img.shape[0], img.shape[1] : 2 * img.shape[1]
    ]

    return z_on_new
//  [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
    ui = intp.interp2d(G['lon_u'][0, :], G['lat_u'][:, 0], ud)
    vi = intp.interp2d(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 = 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')