def build_linear_interp_func(data):
     d0, d1, d2 = data.shape
     a = np.array([0, 0, 0])
     b = np.array([d0 - 1, d1 - 1, d2 - 1])
     orders = np.array([d0, d1, d2])
     lin = LinearSpline(a, b, orders, data)
     return lin
Ejemplo n.º 2
0
    def get_interpolants(self, method='linear'):
        """

        Get the interpolant functions using the scipy engine or the interpolation.splines engine.
        The second option requires the installation of this package with pip.
        It provides a very faster interpolation algorithm, however, the data points 
        should be regularly spaced. The scipy is more flexible, allowing not equally spaced 
        points in a dimension, but it is slower.


        Args:
            - numba_interpolant (bool, optional): Select scipy or interpolation engine.
            - method (str, optional): Nearest, linear, spline.

        """
        if self.conversion_grid == 1:
            self.origin_points = np.column_stack(
                ([self.ds[name].values.ravel()
                  for name in self.origin_coords]))
            self.destiny_points = map(
                np.ravel,
                np.meshgrid(*[
                    self.ds[name].values.ravel()
                    for name in self.destiny_coords
                ]))
            # self. = np.column_stack(([mesh.ravel() for mesh in destiny_mesh]))

        if self.numba_interpolant == 0:
            for field in self.fields:
                self.interpolants.append(
                    RegularGridInterpolator(self.grid,
                                            self.ds[field].values,
                                            method,
                                            bounds_error=False))

        elif self.numba_interpolant == 1:
            for field in self.fields:
                self.interpolants.append(
                    LinearSpline(list(map(np.min, self.grid)),
                                 list(map(np.max, self.grid)),
                                 list(map(np.size, self.grid)),
                                 self.ds[field].values))

        return
Ejemplo n.º 3
0
def img_interpol(img, xa, ya, xt, yt, missing=-1):
    """
    Interpolate the image for a given coordinates.
    
    Parameters
    ----------
    img : 2d ndarray
        2 dimensional array of image.
    x : 1d ndarray
        Row vector of x.
    y : 1d ndarray
        Colomn vector of y.
    xt : 2d ndarray
        Coordinates of the positions in the observed frame.
    yt : 2d ndarray
        Coordinates of the positions in the observed frame.
    missing : (optional) float
        The value of extrapolated position.
        Default is -1, and it means the False.
        If False, then extrapolate the given position.
    
    Returns
    -------
    res : 2d ndarray
        2 dimensional interpolated image.
        The size of res is same as input img.
    
    """
    shape = xt.shape
    size = xt.size
    smin = [ya[0, 0], xa[0]]
    smax = [ya[-1, 0], xa[-1]]
    order = [len(ya), len(xa)]
    interp = LinearSpline(smin, smax, order, img)
    a = np.array((yt.reshape(size), xt.reshape(size)))
    b = interp(a.T)
    res = b.reshape(shape)
    if missing != -1:
        mask = np.invert((xt <= xa.max()) * (xt >= xa.min()) *
                         (yt <= ya.max()) * (yt >= ya.min()))
        res[mask] = missing
    return res
Ejemplo n.º 4
0
def cgstki3(velp, zplan, tt, dt, nx, ny, nz, dim, domain, simtstep):
    # x = np.arange(tt)
    print 'domain :'
    print domain
    ttt = int(tt / dt)
    ttt = np.arange(ttt)
    tmin = ttt[0] * dt
    tmax = ttt[-1] * dt
    print 'tmin, tmax', tmin, tmax
    # print ttt[0], ttt[-1]
    nt = len(ttt)
    print 'n time step', nt

    # small (so is your dick) vector d1(d1 0 0) d2(0 d2 0) d3(0 0 d3)
    minx, maxx, miny, maxy, minz, maxz = domain

    dx = (maxx - minx) / nx
    dy = (maxy - miny) / ny
    dz = (maxz - minz) / nz
    print 'dx=', dx
    if abs(dx - dy) > 1e-5 or abs(dx - dz) > 1e-5:
        print 'bad spacing', dx, dy, dz
        quit()
    a = np.array([minx, miny, minz, tmin])  # lower boundaries
    b = np.array([maxx, maxy, maxz, tmax])  # upper boundaries

    orders = np.array([nx, ny, nz, nt])  # 10 points along each dimension

    velpu = velp[:, :, :, 0, :]
    velpv = velp[:, :, :, 1, :]
    velpw = velp[:, :, :, 2, :]
    if cubicADV:
        linx = CubicSpline(a, b, orders, velpu)
        liny = CubicSpline(a, b, orders, velpv)
        linz = CubicSpline(a, b, orders, velpw)
    else:
        linx = LinearSpline(a, b, orders, velpu)
        liny = LinearSpline(a, b, orders, velpv)
        linz = LinearSpline(a, b, orders, velpw)
    # intitial pos:
    grid_x, grid_y, grid_z, grid_t = np.mgrid[minx:maxx - dx:nx * 1j, miny:maxy - dx:ny * 1j,
                                     minz:maxz - dx:nz * 1j, tmin:tmax:nt * 1j]

    positions = np.vstack([grid_x.ravel(), grid_y.ravel(), grid_z.ravel(), grid_t.ravel()]).T

    # interpUZ = linz(positions)
    # interpUX = linx(positions)
    # interpUY = liny(positions)

    pos_x, pos_y, pos_z = np.mgrid[minx:maxx - dx:nx * 1j, miny:maxy - dx:ny * 1j,
                          minz:maxz - dx:nz * 1j]
    pos_x = pos_x.ravel()
    pos_y = pos_y.ravel()
    pos_z = pos_z.ravel()

    # cheap advection

    t0 = tmin
    z0 = positions
    t1 = tmax
    dt = 0.005  # interp step
    listt = np.linspace(t0, t1, int((tmax - tmin) / dt))
    print 'number of interp steps', len(listt)
    for t in listt:
        aa = np.empty([pos_x.shape[0], 4])
        aa[:, 0] = pos_x
        aa[:, 1] = pos_y
        aa[:, 2] = pos_z
        aa[:, 3] = t
        pos_x += linx(aa) * dt
        pos_y += liny(aa) * dt
        pos_z += linz(aa) * dt

    pos_final = np.empty([nx, ny, nz, 3])
    ind = 0
    for i in xrange(nx):
        for j in xrange(ny):
            for k in xrange(nz):
                pos_final[i, j, k, :] = pos_x[ind], pos_y[ind], pos_z[ind]
                ind += 1
    plot = 0
    if plot:
        fig = plt.figure()
        ax1 = fig.add_subplot(311)
        ax1.imshow(pos_final[:, :, int(nz / 2), 0])
        ax2 = fig.add_subplot(312)
        ax2.imshow(pos_final[:, :, int(nz / 2), 1])
        ax3 = fig.add_subplot(313)
        ax3.imshow(pos_final[:, :, int(nz / 2), 2])
        plt.show()

    print 'advection computed with brio'
    print 'let\' compute the muthafucking CG tenseor now'

    # interpolator for the final positions (aka flow map)
    a = np.array([minx, miny, minz])  # lower boundaries
    b = np.array([maxx, maxy, maxz])  # upper boundaries

    orders = np.array([nx, ny, nz])
    if cubicCG:
        FMx = CubicSpline(a, b, orders, pos_final[:, :, :, 0])
        FMy = CubicSpline(a, b, orders, pos_final[:, :, :, 1])
        FMz = CubicSpline(a, b, orders, pos_final[:, :, :, 2])
    else:
        FMx = LinearSpline(a, b, orders, pos_final[:, :, :, 0])
        FMy = LinearSpline(a, b, orders, pos_final[:, :, :, 1])
        FMz = LinearSpline(a, b, orders, pos_final[:, :, :, 2])

        pos_x, pos_y, pos_z = np.mgrid[minx:maxx - dx:nx * 1j, miny:maxy - dx:ny * 1j,
                              minz:maxz - dx:nz * 1j]

    pos_x = pos_x.ravel()
    pos_y = pos_y.ravel()
    pos_z = pos_z.ravel()
    delta = 1e-4

    ap = np.empty([pos_x.shape[0], 3])
    ap[:, 0] = pos_x + delta
    ap[:, 1] = pos_y
    ap[:, 2] = pos_z
    am = np.empty([pos_x.shape[0], 3])
    am[:, 0] = pos_x - delta
    am[:, 1] = pos_y
    am[:, 2] = pos_z
    g00 = (FMx(ap) - FMx(am)) / (2 * delta)
    g10 = (FMy(ap) - FMy(am)) / (2 * delta)
    g20 = (FMz(ap) - FMz(am)) / (2 * delta)

    ap = np.empty([pos_x.shape[0], 3])
    ap[:, 0] = pos_x
    ap[:, 1] = pos_y + delta
    ap[:, 2] = pos_z
    am = np.empty([pos_x.shape[0], 3])
    am[:, 0] = pos_x
    am[:, 1] = pos_y - delta
    am[:, 2] = pos_z
    g01 = (FMx(ap) - FMx(am)) / (2 * delta)
    g11 = (FMy(ap) - FMy(am)) / (2 * delta)
    g21 = (FMz(ap) - FMz(am)) / (2 * delta)

    ap = np.empty([pos_x.shape[0], 3])
    ap[:, 0] = pos_x
    ap[:, 1] = pos_y
    ap[:, 2] = pos_z + delta
    am = np.empty([pos_x.shape[0], 3])
    am[:, 0] = pos_x
    am[:, 1] = pos_y
    am[:, 2] = pos_z - delta
    g02 = (FMx(ap) - FMx(am)) / (2 * delta)
    g12 = (FMy(ap) - FMy(am)) / (2 * delta)
    g22 = (FMz(ap) - FMz(am)) / (2 * delta)

    ggrid = np.empty([nx, ny, nz, 3, 3])
    ind = 0
    for i in xrange(nx):
        for j in xrange(ny):
            for k in xrange(nz):
                ggrid[i, j, k, 0, 0] = g00[ind]
                ggrid[i, j, k, 0, 1] = g01[ind]
                ggrid[i, j, k, 0, 2] = g02[ind]
                ggrid[i, j, k, 1, 0] = g10[ind]
                ggrid[i, j, k, 1, 1] = g11[ind]
                ggrid[i, j, k, 1, 2] = g12[ind]
                ggrid[i, j, k, 2, 0] = g20[ind]
                ggrid[i, j, k, 2, 1] = g21[ind]
                ggrid[i, j, k, 2, 2] = g22[ind]
                ind += 1
    plot = 0
    if plot:
        fig = plt.figure()
        ax1 = fig.add_subplot(311)
        ax1.imshow(ggrid[:, :, int(nz / 2), 0, 0])
        ax2 = fig.add_subplot(312)
        ax2.imshow(ggrid[:, :, int(nz / 2), 1, 1])
        ax3 = fig.add_subplot(313)
        ax3.imshow(ggrid[:, :, int(nz / 2), 2, 2])
        plt.show()

    print " CG tensor computed"
    eigenValues, eigenVectors = LA.eig(ggrid)

    eigvec1 = np.empty((nx, ny, nz, 3))
    eigvec3 = np.empty((nx, ny, nz, 3))
    eigval1 = np.empty((nx, ny, nz))
    eigval3 = np.empty((nx, ny, nz))
    for i in xrange(nx):
        for j in xrange(ny):
            for k in xrange(nz):
                mineig = np.argmin(eigenValues[i, j, k, :])
                maxeig = np.argmax(eigenValues[i, j, k, :])
                eigval1[i, j, k] = eigenValues[i, j, k, mineig]
                eigval3[i, j, k] = eigenValues[i, j, k, maxeig]
                eigvec1[i, j, k, :] = eigenVectors[i, j, k, :, mineig]
                eigvec3[i, j, k, :] = eigenVectors[i, j, k, :, maxeig]
    print " eigVal, eigVec computed"
    plot = 0
    if plot:
        fig = plt.figure()
        ax1 = fig.add_subplot(211)
        ax1.imshow(eigval3[:, :, int(nz / 2)])
        ax2 = fig.add_subplot(212)
        ax2.imshow(eigval1[:, :, int(nz / 2)])
        plt.show()

    return ggrid, eigval1, eigval3, eigvec1, eigvec3
Ejemplo n.º 5
0
    def interpolate(self,
                    lat,
                    lon,
                    times=None,
                    padding=1.,
                    method='linear',
                    engine='interp',
                    do_pmm=False,
                    output_file=None,
                    verbose=False):
        """

        :param lat: 2-d array: latitude values to interpolate to
        :param lon: 2-d array: longitude values to interpolate to
        :param times: list: datetime times to process
        :param padding: float: in degrees, the number of degrees in each cardinal direction to add to the radar domain,
            used to compensate for the curvature of the ensemble projection
        :param method: str: method of interpolation for engine ('linear', 'nearest', or 'cubic')
        :param engine: str: 'scipy' or 'interp'. If using scipy, then the method can be any value; for interp, only
            'linear' and 'cubic' are available
        :param do_pmm: bool: if True, uses a probability matching to retain extreme values
        :param output_file: str or None: if None, does the operations in-memory and returns an xarray Dataset.
            Otherwise, writes to the netCDF file and returns an opened xarray Dataset.
        :param verbose: bool: print progress statements
        :return: dask array: interpolated radar data
        """
        if self.Dataset is None:
            raise ValueError('data must be opened to interpolate')
        if times is not None:
            self.set_times(times)
        if len(self.times) < 1:
            raise ValueError(
                'no times loaded in dataset or provided as keyword arg')
        times = self._time_coord
        if lat.shape != lon.shape:
            raise ValueError("shapes of 'lat' and 'lon' must match")
        if engine not in ('interp', 'scipy'):
            raise ValueError("'engine' must be 'interp' or 'scipy'")
        if method not in ('linear', 'cubic', 'nearest'):
            raise ValueError(
                "'method' must be 'linear', 'cubic', or 'nearest'")
        if method == 'nearest' and engine == 'interp':
            print(
                "interpolate warning: 'nearest' method unavailable for 'interp' engine; using 'linear'"
            )
            method = 'linear'

        # Get the radar array bounds
        y1r, x1r = self.closest_lat_lon(
            np.min(lat) - padding,
            np.min(lon) - padding)
        y2r, x2r = self.closest_lat_lon(
            np.max(lat) + padding,
            np.max(lon) + padding)
        lon_subset_r, lat_subset_r = np.meshgrid(self.lon[x1r:x2r],
                                                 self.lat[y1r:y2r])
        radar_ds = self.Dataset.isel(lat=slice(y1r, y2r), lon=slice(x1r, x2r))
        if engine == 'interp':
            lower_bound = (self.lat[y1r], self.lon[x1r])
            upper_bound = (self.lat[y2r], self.lon[x2r])

        if output_file is not None:
            nc_fid = nc.Dataset(output_file, 'w', format='NETCDF4')
            if verbose:
                print('Creating coordinate dimensions for file %s' %
                      self.file_name)
            nc_fid.description = (
                "Interpolated Iowa Environmental Mesonet composite '%s' reflectivity"
                % self._composite_type)
            nc_fid.createDimension('time', 0)
            nc_fid.createDimension('south_north', lat.shape[0])
            nc_fid.createDimension('west_east', lat.shape[1])

            # Create time variable
            nc_var = nc_fid.createVariable(
                'time',
                np.int64,
                'time',
            )
            nc_var.setncatts({
                'long_name': 'Time',
                'units': 'seconds since 1970-01-01 00:00'
            })
            nc_fid.variables['time'][:] = self._time_coord

            # Create the latitude and longitude variables
            nc_var = nc_fid.createVariable('latitude', np.float32,
                                           ('south_north', 'west_east'))
            nc_var.setncatts({
                'long_name': 'Latitude',
                'units': 'degrees_north',
                '_FillValue': fill_value
            })
            nc_var = nc_fid.createVariable('longitude', np.float32,
                                           ('south_north', 'west_east'))
            nc_var.setncatts({
                'long_name': 'Longitude',
                'units': 'degrees_east',
                '_FillValue': fill_value
            })

            # Create the reflectivity variable
            nc_var = nc_fid.createVariable(
                'composite_%s' % self._composite_type,
                np.float32, ('time', 'south_north', 'west_east'),
                zlib=True)
            nc_var.setncatts({
                'long_name': 'Base reflectivity',
                'units': 'dBZ',
                'coordinates': 'longitude latitude',
                '_FillValue': fill_value
            })

            # Target array for writing
            target = nc_fid.variables['composite_%s' % self._composite_type]
        else:
            data = np.zeros((len(times), ) + lat.shape, dtype=np.float32)
            ds = xr.Dataset(
                {
                    'composite_%s' % self._composite_type:
                    (['time', 'south_north', 'west_east'], data)
                },
                coords={
                    'latitude': (['south_north', 'west_east'], lat),
                    'longitude': (['south_north', 'west_east'], lon),
                    'time': self.times
                })
            target = ds.variables['composite_%s' % self._composite_type]

        for t, time_val in enumerate(times):
            if verbose:
                print('IEMRadar.interpolate: time %d of %d (%s)' %
                      (t + 1, len(times), time_val))
                load_start = time.time()
            radar_array = radar_ds.sel(time=np.datetime64(
                self.times[t])).variables['composite_n0q'].values
            radar_array[np.isnan(radar_array)] = -30.
            if verbose:
                calc_start = time.time()
                print('  loaded data in %s seconds' %
                      (calc_start - load_start))
            if engine == 'scipy':
                radar_interpolated = griddata(np.vstack(
                    (lat_subset_r.flatten(), lon_subset_r.flatten())).T,
                                              radar_array.flatten(),
                                              np.vstack((lat.flatten(),
                                                         lon.flatten())).T,
                                              method=method)
                radar_interpolated = radar_interpolated.reshape(lat.shape)
            elif engine == 'interp':
                if method == 'linear':
                    spline = LinearSpline(lower_bound, upper_bound,
                                          radar_array.shape, radar_array)
                elif method == 'cubic':
                    spline = CubicSpline(lower_bound, upper_bound,
                                         radar_array.shape, radar_array)
                radar_interpolated = spline(
                    np.vstack(
                        (lat.flatten(), lon.flatten())).T).reshape(lat.shape)
            if verbose:
                print('  interpolated in %s seconds' %
                      (time.time() - calc_start))
            target[t, ...] = radar_interpolated

        if output_file is not None:
            nc_fid.close()
            ds = xr.open_dataset(output_file)
        return ds
Ejemplo n.º 6
0
def lambdameter(wv, data0, hw=0.03, sp=5000, wvinput=True):
    """
    Determine the Lambdameter chord center for a given half width or intensity.
    
    Parameters
    ----------
    wv : 1d ndarray
        A Calibrated wavelength.
    data : nd ndarray
        n (n>=2) dimensional spectral profile data, 
        the last dimension component must be the spectral component,
        and the size is equal to the size of wv.
    wvinput : bool
        There are two cases.
            
        Case wvinput==True
        ------------------
        hw : float
            A half width of the horizontal line segment.
        Returns
        -------
        wc : nd ndarray
            n dimensional array of central wavelength values.
        intc : nd ndarray
            n dimensional array of intensies of the line segment.
        
        Case wvinput==False
        -------------------
        sp : float
            An intensity of the horiznotal segment.
        Returns
        -------
        wc : nd ndarray
            n dimensional array of central wavelength values.
        hwc : nd ndarray
            n dimensional array of half widths of the line segment.
    
    Notes
    -----
    * This function is based on the IDL code BISECTOR_D.PRO
        written by J. Chae.
    
    Example
    -------
    >>> from fisspy.analysis import doppler
    >>> wc, inten = doppler.labdameter(wv,data,0.2)
    
    """

    shape = data0.shape
    nw = shape[-1]
    reshape = shape[:-1]
    if wv.shape[0] != nw:
        raise ValueError(
            'The number of elements of wv and '
            'the number of elements of last axis for data are not equal.')

    na = int(data0.size / nw)
    data = data0.reshape((na, nw))
    s = data.argmin(axis=-1)

    if wvinput and hw == 0.:
        raise ValueError('The half-width value must be greater than 0.')


#        fna=range(na)
#        wtmp=wv[np.array((s-5,s-4,s-3,s-2,s-1,s,s+1,s+2,s+3,s+4,s+5))]
#        mwtmp=np.median(wtmp,axis=0)
#        sp0=np.array([data[i,s[i]-5:s[i]+6] for i in fna])
#        c=np.array([scipy.polyfit(wtmp[:,i]-mwtmp[i],sp0[i,:],2) for i in fna])
#        wc=mwtmp-c[:,1]/(2*c[:,0])
#        p=[scipy.poly1d(c[i,:]) for i in fna]
#        intc=np.array([p[i](wc[i]-mwtmp[i]) for i in fna])
#        wc=wc.reshape(reshape).T
#        intc=intc.reshape(reshape).T
#        return wc, intc

    posi0 = np.arange(na)
    smin = [0, wv[0]]
    smax = [na - 1, wv[-1]]
    order = [na, len(wv)]
    if wvinput:
        interp = LinearSpline(smin, smax, order, data)
        wl = np.array((posi0, wv[s] - hw)).T
        wr = np.array((posi0, wv[s] + hw)).T
        intc = 0.5 * (interp(wl) + interp(wr))
    else:
        intc = np.ones(na) * sp

    wc = np.zeros(na)
    hwc = np.zeros(na)
    ref = 1
    rep = 0
    s0 = s.copy()
    more = data[posi0, s0] > 100

    while ref > 0.00001 and rep < 6:
        sp1 = data - intc[:, None]
        comp = sp1[:, 0:nw - 1] * sp1[:, 1:nw]

        s = comp[more] <= 0.
        nsol = s.sum(axis=1)
        j = nsol // 2
        whl = nsol.cumsum() - nsol + j - 1
        whr = nsol.cumsum() - nsol + j
        whp, whs = np.where(s)
        l = whs[whl]
        r = whs[whr]
        posi = posi0[more]
        wl0 = wv[l] - (wv[l + 1] - wv[l]) / (sp1[posi, l + 1] -
                                             sp1[posi, l]) * sp1[posi, l]
        wr0 = wv[r] - (wv[r + 1] - wv[r]) / (sp1[posi, r + 1] -
                                             sp1[posi, r]) * sp1[posi, r]
        wc[more] = 0.5 * (wl0 + wr0)
        hwc[more] = 0.5 * np.abs(wr0 - wl0)

        if wvinput:
            wl = np.array((posi, wc[more] - hw)).T
            wr = np.array((posi, wc[more] + hw)).T
            intc[more] = 0.5 * (interp(wl) + interp(wr))
            ref0 = np.abs(hwc - hw)
            ref = ref0.max()
            more = (ref0 > 0.00001) * (data[posi0, s0] > 100)
        else:
            ref = 0
        rep += 1

    wc = wc.reshape(reshape)
    if wvinput:
        intc = intc.reshape(reshape)
        return wc, intc
    else:
        hwc = hwc.reshape(reshape)
        return wc, hwc