eccodes/examples/python/bufr_read_tropical_cyclone.py

268 lines
9.0 KiB
Python
Raw Normal View History

2020-01-28 14:32:34 +00:00
# (C) Copyright 2005- ECMWF.
2015-12-16 11:03:37 +00:00
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
#
# In applying this licence, ECMWF does not waive the privileges and immunities granted to it by
# virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction.
#
# Python implementation: bufr_read_tropical_cyclone
#
# Description: how to read data of the ECMWF EPS tropical cyclone tracks encoded in BUFR format.
#
2020-06-25 11:28:34 +00:00
# Please note that tropical cyclone tracks can be encoded in various ways in BUFR.
# Therefore the code below might not work directly for other types of messages
# than the one used in the example. It is advised to use bufr_dump to
# understand the structure of the messages.
#
2015-12-16 11:03:37 +00:00
import collections
2021-09-15 11:28:05 +00:00
import sys
import traceback
2015-12-16 11:03:37 +00:00
from eccodes import *
2021-09-15 19:45:34 +00:00
INPUT = "../../data/bufr/tropical_cyclone.bufr"
2015-12-16 11:03:37 +00:00
VERBOSE = 1 # verbose error reporting
data = collections.defaultdict(dict)
2015-12-29 13:53:51 +00:00
2015-12-16 11:03:37 +00:00
def example():
2016-10-18 10:55:14 +00:00
# open BUFR file
2021-09-15 19:45:34 +00:00
f = open(INPUT, "rb")
2015-12-16 11:03:37 +00:00
cnt = 0
2015-12-16 11:03:37 +00:00
# loop for the messages in the file
while 1:
# get handle for message
2016-10-18 10:55:14 +00:00
bufr = codes_bufr_new_from_file(f)
if bufr is None:
2015-12-16 11:03:37 +00:00
break
2021-09-15 19:45:34 +00:00
print("**************** MESSAGE: ", cnt + 1, " *****************")
2015-12-16 11:03:37 +00:00
# we need to instruct ecCodes to expand all the descriptors
# i.e. unpack the data values
2021-09-15 19:45:34 +00:00
codes_set(bufr, "unpack", 1)
2015-12-16 11:03:37 +00:00
numObs = codes_get(bufr, "numberOfSubsets")
year = codes_get(bufr, "year")
2016-10-18 10:55:14 +00:00
month = codes_get(bufr, "month")
day = codes_get(bufr, "day")
hour = codes_get(bufr, "hour")
minute = codes_get(bufr, "minute")
2015-12-29 13:53:51 +00:00
2021-09-15 19:45:34 +00:00
print("Date and time: ", day, ".", month, ".", year, " ", hour, ":", minute)
2015-12-16 11:03:37 +00:00
stormIdentifier = codes_get(bufr, "stormIdentifier")
2021-09-15 19:45:34 +00:00
print("Storm identifier: ", stormIdentifier)
2015-12-16 11:03:37 +00:00
2016-10-18 10:55:14 +00:00
# How many different timePeriod in the data structure?
numberOfPeriods = 0
2015-12-16 11:03:37 +00:00
while True:
numberOfPeriods = numberOfPeriods + 1
2015-12-16 11:03:37 +00:00
try:
codes_get_array(bufr, "#%d#timePeriod" % numberOfPeriods)
except CodesInternalError as err:
2015-12-16 11:03:37 +00:00
break
# the numberOfPeriods includes the analysis (period=0)
2015-12-16 11:03:37 +00:00
# Get ensembleMemberNumber
2016-10-18 10:55:14 +00:00
memberNumber = codes_get_array(bufr, "ensembleMemberNumber")
memberNumberLen = len(memberNumber)
2015-12-29 13:53:51 +00:00
2015-12-16 11:03:37 +00:00
# Observed Storm Centre
2021-09-15 19:45:34 +00:00
significance = codes_get(bufr, "#1#meteorologicalAttributeSignificance")
latitudeCentre = codes_get(bufr, "#1#latitude")
longitudeCentre = codes_get(bufr, "#1#longitude")
2015-12-16 11:03:37 +00:00
if significance != 1:
2021-09-15 19:45:34 +00:00
print("ERROR: unexpected #1#meteorologicalAttributeSignificance")
2015-12-16 11:03:37 +00:00
return 1
2021-09-15 19:45:34 +00:00
if (latitudeCentre == CODES_MISSING_DOUBLE) and (
longitudeCentre == CODES_MISSING_DOUBLE
):
print("Observed storm centre position missing")
2015-12-16 11:03:37 +00:00
else:
2021-09-15 19:45:34 +00:00
print(
"Observed storm centre: latitude=",
latitudeCentre,
" longitude=",
longitudeCentre,
)
2015-12-16 11:03:37 +00:00
# Location of storm in perturbed analysis
2021-09-15 19:45:34 +00:00
significance = codes_get(bufr, "#2#meteorologicalAttributeSignificance")
2015-12-16 11:03:37 +00:00
if significance != 4:
2021-09-15 19:45:34 +00:00
print("ERROR: unexpected #2#meteorologicalAttributeSignificance")
2015-12-16 11:03:37 +00:00
return 1
2021-09-15 19:45:34 +00:00
latitudeAnalysis = codes_get_array(bufr, "#2#latitude")
longitudeAnalysis = codes_get_array(bufr, "#2#longitude")
pressureAnalysis = codes_get_array(bufr, "#1#pressureReducedToMeanSeaLevel")
2015-12-16 11:03:37 +00:00
# Location of Maximum Wind
2021-09-15 19:45:34 +00:00
significance = codes_get(bufr, "#3#meteorologicalAttributeSignificance")
2015-12-16 11:03:37 +00:00
if significance != 3:
2021-09-15 19:45:34 +00:00
print(
"ERROR: unexpected #3#meteorologicalAttributeSignificance=",
significance,
)
2015-12-16 11:03:37 +00:00
return 1
2021-09-15 19:45:34 +00:00
latitudeMaxWind0 = codes_get_array(bufr, "#3#latitude")
longitudeMaxWind0 = codes_get_array(bufr, "#3#longitude")
windMaxWind0 = codes_get_array(bufr, "#1#windSpeedAt10M")
2015-12-16 11:03:37 +00:00
2021-09-15 19:45:34 +00:00
if len(latitudeAnalysis) == len(memberNumber) and len(latitudeMaxWind0) == len(
memberNumber
):
for k in range(len(memberNumber)):
2021-09-15 19:45:34 +00:00
data[k][0] = [
latitudeAnalysis[k],
longitudeAnalysis[k],
pressureAnalysis[k],
latitudeMaxWind0[k],
longitudeMaxWind0[k],
windMaxWind0[k],
]
2015-12-16 11:03:37 +00:00
else:
for k in range(len(memberNumber)):
2021-09-15 19:45:34 +00:00
data[k][0] = [
latitudeAnalysis[0],
longitudeAnalysis[0],
pressureAnalysis[k],
latitudeMaxWind0[0],
longitudeMaxWind0[0],
windMaxWind0[k],
]
timePeriod = [0 for x in range(numberOfPeriods)]
for i in range(1, numberOfPeriods):
2015-12-16 11:03:37 +00:00
rank1 = i * 2 + 2
rank3 = i * 2 + 3
ivalues = codes_get_array(bufr, "#%d#timePeriod" % i)
2015-12-16 11:03:37 +00:00
if len(ivalues) == 1:
timePeriod[i] = ivalues[0]
2015-12-16 11:03:37 +00:00
else:
for j in range(len(ivalues)):
if ivalues[j] != CODES_MISSING_LONG:
timePeriod[i] = ivalues[j]
2015-12-29 13:53:51 +00:00
break
2015-12-16 11:03:37 +00:00
2016-10-18 10:55:14 +00:00
# Location of the storm
2021-09-15 19:45:34 +00:00
values = codes_get_array(
bufr, "#%d#meteorologicalAttributeSignificance" % rank1
)
if len(values) == 1:
significance = values[0]
2015-12-16 11:03:37 +00:00
else:
for j in range(len(values)):
if values[j] != CODES_MISSING_LONG:
significance = values[j]
2015-12-29 13:53:51 +00:00
break
if significance == 1:
2016-10-18 10:55:14 +00:00
lat = codes_get_array(bufr, "#%d#latitude" % rank1)
lon = codes_get_array(bufr, "#%d#longitude" % rank1)
2021-09-15 19:45:34 +00:00
press = codes_get_array(
bufr, "#%d#pressureReducedToMeanSeaLevel" % (i + 1)
)
2015-12-16 11:03:37 +00:00
else:
2021-09-15 19:45:34 +00:00
print(
"ERROR: unexpected meteorologicalAttributeSignificance=",
significance,
)
2015-12-16 11:03:37 +00:00
2016-10-18 10:55:14 +00:00
# Location of maximum wind
2021-09-15 19:45:34 +00:00
values = codes_get_array(
bufr, "#%d#meteorologicalAttributeSignificance" % rank3
)
if len(values) == 1:
significanceWind = values[0]
2015-12-16 11:03:37 +00:00
else:
for j in range(len(values)):
if values[j] != CODES_MISSING_LONG:
significanceWind = values[j]
2015-12-29 13:53:51 +00:00
break
2015-12-16 11:03:37 +00:00
if significanceWind == 3:
2016-10-18 10:55:14 +00:00
latWind = codes_get_array(bufr, "#%d#latitude" % rank3)
lonWind = codes_get_array(bufr, "#%d#longitude" % rank3)
wind10m = codes_get_array(bufr, "#%d#windSpeedAt10M" % (i + 1))
2015-12-16 11:03:37 +00:00
else:
2021-09-15 19:45:34 +00:00
print(
"ERROR: unexpected meteorologicalAttributeSignificance=",
significanceWind,
)
2015-12-16 11:03:37 +00:00
for k in range(len(memberNumber)):
2021-09-15 19:45:34 +00:00
data[k][i] = [
lat[k],
lon[k],
press[k],
latWind[k],
lonWind[k],
wind10m[k],
]
2015-12-16 11:03:37 +00:00
2021-09-15 19:36:30 +00:00
# ---------------------------------------- Print the values -------------
for m in range(len(memberNumber)):
print("== Member %d" % memberNumber[m])
print("step latitude longitude pressure latitude longitude wind")
for s in range(len(timePeriod)):
2021-09-15 19:45:34 +00:00
if (
data[m][s][0] != CODES_MISSING_DOUBLE
and data[m][s][1] != CODES_MISSING_DOUBLE
):
print(
" {0:>3d}{1}{2:>6.1f}{3}{4:>6.1f}{5}{6:>8.1f}{7}{8:>6.1f}{9}{10:>6.1f}{11}{12:>6.1f}".format(
timePeriod[s],
" ",
data[m][s][0],
" ",
data[m][s][1],
" ",
data[m][s][2],
" ",
data[m][s][3],
" ",
data[m][s][4],
" ",
data[m][s][5],
)
)
2015-12-16 11:03:37 +00:00
# -----------------------------------------------------------------------
cnt += 1
2015-12-16 11:03:37 +00:00
# release the BUFR message
2016-10-18 10:55:14 +00:00
codes_release(bufr)
2015-12-16 11:03:37 +00:00
# close the file
2015-12-16 11:03:37 +00:00
f.close()
def main():
try:
example()
except CodesInternalError as err:
2015-12-16 11:03:37 +00:00
if VERBOSE:
traceback.print_exc(file=sys.stderr)
else:
2021-09-15 19:45:34 +00:00
sys.stderr.write(err.msg + "\n")
2015-12-16 11:03:37 +00:00
return 1
2015-12-16 11:03:37 +00:00
if __name__ == "__main__":
sys.exit(main())