From 37d27c5c2dff1fadd1572a9c8fc0c5e4c901fb01 Mon Sep 17 00:00:00 2001 From: Meghan Jones Date: Wed, 11 Aug 2021 13:46:39 -0400 Subject: [PATCH 01/13] Create process_output_grid function in pygmt/io.py --- pygmt/io.py | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 pygmt/io.py diff --git a/pygmt/io.py b/pygmt/io.py new file mode 100644 index 00000000000..873e4b0ce27 --- /dev/null +++ b/pygmt/io.py @@ -0,0 +1,36 @@ +""" +PyGMT i/o utilities. +""" +import xarray as xr + + +def process_output_grid(grid_name, tmpfile_name): + """ + Processes the output from the GMT API to return an xarray.DataArray if + ``grid_name`` matches ``tmpfile_name`` and return None if it does not. + + Parameters + ---------- + grid_name : str + The name of the output netCDF file with extension .nc to store the grid + in. + tmpfile_name : str + The name attribute from a GMTTempFile instance. + + Returns + ------- + ret: xarray.DataArray or None + Return type depends on whether the ``outgrid`` parameter is set: + + - :class:`xarray.DataArray` if ``outgrid`` is not set + - None if ``outgrid`` is set (grid output will be stored in file set by + ``outgrid``) + """ + if grid_name == tmpfile_name: # Implies user did not set outgrid, return DataArray + with xr.open_dataarray(grid_name) as dataarray: + result = dataarray.load() + _ = result.gmt # load GMTDataArray accessor information + else: + result = None # Implies user set an outgrid, return None + + return result From 2214237c333827021215b6231d95b453a72b72a1 Mon Sep 17 00:00:00 2001 From: Meghan Jones Date: Wed, 11 Aug 2021 13:48:00 -0400 Subject: [PATCH 02/13] Use process_output_grid() to return dataarray or None --- pygmt/src/grdclip.py | 11 ++--------- pygmt/src/grdcut.py | 11 ++--------- pygmt/src/grdfill.py | 11 ++--------- pygmt/src/grdfilter.py | 11 ++--------- pygmt/src/grdgradient.py | 11 ++--------- pygmt/src/grdlandmask.py | 11 ++--------- pygmt/src/grdsample.py | 11 ++--------- pygmt/src/surface.py | 11 ++--------- pygmt/src/xyz2grd.py | 11 ++--------- 9 files changed, 18 insertions(+), 81 deletions(-) diff --git a/pygmt/src/grdclip.py b/pygmt/src/grdclip.py index bead6dcae74..20ac69b8da1 100644 --- a/pygmt/src/grdclip.py +++ b/pygmt/src/grdclip.py @@ -2,7 +2,6 @@ grdclip - Change the range and extremes of grid values. """ -import xarray as xr from pygmt.clib import Session from pygmt.helpers import ( GMTTempFile, @@ -11,6 +10,7 @@ kwargs_to_strings, use_alias, ) +from pygmt.io import process_output_grid @fmt_docstring @@ -88,11 +88,4 @@ def grdclip(grid, **kwargs): arg_str = " ".join([infile, build_arg_string(kwargs)]) lib.call_module("grdclip", arg_str) - if outgrid == tmpfile.name: # if user did not set outgrid, return DataArray - with xr.open_dataarray(outgrid) as dataarray: - result = dataarray.load() - _ = result.gmt # load GMTDataArray accessor information - else: - result = None # if user sets an outgrid, return None - - return result + return process_output_grid(outgrid, tmpfile.name) diff --git a/pygmt/src/grdcut.py b/pygmt/src/grdcut.py index 353b82bc3a5..d47620ee428 100644 --- a/pygmt/src/grdcut.py +++ b/pygmt/src/grdcut.py @@ -2,7 +2,6 @@ grdcut - Extract subregion from a grid. """ -import xarray as xr from pygmt.clib import Session from pygmt.helpers import ( GMTTempFile, @@ -11,6 +10,7 @@ kwargs_to_strings, use_alias, ) +from pygmt.io import process_output_grid @fmt_docstring @@ -98,11 +98,4 @@ def grdcut(grid, **kwargs): arg_str = " ".join([infile, build_arg_string(kwargs)]) lib.call_module("grdcut", arg_str) - if outgrid == tmpfile.name: # if user did not set outgrid, return DataArray - with xr.open_dataarray(outgrid) as dataarray: - result = dataarray.load() - _ = result.gmt # load GMTDataArray accessor information - else: - result = None # if user sets an outgrid, return None - - return result + return process_output_grid(outgrid, tmpfile.name) diff --git a/pygmt/src/grdfill.py b/pygmt/src/grdfill.py index 6b553b964fe..cdaa0493eed 100644 --- a/pygmt/src/grdfill.py +++ b/pygmt/src/grdfill.py @@ -2,7 +2,6 @@ grdfill - Fill blank areas from a grid. """ -import xarray as xr from pygmt.clib import Session from pygmt.exceptions import GMTInvalidInput from pygmt.helpers import ( @@ -12,6 +11,7 @@ kwargs_to_strings, use_alias, ) +from pygmt.io import process_output_grid @fmt_docstring @@ -75,11 +75,4 @@ def grdfill(grid, **kwargs): arg_str = " ".join([infile, build_arg_string(kwargs)]) lib.call_module("grdfill", arg_str) - if outgrid == tmpfile.name: # if user did not set outgrid, return DataArray - with xr.open_dataarray(outgrid) as dataarray: - result = dataarray.load() - _ = result.gmt # load GMTDataArray accessor information - else: - result = None # if user sets an outgrid, return None - - return result + return process_output_grid(outgrid, tmpfile.name) diff --git a/pygmt/src/grdfilter.py b/pygmt/src/grdfilter.py index 46debc21534..1a13d717f3d 100644 --- a/pygmt/src/grdfilter.py +++ b/pygmt/src/grdfilter.py @@ -2,7 +2,6 @@ grdfilter - Filter a grid in the space (or time) domain. """ -import xarray as xr from pygmt.clib import Session from pygmt.helpers import ( GMTTempFile, @@ -11,6 +10,7 @@ kwargs_to_strings, use_alias, ) +from pygmt.io import process_output_grid @fmt_docstring @@ -151,11 +151,4 @@ def grdfilter(grid, **kwargs): arg_str = " ".join([infile, build_arg_string(kwargs)]) lib.call_module("grdfilter", arg_str) - if outgrid == tmpfile.name: # if user did not set outgrid, return DataArray - with xr.open_dataarray(outgrid) as dataarray: - result = dataarray.load() - _ = result.gmt # load GMTDataArray accessor information - else: - result = None # if user sets an outgrid, return None - - return result + return process_output_grid(outgrid, tmpfile.name) diff --git a/pygmt/src/grdgradient.py b/pygmt/src/grdgradient.py index edbebcb402e..9eda09b2572 100644 --- a/pygmt/src/grdgradient.py +++ b/pygmt/src/grdgradient.py @@ -2,7 +2,6 @@ grdgradient - Compute directional gradients from a grid. """ -import xarray as xr from pygmt.clib import Session from pygmt.exceptions import GMTInvalidInput from pygmt.helpers import ( @@ -13,6 +12,7 @@ kwargs_to_strings, use_alias, ) +from pygmt.io import process_output_grid @fmt_docstring @@ -117,11 +117,4 @@ def grdgradient(grid, **kwargs): arg_str = " ".join([infile, build_arg_string(kwargs)]) lib.call_module("grdgradient", arg_str) - if outgrid == tmpfile.name: # if user did not set outgrid, return DataArray - with xr.open_dataarray(outgrid) as dataarray: - result = dataarray.load() - _ = result.gmt # load GMTDataArray accessor information - else: - result = None # if user sets an outgrid, return None - - return result + return process_output_grid(outgrid, tmpfile.name) diff --git a/pygmt/src/grdlandmask.py b/pygmt/src/grdlandmask.py index 1da363dc2fe..ffc2320b179 100644 --- a/pygmt/src/grdlandmask.py +++ b/pygmt/src/grdlandmask.py @@ -2,7 +2,6 @@ grdlandmask - Create a "wet-dry" mask grid from shoreline data base """ -import xarray as xr from pygmt.clib import Session from pygmt.exceptions import GMTInvalidInput from pygmt.helpers import ( @@ -12,6 +11,7 @@ kwargs_to_strings, use_alias, ) +from pygmt.io import process_output_grid @fmt_docstring @@ -68,11 +68,4 @@ def grdlandmask(**kwargs): arg_str = build_arg_string(kwargs) lib.call_module("grdlandmask", arg_str) - if outgrid == tmpfile.name: # if user did not set outgrid, return DataArray - with xr.open_dataarray(outgrid) as dataarray: - result = dataarray.load() - _ = result.gmt # load GMTDataArray accessor information - else: - result = None # if user sets an outgrid, return None - - return result + return process_output_grid(outgrid, tmpfile.name) diff --git a/pygmt/src/grdsample.py b/pygmt/src/grdsample.py index b1c807ccf94..033a1908017 100644 --- a/pygmt/src/grdsample.py +++ b/pygmt/src/grdsample.py @@ -2,7 +2,6 @@ grdsample - Resample a grid onto a new lattice """ -import xarray as xr from pygmt.clib import Session from pygmt.helpers import ( GMTTempFile, @@ -11,6 +10,7 @@ kwargs_to_strings, use_alias, ) +from pygmt.io import process_output_grid @fmt_docstring @@ -85,11 +85,4 @@ def grdsample(grid, **kwargs): arg_str = " ".join([infile, build_arg_string(kwargs)]) lib.call_module("grdsample", arg_str) - if outgrid == tmpfile.name: # if user did not set outgrid, return DataArray - with xr.open_dataarray(outgrid) as dataarray: - result = dataarray.load() - _ = result.gmt # load GMTDataArray accessor information - else: - result = None # if user sets an outgrid, return None - - return result + return process_output_grid(outgrid, tmpfile.name) diff --git a/pygmt/src/surface.py b/pygmt/src/surface.py index 1d24a438595..925baec301d 100644 --- a/pygmt/src/surface.py +++ b/pygmt/src/surface.py @@ -2,7 +2,6 @@ surface - Grids table data using adjustable tension continuous curvature splines. """ -import xarray as xr from pygmt.clib import Session from pygmt.exceptions import GMTInvalidInput from pygmt.helpers import ( @@ -14,6 +13,7 @@ kwargs_to_strings, use_alias, ) +from pygmt.io import process_output_grid @fmt_docstring @@ -99,11 +99,4 @@ def surface(x=None, y=None, z=None, data=None, **kwargs): arg_str = " ".join([infile, build_arg_string(kwargs)]) lib.call_module(module="surface", args=arg_str) - if outfile == tmpfile.name: # if user did not set outfile, return DataArray - with xr.open_dataarray(outfile) as dataarray: - result = dataarray.load() - _ = result.gmt # load GMTDataArray accessor information - elif outfile != tmpfile.name: # if user sets an outfile, return None - result = None - - return result + return process_output_grid(outfile, tmpfile.name) diff --git a/pygmt/src/xyz2grd.py b/pygmt/src/xyz2grd.py index ef40abc889d..03b88f127b9 100644 --- a/pygmt/src/xyz2grd.py +++ b/pygmt/src/xyz2grd.py @@ -1,7 +1,6 @@ """ xyz2grd - Convert data table to a grid. """ -import xarray as xr from pygmt.clib import Session from pygmt.helpers import ( GMTTempFile, @@ -10,6 +9,7 @@ kwargs_to_strings, use_alias, ) +from pygmt.io import process_output_grid @fmt_docstring @@ -64,11 +64,4 @@ def xyz2grd(table, **kwargs): arg_str = " ".join([infile, arg_str]) lib.call_module("xyz2grd", arg_str) - if outgrid == tmpfile.name: # if user did not set outgrid, return DataArray - with xr.open_dataarray(outgrid) as dataarray: - result = dataarray.load() - _ = result.gmt # load GMTDataArray accessor information - else: - result = None # if user sets an outgrid, return None - - return result + return process_output_grid(outgrid, tmpfile.name) From ab8954eb3c42d1fad6c876552d6c110259dff6e0 Mon Sep 17 00:00:00 2001 From: Meghan Jones Date: Wed, 11 Aug 2021 19:15:50 -0400 Subject: [PATCH 03/13] Update pygmt/io.py Co-authored-by: Wei Ji <23487320+weiji14@users.noreply.github.com> --- pygmt/io.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pygmt/io.py b/pygmt/io.py index 873e4b0ce27..d3c3857fe99 100644 --- a/pygmt/io.py +++ b/pygmt/io.py @@ -1,5 +1,5 @@ """ -PyGMT i/o utilities. +PyGMT input/output (I/O) utilities. """ import xarray as xr From fd3ae22629880a15b59ce5da0395f99040148040 Mon Sep 17 00:00:00 2001 From: Meghan Jones Date: Tue, 31 Aug 2021 11:30:32 -0400 Subject: [PATCH 04/13] Apply suggestions from code review Co-authored-by: Wei Ji <23487320+weiji14@users.noreply.github.com> --- pygmt/io.py | 46 ++++++++++++++++++++++++++------------------ pygmt/src/grdclip.py | 4 ++-- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/pygmt/io.py b/pygmt/io.py index d3c3857fe99..7384e4022cb 100644 --- a/pygmt/io.py +++ b/pygmt/io.py @@ -4,33 +4,41 @@ import xarray as xr -def process_output_grid(grid_name, tmpfile_name): +def load_datagrid(filename_or_obj, **kwargs): """ - Processes the output from the GMT API to return an xarray.DataArray if - ``grid_name`` matches ``tmpfile_name`` and return None if it does not. + Open, load into memory, and close a DataArray from a file or file-like + object containing a single data variable. + + This is a thin wrapper around :py:meth:`xarray.open_dataarray`. It differs + from `open_dataarray` in that it loads the DataArray into memory, gets GMT + specific metadata about the grid via :meth:`GMTDataArrayAccessor`, closes + the file, and returns the DataArray. In contrast, `open_dataarray` keeps + the file handle open and lazy loads its contents. All parameters are passed + directly to `open_dataarray`. See that documentation for further details. Parameters ---------- - grid_name : str - The name of the output netCDF file with extension .nc to store the grid - in. - tmpfile_name : str - The name attribute from a GMTTempFile instance. + filename_or_obj : str or Path or file-like or DataStore + Strings and Path objects are interpreted as a path to a netCDF file + or an OpenDAP URL and opened with python-netCDF4, unless the filename + ends with .gz, in which case the file is gunzipped and opened with + scipy.io.netcdf (only netCDF3 supported). Byte-strings or file-like + objects are opened by scipy.io.netcdf (netCDF3) or h5py (netCDF4/HDF). Returns ------- - ret: xarray.DataArray or None - Return type depends on whether the ``outgrid`` parameter is set: + datarray : xarray.DataArray + The newly created DataArray. - - :class:`xarray.DataArray` if ``outgrid`` is not set - - None if ``outgrid`` is set (grid output will be stored in file set by - ``outgrid``) + See Also + -------- + xarray.open_dataarray """ - if grid_name == tmpfile_name: # Implies user did not set outgrid, return DataArray - with xr.open_dataarray(grid_name) as dataarray: - result = dataarray.load() - _ = result.gmt # load GMTDataArray accessor information - else: - result = None # Implies user set an outgrid, return None + if "cache" in kwargs: + raise TypeError("cache has no effect in this context") + + with xr.open_dataarray(grid_name, **kwargs) as dataarray: + result = dataarray.load() + _ = result.gmt # load GMTDataArray accessor information return result diff --git a/pygmt/src/grdclip.py b/pygmt/src/grdclip.py index 20ac69b8da1..565853ef2a7 100644 --- a/pygmt/src/grdclip.py +++ b/pygmt/src/grdclip.py @@ -10,7 +10,7 @@ kwargs_to_strings, use_alias, ) -from pygmt.io import process_output_grid +from pygmt.io import load_datagrid @fmt_docstring @@ -88,4 +88,4 @@ def grdclip(grid, **kwargs): arg_str = " ".join([infile, build_arg_string(kwargs)]) lib.call_module("grdclip", arg_str) - return process_output_grid(outgrid, tmpfile.name) + return load_datagrid(outgrid) if outgrid == tmpfile.name else None From 269b185d7549cc227526cff534d6997737ef0b9e Mon Sep 17 00:00:00 2001 From: Meghan Jones Date: Tue, 31 Aug 2021 11:37:27 -0400 Subject: [PATCH 05/13] Update var name --- pygmt/io.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pygmt/io.py b/pygmt/io.py index 7384e4022cb..c6055c0c22a 100644 --- a/pygmt/io.py +++ b/pygmt/io.py @@ -37,7 +37,7 @@ def load_datagrid(filename_or_obj, **kwargs): if "cache" in kwargs: raise TypeError("cache has no effect in this context") - with xr.open_dataarray(grid_name, **kwargs) as dataarray: + with xr.open_dataarray(filename_or_obj, **kwargs) as dataarray: result = dataarray.load() _ = result.gmt # load GMTDataArray accessor information From d56c626697657e6e84ce4f98f01e40fd49a0079a Mon Sep 17 00:00:00 2001 From: Meghan Jones Date: Tue, 31 Aug 2021 12:04:43 -0400 Subject: [PATCH 06/13] Update function name --- pygmt/io.py | 2 +- pygmt/src/grdclip.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pygmt/io.py b/pygmt/io.py index c6055c0c22a..83932542aa8 100644 --- a/pygmt/io.py +++ b/pygmt/io.py @@ -4,7 +4,7 @@ import xarray as xr -def load_datagrid(filename_or_obj, **kwargs): +def load_dataarray(filename_or_obj, **kwargs): """ Open, load into memory, and close a DataArray from a file or file-like object containing a single data variable. diff --git a/pygmt/src/grdclip.py b/pygmt/src/grdclip.py index 565853ef2a7..8c3a66d63c9 100644 --- a/pygmt/src/grdclip.py +++ b/pygmt/src/grdclip.py @@ -10,7 +10,7 @@ kwargs_to_strings, use_alias, ) -from pygmt.io import load_datagrid +from pygmt.io import load_dataarray @fmt_docstring @@ -88,4 +88,4 @@ def grdclip(grid, **kwargs): arg_str = " ".join([infile, build_arg_string(kwargs)]) lib.call_module("grdclip", arg_str) - return load_datagrid(outgrid) if outgrid == tmpfile.name else None + return load_dataarray(outgrid) if outgrid == tmpfile.name else None From 6bfd0a3e9ba7fdea3d94bfa6bb2e50abdf6095b3 Mon Sep 17 00:00:00 2001 From: Meghan Jones Date: Tue, 31 Aug 2021 12:06:50 -0400 Subject: [PATCH 07/13] Update modules to use load_dataarray --- pygmt/src/grdcut.py | 4 ++-- pygmt/src/grdfill.py | 4 ++-- pygmt/src/grdfilter.py | 4 ++-- pygmt/src/grdgradient.py | 4 ++-- pygmt/src/grdlandmask.py | 4 ++-- pygmt/src/grdsample.py | 4 ++-- pygmt/src/surface.py | 4 ++-- pygmt/src/xyz2grd.py | 4 ++-- 8 files changed, 16 insertions(+), 16 deletions(-) diff --git a/pygmt/src/grdcut.py b/pygmt/src/grdcut.py index d47620ee428..4842bfc0872 100644 --- a/pygmt/src/grdcut.py +++ b/pygmt/src/grdcut.py @@ -10,7 +10,7 @@ kwargs_to_strings, use_alias, ) -from pygmt.io import process_output_grid +from pygmt.io import load_dataarray @fmt_docstring @@ -98,4 +98,4 @@ def grdcut(grid, **kwargs): arg_str = " ".join([infile, build_arg_string(kwargs)]) lib.call_module("grdcut", arg_str) - return process_output_grid(outgrid, tmpfile.name) + return load_dataarray(outgrid) if outgrid == tmpfile.name else None diff --git a/pygmt/src/grdfill.py b/pygmt/src/grdfill.py index cdaa0493eed..92f06b7a1db 100644 --- a/pygmt/src/grdfill.py +++ b/pygmt/src/grdfill.py @@ -11,7 +11,7 @@ kwargs_to_strings, use_alias, ) -from pygmt.io import process_output_grid +from pygmt.io import load_dataarray @fmt_docstring @@ -75,4 +75,4 @@ def grdfill(grid, **kwargs): arg_str = " ".join([infile, build_arg_string(kwargs)]) lib.call_module("grdfill", arg_str) - return process_output_grid(outgrid, tmpfile.name) + return load_dataarray(outgrid) if outgrid == tmpfile.name else None diff --git a/pygmt/src/grdfilter.py b/pygmt/src/grdfilter.py index 1a13d717f3d..33eb0afff72 100644 --- a/pygmt/src/grdfilter.py +++ b/pygmt/src/grdfilter.py @@ -10,7 +10,7 @@ kwargs_to_strings, use_alias, ) -from pygmt.io import process_output_grid +from pygmt.io import load_dataarray @fmt_docstring @@ -151,4 +151,4 @@ def grdfilter(grid, **kwargs): arg_str = " ".join([infile, build_arg_string(kwargs)]) lib.call_module("grdfilter", arg_str) - return process_output_grid(outgrid, tmpfile.name) + return load_dataarray(outgrid) if outgrid == tmpfile.name else None diff --git a/pygmt/src/grdgradient.py b/pygmt/src/grdgradient.py index 9eda09b2572..124adf882f5 100644 --- a/pygmt/src/grdgradient.py +++ b/pygmt/src/grdgradient.py @@ -12,7 +12,7 @@ kwargs_to_strings, use_alias, ) -from pygmt.io import process_output_grid +from pygmt.io import load_dataarray @fmt_docstring @@ -117,4 +117,4 @@ def grdgradient(grid, **kwargs): arg_str = " ".join([infile, build_arg_string(kwargs)]) lib.call_module("grdgradient", arg_str) - return process_output_grid(outgrid, tmpfile.name) + return load_dataarray(outgrid) if outgrid == tmpfile.name else None diff --git a/pygmt/src/grdlandmask.py b/pygmt/src/grdlandmask.py index ffc2320b179..8cab1dacbb6 100644 --- a/pygmt/src/grdlandmask.py +++ b/pygmt/src/grdlandmask.py @@ -11,7 +11,7 @@ kwargs_to_strings, use_alias, ) -from pygmt.io import process_output_grid +from pygmt.io import load_dataarray @fmt_docstring @@ -68,4 +68,4 @@ def grdlandmask(**kwargs): arg_str = build_arg_string(kwargs) lib.call_module("grdlandmask", arg_str) - return process_output_grid(outgrid, tmpfile.name) + return load_dataarray(outgrid) if outgrid == tmpfile.name else None diff --git a/pygmt/src/grdsample.py b/pygmt/src/grdsample.py index 033a1908017..d1416c34383 100644 --- a/pygmt/src/grdsample.py +++ b/pygmt/src/grdsample.py @@ -10,7 +10,7 @@ kwargs_to_strings, use_alias, ) -from pygmt.io import process_output_grid +from pygmt.io import load_dataarray @fmt_docstring @@ -85,4 +85,4 @@ def grdsample(grid, **kwargs): arg_str = " ".join([infile, build_arg_string(kwargs)]) lib.call_module("grdsample", arg_str) - return process_output_grid(outgrid, tmpfile.name) + return load_dataarray(outgrid) if outgrid == tmpfile.name else None diff --git a/pygmt/src/surface.py b/pygmt/src/surface.py index 925baec301d..48df437c916 100644 --- a/pygmt/src/surface.py +++ b/pygmt/src/surface.py @@ -13,7 +13,7 @@ kwargs_to_strings, use_alias, ) -from pygmt.io import process_output_grid +from pygmt.io import load_dataarray @fmt_docstring @@ -99,4 +99,4 @@ def surface(x=None, y=None, z=None, data=None, **kwargs): arg_str = " ".join([infile, build_arg_string(kwargs)]) lib.call_module(module="surface", args=arg_str) - return process_output_grid(outfile, tmpfile.name) + return load_dataarray(outfile) if outfile == tmpfile.name else None diff --git a/pygmt/src/xyz2grd.py b/pygmt/src/xyz2grd.py index 03b88f127b9..be08657f463 100644 --- a/pygmt/src/xyz2grd.py +++ b/pygmt/src/xyz2grd.py @@ -9,7 +9,7 @@ kwargs_to_strings, use_alias, ) -from pygmt.io import process_output_grid +from pygmt.io import load_dataarray @fmt_docstring @@ -64,4 +64,4 @@ def xyz2grd(table, **kwargs): arg_str = " ".join([infile, arg_str]) lib.call_module("xyz2grd", arg_str) - return process_output_grid(outgrid, tmpfile.name) + return load_dataarray(outgrid) if outgrid == tmpfile.name else None From 66fbfed9ec252faa3520bf51c8887fd2ec2d696f Mon Sep 17 00:00:00 2001 From: Meghan Jones Date: Tue, 31 Aug 2021 12:08:48 -0400 Subject: [PATCH 08/13] Update grdproject --- pygmt/src/grdproject.py | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/pygmt/src/grdproject.py b/pygmt/src/grdproject.py index c8a5d539421..d50c654438e 100644 --- a/pygmt/src/grdproject.py +++ b/pygmt/src/grdproject.py @@ -2,7 +2,6 @@ grdproject - Forward and inverse map transformation of grids. """ -import xarray as xr from pygmt.clib import Session from pygmt.exceptions import GMTInvalidInput from pygmt.helpers import ( @@ -12,6 +11,7 @@ kwargs_to_strings, use_alias, ) +from pygmt.io import load_dataarray @fmt_docstring @@ -83,11 +83,4 @@ def grdproject(grid, **kwargs): arg_str = " ".join([infile, build_arg_string(kwargs)]) lib.call_module("grdproject", arg_str) - if outgrid == tmpfile.name: # if user did not set outgrid, return DataArray - with xr.open_dataarray(outgrid) as dataarray: - result = dataarray.load() - _ = result.gmt # load GMTDataArray accessor information - else: - result = None # if user sets an outgrid, return None - - return result + return load_dataarray(outgrid) if outgrid == tmpfile.name else None From 9d4698be8b307b3f8b350f02fd80b2d995494400 Mon Sep 17 00:00:00 2001 From: Meghan Jones Date: Tue, 31 Aug 2021 12:21:31 -0400 Subject: [PATCH 09/13] Make load_dataarray public --- doc/api/index.rst | 8 ++++++++ pygmt/__init__.py | 1 + 2 files changed, 9 insertions(+) diff --git a/doc/api/index.rst b/doc/api/index.rst index 8e888419b57..61ed8498004 100644 --- a/doc/api/index.rst +++ b/doc/api/index.rst @@ -107,6 +107,14 @@ Crossover analysis with x2sys: x2sys_init x2sys_cross +Input/output +------------ + +.. autosummary:: + :toctree: generated + + load_dataarray + GMT Defaults ------------ diff --git a/pygmt/__init__.py b/pygmt/__init__.py index 96fe5cf908d..bd139af3d80 100644 --- a/pygmt/__init__.py +++ b/pygmt/__init__.py @@ -26,6 +26,7 @@ from pygmt import datasets from pygmt.accessors import GMTDataArrayAccessor from pygmt.figure import Figure, set_display +from pygmt.io import load_dataarray from pygmt.session_management import begin as _begin from pygmt.session_management import end as _end from pygmt.src import ( From 3da72c177a848408927cc484d2b922025b7f91ae Mon Sep 17 00:00:00 2001 From: Meghan Jones Date: Tue, 31 Aug 2021 12:29:56 -0400 Subject: [PATCH 10/13] Update docstring --- pygmt/io.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/pygmt/io.py b/pygmt/io.py index 83932542aa8..e01f51e1680 100644 --- a/pygmt/io.py +++ b/pygmt/io.py @@ -10,11 +10,13 @@ def load_dataarray(filename_or_obj, **kwargs): object containing a single data variable. This is a thin wrapper around :py:meth:`xarray.open_dataarray`. It differs - from `open_dataarray` in that it loads the DataArray into memory, gets GMT - specific metadata about the grid via :meth:`GMTDataArrayAccessor`, closes - the file, and returns the DataArray. In contrast, `open_dataarray` keeps - the file handle open and lazy loads its contents. All parameters are passed - directly to `open_dataarray`. See that documentation for further details. + from :py:meth:`xarray.open_dataarray` in that it loads the DataArray into + memory, gets GMT specific metadata about the grid via + :py:meth:`GMTDataArrayAccessor`, closes the file, and returns the + DataArray. In contrast, :py:meth:`xarray.open_dataarray` keeps the file + handle open and lazy loads its contents. All parameters are passed directly + to :py:meth:`xarray.open_dataarray`. See that documentation for further + details. Parameters ---------- From e7c3544b49e3b41a27d829ef2a66bd812245a6be Mon Sep 17 00:00:00 2001 From: Meghan Jones Date: Tue, 31 Aug 2021 16:47:36 -0400 Subject: [PATCH 11/13] Refactor earth_relief.py --- pygmt/datasets/earth_relief.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/pygmt/datasets/earth_relief.py b/pygmt/datasets/earth_relief.py index dacd6333966..73c67273ade 100644 --- a/pygmt/datasets/earth_relief.py +++ b/pygmt/datasets/earth_relief.py @@ -4,9 +4,9 @@ The grids are available in various resolutions. """ -import xarray as xr from pygmt.exceptions import GMTInvalidInput from pygmt.helpers import kwargs_to_strings +from pygmt.io import load_dataarray from pygmt.src import grdcut, which @@ -133,9 +133,7 @@ def load_earth_relief(resolution="01d", region=None, registration=None, use_srtm f"'region' is required for Earth relief resolution '{resolution}'." ) fname = which(f"@earth_relief_{resolution}{reg}", download="a") - with xr.open_dataarray(fname, engine="netcdf4") as dataarray: - grid = dataarray.load() - _ = grid.gmt # load GMTDataArray accessor information + grid = load_dataarray(fname, engine="netcdf4") else: grid = grdcut(f"@{earth_relief_prefix}{resolution}{reg}", region=region) From e4725ef1d73ccc6eb43e27da553809fc7421f0e1 Mon Sep 17 00:00:00 2001 From: Meghan Jones Date: Tue, 31 Aug 2021 20:53:50 -0400 Subject: [PATCH 12/13] Apply suggestions from code review Co-authored-by: Wei Ji <23487320+weiji14@users.noreply.github.com> --- pygmt/io.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pygmt/io.py b/pygmt/io.py index e01f51e1680..2b50ab21770 100644 --- a/pygmt/io.py +++ b/pygmt/io.py @@ -13,14 +13,14 @@ def load_dataarray(filename_or_obj, **kwargs): from :py:meth:`xarray.open_dataarray` in that it loads the DataArray into memory, gets GMT specific metadata about the grid via :py:meth:`GMTDataArrayAccessor`, closes the file, and returns the - DataArray. In contrast, :py:meth:`xarray.open_dataarray` keeps the file + DataArray. In contrast, :py:func:`xarray.open_dataarray` keeps the file handle open and lazy loads its contents. All parameters are passed directly - to :py:meth:`xarray.open_dataarray`. See that documentation for further + to :py:func:`xarray.open_dataarray`. See that documentation for further details. Parameters ---------- - filename_or_obj : str or Path or file-like or DataStore + filename_or_obj : str or pathlib.Path or file-like or DataStore Strings and Path objects are interpreted as a path to a netCDF file or an OpenDAP URL and opened with python-netCDF4, unless the filename ends with .gz, in which case the file is gunzipped and opened with From f19562d3d761279e63bcf63fecdff3a879a3c7ba Mon Sep 17 00:00:00 2001 From: Meghan Jones Date: Tue, 31 Aug 2021 20:54:12 -0400 Subject: [PATCH 13/13] Update pygmt/io.py Co-authored-by: Wei Ji <23487320+weiji14@users.noreply.github.com> --- pygmt/io.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pygmt/io.py b/pygmt/io.py index 2b50ab21770..70bcfbfcdb9 100644 --- a/pygmt/io.py +++ b/pygmt/io.py @@ -9,8 +9,8 @@ def load_dataarray(filename_or_obj, **kwargs): Open, load into memory, and close a DataArray from a file or file-like object containing a single data variable. - This is a thin wrapper around :py:meth:`xarray.open_dataarray`. It differs - from :py:meth:`xarray.open_dataarray` in that it loads the DataArray into + This is a thin wrapper around :py:func:`xarray.open_dataarray`. It differs + from :py:func:`xarray.open_dataarray` in that it loads the DataArray into memory, gets GMT specific metadata about the grid via :py:meth:`GMTDataArrayAccessor`, closes the file, and returns the DataArray. In contrast, :py:func:`xarray.open_dataarray` keeps the file