from eccodes import (
codes_grib_new_from_file, codes_get, codes_release
grib_file = 'cams_AQ_forecast.grib', codes_write)
# Dictionary matching ADS API key/value pairs to grib key/value pairs
definitions = {
'variable': {
'ammonia': {
'parameterNumber': 0,
'constituentType': 9},
'carbon_monoxide': {
'parameterNumber': 0,
'constituentType': 4},
'dust': {
'parameterNumber': 0, # Mass density kg/m3
'constituentType': 62001}, # Dust dry
'non_methane_vocs': {
'parameterNumber': 0,
'constituentType': 60013},
'nitrogen_monoxide': {
'parameterNumber': 0,
'constituentType': 11},
'nitrogen_dioxide': {
'parameterNumber': 0,
'constituentType': 5},
'ozone': {
'parameterNumber': 0, # Mass density kg/m3
'constituentType': 0},
'peroxyacyl_nitrates': {
'parameterNumber': 0,
'constituentType': 60018},
'particulate_matter_10um': {
'parameterNumber': 0,
'constituentType': 40008},
'particulate_matter_2.5um': {
'parameterNumber': 0,
'constituentType': 40009},
'pm2.5_anthropogenic_wood_burning_carbon': {
'parameterNumber': 0,
'constituentType': 62098},
'pm2.5_anthropogenic_fossil_fuel_carbon': {
'parameterNumber': 0,
'constituentType': 62097},
'pm10_wildfires': {
'parameterNumber': 0,
'constituentType': 62096},
'residential_elementary_carbon': {
'parameterNumber': 0,
'constituentType': 62094},
'secondary_inorganic_aerosol': {
'parameterNumber': 0,
'constituentType': 62099},
'sulphur_dioxide': {
'parameterNumber': 0,
'constituentType': 8},
'total_elementary_carbon': {
'parameterNumber': 0,
'constituentType': 62095},
'alder_pollen': {
'parameterNumber': 59, # Number Concentration (1/m3)
'constituentType': 62100},
'birch_pollen': {
'parameterNumber': 59,
'constituentType': 62101},
'grass_pollen': {
'parameterNumber': 59,
'constituentType': 62300},
'mugwort_pollen': {
'parameterNumber': 59,
'constituentType': 62201},
'olive_pollen': {
'parameterNumber': 59,
'constituentType': 64002},
'ragweed_pollen': {
'parameterNumber': 59,
'constituentType': 62200}
},
'model': {
'chimere': {
'centre': 85, # France
'subCentre': 200},
'dehm': {
'centre': 85,
'subCentre': 203},
'emep': {
'centre': 88, # Oslo
'subCentre': 0},
'ensemble': {
'centre': 85, # France
'subCentre': 2},
'euradim': {
'centre': 85, # France
'subCentre': 201},
'gemaq': {
'centre': 85,
'subCentre': 204},
'lotos': {
'centre': 99,
'subCentre': 0},
'match': {
'centre': 82, # Norrkoping
'subCentre': 98},
'mocage': {
'centre': 85, # Meteo France
'subCentre': 1},
'silam': {
'centre': 86, # Helsinki
'subCentre': 0},
}
}
def identify_field(msg): 'minni': {
"""Return a dict identifying the input grib message"""
'centre': 85,
field = {}'subCentre': 205},
for api_key, value_to_grib in definitions.items(): 'monarch': {
for api_value, grib_defn in value_to_grib.items():
'centre': 85,
# Does this message match the key/value pairs in grib_defn?
match = True
'subCentre': 206}
}
}
def identify_field(msg):
"""Return a dict identifying the input grib message"""
field = {}
for gribapi_key, value_to_grib_value in grib_defndefinitions.items():
for api_value, grib_defn in msg_value = codes_get(msg, grib_key,value_to_grib.items():
# Does this message match the key/value pairs in grib_defn?
match = True
ktype=type(grib_value))
for grib_key, grib_value if msg_value != grib_value:
in grib_defn.items():
msg_value = codes_get(msg, grib_key,
match = False
break
if match: ktype=type(grib_value))
field[api_key] if msg_value != apigrib_value:
if api_key not in field:
match = False
raise Exception('Unrecognised field')
return field
# Loop over messages in a grib file, identifying all fieldsbreak
count = 0
with open(grib_file) as f:
while True:
if match:
msg = codes_grib_new_from_file(f)
if msg is None: field[api_key] = api_value
if api_key not in breakfield:
count += 1
raise Exception('Unrecognised field')
return field
def trymain(grib_file, output_filename_template=None):
"""Read all fields in the GRIB file, identify the model fieldand = identify_field(msg)variable of
finally:
codes_release(msg)
each, and optionally write them to output files, split by model or
variable or both.
print('Field ' + str(count) + 'Any is:instance 'of + repr(field))
"<model>" or "<variable>" in output_filename_template
will be replaced by the associated model or variable string for the
field, e.g. output_filename_template='<model>.<variable>.grib'
"""
fields_written = {}
# Loop over messages in a grib file, identifying all fields
count = 0
with open(grib_file) as fin:
while True:
msg = codes_grib_new_from_file(fin)
if msg is None:
break
count += 1
try:
field = identify_field(msg)
print('Field ' + str(count) + ' is: ' + repr(field))
# Write the field to an output file?
if output_filename_template:
name = output_filename_template
for k, v in field.items():
name = name.replace(f'<{k}>', v)
if name not in fields_written:
fields_written[name] = 0
mode = 'w'
else:
mode = 'a'
with open(name, mode + 'b') as fout:
codes_write(msg, fout)
fields_written[name] += 1
finally:
codes_release(msg)
for name, n in fields_written.items():
print(f'Wrote {n} fields to {name}')
if __name__ == '__main__':
main('mydata.grib',
output_filename_template='<model>.<variable>.grib') |