Skip to content

Commit

Permalink
Fix for forecast time conversion
Browse files Browse the repository at this point in the history
_convert_ftime needed to have its logic fixed so that a forecast time of
zero will not cause it to return None.

Added a nearest time method for surface data. This is basically a thin
wrapper for sfjson that gives you the nearest observation to a given
time.

Fixes #2
  • Loading branch information
nawendt committed Apr 25, 2021
1 parent 6816c53 commit c899a3a
Showing 1 changed file with 71 additions and 1 deletion.
72 changes: 71 additions & 1 deletion gempakio/decode.py
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ def _convert_dattim(dattim):
@staticmethod
def _convert_ftime(ftime):
"""Convert GEMPAK forecast time and type integer."""
if ftime:
if ftime >= 0:
iftype = ForecastType(ftime // 100000)
iftime = ftime - iftype.value * 100000
hours = iftime // 100
Expand Down Expand Up @@ -2360,6 +2360,76 @@ def _unpack_standard(self, sfcno):
stations.append(station)
return stations

def nearest_time(self, date_time, station_id=None, station_number=None):
"""Get nearest observation to given time for selected stations.
Parameters
----------
date_time : datetime or array-like of datetime
Valid/observed datetime of the surface station. Alternatively
object or a string with the format YYYYmmddHHMM.
station_id : str or array-like of str
Station ID of the surface station.
station_number : int or array-like of int
Station number of the surface station.
Returns
-------
list
List of dicts/JSONs for each surface station.
Notes
-----
One of either station_id or station_number must be used. If both
are present, station_id will take precedence.
"""

if isinstance(date_time, str):
date_time = datetime.strptime(date_time, '%Y%m%d%H%M')

if station_id is None and station_number is None:
raise ValueError('Must have either station_id or station_number')

if station_id is not None and station_number is not None:
station_number = None

if (station_id is not None
and (not isinstance(station_id, Iterable)
or isinstance(station_id, str))):
station_id = [station_id]
station_id = [c.upper() for c in station_id]

if station_number is not None and not isinstance(station_number, Iterable):
station_number = [station_number]
station_number = [int(sn) for sn in station_number]

time_matched = []
if station_id:
for stn in station_id:
matched = self.sfjson(station_id=stn)

nearest = min(
matched,
key=lambda d: abs(d['properties']['date_time'] - date_time)
)

time_matched.append(nearest)

if station_number:
for stn in station_id:
matched = self.sfjson(station_number=stn)

nearest = min(
matched,
key=lambda d: abs(d['properties']['date_time'] - date_time)
)

time_matched.append(nearest)

return time_matched

def sfjson(self, station_id=None, station_number=None,
date_time=None, state=None, country=None):
"""Select surface stations and output as list of JSON objects.
Expand Down

0 comments on commit c899a3a

Please sign in to comment.