Skip to content

Commit

Permalink
Merge pull request #1908 from 23ccozad/metar_parser_docs
Browse files Browse the repository at this point in the history
Improved formatting of notes section of METAR parser
  • Loading branch information
dopplershift committed Jun 21, 2021
2 parents 09b4514 + ca512ee commit c005c61
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 94 deletions.
4 changes: 4 additions & 0 deletions docs/api/references.rst
Original file line number Diff line number Diff line change
Expand Up @@ -193,5 +193,9 @@ References
.. [WMO8] WMO, 2018: Guide to Meteorological Instruments and Methods of Observation.
`WMO No.8 <https://library.wmo.int/doc_num.php?explnum_id=10616>`_.
.. [WMO306] WMO, 2011: Manual on Codes - International Codes, Volume I.1, Annex II to the WMO
Technical Regulations: Part A - Alphanumeric Codes. `WMO No.306
<https://library.wmo.int/index.php?lvl=notice_display&id=13617>`_.
.. [WMO1966] WMO, 1966: International Meteorological Tables, `WMO-No. 188.TP.94
<https://library.wmo.int/doc_num.php?explnum_id=7997>`_.
1 change: 1 addition & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ per-file-ignores = examples/*.py: D MPY001 T003 T001
src/metpy/deprecation.py: C801
src/metpy/calc/*.py: RST306
src/metpy/interpolate/*.py: RST306
src/metpy/io/*.py: RST306
src/metpy/future.py: RST307
src/metpy/constants.py: RST306
docs/doc-server.py: T001
Expand Down
188 changes: 101 additions & 87 deletions src/metpy/io/metar.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@
'dew_point_temperature': 'degC',
'altimeter': 'inHg',
'air_pressure_at_sea_level': 'hPa',
'present_weather': None,
'past_weather': None,
'past_weather2': None}
'current_wx1_symbol': None,
'current_wx2_symbol': None,
'current_wx3_symbol': None}


@exporter.export
Expand Down Expand Up @@ -87,33 +87,39 @@ def parse_metar_to_dataframe(metar_text, *, year=None, month=None):
Notes
-----
The output has the following columns:
'station_id': Station Identifier (ex. KLOT)
'latitude': Latitude of the observation, measured in degrees
'longitude': Longitude of the observation, measured in degrees
'elevation': Elevation of the observation above sea level, measured in meters
'date_time': Date and time of the observation, datetime object
'wind_direction': Direction the wind is coming from, measured in degrees
'wind_spd': Wind speed, measured in knots
'current_wx1': Current weather (1 of 3)
'current_wx2': Current weather (2 of 3)
'current_wx3': Current weather (3 of 3)
'skyc1': Sky cover (ex. FEW)
'skylev1': Height of sky cover 1, measured in feet
'skyc2': Sky cover (ex. OVC)
'skylev2': Height of sky cover 2, measured in feet
'skyc3': Sky cover (ex. FEW)
'skylev3': Height of sky cover 3, measured in feet
'skyc4': Sky cover (ex. CLR)
'skylev4:': Height of sky cover 4, measured in feet
'cloudcover': Cloud coverage measured in oktas, taken from maximum of sky cover values
'temperature': Temperature, measured in degrees Celsius
'dewpoint': Dew point, measured in degrees Celsius
'altimeter': Altimeter value, measured in inches of mercury, float
'current_wx1_symbol': Current weather symbol (1 of 3), integer
'current_wx2_symbol': Current weather symbol (2 of 3), integer
'current_wx3_symbol': Current weather symbol (3 of 3), integer
'sea_level_pressure': Sea level pressure, derived from temperature, elevation
and altimeter value, float
* 'station_id': Station Identifier (ex. KLOT)
* 'latitude': Latitude of the observation, measured in degrees
* 'longitude': Longitude of the observation, measured in degrees
* 'elevation': Elevation of the observation above sea level, measured in meters
* 'date_time': Date and time of the observation, datetime object
* 'wind_direction': Direction the wind is coming from, measured in degrees
* 'wind_speed': Wind speed, measured in knots
* 'current_wx1': Current weather (1 of 3)
* 'current_wx2': Current weather (2 of 3)
* 'current_wx3': Current weather (3 of 3)
* 'low_cloud_type': Low-level sky cover (ex. FEW)
* 'low_cloud_level': Height of low-level sky cover, measured in feet
* 'medium_cloud_type': Medium-level sky cover (ex. OVC)
* 'medium_cloud_level': Height of medium-level sky cover, measured in feet
* 'high_cloud_type': High-level sky cover (ex. FEW)
* 'high_cloud_level': Height of high-level sky cover, measured in feet
* 'highest_cloud_type': Highest-level Sky cover (ex. CLR)
* 'highest_cloud_level:': Height of highest-level sky cover, measured in feet
* 'cloud_coverage': Cloud cover measured in oktas, taken from maximum of sky cover values
* 'air_temperature': Temperature, measured in degrees Celsius
* 'dew_point_temperature': Dew point, measured in degrees Celsius
* 'altimeter': Altimeter value, measured in inches of mercury
* 'current_wx1_symbol': Current weather symbol (1 of 3), WMO integer code from [WMO306]_
Attachment IV
* 'current_wx2_symbol': Current weather symbol (2 of 3), WMO integer code from [WMO306]_
Attachment IV
* 'current_wx3_symbol': Current weather symbol (3 of 3), WMO integer code from [WMO306]_
Attachment IV
* 'air_pressure_at_sea_level': Sea level pressure, derived from temperature, elevation
and altimeter value
* 'eastward_wind': Eastward component (u-compoment) of the wind vector, measured in knots
* 'northward_wind': Northward component (v-compoment) of the wind vector, measured in knots
"""
# Defaults year and/or month to present reported date if not provided
Expand Down Expand Up @@ -149,9 +155,9 @@ def parse_metar_to_dataframe(metar_text, *, year=None, month=None):
'air_temperature': metar_vars.temperature,
'dew_point_temperature': metar_vars.dewpoint,
'altimeter': metar_vars.altimeter,
'present_weather': metar_vars.current_wx1_symbol,
'past_weather': metar_vars.current_wx2_symbol,
'past_weather2': metar_vars.current_wx3_symbol},
'current_wx1_symbol': metar_vars.current_wx1_symbol,
'current_wx2_symbol': metar_vars.current_wx2_symbol,
'current_wx3_symbol': metar_vars.current_wx3_symbol},
index=[metar_vars.station_id])

# Convert to sea level pressure using calculation in metpy.calc
Expand Down Expand Up @@ -205,33 +211,35 @@ def parse_metar_to_named_tuple(metar_text, station_metadata, year, month):
Notes
-----
Returned data has named tuples with the following attributes:
'station_id': Station Identifier (ex. KLOT)
'latitude': Latitude of the observation, measured in degrees
'longitude': Longitude of the observation, measured in degrees
'elevation': Elevation of the observation above sea level, measured in meters
'date_time': Date and time of the observation, datetime object
'wind_direction': Direction the wind is coming from, measured in degrees
'wind_spd': Wind speed, measured in knots
'current_wx1': Current weather (1 of 3)
'current_wx2': Current weather (2 of 3)
'current_wx3': Current weather (3 of 3)
'skyc1': Sky cover (ex. FEW)
'skylev1': Height of sky cover 1, measured in feet
'skyc2': Sky cover (ex. OVC)
'skylev2': Height of sky cover 2, measured in feet
'skyc3': Sky cover (ex. FEW)
'skylev3': Height of sky cover 3, measured in feet
'skyc4': Sky cover (ex. CLR)
'skylev4:': Height of sky cover 4, measured in feet
'cloudcover': Cloud coverage measured in oktas, taken from maximum of sky cover values
'temperature': Temperature, measured in degrees Celsius
'dewpoint': Dewpoint, measured in degrees Celsius
'altimeter': Altimeter value, measured in inches of mercury, float
'current_wx1_symbol': Current weather symbol (1 of 3), integer
'current_wx2_symbol': Current weather symbol (2 of 3), integer
'current_wx3_symbol': Current weather symbol (3 of 3), integer
'sea_level_pressure': Sea level pressure, derived from temperature, elevation
and altimeter value, float
* 'station_id': Station Identifier (ex. KLOT)
* 'latitude': Latitude of the observation, measured in degrees
* 'longitude': Longitude of the observation, measured in degrees
* 'elevation': Elevation of the observation above sea level, measured in meters
* 'date_time': Date and time of the observation, datetime object
* 'wind_direction': Direction the wind is coming from, measured in degrees
* 'wind_speed': Wind speed, measured in knots
* 'current_wx1': Current weather (1 of 3)
* 'current_wx2': Current weather (2 of 3)
* 'current_wx3': Current weather (3 of 3)
* 'skyc1': Sky cover (ex. FEW)
* 'skylev1': Height of sky cover 1, measured in feet
* 'skyc2': Sky cover (ex. OVC)
* 'skylev2': Height of sky cover 2, measured in feet
* 'skyc3': Sky cover (ex. FEW)
* 'skylev3': Height of sky cover 3, measured in feet
* 'skyc4': Sky cover (ex. CLR)
* 'skylev4:': Height of sky cover 4, measured in feet
* 'cloudcover': Cloud coverage measured in oktas, taken from maximum of sky cover values
* 'temperature': Temperature, measured in degrees Celsius
* 'dewpoint': Dewpoint, measured in degrees Celsius
* 'altimeter': Altimeter value, measured in inches of mercury
* 'current_wx1_symbol': Current weather symbol (1 of 3), WMO integer code from [WMO306]_
Attachment IV
* 'current_wx2_symbol': Current weather symbol (2 of 3), WMO integer code from [WMO306]_
Attachment IV
* 'current_wx3_symbol': Current weather symbol (3 of 3), WMO integer code from [WMO306]_
Attachment IV
"""
# Decode the data using the parser (built using Canopy) the parser utilizes a grammar
Expand Down Expand Up @@ -455,33 +463,39 @@ def parse_metar_file(filename, *, year=None, month=None):
Notes
-----
The returned `pandas.DataFrame` has the following columns:
'station_id': Station Identifier (ex. KLOT)
'latitude': Latitude of the observation, measured in degrees
'longitude': Longitude of the observation, measured in degrees
'elevation': Elevation of the observation above sea level, measured in meters
'date_time': Date and time of the observation, datetime object
'wind_direction': Direction the wind is coming from, measured in degrees
'wind_spd': Wind speed, measured in knots
'current_wx1': Current weather (1 of 3)
'current_wx2': Current weather (2 of 3)
'current_wx3': Current weather (3 of 3)
'skyc1': Sky cover (ex. FEW)
'skylev1': Height of sky cover 1, measured in feet
'skyc2': Sky cover (ex. OVC)
'skylev2': Height of sky cover 2, measured in feet
'skyc3': Sky cover (ex. FEW)
'skylev3': Height of sky cover 3, measured in feet
'skyc4': Sky cover (ex. CLR)
'skylev4:': Height of sky cover 4, measured in feet
'cloudcover': Cloud coverage measured in oktas, taken from maximum of sky cover values
'temperature': Temperature, measured in degrees Celsius
'dewpoint': Dew point, measured in degrees Celsius
'altimeter': Altimeter value, measured in inches of mercury, float
'current_wx1_symbol': Current weather symbol (1 of 3), integer
'current_wx2_symbol': Current weather symbol (2 of 3), integer
'current_wx3_symbol': Current weather symbol (3 of 3), integer
'sea_level_pressure': Sea level pressure, derived from temperature, elevation
and altimeter value, float
* 'station_id': Station Identifier (ex. KLOT)
* 'latitude': Latitude of the observation, measured in degrees
* 'longitude': Longitude of the observation, measured in degrees
* 'elevation': Elevation of the observation above sea level, measured in meters
* 'date_time': Date and time of the observation, datetime object
* 'wind_direction': Direction the wind is coming from, measured in degrees
* 'wind_speed': Wind speed, measured in knots
* 'current_wx1': Current weather (1 of 3)
* 'current_wx2': Current weather (2 of 3)
* 'current_wx3': Current weather (3 of 3)
* 'low_cloud_type': Low-level sky cover (ex. FEW)
* 'low_cloud_level': Height of low-level sky cover, measured in feet
* 'medium_cloud_type': Medium-level sky cover (ex. OVC)
* 'medium_cloud_level': Height of medium-level sky cover, measured in feet
* 'high_cloud_type': High-level sky cover (ex. FEW)
* 'high_cloud_level': Height of high-level sky cover, measured in feet
* 'highest_cloud_type': Highest-level Sky cover (ex. CLR)
* 'highest_cloud_level:': Height of highest-level sky cover, measured in feet
* 'cloud_coverage': Cloud cover measured in oktas, taken from maximum of sky cover values
* 'air_temperature': Temperature, measured in degrees Celsius
* 'dew_point_temperature': Dew point, measured in degrees Celsius
* 'altimeter': Altimeter value, measured in inches of mercury
* 'current_wx1_symbol': Current weather symbol (1 of 3), WMO integer code from [WMO306]_
Attachment IV
* 'current_wx2_symbol': Current weather symbol (2 of 3), WMO integer code from [WMO306]_
Attachment IV
* 'current_wx3_symbol': Current weather symbol (3 of 3), WMO integer code from [WMO306]_
Attachment IV
* 'air_pressure_at_sea_level': Sea level pressure, derived from temperature, elevation
and altimeter value
* 'eastward_wind': Eastward component (u-compoment) of the wind vector, measured in knots
* 'northward_wind': Northward component (v-compoment) of the wind vector, measured in knots
"""
# Defaults year and/or month to present reported date if not provided
Expand Down
7 changes: 3 additions & 4 deletions src/metpy/plots/wx_symbols.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# SPDX-License-Identifier: BSD-3-Clause
"""Simplify using the weather symbol font.
See WMO manual 485 Vol 1 for more info on the symbols.
See WMO No.306 Attachment IV for more info on the symbols.
"""

try:
Expand Down Expand Up @@ -185,9 +185,8 @@ def alt_char(self, code, alt):
#####################################################################
# This dictionary is for mapping METAR present weather text codes
# to WMO codes for plotting wx symbols along with the station plots.
# Pages II-4-3 and II-4-4 of this document describes the difference between
# manned and automated stations:
# https://github.com/Unidata/MetPy/files/1151142/485_Vol_I_en.pdf
# See Attachment IV of WMO No.306 for more information:
# https://library.wmo.int/index.php?lvl=notice_display&id=13617
# It may become necessary to add automated station wx_codes in the future,
# but that will also require knowing the status of all stations.

Expand Down
6 changes: 3 additions & 3 deletions tests/io/test_metar.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,9 @@ def test_missing_values():
assert_almost_equal(df.current_wx1.values, np.nan)
assert_almost_equal(df.current_wx2.values, np.nan)
assert_almost_equal(df.current_wx3.values, np.nan)
assert_almost_equal(df.present_weather.values, 0)
assert_almost_equal(df.past_weather.values, 0)
assert_almost_equal(df.past_weather2.values, 0)
assert_almost_equal(df.current_wx1_symbol.values, 0)
assert_almost_equal(df.current_wx2_symbol.values, 0)
assert_almost_equal(df.current_wx3_symbol.values, 0)
assert_almost_equal(df.low_cloud_type.values, np.nan)
assert_almost_equal(df.medium_cloud_type.values, np.nan)
assert_almost_equal(df.high_cloud_type.values, np.nan)
Expand Down

0 comments on commit c005c61

Please sign in to comment.