Beispiel #1
0
def test_init():
    build_rtree(dtype=np.float32)
    build_rtree(dtype=np.float64)

    with pytest.raises(ValueError):
        build_rtree(np.int8)

    with pytest.raises(ValueError):
        mesh = pyinterp.RTree()
        mesh.__setstate__((1, ))

    with pytest.raises(ValueError):
        pyinterp.RTree(ndims=1)
Beispiel #2
0
    def _spatial_interp(z_model: da.Array, x_model: da.Array,
                        y_model: da.Array, x_sat: np.ndarray,
                        y_sat: np.ndarray) -> np.ndarray:
        """Spatial interpolation of the SSH on the selected maps.

        Args:
            z_model (numpy.ndarray): model SSH
            x_model (numpy.ndarray): model longitude
            y_model (numpy.ndarray): model latitude
            x_sat (numpy.ndarray): satellite longitude
            y_sat (numpy.ndarray): satellite latitude

        Returns:
            numpy.ndarray: interpolated SSH in space.
        """
        mesh = pyinterp.RTree()
        mesh.packing(
            np.vstack((x_model.compute(), y_model.compute())).T,
            z_model.compute())

        z, _ = mesh.radial_basis_function(
            np.vstack((x_sat, y_sat)).T.astype("float32"),
            within=True,
            k=11,
            rbf="thin_plate",
            num_threads=1,
        )
        return z.astype("float32")
Beispiel #3
0
def load_data():
    ds = xr.load_dataset(GRID)
    z = ds.mss.T
    x, y = np.meshgrid(ds.lon.values, ds.lat.values, indexing='ij')
    mesh = pyinterp.RTree()
    mesh.packing(np.vstack((x.flatten(), y.flatten())).T, z.values.flatten())
    return mesh
Beispiel #4
0
def build_rtree(dtype):
    lon = np.arange(-180, 180, 10, dtype=dtype)
    lat = np.arange(-90, 90, 10, dtype=dtype)
    lon, lat = np.meshgrid(lon, lat)
    data = lon * 0
    mesh = pyinterp.RTree(dtype=dtype)
    assert isinstance(mesh, pyinterp.RTree)
    assert len(mesh) == 0
    assert not bool(mesh)
    mesh.packing(np.vstack((lon.flatten(), lat.flatten())).T, data.flatten())
    assert len(mesh) == len(lon.flatten())
    assert bool(mesh)
    (x_min, y_min, z_min), (x_max, y_max, z_max) = mesh.bounds()
    assert x_min == -180
    assert y_min == -90.0
    assert x_max == 180.0
    assert y_max == 80
    assert 0 == pytest.approx(z_min, abs=1e-6 if dtype == np.float64 else 0.5)
    assert 0 == pytest.approx(z_max, abs=1e-6 if dtype == np.float64 else 0.5)
    mesh.clear()
    assert len(mesh) == 0
    assert not bool(mesh)
    mesh.insert(np.vstack((lon.flatten(), lat.flatten())).T, data.flatten())
    assert len(mesh) == len(lon.flatten())
    assert isinstance(pickle.loads(pickle.dumps(mesh)), pyinterp.RTree)
 def init(self, dtype):
     lon = np.arange(-180, 180, 10, dtype=dtype)
     lat = np.arange(-90, 90, 10, dtype=dtype)
     lon, lat = np.meshgrid(lon, lat)
     data = lon * 0
     mesh = pyinterp.RTree(dtype=dtype)
     self.assertIsInstance(mesh, pyinterp.RTree)
     self.assertEqual(len(mesh), 0)
     self.assertFalse(bool(mesh))
     mesh.packing(
         np.vstack((lon.flatten(), lat.flatten())).T, data.flatten())
     self.assertEqual(len(mesh), len(lon.flatten()))
     self.assertTrue(bool(mesh))
     (x_min, y_min, z_min), (x_max, y_max, z_max) = mesh.bounds()
     self.assertEqual(x_min, -180)
     self.assertEqual(y_min, -90.0)
     self.assertEqual(x_max, 180.0)
     self.assertEqual(y_max, 80)
     self.assertAlmostEqual(z_min,
                            0,
                            delta=1e-6 if dtype == np.float64 else 0.5)
     self.assertAlmostEqual(z_max,
                            0,
                            delta=1e-6 if dtype == np.float64 else 0.5)
     mesh.clear()
     self.assertEqual(len(mesh), 0)
     self.assertFalse(bool(mesh))
     mesh.insert(
         np.vstack((lon.flatten(), lat.flatten())).T, data.flatten())
     self.assertEqual(len(mesh), len(lon.flatten()))
     self.assertIsInstance(pickle.loads(pickle.dumps(mesh)), pyinterp.RTree)
Beispiel #6
0
    def _spatial_interp(
        z_model: da.Array,
        x_model: da.Array,
        y_model: da.Array,
        x_sat: np.ndarray,
        y_sat: np.ndarray,
    ) -> np.ndarray:
        """Spatial interpolation of SSH from NATL60 model.

        Args:
            z_model (da.Array): SSH model
            x_model (da.Array): longitude model
            y_model (da.Array): latitude model
            x_sat (np.ndarray): longitude satellite
            y_sat (np.ndarray): latitude satellite

        Returns:
            np.ndarray: SSH satellite
        """
        mesh = pyinterp.RTree(dtype=np.dtype("float32"))

        start_time = time.time()

        ssh = z_model.compute()
        defined = ~np.isnan(ssh)
        ssh = ssh[defined]

        lon = x_model[defined].compute()
        lat = y_model[defined].compute()

        # The tree is built and the interpolation is calculated
        coordinates = np.vstack((lon, lat)).T
        del lon, lat

        LOGGER.debug(
            "loaded %d MB in %.2fs",
            (coordinates.nbytes + ssh.nbytes) // 1024**2,
            time.time() - start_time,
        )

        start_time = time.time()
        mesh.packing(coordinates, ssh)
        del coordinates, ssh
        LOGGER.debug("mesh build in %.2fs", time.time() - start_time)

        start_time = time.time()
        z_sat, _ = mesh.radial_basis_function(
            np.vstack((x_sat, y_sat)).T.astype("float32"),
            within=True,
            k=11,
            radius=8000,
            rbf="thin_plate",
            num_threads=1,
        )
        LOGGER.debug("interpolation done in %.2fs", time.time() - start_time)
        del mesh
        return z_sat.astype("float32")
Beispiel #7
0
def _spatial_interp(z_model: da.array, x_model: da.array, y_model: da.array,
                    x_sat: np.ndarray, y_sat: np.ndarray):
    mesh = pyinterp.RTree(dtype="float32")
    x, y, z = (), (), ()

    start_time = time.time()

    for face in range(13):
        x_face = x_model[face, :].compute()
        y_face = y_model[face, :].compute()

        # We test if the face covers the satellite positions.
        ix0, ix1 = x_face.min(), x_face.max()
        iy0, iy1 = y_face.min(), y_face.max()

        box = pyinterp.geodetic.Box2D(pyinterp.geodetic.Point2D(ix0, iy0),
                                      pyinterp.geodetic.Point2D(ix1, iy1))
        mask = box.covered_by(x_sat, y_sat)
        if not np.any(mask == 1):
            continue
        del box, mask

        # The undefined values are filtered
        z_face = z_model[face, :].compute()
        defined = ~np.isnan(z_face)
        x += (x_face[defined].flatten(), )
        y += (y_face[defined].flatten(), )
        z += (z_face[defined].flatten(), )

    # The tree is built and the interpolation is calculated
    x = np.concatenate(x)
    y = np.concatenate(y)
    coordinates = np.vstack((x, y)).T
    del x, y

    z = np.concatenate(z)
    LOGGER.debug("loaded %d MB in %.2fs",
                 (coordinates.nbytes + z.nbytes) // 1024**2,
                 time.time() - start_time)
    start_time = time.time()
    mesh.packing(coordinates, z)
    LOGGER.debug("mesh build in %.2fs", time.time() - start_time)

    del coordinates, z

    start_time = time.time()
    z, _ = mesh.radial_basis_function(np.vstack(
        (x_sat, y_sat)).T.astype("float32"),
                                      within=True,
                                      k=11,
                                      radius=55000,
                                      rbf="thin_plate",
                                      num_threads=1)
    LOGGER.debug("interpolation done in %.2fs", time.time() - start_time)
    del mesh
    return z.astype("float32")
    def test_init(self):
        self.init(dtype=np.float32)
        self.init(dtype=np.float64)

        with self.assertRaises(ValueError):
            self.init(np.int8)

        with self.assertRaises(ValueError):
            mesh = pyinterp.RTree()
            mesh.__setstate__((1, ))
Beispiel #9
0
def hinterp(ds, var, coords=None):
    """ This is needs proper documentation:
    https://numpydoc.readthedocs.io/en/latest/format.html
    """
    import pyinterp
    #create Tree object
    mesh = pyinterp.RTree()

    #L = ds.dims['x_r'] # NL: assigned but not used
    #M = ds.dims['y_r']
    #N = ds.dims['s_r']
    z_r = get_z(ds)
    #coords = np.array([coords])

    # where I know the values
    z_r = get_z(ds)
    vslice = []
    #lon_r = np.tile(ds.lon_r.values,ds.dims['s_r']).reshape(ds.dims['s_r'], ds.dims['y_r'], ds.dims['x_r'])
    lon_r = (np.tile(ds.lon_r.values,
                     (ds.dims['s_r'], 1, 1)).reshape(ds.dims['s_r'],
                                                     ds.dims['y_r'],
                                                     ds.dims['x_r']))
    lat_r = (np.tile(ds.lat_r.values,
                     (ds.dims['s_r'], 1, 1)).reshape(ds.dims['s_r'],
                                                     ds.dims['y_r'],
                                                     ds.dims['x_r']))
    z_r = get_z(ds)
    mesh.packing(
        np.vstack((lon_r.flatten(), lat_r.flatten(), z_r.values.flatten())).T,
        var.values.flatten())

    # where I want the values
    zcoord = np.zeros_like(ds.lon_r.values)
    zcoord[:] = coords
    vslice, neighbors = mesh.inverse_distance_weighting(
        np.vstack((ds.lon_r.values.flatten(), ds.lat_r.values.flatten(),
                   zcoord.flatten())).T,
        within=True)  # Extrapolation is forbidden)

    # The undefined values must be set to nan.
    print(ds.mask_rho.values)
    #mask=np.where(ds.mask_rho.values==1.,) # NL: assigned but not used
    vslice[int(ds.mask_rho.values)] = float("nan")

    vslice = xr.DataArray(np.asarray(
        vslice.reshape(ds.dims['y_r'], ds.dims['x_r'])),
                          dims=('x_r', 'y_r'))
    yslice = ds.lat_r
    xslice = ds.lon_r

    return [xslice, yslice, vslice]
Beispiel #10
0
def _spatial_interp_2D(z_model: da.array, x_model: da.array, y_model: da.array,
                       x_sat: np.ndarray, y_sat: np.ndarray):
    mesh = pyinterp.RTree(dtype="float32")
    x, y, z = (), (), ()

    start_time = time.time()
    x_face = x_model.compute()
    y_face = y_model.compute()
    # We test if the face covers the satellite positions.
    ix0, ix1 = x_face.min().values, x_face.max().values
    iy0, iy1 = y_face.min().values, y_face.max().values

    box = pyinterp.geodetic.Box2D(pyinterp.geodetic.Point2D(ix0, iy0),
                                  pyinterp.geodetic.Point2D(ix1, iy1))
    mask = box.covered_by(x_sat, y_sat)
    if not np.any(mask == 1):
        print("no covers")
    del box, mask

    # The undefined values are filtered
    z_face = z_model.compute()
    defined = ~np.isnan(z_face)

    # The tree is built and the interpolation is calculated
    x = x_face.values[defined]
    y = y_face.values[defined]

    coordinates = np.vstack((x, y)).T
    del x, y

    z = z_face.values[defined]
    LOGGER.info("loaded %d MB in %.2fs",
                (coordinates.nbytes + z.nbytes) // 1024**2,
                time.time() - start_time)
    start_time = time.time()
    mesh.packing(coordinates, z)
    LOGGER.info("mesh build in %.2fs", time.time() - start_time)

    del coordinates, z

    start_time = time.time()
    z, _ = mesh.inverse_distance_weighting(np.vstack(
        (x_sat, y_sat)).T.astype("float32"),
                                           within=True,
                                           k=11,
                                           radius=8000,
                                           num_threads=1)
    LOGGER.debug("interpolation done in %.2fs", time.time() - start_time)
    del mesh
    return z.astype("float32")
Beispiel #11
0
    def _rtree(ds: xr.Dataset, index: np.uint64) -> pyinterp.RTree:
        """Constructs the interpolator."""
        ssh = ds.variables["elev"].isel(dict(time=index)).values

        # Filter out NaN values.
        mask = ~np.isnan(ssh)
        lon = ds.variables["SCHISM_hgrid_node_x"].values[mask]
        lat = ds.variables["SCHISM_hgrid_node_y"].values[mask]
        ssh = ssh[mask]

        coordinates = np.vstack((lon, lat)).T

        mesh = pyinterp.RTree(dtype=np.dtype("float32"))
        mesh.packing(coordinates, ssh)
        return mesh
Beispiel #12
0
def interp_low(da, df, **kwargs):
    """ low level part that interpolate the field
    
    https://pangeo-pyinterp.readthedocs.io/en/latest/generated/pyinterp.RTree.inverse_distance_weighting.html#pyinterp.RTree.inverse_distance_weighting
    """
    mesh = pyinterp.RTree()
    mesh.packing(
        np.vstack((da.XC.values.flatten(), da.YC.values.flatten())).T,
        da.values.flatten(),
    )

    dkwargs = dict(within=True, radius=None, k=8, num_threads=0)
    # num_threads=0 uses all cpus, set to 1 if you don"t want this
    dkwargs.update(**kwargs)
    idw_eta, neighbors = mesh.inverse_distance_weighting(
        np.vstack((df["lon"], df["lat"])).T, **dkwargs)
    df_out = df["trajectory"].to_frame()
    df_out.loc[:, da.name + "_interpolated"] = idw_eta[:]
    return df_out
Beispiel #13
0
The interpolation of this object is based on a :py:class:`R*Tree
<pyinterp.RTree>` structure. To begin with, we start by building this
object. By default, this object considers the WGS-84 geodetic coordinate system.
But you can define another one using the class :py:class:`System
<pyinterp.geodetic.System>`.
"""
import numpy
import cartopy.crs
import cartopy.mpl.ticker
import intake
import matplotlib.pyplot

#%%
import pyinterp

mesh = pyinterp.RTree()

#%%
# Then, we will insert points into the tree. The class allows you to add points
# using two algorithms. The first one, called :py:meth:`packing
# <pyinterp.RTree.packing>`, will enable you to enter the values in the tree at
# once. This mechanism is the recommended solution to create an optimized
# in-memory structure, both in terms of construction time and queries. When this
# is not possible, you can insert new information into the tree as you go along
# using the :py:meth:`insert <pyinterp.RTree.insert>` method.
cat_url = "https://raw.githubusercontent.com/pangeo-data/pangeo-datastore" \
    "/master/intake-catalogs/ocean/llc4320.yaml"
cat = intake.open_catalog(cat_url)

#%%
# Grid subsampling (orginal volume is too huge for this example)