Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ Features added
OPeNDAP URLs.
* `iris.experimental.raster.export_geotiff` now provides experimental
GeoTiff export functionality.
* Cubes with no vertical coordinate can now be output to Grib format. In these
cases, "Type of first fixed surface" is set to 1, "ground or water surface".
( This is a common usage for data with no defined level, but may not be
strictly correct - see https://github.com/SciTools/iris/issues/519 ).

Bugs fixed
----------
Expand Down
4 changes: 4 additions & 0 deletions docs/iris/src/whatsnew/1.4.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ A summary of the main features added with version 1.4:
OPeNDAP URLs.
* :func:`iris.experimental.raster.export_geotiff` now provides experimental
GeoTiff export functionality.
* Cubes with no vertical coordinate can now be output to Grib format. In these
cases, "Type of first fixed surface" is set to 1, "ground or water surface".
( This is a common usage for data with no defined level, but may not be
strictly correct - see https://github.com/SciTools/iris/issues/519 ).

Bugs fixed
----------
Expand Down
13,945 changes: 11,243 additions & 2,702 deletions etc/cf-standard-name-table.xml

Large diffs are not rendered by default.

271 changes: 41 additions & 230 deletions lib/iris/etc/grib_rules.txt
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,15 @@ CoordAndDims(DimCoord(grib._x_points, grib._x_coord_name, units='degrees', coord



####################
### Grib1 params ###
####################
######################################################################
### A few selected standard Grib1 params (none yet in grib_cf_map) ###
######################################################################

IF
grib.edition == 1
grib.table2Version < 128
grib.indicatorOfParameter == 11
grib._cf_data is None
THEN
CMAttribute("standard_name", "air_temperature")
CMAttribute("units", "kelvin")
Expand All @@ -67,6 +68,7 @@ IF
grib.edition == 1
grib.table2Version < 128
grib.indicatorOfParameter == 33
grib._cf_data is None
THEN
CMAttribute("standard_name", "x_wind")
CMAttribute("units", "m s-1")
Expand All @@ -75,13 +77,31 @@ IF
grib.edition == 1
grib.table2Version < 128
grib.indicatorOfParameter == 34
grib._cf_data is None
THEN
CMAttribute("standard_name", "y_wind")
CMAttribute("units", "m s-1")

###############################################################
### Hook for ECMWF GRIB1 local params listed in grib_cf_map ###
###############################################################

IF
grib.edition == 1
grib._cf_data is not None
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a mismatch between the name _cf_data and the comment "ECMWF GRIB1 local params"

THEN
CMAttribute("standard_name", grib._cf_data.standard_name)
CMAttribute("long_name", grib._cf_data.standard_name or grib._cf_data.long_name)
CMAttribute("units", grib._cf_data.units)

##################################################################
### Construct magic names for otherwise unrecognised phenomena ###
##################################################################

IF
grib.edition == 1
grib.table2Version >= 128
grib._cf_data is None
THEN
CMAttribute("long_name", "UNKNOWN LOCAL PARAM " + str(grib.indicatorOfParameter) + "." + str(grib.table2Version))
CMAttribute("units", "???")
Expand All @@ -94,238 +114,18 @@ THEN
CMAttribute("long_name", "UNKNOWN LOCAL PARAM " + str(grib.indicatorOfParameter) + "." + str(grib.table2Version))
CMAttribute("units", "???")

####################
### Grib2 params ###
####################

## Note: Do we really want to be maintaining a list of these? There's lots of them...
## Future grib api versions may have "cfName" available for more params...

IF
grib.edition == 2
grib.discipline == 0
grib.parameterCategory == 0
grib.parameterNumber == 0
THEN
CMAttribute("standard_name", "air_temperature")
CMAttribute("units", "kelvin")

IF
grib.edition == 2
grib.discipline == 0
grib.parameterCategory == 0
grib.parameterNumber == 2
THEN
CMAttribute("standard_name", "potential_temperature")
CMAttribute("units", "K")

IF
grib.edition == 2
grib.discipline == 0
grib.parameterCategory == 1
grib.parameterNumber == 0
THEN
CMAttribute("standard_name", "specific_humidity")
CMAttribute("units", "kg kg-1")

IF
grib.edition == 2
grib.discipline == 0
grib.parameterCategory == 1
grib.parameterNumber == 1
THEN
CMAttribute("standard_name", "relative_humidity")
CMAttribute("units", "%")

IF
grib.edition == 2
grib.discipline == 0
grib.parameterCategory == 1
grib.parameterNumber == 3
THEN
CMAttribute("standard_name", "precipitable_water")
CMAttribute("units", "kg m-2")

IF
grib.edition == 2
grib.discipline == 0
grib.parameterCategory == 1
grib.parameterNumber == 22
THEN
CMAttribute("standard_name", "cloud_mixing_ratio")
CMAttribute("units", "kg kg-1")

IF
grib.edition == 2
grib.discipline == 0
grib.parameterCategory == 1
grib.parameterNumber == 13
THEN
CMAttribute("standard_name", "water_equivalent_of_accumulated_snow_depth")
CMAttribute("units", "kg m-2")
#####################################
### Grib2 params from grib_cf_map ###
#####################################

IF
grib.edition == 2
grib.discipline == 0
grib.parameterCategory == 2
grib.parameterNumber == 1
grib._cf_data is not None
THEN
CMAttribute("standard_name", "wind_speed")
CMAttribute("units", "m s-1")

IF
grib.edition == 2
grib.discipline == 0
grib.parameterCategory == 2
grib.parameterNumber == 2
THEN
CMAttribute("standard_name", "x_wind")
CMAttribute("units", "m s-1")

IF
grib.edition == 2
grib.discipline == 0
grib.parameterCategory == 2
grib.parameterNumber == 3
THEN
CMAttribute("standard_name", "y_wind")
CMAttribute("units", "m s-1")

IF
grib.edition == 2
grib.discipline == 0
grib.parameterCategory == 2
grib.parameterNumber == 8
THEN
CMAttribute("standard_name", "vertical_velocity_(pressure)")
CMAttribute("units", "Pa s-1")

IF
grib.edition == 2
grib.discipline == 0
grib.parameterCategory == 2
grib.parameterNumber == 10
THEN
CMAttribute("standard_name", "absolute_vorticity")
CMAttribute("units", "s-1")

IF
grib.edition == 2
grib.discipline == 0
grib.parameterCategory == 3
grib.parameterNumber == 0
THEN
CMAttribute("standard_name", "pressure")
CMAttribute("units", "Pa")

IF
grib.edition == 2
grib.discipline == 0
grib.parameterCategory == 3
grib.parameterNumber == 1
THEN
CMAttribute("standard_name", "pressure_reduced_to_msl")
CMAttribute("units", "Pa")

IF
grib.edition == 2
grib.discipline == 0
grib.parameterCategory == 3
grib.parameterNumber == 3
THEN
CMAttribute("standard_name", "icao_standard_atmosphere_reference_height")
CMAttribute("units", "m")

IF
grib.edition == 2
grib.discipline == 0
grib.parameterCategory == 3
grib.parameterNumber == 5
THEN
CMAttribute("standard_name", "geopotential_height")
CMAttribute("units", "gpm")

IF
grib.edition == 2
grib.discipline == 0
grib.parameterCategory == 3
grib.parameterNumber == 9
THEN
CMAttribute("standard_name", "geopotential_height_anomaly")
CMAttribute("units", "gpm")

IF
grib.edition == 2
grib.discipline == 0
grib.parameterCategory == 6
grib.parameterNumber == 1
THEN
CMAttribute("standard_name", "total_cloud_cover")
CMAttribute("units", "%")

IF
grib.edition == 2
grib.discipline == 0
grib.parameterCategory == 6
grib.parameterNumber == 6
THEN
CMAttribute("standard_name", "cloud_water")
CMAttribute("units", "kg m-2")

IF
grib.edition == 2
grib.discipline == 0
grib.parameterCategory == 7
grib.parameterNumber == 6
THEN
CMAttribute("standard_name", "convective_available_potential_energy")
CMAttribute("units", "J kg-1")

IF
grib.edition == 2
grib.discipline == 0
grib.parameterCategory == 7
grib.parameterNumber == 7
THEN
CMAttribute("standard_name", "convective_inhibition")
CMAttribute("units", "J kg-1")

IF
grib.edition == 2
grib.discipline == 0
grib.parameterCategory == 7
grib.parameterNumber == 8
THEN
CMAttribute("standard_name", "storm_relative_helicity")
CMAttribute("units", "J kg-1")

IF
grib.edition == 2
grib.discipline == 0
grib.parameterCategory == 14
grib.parameterNumber == 0
THEN
CMAttribute("standard_name", "total_ozone")
CMAttribute("units", "Dobson")

IF
grib.edition == 2
grib.discipline == 2
grib.parameterCategory == 0
grib.parameterNumber == 0
THEN
CMAttribute("standard_name", "land_cover")
CMAttribute("units", "proportion")

IF
grib.edition == 2
grib.discipline == 10
grib.parameterCategory == 2
grib.parameterNumber == 0
THEN
CMAttribute("standard_name", "ice_cover")
CMAttribute("units", "proportion")

CMAttribute("standard_name", grib._cf_data.standard_name)
CMAttribute("long_name", grib._cf_data.long_name)
CMAttribute("units", grib._cf_data.units)

#######################################
### Grib1 verification dates ##########
Expand Down Expand Up @@ -557,6 +357,15 @@ grib.levelType == 'pl'
THEN
CoordAndDims(DimCoord(points=grib.level, long_name="pressure", units="hPa"))

# Handle grib1 phenomena which define an "implied" height value, for example
# "2-metre temperature". (note: Grib2 rules out such things)
IF
grib.edition == 1
grib.levelType == 'sfc'
grib._cf_data is not None
grib._cf_data.set_height is not None
THEN
CoordAndDims(DimCoord(points=grib._cf_data.set_height, long_name="height", units="m", attributes={'positive':'up'}))


###################
Expand Down Expand Up @@ -632,3 +441,5 @@ IF
grib.productDefinitionTemplateNumber not in (0, 8)
THEN
CMCustomAttribute("GRIB_LOAD_WARNING",("unsupported GRIB%d ProductDefinitionTemplate: #4.%d" % (grib.edition, grib.productDefinitionTemplateNumber)))


Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,10 @@
iris.proxy.apply_proxy('gribapi', globals())

import iris.coord_systems as coord_systems
# NOTE: careful here, to avoid circular imports (as iris imports grib)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove please

from iris.fileformats.grib import grib_phenom_translation as gptx
from iris.fileformats.grib import grib_save_rules
import iris.unit
import grib_save_rules



Expand Down Expand Up @@ -308,7 +310,29 @@ def _compute_extra_keys(self):
'_x_coord_name':unknown_string, '_y_coord_name':unknown_string,
# These are here to avoid repetition in the rules files,
# and reduce the very long line lengths.
'_x_points':None, '_y_points':None}
'_x_points':None, '_y_points':None,
'_cf_data':None}

# cf phenomenon translation
if edition == 1:
# Get centre code (N.B. self.centre has default type = string)
centre_number = gribapi.grib_get_long(self.grib_message, "centre")
# Look for a known grib1-to-cf translation (or None).
cf_data = gptx.grib1_phenom_to_cf_info(
table2_version=self.table2Version,
centre_number=centre_number,
param_number=self.indicatorOfParameter)
self.extra_keys['_cf_data'] = cf_data
elif edition == 2:
# Don't attempt to interpret params if 'master tables version' is
# 255, as local params may then have same codes as standard ones.
if self.tablesVersion != 255:
# Look for a known grib2-to-cf translation (or None).
cf_data = gptx.grib2_phenom_to_cf_info(
param_discipline=self.discipline,
param_category=self.parameterCategory,
param_number=self.parameterNumber)
self.extra_keys['_cf_data'] = cf_data

#reference date
self.extra_keys['_referenceDateTime'] = \
Expand Down
Loading