Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Derive #16

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@
.DS_Store
*.nc
data/

*.egg-info/
67 changes: 67 additions & 0 deletions eurec4a_environment/interface.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Example function for testing calculate
def _thingness(u, v, T):
return u*v*T


def calculate(name, ds):
"""Calculate a variable from the given dataset by CF standard name

Args:
name (str): The CF standard name of the variable to be calculated
ds (xarray.DataSet): The dataset to calculate the variable from

Returns:
xarray.DataArray:

Raises:
ValueError: If the requested variable (or a variable required to calculate it)
is not available in the dataset
"""
# If the variable is in the dataset, just return it
if name in ds:
return ds[name]

# Also check if the name matches a CF standard name
# Create a mapping of CF standard names in the dataset to their variable name
translation_table = dict()
for varname in ds:
try:
translation_table[ds[varname].attrs["standard_name"]] = varname
except KeyError:
# Skip variables without a standard_name attribute
pass

# Check whether the requested variable matches a standard name
if name in translation_table:
result = ds[translation_table[name]].copy()
_rename_xarray(result, name)
return result

# Otherwise calculate the requested variable using variables in the dataset
if name in available:
arguments = []
for argument_name in available[name]["arguments"]:
arguments.append(calculate(argument_name, ds))

result = available[name]["function"](*arguments)
_rename_xarray(result, name)
return result

# If you get this far without returning a variable then something has gone wrong
raise ValueError("Can not calculate {} from dataset".format(name))


def _rename_xarray(array, name):
array.rename(name)
array.attrs["standard_name"] = name
array.attrs["long_name"] = name


# A dictionary mapping variables that can be calculated to the functions to calculate
# them and the required input arguments (by CF standard names)
available = dict(
thingness=dict(
function=_thingness,
arguments=["eastward_wind", "northward_wind", "air_temperature"],
)
)
9 changes: 8 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,14 @@
from setuptools import setup, find_packages
import versioneer

INSTALL_REQUIRES = ["xarray", "netcdf4", "typhon", "tqdm"]
INSTALL_REQUIRES = [
"xarray",
"netcdf4",
"typhon",
"tqdm",
"requests",
"pyyaml",
]

setup(
name="eurec4a-environment",
Expand Down
21 changes: 21 additions & 0 deletions tests/test_interface.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import numpy as np

from eurec4a_environment.source_data import open_joanne_dataset
from eurec4a_environment.interface import calculate


def test_calc():
ds_joanne = open_joanne_dataset()

result = calculate("thingness", ds_joanne)
expected = ds_joanne.u*ds_joanne.v*ds_joanne.T

expected = _mask_nans(expected.values)
result = _mask_nans(result.values)

assert (result == expected).all()


def _mask_nans(array):
# NaNs mess up array-wise equality checks
return np.ma.masked_where(np.isnan(array), array)