Module pycascadia.grid
Grid contains a grid of data in xarray format
Expand source code
"""Grid contains a grid of data in xarray format"""
import os
import pandas
from pygmt import grdcut
from pycascadia.loaders import load_source, extract_region
from pycascadia.utility import region_to_str, xr_to_xyz, filter_nodata
class Grid:
"""Grid contains a grid of data in xarray format and optionally as xyz points in pandas dataframe format.
Grids are intended to be initially loaded from file and can be further manipulated in the following ways:
- resampling to a different grid spacing
- cropping to a given region
- conversion to a list of xyz datapoints.
- saved to file
Coordinates will be labelled `x` and `y`, and (depth/elevation) values will be labelled `z`.
The internal grid may also be manipulated and is exposed through Grid.grid or Grid.xyz (if the grid has already been converted).
"""
def __init__(self, fname: str, convert_to_xyz: bool = False) -> None:
"""
Constructor
Args:
fname: Input grid filename.
convert_to_xyz: Whether the grid should be converted to xyz points.
"""
self.load(fname)
if convert_to_xyz:
self.xyz = self.as_xyz()
def load(self, fname: str) -> None:
"""
Loads data from file. See loaders for supported file formats.
Args:
fname: Input grid filename.
"""
self.grid, self.region, self.spacing = load_source(fname)
def crop(self, region: list) -> None:
"""
Crops grid using grdcut.
Args:
region: Bounding box of region to crop to (in format [xmin, xmax, ymin, ymax]).
"""
if region == self.region:
return
self.grid = grdcut(self.grid, region=region)
self.region = extract_region(self.grid)
def resample(self, spacing: float) -> None:
"""
Resamples the loaded grid using gdal's grdsample.
Args:
spacing: Grid spacing of resampled grid.
"""
if spacing == self.spacing:
return
print(f"Resampling from {self.spacing} to {spacing}")
in_fname = "original.nc"
self.save_grid(in_fname)
out_fname = "resampled.nc"
os.system(
f"gmt grdsample {in_fname} -G{out_fname} -R{region_to_str(self.region)} -I{spacing} -V"
)
self.load(out_fname)
os.remove(in_fname)
os.remove(out_fname)
def as_xyz(self) -> pandas.DataFrame:
"""
Returns pandas dataframe representation.
"""
xyz_data = xr_to_xyz(self.grid)
if hasattr(self.grid, "nodatavals"):
filter_nodata(xyz_data, self.grid.nodatavals)
return xyz_data
def plot(self, ax=None) -> None:
"""
Plots data (useful for testing).
Args:
ax: Axis used for plotting (will be created if not supplied).
"""
self.grid.plot(ax=ax)
def save_grid(self, fname: str) -> None:
"""
Saves grid to netcdf file.
Args:
fname: Output filename.
"""
self.grid.to_netcdf(fname)
Classes
class Grid (fname: str, convert_to_xyz: bool = False)
-
Grid contains a grid of data in xarray format and optionally as xyz points in pandas dataframe format.
Grids are intended to be initially loaded from file and can be further manipulated in the following ways:
- resampling to a different grid spacing
- cropping to a given region
- conversion to a list of xyz datapoints.
- saved to file
Coordinates will be labelled
x
andy
, and (depth/elevation) values will be labelledz
.The internal grid may also be manipulated and is exposed through Grid.grid or Grid.xyz (if the grid has already been converted).
Constructor
Args
fname
- Input grid filename.
convert_to_xyz
- Whether the grid should be converted to xyz points.
Expand source code
class Grid: """Grid contains a grid of data in xarray format and optionally as xyz points in pandas dataframe format. Grids are intended to be initially loaded from file and can be further manipulated in the following ways: - resampling to a different grid spacing - cropping to a given region - conversion to a list of xyz datapoints. - saved to file Coordinates will be labelled `x` and `y`, and (depth/elevation) values will be labelled `z`. The internal grid may also be manipulated and is exposed through Grid.grid or Grid.xyz (if the grid has already been converted). """ def __init__(self, fname: str, convert_to_xyz: bool = False) -> None: """ Constructor Args: fname: Input grid filename. convert_to_xyz: Whether the grid should be converted to xyz points. """ self.load(fname) if convert_to_xyz: self.xyz = self.as_xyz() def load(self, fname: str) -> None: """ Loads data from file. See loaders for supported file formats. Args: fname: Input grid filename. """ self.grid, self.region, self.spacing = load_source(fname) def crop(self, region: list) -> None: """ Crops grid using grdcut. Args: region: Bounding box of region to crop to (in format [xmin, xmax, ymin, ymax]). """ if region == self.region: return self.grid = grdcut(self.grid, region=region) self.region = extract_region(self.grid) def resample(self, spacing: float) -> None: """ Resamples the loaded grid using gdal's grdsample. Args: spacing: Grid spacing of resampled grid. """ if spacing == self.spacing: return print(f"Resampling from {self.spacing} to {spacing}") in_fname = "original.nc" self.save_grid(in_fname) out_fname = "resampled.nc" os.system( f"gmt grdsample {in_fname} -G{out_fname} -R{region_to_str(self.region)} -I{spacing} -V" ) self.load(out_fname) os.remove(in_fname) os.remove(out_fname) def as_xyz(self) -> pandas.DataFrame: """ Returns pandas dataframe representation. """ xyz_data = xr_to_xyz(self.grid) if hasattr(self.grid, "nodatavals"): filter_nodata(xyz_data, self.grid.nodatavals) return xyz_data def plot(self, ax=None) -> None: """ Plots data (useful for testing). Args: ax: Axis used for plotting (will be created if not supplied). """ self.grid.plot(ax=ax) def save_grid(self, fname: str) -> None: """ Saves grid to netcdf file. Args: fname: Output filename. """ self.grid.to_netcdf(fname)
Methods
def as_xyz(self) -> pandas.core.frame.DataFrame
-
Returns pandas dataframe representation.
Expand source code
def as_xyz(self) -> pandas.DataFrame: """ Returns pandas dataframe representation. """ xyz_data = xr_to_xyz(self.grid) if hasattr(self.grid, "nodatavals"): filter_nodata(xyz_data, self.grid.nodatavals) return xyz_data
def crop(self, region: list) -> NoneType
-
Crops grid using grdcut.
Args
region
- Bounding box of region to crop to (in format [xmin, xmax, ymin, ymax]).
Expand source code
def crop(self, region: list) -> None: """ Crops grid using grdcut. Args: region: Bounding box of region to crop to (in format [xmin, xmax, ymin, ymax]). """ if region == self.region: return self.grid = grdcut(self.grid, region=region) self.region = extract_region(self.grid)
def load(self, fname: str) -> NoneType
-
Loads data from file. See loaders for supported file formats.
Args
fname
- Input grid filename.
Expand source code
def load(self, fname: str) -> None: """ Loads data from file. See loaders for supported file formats. Args: fname: Input grid filename. """ self.grid, self.region, self.spacing = load_source(fname)
def plot(self, ax=None) -> NoneType
-
Plots data (useful for testing).
Args
ax
- Axis used for plotting (will be created if not supplied).
Expand source code
def plot(self, ax=None) -> None: """ Plots data (useful for testing). Args: ax: Axis used for plotting (will be created if not supplied). """ self.grid.plot(ax=ax)
def resample(self, spacing: float) -> NoneType
-
Resamples the loaded grid using gdal's grdsample.
Args
spacing
- Grid spacing of resampled grid.
Expand source code
def resample(self, spacing: float) -> None: """ Resamples the loaded grid using gdal's grdsample. Args: spacing: Grid spacing of resampled grid. """ if spacing == self.spacing: return print(f"Resampling from {self.spacing} to {spacing}") in_fname = "original.nc" self.save_grid(in_fname) out_fname = "resampled.nc" os.system( f"gmt grdsample {in_fname} -G{out_fname} -R{region_to_str(self.region)} -I{spacing} -V" ) self.load(out_fname) os.remove(in_fname) os.remove(out_fname)
def save_grid(self, fname: str) -> NoneType
-
Saves grid to netcdf file.
Args
fname
- Output filename.
Expand source code
def save_grid(self, fname: str) -> None: """ Saves grid to netcdf file. Args: fname: Output filename. """ self.grid.to_netcdf(fname)