diff --git a/src/siphon/simplewebservice/wyoming.py b/src/siphon/simplewebservice/wyoming.py index 305ba8e0c..abacbecdd 100644 --- a/src/siphon/simplewebservice/wyoming.py +++ b/src/siphon/simplewebservice/wyoming.py @@ -26,7 +26,7 @@ def __init__(self): super().__init__('http://weather.uwyo.edu/cgi-bin/sounding') @classmethod - def request_data(cls, time, site_id, **kwargs): + def request_data(cls, time, site_id, recalc=False, **kwargs): r"""Retrieve upper air observations from the Wyoming archive. Parameters @@ -38,6 +38,9 @@ def request_data(cls, time, site_id, **kwargs): The three letter ICAO identifier of the station for which data should be downloaded. + recalc : bool + Returns recalculated data if True. Defaults to False. + kwargs Arbitrary keyword arguments to use to initialize source @@ -47,10 +50,10 @@ def request_data(cls, time, site_id, **kwargs): """ endpoint = cls() - df = endpoint._get_data(time, site_id) + df = endpoint._get_data(time, site_id, recalc=recalc) return df - def _get_data(self, time, site_id): + def _get_data(self, time, site_id, recalc=False): r"""Download and parse upper air observations from an online archive. Parameters @@ -62,12 +65,15 @@ def _get_data(self, time, site_id): The three letter ICAO identifier of the station for which data should be downloaded. + recalc : bool + Returns recalculated data if True. Defaults to False. + Returns ------- :class:`pandas.DataFrame` containing the data """ - raw_data = self._get_data_raw(time, site_id) + raw_data = self._get_data_raw(time, site_id, recalc=recalc) soup = BeautifulSoup(raw_data, 'html.parser') tabular_data = StringIO(soup.find_all('pre')[0].contents[0]) col_names = ['pressure', 'height', 'temperature', 'dewpoint', 'direction', 'speed'] @@ -124,7 +130,7 @@ def _get_data(self, time, site_id): 'pw': 'millimeter'} return df - def _get_data_raw(self, time, site_id): + def _get_data_raw(self, time, site_id, recalc=False): """Download data from the University of Wyoming's upper air archive. Parameters @@ -133,6 +139,8 @@ def _get_data_raw(self, time, site_id): Date and time for which data should be downloaded site_id : str Site id for which data should be downloaded + recalc : bool + Returns recalculated data if True. Defaults to False. Returns ------- @@ -142,7 +150,8 @@ def _get_data_raw(self, time, site_id): path = ('?region=naconf&TYPE=TEXT%3ALIST' '&YEAR={time:%Y}&MONTH={time:%m}&FROM={time:%d%H}&TO={time:%d%H}' '&STNM={stid}').format(time=time, stid=site_id) - + if recalc: + path += '&REPLOT=1' resp = self.get_path(path) # See if the return is valid, but has no data if resp.text.find("Can't") != -1: diff --git a/tests/test_wyoming.py b/tests/test_wyoming.py index 44b58a7d0..6e670b3c3 100644 --- a/tests/test_wyoming.py +++ b/tests/test_wyoming.py @@ -53,6 +53,45 @@ def test_wyoming(): assert df.units['time'] is None +@recorder.use_cassette('wyoming_sounding_recalculate') +def test_wyoming_recalculate(): + """Test that recalculation request returns the same data.""" + df = WyomingUpperAir.request_data( + datetime(1999, 5, 4, 0), 'OUN', recalc=True) + + assert df['time'][0] == datetime(1999, 5, 4, 0) + assert df['station'][0] == 'OUN' + assert df['station_number'][0] == 72357 + assert df['latitude'][0] == 35.18 + assert df['longitude'][0] == -97.44 + assert df['elevation'][0] == 345.0 + + assert_almost_equal(df['pressure'][5], 867.9, 2) + assert_almost_equal(df['height'][5], 1219., 2) + assert_almost_equal(df['height'][30], 10505., 2) + assert_almost_equal(df['temperature'][5], 17.4, 2) + assert_almost_equal(df['dewpoint'][5], 14.3, 2) + assert_almost_equal(df['u_wind'][5], 6.60, 2) + assert_almost_equal(df['v_wind'][5], 37.42, 2) + assert_almost_equal(df['speed'][5], 38.0, 1) + assert_almost_equal(df['direction'][5], 190.0, 1) + + assert df.units['pressure'] == 'hPa' + assert df.units['height'] == 'meter' + assert df.units['temperature'] == 'degC' + assert df.units['dewpoint'] == 'degC' + assert df.units['u_wind'] == 'knot' + assert df.units['v_wind'] == 'knot' + assert df.units['speed'] == 'knot' + assert df.units['direction'] == 'degrees' + assert df.units['latitude'] == 'degrees' + assert df.units['longitude'] == 'degrees' + assert df.units['elevation'] == 'meter' + assert df.units['station'] is None + assert df.units['station_number'] is None + assert df.units['time'] is None + + @recorder.use_cassette('wyoming_sounding_no_station') def test_wyoming_no_station(): """Test that we handle stations with no ID from the Wyoming archive."""