RealizationSelection plugin modification#2364
Open
gavinevans wants to merge 23 commits into
Open
Conversation
…erent inputs can be reset to have a common forecast_reference_time.
…n and improve error handling.
…_realization_selection_error * mobt_783_reset_cycletime_when_clustering: Modifications Modifications following review. Modifications following review comments. Add handling for cube without forecast_reference_time coordinate. Add cycletime argument to realization_cluster_and_match, so that different inputs can be reset to have a common forecast_reference_time.
…ion_selection_error * upstream/master: Support resetting the forecast_reference_time when clustering (metoppv#2359) Added support for equality operator (metoppv#2362)
2 tasks
houndci-bot
reviewed
Jun 9, 2026
| model_id_attr (str): | ||
| The name of the cube attribute used to identify the model source. | ||
| cycletime (str): | ||
| The forecast_reference_time on the input forecast cubes will be reset to |
| ) | ||
| result_cube = MergeCubes()(CubeList(selected_cubes)) | ||
| if "cluster_sources" in cluster_cube.attributes: | ||
| result_cube.attributes["cluster_sources"] = cluster_cube.attributes[ |
| n_realizations = len(model_cube.coord("realization").points) | ||
| if realization_index < 0 or realization_index >= n_realizations: | ||
| raise ValueError( | ||
| f"Realization index {realization_index} is out of bounds for " |
| if not model_cube.coords("realization"): | ||
| selected = model_cube | ||
| selected.add_aux_coord( | ||
| AuxCoord(cluster_idx, standard_name="realization", units="1") |
|
|
||
| Raises: | ||
| ValueError: If no forecast cube is found for a specified model name. | ||
| ValueError: If a specified realization index is out of bounds for the |
| """ | ||
| Find the nearest forecast period in the secondary mapping to the requested | ||
| forecast period. | ||
| Find the nearest forecast period in the secondary mapping that is greater |
| reset to this value. The forecast periods will be adjusted accordingly | ||
| with the validity times kept fixed. cycletime should be provided in the | ||
| format YYYYMMDDTHHMMZ (e.g., 20240101T0000Z). If not provided, the | ||
| forecast_reference_time on the input cubes will be left unchanged. |
| cycletime: The forecast_reference_time on the input forecast cubes will be | ||
| reset to this value. The forecast periods will be adjusted accordingly | ||
| with the validity times kept fixed. cycletime should be provided in the | ||
| format YYYYMMDDTHHMMZ (e.g., 20240101T0000Z). If not provided, the |
|
|
||
| cycletime: The forecast_reference_time on the input forecast cubes will be | ||
| reset to this value. The forecast periods will be adjusted accordingly | ||
| with the validity times kept fixed. cycletime should be provided in the |
| source. | ||
|
|
||
| cycletime: The forecast_reference_time on the input forecast cubes will be | ||
| reset to this value. The forecast periods will be adjusted accordingly |
…ion_selection_error * upstream/master: (22 commits) Refine realization coordinate handling when clustering (metoppv#2361) Mobt1205 better accum temporal interp (metoppv#2390) Refactor pollen forecast period setting (metoppv#2385) Changes to how we do distance_to calculations (metoppv#2379) Mobt 1138 ignore git hash cli (metoppv#2388) Ensure that the SubperiodSelector plugin and CLI returns a cube with the model_id_attr, if requested. (metoppv#2386) Add option to update a scalar coordinate attribute as part of the StandardiseMetadata plugin (metoppv#2378) Allow cube-extraction to use a formatted time string (metoppv#2380) Removing a name from CONTRIBUTING.md (metoppv#2384) Support more complex forecast period filtering when training QRF (metoppv#2383) Mobt1161 precip phase decision tree (metoppv#2376) MOBT-1148 Add subperiod-selector tool (metoppv#2373) Revert "change ApplyDecisionTree categorical cube dtype from int32 to int16 (…" (metoppv#2382) change ApplyDecisionTree categorical cube dtype from int32 to int16 (metoppv#2371) Changed implementation from clipping to masking + added Unit Tests (metoppv#2366) Adding kwarg as CLI argument & updating acceptance tests. (metoppv#2377) Refactor Pollen index for daily and hourly to single plugin (metoppv#2372) EPPT-3259 fix fsi duplicate metadata (metoppv#2370) Changes to Pollen classes for refactoring cube long names and units of concentration (metoppv#2368) Eppt 3223 lifted index investigate why the values are wrong (metoppv#2365) ...
houndci-bot
reviewed
Jun 9, 2026
| model_id_attr: The name of the cube attribute used to identify the model | ||
| source. | ||
|
|
||
| cycletime: The forecast_reference_time on the input forecast cubes will be |
| frt=datetime(2017, 1, 10, 3), | ||
| ) | ||
| deterministic_cube.coord("forecast_period").points = [3600] | ||
| deterministic_cube.attributes["mosg__model_configuration"] = "primary_model" |
|
|
||
|
|
||
| def test_realizationselection_deterministic_input_no_realization_coord(): | ||
| """Test deterministic forecast input is handled without a realization coord.""" |
| cubes = CubeList([cluster_cube]) | ||
|
|
||
| plugin = RealizationSelection(forecast_period=3600) | ||
| with pytest.raises(ValueError, match="No forecast cubes found in input cubes."): |
| } | ||
| cluster_cube = _make_cluster_cube_for_selection(primary_map, secondary_map) | ||
| # Forecast cubes: secondary model, fp=4000 (nearest is 3600) | ||
| # Forecast cubes: secondary model, fp=4000 (nearest greater-or-equal is 5400) |
| def test_realizationselection_secondary_nearest_fp(): | ||
| """Test nearest forecast period is used from secondary mapping.""" | ||
| def test_realizationselection_secondary_nearest_greater_or_equal_fp(): | ||
| """Test nearest greater-or-equal forecast period is used from secondary mapping.""" |
|
|
||
| def test_realizationselection_secondary_nearest_fp(): | ||
| """Test nearest forecast period is used from secondary mapping.""" | ||
| def test_realizationselection_secondary_nearest_greater_or_equal_fp(): |
| ) | ||
| result = plugin.process(cubes) | ||
|
|
||
| assert result.coord("forecast_reference_time").cell(0).point._to_real_datetime() == datetime.strptime("20170110T0400Z", "%Y%m%dT%H%MZ") |
There was a problem hiding this comment.
line too long (139 > 79 characters)
| cluster_cube = _make_cluster_cube_for_selection(primary_map) | ||
|
|
||
| # Initial forecast period is 7200s with forecast reference time at 03:00 | ||
| # and validity at 05:00. Setting cycletime to 04:00 should keep validity fixed |
|
|
||
|
|
||
| def test_realizationselection_cycletime(): | ||
| """Test that cycletime resets forecast_reference_time and forecast_period.""" |
…ion_selection_error * upstream/master: Ensure blend_time is consistent with forecast_reference_time when resetting (metoppv#2392)
houndci-bot
reviewed
Jun 9, 2026
| frt_coord.rename("blend_time") | ||
| frt_coord.bounds = None | ||
| frt_dims = cube.coord_dims("forecast_reference_time") | ||
| cube.add_aux_coord(frt_coord, data_dims=frt_dims if frt_dims else None) |
|
|
||
| If blend_time exists on at least one selected cube, any selected cube | ||
| without blend_time is given one copied from forecast_reference_time. If | ||
| cycletime is provided, reset_forecast_reference_time_and_period is applied |
| selected_cubes.append(selected) | ||
| return selected_cubes | ||
|
|
||
| def _ensure_blend_time_on_selected_cubes(self, selected_cubes: list[Cube]) -> None: |
| result.coord("blend_time").points, | ||
| result.coord("forecast_reference_time").points, | ||
| ) | ||
| assert result.coord("forecast_reference_time").cell(0).point._to_real_datetime() == datetime.strptime("20170110T0400Z", "%Y%m%dT%H%MZ") |
There was a problem hiding this comment.
line too long (139 > 79 characters)
|
|
||
|
|
||
| def test_realizationselection_blend_time_propagated_and_aligned_with_cycletime(): | ||
| """Test blend_time is added to all selected cubes and aligned to cycletime.""" |
| assert result.coord("forecast_period").points[0] == 3600 | ||
|
|
||
|
|
||
| def test_realizationselection_blend_time_propagated_and_aligned_with_cycletime(): |
houndci-bot
reviewed
Jun 9, 2026
| """Remove blend_time coordinate from all selected cubes if present on any. | ||
|
|
||
| blend_time is removed to avoid ambiguity in the merged output, as selected | ||
| cubes may come from different source models with differing blend_time values. |
| ) -> None: | ||
| """Remove blend_time coordinate from all selected cubes if present on any. | ||
|
|
||
| blend_time is removed to avoid ambiguity in the merged output, as selected |
| if not model_cube.coords("realization"): | ||
| selected = model_cube | ||
| selected.add_aux_coord( | ||
| DimCoord(cluster_idx, standard_name="realization", units="1") |
|
|
||
|
|
||
| def test_realizationselection_blend_time_removed_from_selected_cubes(): | ||
| """Test blend_time is removed from all selected cubes when present on any input.""" |
mo-jbeaver
requested changes
Jun 10, 2026
mo-jbeaver
left a comment
Contributor
There was a problem hiding this comment.
One small comment, but overall happy with the changes. Tests ran successfully.
| """ | ||
| self.forecast_period = forecast_period | ||
| self.model_id_attr = model_id_attr | ||
| self.cycletime = cycletime |
Contributor
There was a problem hiding this comment.
Is a check needed here to make sure it is in the correct YYYYMMDDTHHMMZ format?
Contributor
Author
There was a problem hiding this comment.
I've added some validation of the cycletime format.
maxwhitemet
requested changes
Jun 10, 2026
Contributor
|
Only some small comments added. Happy to approve otherwise 👍 |
maxwhitemet
approved these changes
Jun 10, 2026
maxwhitemet
left a comment
Contributor
There was a problem hiding this comment.
Thanks @gavinevans. Happy to approve 👍
mo-jbeaver
approved these changes
Jun 11, 2026
mo-jbeaver
left a comment
Contributor
There was a problem hiding this comment.
Happy with the update and additional tests ran successfully.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Related to https://github.com/metoppv/mo-blue-team/issues/783
improver_test_data PR: metoppv/improver_test_data#140
Description
This PR makes a number of updates to the RealizationSelection plugin following trying to use the plugin with more realistic data:
Testing: