Skip to content

Commit

Permalink
Minor bug fixes and new tests
Browse files Browse the repository at this point in the history
  • Loading branch information
nawendt committed Oct 27, 2022
1 parent 19d0339 commit e8cd380
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 10 deletions.
25 changes: 17 additions & 8 deletions gempakio/decode/gempak.py
Original file line number Diff line number Diff line change
Expand Up @@ -900,7 +900,9 @@ def gdxarray(self, parameter=None, date_time=None, coordinate=None,
date_time2 : datetime or array-like of datetime
Secondary valid datetime of the grid. Alternatively
can be a string with the format YYYYmmddHHMM.
a string with the format YYYYmmddHHMM or first|FIRST
or last|LAST which function to retrieve the latest
and oldest time within the file, respectively.
level2: float or array_like of float
Secondary vertical level. Typically used for layers.
Expand Down Expand Up @@ -947,11 +949,13 @@ def gdxarray(self, parameter=None, date_time=None, coordinate=None,

if date_time2 is not None:
if (not isinstance(date_time2, Iterable)
or isinstance(date_time2, str)):
or (isinstance(date_time2, str)
and date_time2 not in ['first', 'FIRST', 'last', 'LAST'])):
date_time2 = [date_time2]
for i, dt in enumerate(date_time2):
if isinstance(dt, str):
date_time2[i] = datetime.strptime(dt, '%Y%m%d%H%M')
if date_time2 not in ['first', 'FIRST', 'last', 'LAST']:
for i, dt in enumerate(date_time2):
if isinstance(dt, str):
date_time2[i] = datetime.strptime(dt, '%Y%m%d%H%M')

if level2 is not None and not isinstance(level2, Iterable):
level2 = [level2]
Expand All @@ -962,9 +966,14 @@ def gdxarray(self, parameter=None, date_time=None, coordinate=None,
# Do this now or the matched filter iterator will be consumed
# prematurely.
if date_time in ['last', 'LAST']:
date_time = [max((d.DATTIM for d in matched))]
date_time = [max((d.DATTIM1 for d in matched))]
elif date_time in ['first', 'FIRST']:
date_time = [min((d.DATTIM for d in matched))]
date_time = [min((d.DATTIM1 for d in matched))]

if date_time2 in ['last', 'LAST']:
date_time2 = [max((d.DATTIM2 for d in matched))]
elif date_time2 in ['first', 'FIRST']:
date_time2 = [min((d.DATTIM2 for d in matched))]

if parameter is not None:
matched = filter(
Expand Down Expand Up @@ -2052,7 +2061,7 @@ def snxarray(self, station_id=None, station_number=None,
if 'TXPB' in snd:
wmo_text['txpb'] = snd.pop('TXPB')
if wmo_text:
attrs['WMO_CODES'] = wmo_text
attrs['wmo_codes'] = wmo_text

dt = datetime.combine(snd.pop('DATE'), snd.pop('TIME'))
if vcoord == 'pres':
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from setuptools import find_packages, setup

NAME = 'gempakio'
VERSION = '0.8.0'
VERSION = '0.8.1'
DESCR = 'Read GEMPAK data with pure Python.'
URL = 'https://github.com/nawendt/gempakio'
REQUIRES = ['pyproj', 'xarray']
Expand Down
Binary file added tests/data/multi_date.grd
Binary file not shown.
17 changes: 17 additions & 0 deletions tests/test_grids.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"""Tests for decoding GEMPAK grid files."""


from datetime import datetime, timedelta
from pathlib import Path

import numpy as np
Expand All @@ -24,3 +25,19 @@ def test_grid_loading(grid_name):
gempak = np.load(d)['values']

np.testing.assert_allclose(gio, gempak, rtol=1e-6, atol=0)


@pytest.mark.parametrize('keyword,date_time', [
('FIRST', '201204141200'), ('LAST', '201204150000')
])
def test_time_keywords(keyword, date_time):
"""Test time keywords FIRST and LAST."""
g = Path(__file__).parent / 'data' / 'multi_date.grd'

grid = GempakGrid(g).gdxarray(date_time=keyword)[0]
dt64 = grid.time.values[0]
epoch_seconds = int(dt64) / 1e9
grid_dt = datetime(1970, 1, 1) + timedelta(seconds=epoch_seconds)
expected = datetime.strptime(date_time, '%Y%m%d%H%M')

assert grid_dt == expected
19 changes: 18 additions & 1 deletion tests/test_soundings.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# SPDX-License-Identifier: BSD-3-Clause
"""Tests for decoding GEMPAK grid files."""

from datetime import datetime, timedelta
from pathlib import Path

import numpy as np
Expand Down Expand Up @@ -84,7 +85,7 @@ def test_sounding_text(text_type):
gso = GempakSounding(g).snxarray(station_id='OUN')[0]
gempak = pd.read_csv(d)

text = gso.attrs['WMO_CODES'][text_type]
text = gso.attrs['wmo_codes'][text_type]
gem_text = gempak.loc[:, text_type.upper()][0]

assert text == gem_text
Expand Down Expand Up @@ -157,3 +158,19 @@ def test_unmerged_sigw_pressure_sounding():
np.testing.assert_allclose(gdrct, ddrct, rtol=1e-10, atol=1e-2)
np.testing.assert_allclose(gsped, dsped, rtol=1e-10, atol=1e-2)
np.testing.assert_allclose(ghght, dhght, rtol=1e-10, atol=1e-1)


@pytest.mark.parametrize('keyword,date_time', [
('FIRST', '202011070000'), ('LAST', '202011070100')
])
def test_time_keywords(keyword, date_time):
"""Test time keywords FIRST and LAST."""
g = Path(__file__).parent / 'data' / 'unmerged_with_text.snd'

gso = GempakSounding(g).snxarray(date_time=keyword)[0]
expected = datetime.strptime(date_time, '%Y%m%d%H%M')
dt64 = gso.time.values[0]
epoch_seconds = int(dt64) / 1e9
sounding_dt = datetime(1970, 1, 1) + timedelta(seconds=epoch_seconds)

assert sounding_dt == expected
14 changes: 14 additions & 0 deletions tests/test_surface.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,17 @@ def test_multiple_special_observations():

assert date_time == datetime(2021, 9, 7, 16, 4)
assert text == gem_text


@pytest.mark.parametrize('keyword,date_time', [
('FIRST', '202109062353'), ('LAST', '202109071604')
])
def test_time_keywords(keyword, date_time):
"""Test time keywords FIRST and LAST."""
g = Path(__file__).parent / 'data' / 'msn_std_sfc.sfc'

gsf = GempakSurface(g).sfjson(date_time=keyword)[-1]
expected = datetime.strptime(date_time, '%Y%m%d%H%M')
surface_dt = gsf['properties']['date_time']

assert surface_dt == expected

0 comments on commit e8cd380

Please sign in to comment.