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

Add support for met_em files #46

Merged
merged 18 commits into from
Feb 16, 2022
Merged
Show file tree
Hide file tree
Changes from 13 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
15 changes: 13 additions & 2 deletions tests/test_postprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ def dummy_attrs_only_dataset(request):
return xwrf.tutorial.open_dataset(request.param)


@pytest.fixture(scope='session', params=['met_em.d01.2005-08-28_12:00:00.nc'])
def met_em_dataset(request):
return xwrf.tutorial.open_dataset(request.param)


@pytest.mark.parametrize('variable', ('Q2', 'PSFC'))
def test_cf_attrs_added(dummy_dataset, variable):
dataset = xwrf.postprocess._modify_attrs_to_cf(dummy_dataset)
Expand All @@ -22,6 +27,12 @@ def test_cf_attrs_added(dummy_dataset, variable):


@pytest.mark.parametrize('variable', ('THIS_IS_AN_IDEAL_RUN', 'SAVE_TOPO_FROM_REAL'))
def test_remove_units_from_bool_arrays(dummy_attrs_only_dataset, variable):
dataset = xwrf.postprocess._remove_units_from_bool_arrays(dummy_attrs_only_dataset)
def test_remove_invalid_units(dummy_attrs_only_dataset, variable):
dataset = xwrf.postprocess._make_units_pint_friendly(dummy_attrs_only_dataset)
assert 'units' not in dataset[variable].attrs


@pytest.mark.parametrize('variable', ('OL4', 'GREENFRAC'))
def test_met_em_parsing(met_em_dataset, variable):
dataset = xwrf.postprocess._make_units_pint_friendly(met_em_dataset)
assert dataset[variable].attrs['units'] == 'dimensionless'
4 changes: 2 additions & 2 deletions xwrf/accessors.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
from .postprocess import (
_collapse_time_dim,
_decode_times,
_make_units_pint_friendly,
_modify_attrs_to_cf,
_remove_units_from_bool_arrays,
)


Expand Down Expand Up @@ -41,7 +41,7 @@ def postprocess(self, decode_times=True) -> xr.Dataset:
"""
ds = (
self.xarray_obj.pipe(_modify_attrs_to_cf)
.pipe(_remove_units_from_bool_arrays)
.pipe(_make_units_pint_friendly)
.pipe(_collapse_time_dim)
)
if decode_times:
Expand Down
32 changes: 29 additions & 3 deletions xwrf/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,20 @@ time_coords:
- Time
- time

boolean_units_attrs:
- '-'
- flag
unit_harmonization_map:
kelvin:
- Kelvin
dimensionless:
- fraction
invalid:
- '-'
- flag
- '0/1 Flag'
- whoknows
- category
- none
meters:
- 'meters MSL'

cf_attribute_map:
ZNW:
Expand Down Expand Up @@ -82,3 +93,18 @@ cf_attribute_map:
standard_name: integral_of_surface_upward_heat_flux_in_air_wrt_time
ACLHF:
standard_name: integral_of_surface_upward_latent_heat_flux_in_air_wrf_time
VAR_SSO:
units: m2
description: Variance of Subgrid Scale Orography MSL
HGT_V:
standard_name: surface_altitude
HGT_U:
standard_name: surface_altitude
HGT_M:
standard_name: surface_altitude
PRES:
units: Pa
ST:
units: kelvin
RH:
units: '%'
34 changes: 23 additions & 11 deletions xwrf/postprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,34 @@ def _decode_times(ds: xr.Dataset) -> xr.Dataset:
"""
Decode the time variable to datetime64.
"""
ds = ds.assign_coords(
{
'Time': pd.to_datetime(
ds.Times.data.astype('str'), errors='raise', format='%Y-%m-%d_%H:%M:%S'
)
}
)
try:
_time = pd.to_datetime(
ds.Times.data.astype('str'), errors='raise', format='%Y-%m-%d_%H:%M:%S'
)
except ValueError:
_time = pd.to_datetime(
ds.Times.data.astype('str'), errors='raise', format='%Y-%m-%dT%H:%M:%S.%f'
)
ds = ds.assign_coords({'Time': _time})
ds.Time.attrs = {'long_name': 'Time', 'standard_name': 'time'}
return ds


def _remove_units_from_bool_arrays(ds: xr.Dataset) -> xr.Dataset:
boolean_units_attrs = config.get('boolean_units_attrs')
def _make_units_pint_friendly(ds: xr.Dataset) -> xr.Dataset:
"""
Harmonizes awkward WRF units into pint-friendly ones
"""
# We have to invert the mapping from "new_unit -> wrf_units" to "wrf_unit -> new_unit"
wrf_units_map = {
v: k for (k, val_list) in config.get('unit_harmonization_map').items() for v in val_list
}
for variable in ds.data_vars:
if ds[variable].attrs.get('units') in boolean_units_attrs:
ds[variable].attrs.pop('units', None)
if ds[variable].attrs.get('units') in wrf_units_map:
harmonized_unit = wrf_units_map[ds[variable].attrs['units']]
if harmonized_unit == 'invalid':
ds[variable].attrs.pop('units', None)
else:
ds[variable].attrs['units'] = harmonized_unit
return ds


Expand Down
1 change: 1 addition & 0 deletions xwrf/tutorial.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ def _construct_cache_dir(path):
'lambert_conformal': 'data/lambert_conformal_sample.nc',
'mercator': 'data/mercator_sample.nc',
'tiny': 'data/tiny.nc',
'met_em.d01.2005-08-28_12:00:00.nc': 'data/met_em.d01.2005-08-28_12:00:00.nc',
}


Expand Down