|
| 1 | +""" |
| 2 | +grdvolume - Calculate grid volume and area constrained by a contour. |
| 3 | +""" |
| 4 | +import pandas as pd |
| 5 | +from pygmt.clib import Session |
| 6 | +from pygmt.exceptions import GMTInvalidInput |
| 7 | +from pygmt.helpers import ( |
| 8 | + GMTTempFile, |
| 9 | + build_arg_string, |
| 10 | + fmt_docstring, |
| 11 | + kwargs_to_strings, |
| 12 | + use_alias, |
| 13 | +) |
| 14 | + |
| 15 | + |
| 16 | +@fmt_docstring |
| 17 | +@use_alias( |
| 18 | + C="contour", |
| 19 | + R="region", |
| 20 | + S="unit", |
| 21 | + V="verbose", |
| 22 | +) |
| 23 | +@kwargs_to_strings(C="sequence", R="sequence") |
| 24 | +def grdvolume(grid, output_type="pandas", outfile=None, **kwargs): |
| 25 | + r""" |
| 26 | + Determine the volume between the surface of a grid and a plane. |
| 27 | +
|
| 28 | + Read a 2-D grid file and calculate the volume contained below the surface |
| 29 | + and above the plane specified by the given contour (or zero if not given) |
| 30 | + and return the contour, area, volume, and maximum mean height |
| 31 | + (volume/area). Alternatively, a range of contours can be specified to |
| 32 | + return the volume and area inside the contour for all contour values. |
| 33 | +
|
| 34 | + Full option list at :gmt-docs:`grdvolume.html` |
| 35 | +
|
| 36 | + {aliases} |
| 37 | +
|
| 38 | + Parameters |
| 39 | + ---------- |
| 40 | + grid : str or xarray.DataArray |
| 41 | + The file name of the input grid or the grid loaded as a DataArray. |
| 42 | + output_type : str |
| 43 | + Determine the format the output data will be returned in [Default is |
| 44 | + ``pandas``]: |
| 45 | +
|
| 46 | + - ``numpy`` - :class:`numpy.ndarray` |
| 47 | + - ``pandas``- :class:`pandas.DataFrame` |
| 48 | + - ``file`` - ASCII file (requires ``outfile``) |
| 49 | + outfile : str |
| 50 | + The file name for the output ASCII file. |
| 51 | + contour : str or int or float or list |
| 52 | + *cval*\|\ *low/high/delta*\|\ **r**\ *low/high*\|\ **r**\ *cval*. |
| 53 | + Find area, volume and mean height (volume/area) inside and above the |
| 54 | + *cval* contour. Alternatively, search using all contours from *low* to |
| 55 | + *high* in steps of *delta*. [Default returns area, volume and mean |
| 56 | + height of the entire grid]. The area is measured in the plane of the |
| 57 | + contour. Adding the **r** prefix computes the volume below the grid |
| 58 | + surface and above the planes defined by *low* and *high*, or below |
| 59 | + *cval* and grid's minimum. Note that this is an *outside* volume |
| 60 | + whilst the other forms compute an *inside* (below the surface) area |
| 61 | + volume. Use this form to compute for example the volume of water |
| 62 | + between two contours. If no *contour* is given then there is no contour |
| 63 | + and the entire grid area, volume and the mean height is returned and |
| 64 | + *cval* will be reported as 0. |
| 65 | + {R} |
| 66 | + {V} |
| 67 | +
|
| 68 | + Returns |
| 69 | + ------- |
| 70 | + ret : pandas.DataFrame or numpy.ndarray or None |
| 71 | + Return type depends on ``outfile`` and ``output_type``: |
| 72 | +
|
| 73 | + - None if ``outfile`` is set (output will be stored in file set by |
| 74 | + ``outfile``) |
| 75 | + - :class:`pandas.DataFrame` or :class:`numpy.ndarray` if ``outfile`` |
| 76 | + is not set (depends on ``output_type`` [Default is |
| 77 | + class:`pandas.DataFrame`]) |
| 78 | + """ |
| 79 | + if output_type not in ["numpy", "pandas", "file"]: |
| 80 | + raise GMTInvalidInput( |
| 81 | + """Must specify format as either numpy, pandas, or file.""" |
| 82 | + ) |
| 83 | + if output_type == "file" and outfile is None: |
| 84 | + raise GMTInvalidInput("""Must specify outfile for ASCII output.""") |
| 85 | + |
| 86 | + with GMTTempFile() as tmpfile: |
| 87 | + with Session() as lib: |
| 88 | + file_context = lib.virtualfile_from_data(check_kind="raster", data=grid) |
| 89 | + with file_context as infile: |
| 90 | + if outfile is None: |
| 91 | + outfile = tmpfile.name |
| 92 | + arg_str = " ".join([infile, build_arg_string(kwargs), "->" + outfile]) |
| 93 | + lib.call_module("grdvolume", arg_str) |
| 94 | + |
| 95 | + # Read temporary csv output to a pandas table |
| 96 | + if outfile == tmpfile.name: # if user did not set outfile, return pd.DataFrame |
| 97 | + result = pd.read_csv(tmpfile.name, sep="\t", header=None, comment=">") |
| 98 | + elif outfile != tmpfile.name: # return None if outfile set, output in outfile |
| 99 | + result = None |
| 100 | + |
| 101 | + if output_type == "numpy": |
| 102 | + result = result.to_numpy() |
| 103 | + return result |
0 commit comments