Skip to content

New plugin to calculate the standard geopotential height#2338

Open
mo-robertneal wants to merge 2 commits into
metoppv:masterfrom
mo-robertneal:EPPT_2873_d-factors_functionality
Open

New plugin to calculate the standard geopotential height#2338
mo-robertneal wants to merge 2 commits into
metoppv:masterfrom
mo-robertneal:EPPT_2873_d-factors_functionality

Conversation

@mo-robertneal

Copy link
Copy Markdown
Contributor

A new plugin is added to generate the standard geopotential height using a lookup table, where values are read based on an input pressure level.

Usage:

import iris
import improver
incube = iris.load_cube(
    "/data/users/eppdev/EPP_data_cache/global/20260319T1200Z/20260325T1200Z-PT0144H00M-geopotential_height_on_pressure_levels.nc")

from improver.standard_geopotential_height.standard_geopotential_height import (
    StandardGeopotentialHeight,
)
plugin = StandardGeopotentialHeight()

outcube = plugin(incube)

@alexslittle alexslittle left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hi Rob, I'm less confident on the engineering side of this PR, but the science implementation (formulae, parameter values, etc.) look fine, I've cross-referenced them with the details in the ticket.

@ryan-cocking-mo ryan-cocking-mo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The code looks good, but I've made some suggestions around documentation.

return np.broadcast_to(z_reshaped, template.shape).astype(np.float32)

def process(self, geopotential_height_cube: Cube) -> Cube:
"""Create standard geopotential height cube using pressure-filtered template.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
"""Create standard geopotential height cube using pressure-filtered template.
"""Create standard geopotential height cube using pressure-filtered template cube.

Comment on lines +5 to +21
"""Module containing plugin to calculate standard geopotential height on pressure levels.

The standard geopotential height is calculated using the ICAO standard atmosphere
lookup table and barometric formulae described in the D-Factors workflow design.

Pressure handling:
Only pressure levels within the configured range (default 10–1000 hPa) are
processed and included in the output cube. Any levels outside this range are
excluded from the returned cube (i.e. the pressure dimension is reduced).

Equations:
If β = 0:
Zstd(p) = Zb - (R Tb / g) ln(p / Pb)

If β ≠ 0:
Zstd(p) = Zb + (Tb / β) [ (p / Pb)^(-β R / g) - 1 ]
"""

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
"""Module containing plugin to calculate standard geopotential height on pressure levels.
The standard geopotential height is calculated using the ICAO standard atmosphere
lookup table and barometric formulae described in the D-Factors workflow design.
Pressure handling:
Only pressure levels within the configured range (default 101000 hPa) are
processed and included in the output cube. Any levels outside this range are
excluded from the returned cube (i.e. the pressure dimension is reduced).
Equations:
If β = 0:
Zstd(p) = Zb - (R Tb / g) ln(p / Pb)
If β0:
Zstd(p) = Zb + (Tb / β) [ (p / Pb)^(-β R / g) - 1 ]
"""
"""Module containing plugin to calculate standard geopotential height on pressure levels."""

This extra information should be included in the docstring for the StandardGeopotentialHeight class. This follows convention, avoids repeating information, and allows the class (rather than the module) to be queried for this detailed documentation, e.g. StandardGeopotentialHeight.__doc__.

The text of both the header and the __init__ method get rendered on the same web page in the IMPROVER docs.

Comment on lines +75 to +90
Args:
model_id_attr:
Name of the attribute used to identify the source model. If provided,
mandatory attributes will be generated consistently.
pressure_min_hpa:
Minimum pressure processed (hPa). Defaults to 10 hPa.
pressure_max_hpa:
Maximum pressure processed (hPa). Defaults to 1000 hPa.
"""

def __init__(
self,
model_id_attr: Optional[str] = None,
pressure_min_hpa: float = 10.0,
pressure_max_hpa: float = 1000.0,
) -> None:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
Args:
model_id_attr:
Name of the attribute used to identify the source model. If provided,
mandatory attributes will be generated consistently.
pressure_min_hpa:
Minimum pressure processed (hPa). Defaults to 10 hPa.
pressure_max_hpa:
Maximum pressure processed (hPa). Defaults to 1000 hPa.
"""
def __init__(
self,
model_id_attr: Optional[str] = None,
pressure_min_hpa: float = 10.0,
pressure_max_hpa: float = 1000.0,
) -> None:
def __init__(
self,
model_id_attr: Optional[str] = None,
pressure_min_hpa: float = 10.0,
pressure_max_hpa: float = 1000.0,
) -> None:
"""
Initialise the class.
Args:
model_id_attr:
Name of the attribute used to identify the source model. If provided,
mandatory attributes will be generated consistently.
pressure_min_hpa:
Minimum pressure processed (hPa). Defaults to 10 hPa.
pressure_max_hpa:
Maximum pressure processed (hPa). Defaults to 1000 hPa.
"""

Docstring argument list for __init__ method was in wrong place.

Comment on lines +68 to +73
"""Calculate standard geopotential height on the pressure levels of an input cube.

The input cube is used as a template. The output values depend only on the
pressure coordinate points and are broadcast across the remaining dimensions.

Any pressure levels outside the configured range are excluded from the output.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Please move information from the header to here, as per a previous comment.

The input cube is used as a template. The output values depend only on the
pressure coordinate points and are broadcast across the remaining dimensions.

Any pressure levels outside the configured range are excluded from the output.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Please move information from the header to here, as per a previous comment.

) from exc

def _extract_expected_pressure_levels(self, cube: Cube, pressure_coord: Coord) -> Cube:
"""Extract pressure levels within the configured expected range.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Docstring needs Args:.

Comment on lines +97 to +101
"""Return the pressure coordinate from the cube.

Raises:
ValueError: If a suitable pressure coordinate is not found.
"""

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
"""Return the pressure coordinate from the cube.
Raises:
ValueError: If a suitable pressure coordinate is not found.
"""
"""Return the pressure coordinate from the cube."""

Simple enough that I think this can be a one-liner.


@staticmethod
def _to_hpa(pressure_coord: Coord) -> np.ndarray:
"""Convert pressure coordinate points to hPa without mutating the cube."""

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Docstring needs Args:, Returns:, and Raises:.

Comment on lines +55 to +56
zb_m: float
tb_k: float

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
zb_m: float
tb_k: float
tb_k: float
zb_m: float

Flipped to match order written in docstring.

Zstd(p) = Zb - (R Tb / g) ln(p / Pb)

If β ≠ 0:
Zstd(p) = Zb + (Tb / β) [ (p / Pb)^(-β R / g) - 1 ]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If physical equations are going to be included in code documentation, I think there should be a line here that states what the equation symbols represent, e.g. where β is blahblah, Zb is blahblah, etc. For the benefit of non-meteorologists :) .

An alternative is to instead add these formatted equations into an .rst file and .. include:: them in the docstring from doc/source/extended_documentation. This is not essential, but it does render nicely for the website documentation. See an example here from the contrails plugin.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants