Skip to content

Conversation

@sandorkertesz
Copy link
Collaborator

@sandorkertesz sandorkertesz commented Dec 8, 2025

Description

This PR adds the following array based methods:

Hybrid level (IFS model) computations:

# Get the A and B parameters of hybrid levels for a given configuration
hybrid_level_parameters(n_levels: int, model: str = "ifs")

# Compute pressure and related parameters on hybrid (IFS model) levels
pressure_on_hybrid_levels(A: ArrayLike, B: ArrayLike, sp: ArrayLike, 
      levels=None, alpha_top="ifs", output="full")

# Compute the geopotential thickness between the surface and hybrid (IFS model) full-levels
relative_geopotential_thickness_on_hybrid_levels(t: ArrayLike, q: ArrayLike, 
      A: ArrayLike, B: ArrayLike, sp: ArrayLike, alpha_top="ifs",)

# Compute the geopotential thickness between the surface and hybrid (IFS model) full-levels
relative_geopotential_thickness_on_hybrid_levels_from_alpha_delta(t: ArrayLike, q: ArrayLike, 
      alpha: ArrayLike, delta: ArrayLike,)

# Compute the geopotential on hybrid (IFS model) full-levels
geopotential_on_hybrid_levels(t: ArrayLike, q: ArrayLike, zs: ArrayLike,  
       A: ArrayLike, B: ArrayLike, sp: ArrayLike, alpha_top="ifs",)

# Compute the height on hybrid (IFS model) full-levels
height_on_hybrid_levels(  t: ArrayLike,  q: ArrayLike, zs: ArrayLike, 
     A: ArrayLike, B: ArrayLike, sp: ArrayLike,  
     alpha_top="ifs",
     h_type: str = "geometric", 
     h_reference: str = "ground",)

Interpolation:

# convenience method, calls interpolate_monotonic()
interpolate_hybrid_to_pressure_levels(data: ArrayLike,
    target_p: ArrayLike,
    A: ArrayLike,
    B: ArrayLike,
    sp: ArrayLike,
    alpha_top="ifs",
    interpolation: str = "linear",)

# convenience method, calls interpolate_monotonic()
interpolate_hybrid_to_height_levels(data: ArrayLike,
    t: ArrayLike,
    q: ArrayLike,
    zs: ArrayLike,
    A: ArrayLike,
    B: ArrayLike,
    sp: ArrayLike,
    target_h: ArrayLike,
    alpha_top="ifs",
    h_type: str = "geometric",
    h_reference: str = "ground",
    interpolation: str = "linear",
    aux_bottom_data=None,
    aux_bottom_h=None,
)

# convenience method, calls interpolate_monotonic()
def interpolate_pressure_to_height_levels(
    data: ArrayLike,
    z: ArrayLike,
    zs: ArrayLike,
    target_h: ArrayLike,
    h_type: str = "geometric",
    h_reference: str = "ground",
    interpolation: str = "linear",
    aux_bottom_data=None,
    aux_bottom_h=None,
)

# Interpolate data with the same type of source and target monotonic coordinate levels
interpolate_monotonic(data: ArrayLike,
    coord: Union[ArrayLike, list, tuple, float, int],
    target_coord: Union[ArrayLike, list, tuple, float, int],
    interpolation: str = "linear",
    aux_min_level_data=None,
    aux_min_level_coord=None,
    aux_max_level_data=None,
    aux_max_level_coord=None,
)

The following methods become deprecated:

  • pressure_at_model_levels
  • relative_geopotential_thickness
  • pressure_at_height_levels

Hybrid coordinates

For hybrid level computations/interpolations the pressure related parameters can be specified in two ways:

  • Option A: specify A, B, surface pressure and alpha_top. All the needed quantities can be computed from these
  • Option B: specify only the pressure related parameters that are actually needed, e.g. alpha, delta

So far all the methods uses Option A. The exception is relative_geopotential_thickness_on_hybrid_levels, this should be revisited though:

# Note: the actual computation here only uses alpha and delta!

relative_geopotential_thickness_on_hybrid_levels(t: ArrayLike, q: ArrayLike, 
      A: ArrayLike, B: ArrayLike, sp: ArrayLike, alpha_top="ifs",)

relative_geopotential_thickness_on_hybrid_levels_from_alpha_delta(t: ArrayLike, q: ArrayLike, 
      alpha: ArrayLike, delta: ArrayLike,)

Problems/questions:

  • very long method names if both Option A and B are needed (since we need to distingish them)
  • for option A we need to pass all the 4 parameters to all the hybrid coordinate methods. With this methods like interpolate_hybrid_to_height_levels has a large number of args/kwargs

Aux coordinates

The aux data/coord helps interpolation below or above the coordinate range. A typical use case is to interpolate to height levels between the surface and a lowest hybrid (model) level.

Right now, there is an inconsistency in the kwarg names. The generic interpolate_monotonic() uses aux_min_level_data and aux_min_level_coord. However, in interpolate_hybrid_to_height_levels() the corresponding kwags are called as aux_bottom_data and aux_bottom_h. The reason behind this is that in the generic case we do not now the name and nature of the coordinate so the terms min/max and coord have to be used. In the concrete case top/bottom have a meaning and the coordinate is already referred to as h in the other kwargs.

A decision has to be made whether it is the right approach or just confusing for users.

TODO

These will be sorted out in separate PRs

  • make the vertical interpolation array format agnostic
  • review args/kwargs names and order

Contributor Declaration

By opening this pull request, I affirm the following:

  • All authors agree to the Contributor License Agreement.
  • The code follows the project's coding standards.
  • I have performed self-review and added comments where needed.
  • I have added or updated tests to verify that my changes are effective and functional.
  • I have run all existing tests and confirmed they pass.

@codecov-commenter
Copy link

codecov-commenter commented Dec 8, 2025

Codecov Report

❌ Patch coverage is 94.22043% with 43 lines in your changes missing coverage. Please review.
✅ Project coverage is 96.97%. Comparing base (02051e5) to head (5d0fe03).
⚠️ Report is 8 commits behind head on develop.

Files with missing lines Patch % Lines
tests/vertical/test_xr_monotonic.py 43.47% 38 Missing and 1 partial ⚠️
tests/documentation/test_examples.py 85.18% 2 Missing and 2 partials ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop      #85      +/-   ##
===========================================
- Coverage    99.58%   96.97%   -2.61%     
===========================================
  Files           14       21       +7     
  Lines          962     1556     +594     
  Branches        15       33      +18     
===========================================
+ Hits           958     1509     +551     
- Misses           2       42      +40     
- Partials         2        5       +3     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@sandorkertesz sandorkertesz changed the title WIP: array based vertical interpolation Array based vertical interpolation Jan 5, 2026
@sandorkertesz sandorkertesz marked this pull request as ready for review January 5, 2026 15:49

def interpolate_hybrid_to_pressure_levels(
data: ArrayLike,
target_p: ArrayLike,
Copy link
Member

Choose a reason for hiding this comment

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

A very small point, but perhaps it is better to put target_p after sp in order to be more consistent in parameter ordering with the other functions - it would make it more consistent when passing positional parameters to these functions.

@iainrussell
Copy link
Member

Concerning the hybrid coordinates, I would marginally vote for option A, i.e. do not duplicate the functions in order to specify different kwargs. I think we can/should detect if too much/little information is passed in kwargs and raise an error if the user passes both kinds of information.

@iainrussell
Copy link
Member

Concerning the aux coords, I think the current approach is good - the generic monotonic function is for advanced users with specific needs, and it makes sense for it to have more generic parameters, while the higher-level functions have more 'useful' parameter names because we know the context.

@sandorkertesz sandorkertesz merged commit 02746ee into develop Jan 16, 2026
139 of 149 checks passed
@sandorkertesz sandorkertesz deleted the feature/array-vertical-interpolation branch January 16, 2026 14:45
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.

4 participants