-
Notifications
You must be signed in to change notification settings - Fork 3
Drive vcoord_type and origin_z from grib message #120
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,12 +11,38 @@ | |
import xarray as xr | ||
from earthkit.data.writers import write # type: ignore | ||
|
||
# Local | ||
from . import grib_decoder | ||
|
||
VCOORD_TYPE = { | ||
"generalVertical": ("model_level", -0.5), | ||
"generalVerticalLayer": ("model_level", 0.0), | ||
"isobaricInPa": ("pressure", 0.0), | ||
} | ||
|
||
|
||
def extract(metadata): | ||
[vref_flag] = grib_decoder.get_code_flag( | ||
metadata.get("resolutionAndComponentFlags"), [5] | ||
) | ||
level_type = metadata.get("typeOfLevel") | ||
vcoord_type, zshift = VCOORD_TYPE.get(level_type, (level_type, 0.0)) | ||
|
||
return { | ||
"parameter": metadata.as_namespace("parameter"), | ||
"geography": metadata.as_namespace("geography"), | ||
"vref": "native" if vref_flag else "geo", | ||
"vcoord_type": vcoord_type, | ||
"origin_z": zshift, | ||
} | ||
|
||
|
||
def override(message: bytes, **kwargs: typing.Any) -> dict[str, typing.Any]: | ||
"""Override GRIB metadata contained in message. | ||
|
||
Note that no special consideration is made for maintaining consistency when | ||
overriding template definition keys such as productDefinitionTemplateNumber. | ||
Note that the origin components in x and y will be unset. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I cant see where in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah this note is a bit outdated, in the current implementation, the origin_xy values just remain untouched. I'll update the note There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes thanks, since untouched and unset have different meanings it would be good to update |
||
|
||
Parameters | ||
---------- | ||
|
@@ -40,8 +66,7 @@ def override(message: bytes, **kwargs: typing.Any) -> dict[str, typing.Any]: | |
|
||
return { | ||
"message": out.getvalue(), | ||
"geography": md.as_namespace("geography"), | ||
"parameter": md.as_namespace("parameter"), | ||
**extract(md), | ||
} | ||
|
||
|
||
|
@@ -112,8 +137,8 @@ def compute_origin(ref_grid: Grid, field: xr.DataArray) -> dict[str, float]: | |
y0_key = "latitudeOfFirstGridPointInDegrees" | ||
|
||
return { | ||
"x": np.round((geo[x0_key] % 360 - x0) / dx, 1), | ||
"y": np.round((geo[y0_key] - y0) / dy, 1), | ||
"origin_x": np.round((geo[x0_key] % 360 - x0) / dx, 1), | ||
"origin_y": np.round((geo[y0_key] - y0) / dy, 1), | ||
} | ||
|
||
|
||
|
@@ -138,4 +163,4 @@ def set_origin_xy(ds: dict[str, xr.DataArray], ref_param: str) -> None: | |
|
||
ref_grid = load_grid_reference(ds[ref_param].message) | ||
for field in ds.values(): | ||
field.attrs["origin"] |= compute_origin(ref_grid, field) | ||
field.attrs |= compute_origin(ref_grid, field) |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -96,6 +96,15 @@ def _update_grid(field: xr.DataArray, dim: Literal["x", "y"]) -> dict[str, Any]: | |||||
) | ||||||
|
||||||
|
||||||
def _update_vertical(field) -> dict[str, Any]: | ||||||
if field.vcoord_type != "model_level": | ||||||
raise ValueError("Field.vcoord_type must model_level") | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
return metadata.override( | ||||||
field.message, | ||||||
typeOfLevel="generalVerticalLayer", | ||||||
) | ||||||
|
||||||
|
||||||
def destagger( | ||||||
field: xr.DataArray, | ||||||
dim: Literal["x", "y", "z"], | ||||||
|
@@ -128,7 +137,7 @@ def destagger( | |||||
""" | ||||||
dims = list(field.sizes.keys()) | ||||||
if dim == "x" or dim == "y": | ||||||
if field.origin[dim] != 0.5: | ||||||
if field.attrs[f"origin_{dim}"] != 0.5: | ||||||
raise ValueError | ||||||
return ( | ||||||
xr.apply_ufunc( | ||||||
|
@@ -140,10 +149,10 @@ def destagger( | |||||
keep_attrs=True, | ||||||
) | ||||||
.transpose(*dims) | ||||||
.assign_attrs(origin=field.origin | {dim: 0.0}, **_update_grid(field, dim)) | ||||||
.assign_attrs({f"origin_{dim}": 0.0}, **_update_grid(field, dim)) | ||||||
) | ||||||
elif dim == "z": | ||||||
if field.origin[dim] != -0.5: | ||||||
if field.origin_z != -0.5: | ||||||
raise ValueError | ||||||
return ( | ||||||
xr.apply_ufunc( | ||||||
|
@@ -155,7 +164,7 @@ def destagger( | |||||
keep_attrs=True, | ||||||
) | ||||||
.transpose(*dims) | ||||||
.assign_attrs(origin=field.origin | {dim: 0.0}) | ||||||
.assign_attrs({f"origin_{dim}": 0.0}, **_update_vertical(field)) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why does destaggering There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All staggered fields should be defined on the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But why then does it change from There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe that's just the way that those level types are defined. |
||||||
) | ||||||
|
||||||
raise ValueError("Unknown dimension", dim) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How come surface and hybrid keys are removed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
typeOfLevel
is the same as thevcoord_type
for those so they're actually handled by the pass throughThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah ok thanks