Пример #1
0
    def load_dataset(
            self, first_date: np.datetime64,
            last_date: np.datetime64) -> pyinterp.backends.xarray.Grid3D:
        """Loads the 3D cube describing the SSH in time and space."""
        if first_date < self.ts["date"][0] or last_date > self.ts["date"][-1]:
            raise IndexError(
                f"period [{first_date}, {last_date}] is out of range: "
                f"[{self.ts['date'][0]}, {self.ts['date'][-1]}]")
        first_date -= self.dt
        last_date += self.dt

        selected = self.ts["path"][:]

        ds = xr.open_mfdataset(selected,
                               concat_dim="time",
                               combine="nested",
                               decode_times=False)
        ds = ds.sel(depth=0)

        x_axis = pyinterp.Axis(ds.variables["lon"][:], is_circle=True)
        y_axis = pyinterp.Axis(ds.variables["lat"][:])
        hours = (ds.variables['time'][:].data *
                 3600000000).astype('timedelta64[us]')
        time = np.datetime64('2000') + hours
        z_axis = pyinterp.TemporalAxis(time)
        var = ds.surf_el[:].T
        return pyinterp.Grid3D(x_axis, y_axis, z_axis, var)
Пример #2
0
def test_bicubic():
    grid = pyinterp.backends.xarray.Grid2D(xr.load_dataset(GRID).mss)

    lon = np.arange(-180, 180, 1) + 1 / 3.0
    lat = np.arange(-90, 90, 1) + 1 / 3.0
    x, y = np.meshgrid(lon, lat, indexing="ij")

    z = grid.bicubic(collections.OrderedDict(lon=x.flatten(), lat=y.flatten()))
    assert isinstance(z, np.ndarray)

    for fitting_model in [
            'linear', 'bicubic', 'polynomial', 'c_spline', 'c_spline_periodic',
            'akima', 'akima_periodic', 'steffen'
    ]:
        other = grid.bicubic(collections.OrderedDict(lon=x.flatten(),
                                                     lat=y.flatten()),
                             fitting_model=fitting_model)
        assert (z - other).mean() != 0

    with pytest.raises(ValueError):
        grid.bicubic(collections.OrderedDict(lon=x.flatten(), lat=y.flatten()),
                     bounds_error=True)

    with pytest.raises(ValueError):
        grid.bicubic(collections.OrderedDict(lon=x.flatten(), lat=y.flatten()),
                     bounds_error=True,
                     boundary="sym")

    x_axis = pyinterp.Axis(np.linspace(-180, 179, 360), is_circle=True)
    y_axis = pyinterp.Axis(np.linspace(-90, 90, 181), is_circle=False)
    z_axis = pyinterp.Axis(np.linspace(0, 10, 10), is_circle=False)
    matrix, _ = np.meshgrid(x_axis[:], y_axis[:])
    grid = pyinterp.Grid2D(x_axis, y_axis, matrix.T)

    assert isinstance(grid, pyinterp.Grid2D)
    with pytest.raises(ValueError):
        pyinterp.bicubic(grid, x.flatten(), y.flatten(), fitting_model='_')
    with pytest.raises(ValueError):
        pyinterp.bicubic(grid, x.flatten(), y.flatten(), boundary='_')
    grid = pyinterp.Grid2D(x_axis.flip(inplace=False), y_axis, matrix.T)
    with pytest.raises(ValueError):
        pyinterp.bicubic(grid, x.flatten(), y.flatten())

    grid = pyinterp.Grid2D(x_axis, y_axis.flip(), matrix.T)
    with pytest.raises(ValueError):
        pyinterp.bicubic(grid, x.flatten(), y.flatten())

    matrix, _, _ = np.meshgrid(x_axis[:], y_axis[:], z_axis[:])
    grid = pyinterp.Grid3D(x_axis, y_axis, z_axis, matrix.transpose(1, 0, 2))
    with pytest.raises(ValueError):
        pyinterp.bicubic(grid, x.flatten(), y.flatten())

    grid = pyinterp.backends.xarray.RegularGridInterpolator(
        xr.load_dataset(GRID).mss)
    assert grid.ndim == 2
    assert isinstance(grid.grid, pyinterp.backends.xarray.Grid2D)
    z = grid(collections.OrderedDict(lon=x.flatten(), lat=y.flatten()),
             method="bicubic",
             bicubic_kwargs=dict(nx=3, ny=3))
    assert isinstance(z, np.ndarray)
Пример #3
0
def bfn_grid_dataset(list_of_file, var2add, var2sub, 
                       lon_min=0., lon_max=360., 
                       lat_min=-90, lat_max=90., 
                       time_min='1900-10-01', time_max='2100-01-01', is_circle=True):
    
    
    ds = xr.open_mfdataset(list_of_file, concat_dim ='time', combine='nested', parallel=True)
    ds = ds.sel(time=slice(time_min, time_max))
    ds = ds.where((ds["lon"]%360. >= lon_min) & (ds["lon"]%360. <= lon_max), drop=True)
    ds = ds.where((ds["lat"] >= lat_min) & (ds["lat"] <= lat_max), drop=True)
    
    x_axis = pyinterp.Axis(ds["lon"][:]%360., is_circle=is_circle)
    y_axis = pyinterp.Axis(ds["lat"][:])
    z_axis = pyinterp.TemporalAxis(ds["time"][:])
    
    for variable_name in var2add:
        try:
            var += ds[variable_name][:]
        except UnboundLocalError:
            var = ds[variable_name][:]
    
    for variable_name in var2sub:
        try:
            var -= ds[variable_name][:] 
        except UnboundLocalError:
            var = ds[variable_name][:]

    # MB clean boundary for file OSE_GULFSTREAM_FPGENN.nc
    #var.values[:, 0:3, :] = np.nan
    #var.values[:, :, 0:3] = np.nan
    
    # ds['time'] = (ds['time'] - np.datetime64('1950-01-01T00:00:00Z')) / np.timedelta64(1, 'D')
    
    var = var.transpose('lon', 'lat', 'time')

    # The undefined values must be set to nan.
    try:
        var[var.mask] = float("nan")
    except AttributeError:
        pass
    
    grid = pyinterp.Grid3D(x_axis, y_axis, z_axis, var.data)
    
    del ds
    
    return x_axis, y_axis, z_axis, grid
Пример #4
0
def dymost_grid_dataset(list_of_file, var2add, var2sub, 
                       lon_min=0., lon_max=360., 
                       lat_min=-90, lat_max=90., 
                       time_min='1900-10-01', time_max='2100-01-01', is_circle=True):
    
    
    ds = xr.open_mfdataset(list_of_file, concat_dim ='time', combine='nested', parallel=True)
    ds = ds.sel(time=slice(time_min, time_max))
    ds = ds.where((ds["lon"] >= lon_min) & (ds["lon"] <= lon_max), drop=True)
    ds = ds.where((ds["lat"] >= lat_min) & (ds["lat"] <= lat_max), drop=True)
    
    # print(ds)
    
    x_axis = pyinterp.Axis(ds["lon"][0, :], is_circle=is_circle)
    y_axis = pyinterp.Axis(ds["lat"][:, 0])
    z_axis = pyinterp.TemporalAxis(ds["time"][:])
    
    for variable_name in var2add:
        try:
            var += ds[variable_name][:]   #ds['Ha'][:]
        except UnboundLocalError:
            var = ds[variable_name][:]
    
    for variable_name in var2sub:
        try:
            var -= ds[variable_name][:] 
        except UnboundLocalError:
            var = ds[variable_name][:]
        
    var = var.transpose('x', 'y', 'time')
    # The undefined values must be set to nan.
    try:
        var[var.mask] = float("nan")
    except AttributeError:
        pass
    
    grid = pyinterp.Grid3D(x_axis, y_axis, z_axis, var.data)
    
    del ds
    
    return x_axis, y_axis, z_axis, grid 
Пример #5
0
def duacs_grid_dataset(list_of_file, variable_name='Grid_0001', 
                       lon_min=0., lon_max=360., 
                       lat_min=-90, lat_max=90., 
                       time_min='1900-10-01', time_max='2100-01-01', is_circle=True):
    
    def preprocess_duacs_maps(ds):
        
        vtime = ds[variable_name].attrs['Date_CNES_JD']        
        ds.coords['time'] = np.datetime64(netCDF4.num2date(vtime, units='days since 1950-01-01'))
        
        if ds[variable_name].units == 'cm':
            ds[variable_name] = ds[variable_name] / 100.
            ds[variable_name].attrs = {'units': 'm'}

        return ds
    
    ds = xr.open_mfdataset(list_of_file, concat_dim ='time', combine='nested', parallel=True, preprocess=preprocess_duacs_maps)
    ds = ds.sel(time=slice(time_min, time_max))
    ds = ds.where((ds["NbLongitudes"] >= lon_min) & (ds["NbLongitudes"] <= lon_max), drop=True)
    ds = ds.where((ds["NbLatitudes"] >= lat_min) & (ds["NbLatitudes"] <= lat_max), drop=True)
    
    x_axis = pyinterp.Axis(ds["NbLongitudes"][:], is_circle=is_circle)
    y_axis = pyinterp.Axis(ds["NbLatitudes"][:])
    z_axis = pyinterp.TemporalAxis(ds["time"][:])
    
    var = ds[variable_name][:].transpose('NbLongitudes', 'NbLatitudes', 'time')
    # The undefined values must be set to nan.
    try:
        var[var.mask] = float("nan")
    except AttributeError:
        pass
    
    grid = pyinterp.Grid3D(x_axis, y_axis, z_axis, var.data)
    
    del ds
    
    return x_axis, y_axis, z_axis, grid
def read_l4_dataset(list_of_file,
                    lon_min=0.,
                    lon_max=360.,
                    lat_min=-90,
                    lat_max=90.,
                    time_min='1900-10-01',
                    time_max='2100-01-01',
                    is_circle=True):

    ds = xr.open_mfdataset(list_of_file,
                           concat_dim='time',
                           combine='nested',
                           parallel=True)
    ds = ds.sel(time=slice(time_min, time_max), drop=True)
    ds = ds.where(
        (ds["lon"] % 360. >= lon_min) & (ds["lon"] % 360. <= lon_max),
        drop=True)
    ds = ds.where((ds["lat"] >= lat_min) & (ds["lat"] <= lat_max), drop=True)

    x_axis = pyinterp.Axis(ds["lon"][:] % 360., is_circle=is_circle)
    y_axis = pyinterp.Axis(ds["lat"][:])
    z_axis = pyinterp.TemporalAxis(ds["time"][:])

    var = ds['ssh'][:]
    var = var.transpose('lon', 'lat', 'time')

    # The undefined values must be set to nan.
    try:
        var[var.mask] = float("nan")
    except AttributeError:
        pass

    grid = pyinterp.Grid3D(x_axis, y_axis, z_axis, var.data)

    del ds

    return x_axis, y_axis, z_axis, grid
Пример #7
0
def oi_regrid(ds_source, ds_target):

    logging.info('     Regridding...')

    # Define source grid
    x_source_axis = pyinterp.Axis(ds_source["lon"][:], is_circle=False)
    y_source_axis = pyinterp.Axis(ds_source["lat"][:])
    z_source_axis = pyinterp.TemporalAxis(ds_source["time"][:])
    ssh_source = ds_source["gssh"][:].T
    grid_source = pyinterp.Grid3D(x_source_axis, y_source_axis, z_source_axis,
                                  ssh_source.data)

    # Define target grid
    mx_target, my_target, mz_target = numpy.meshgrid(
        ds_target['lon'].values,
        ds_target['lat'].values,
        z_source_axis.safe_cast(ds_target['time'].values),
        indexing="ij")
    # Spatio-temporal Interpolation
    ssh_interp = pyinterp.trivariate(grid_source,
                                     mx_target.flatten(),
                                     my_target.flatten(),
                                     mz_target.flatten(),
                                     bounds_error=True).reshape(
                                         mx_target.shape).T

    # Save to dataset
    ds_ssh_interp = xr.Dataset(
        {'sossheig': (('time', 'lat', 'lon'), ssh_interp)},
        coords={
            'time': ds_target['time'].values,
            'lon': ds_target['lon'].values,
            'lat': ds_target['lat'].values,
        })

    return ds_ssh_interp
Пример #8
0
    def load_dataset(
            self, first_date: np.datetime64,
            last_date: np.datetime64) -> pyinterp.backends.xarray.Grid3D:
        """Loads the 3D cube describing the SSH in time and space."""
        if first_date < self.ts["date"][0] or last_date > self.ts["date"][-1]:
            raise IndexError(
                f"period [{first_date}, {last_date}] is out of range: "
                f"[{self.ts['date'][0]}, {self.ts['date'][-1]}]")
        first_date -= self.dt
        last_date += self.dt

        selected = self.ts["path"][(self.ts["date"] >= first_date)
                                   & (self.ts["date"] < last_date)]

        ds = xr.open_mfdataset(selected,
                               concat_dim="time",
                               combine="nested",
                               decode_times=True)

        x_axis = pyinterp.Axis(ds.variables["longitude"][:], is_circle=True)
        y_axis = pyinterp.Axis(ds.variables["latitude"][:])
        z_axis = pyinterp.TemporalAxis(ds.time)
        var = ds.wlv[:].T
        return pyinterp.Grid3D(x_axis, y_axis, z_axis, var)
Пример #9
0
    def interpolate(self, lon: np.ndarray, lat: np.ndarray,
                    dates: np.ndarray) -> np.ndarray:
        """Interpolate the SSH to the required coordinates."""
        ds = self._select_ds(
            dates.min(),  # type: ignore
            dates.max())  # type: ignore

        assert np.all(np.diff(ds.ocean_time.values) == self._dt)
        assert np.all(np.diff(ds.lon_rho.values, axis=0) < 1e-10)
        assert np.all(np.diff(ds.lat_rho.values, axis=1) < 1e-10)

        t_axis = pyinterp.TemporalAxis(ds.ocean_time.values)

        grid3d = pyinterp.Grid3D(
            pyinterp.Axis(ds.lon_rho.values[0, :], is_circle=True),
            pyinterp.Axis(ds.lat_rho.values[:, 0]), t_axis,
            ds[self.ssh].values.T)

        ssh = pyinterp.trivariate(grid3d,
                                  lon.ravel(),
                                  lat.ravel(),
                                  t_axis.safe_cast(dates.ravel()),
                                  num_threads=1).reshape(lon.shape)
        return ssh
Пример #10
0
# tensor data so that it is properly stored in memory for pyinterp.

#%%
#   * The shape of the tensor must be (len(x_axis), len(y_axis), len(t_axis))
tcw = tcw.T
#%%
#   * The undefined values must be set to nan.
tcw[tcw.mask] = float("nan")

#%%
# Now we can build the object handling the regular 3-dimensional grid.
#
# .. note::
#   Grid data are not copied, the Grid3D class just keeps a reference on the
#   handled array. Axis data are copied for non-uniform axes, and only examined
#   for regular axes.
grid_3d = pyinterp.Grid3D(x_axis, y_axis, t_axis, tcw)
grid_3d

#%%
# xarray backend
# ##############
#
# The construction of these objects manipulating the :py:class:`regular grids
# <pyinterp.backends.xarray.RegularGridInterpolator>` can be done more easily
# using the `xarray <http://xarray.pydata.org/>`_ library and `CF
# <https://cfconventions.org/>`_ convention usually found in NetCDF files.
interpolator = pyinterp.backends.xarray.RegularGridInterpolator(
    xarray.open_dataset(TCW).tcw)
interpolator.grid