Skip to content

Spatial morphing - #2441

Merged
gavinevans merged 28 commits into
metoppv:masterfrom
gavinevans:mobt_1244_spatial_morphing
Sep 18, 2026
Merged

gavinevans merged 28 commits into
metoppv:masterfrom
gavinevans:mobt_1244_spatial_morphing

Conversation

@gavinevans

@gavinevans gavinevans commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Related to https://github.com/metoppv/mo-blue-team/issues/1268
improver_test_data PR: metoppv/improver_test_data#146

Description
This PR seeks to address weaknesses with the current use of temporal interpolation as implemented using the ForecastTrajectoryGapFiller plugin. The main weaknesses are:

  1. As Google FILM only knows about the frames at the start and end of a time period, it doesn't have a sense of the general meteorological flow. Therefore, although the morphing from one feature to another is reasonable, the direction of the movement during the temporal interpolation period can be perpendicular to the general direction of the meteorological flow. To alleviate this issue, this PR creates a new plugin to use Google FILM in a different way i.e. as a spatial morphing tool, rather than for strictly doing temporal interpolation. This means that this plugin uses Google FILM to blend together two forecast sources at the same validity time, where the timestep between source A and source B re-interpreted as a weight.
  2. The temporal interpolation can result in an overabundance of low precipitation amounts. This plugin therefore includes the application of Quantile Mapping, which helps to reduce amount of non-zero precipitation introduced as intermediate timesteps.

The SpatialMorphing plugin effectively combines two existing plugins i.e. RealizationSelection and ForecastTrajectoryGapFiller, as this plugin itself takes the clustering cube as an input, so that it can select the relevant realizations to use as input to Google FILM.

Testing:

  • Ran tests and they passed OK
  • Added new tests for the new feature(s)

@mo-jbeaver mo-jbeaver 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.

I've added some comments below, majority are docstring related. The unit tests passed successfully but the acceptance tests failed with assertion errors

Comment thread improver/utilities/temporal_interpolation.py
Comment thread improver/utilities/temporal_interpolation.py
Comment thread improver/utilities/temporal_interpolation.py
Comment thread improver/utilities/temporal_interpolation.py
Comment thread improver/utilities/temporal_interpolation.py
nearest_fp, use_secondary, secondary_map, primary_map, cluster_cube
)
if self.cluster_number not in full_cluster_to_selection:
raise ValueError(

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.

Value Error should possibly be added to the docstring

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added.

Comment thread improver/utilities/spatial_morphing.py Outdated
Comment thread improver/utilities/spatial_morphing.py Outdated
Comment thread improver/utilities/spatial_morphing.py
Comment thread improver_tests/acceptance/test_spatial_morphing.py
@mo-jbeaver mo-jbeaver assigned gavinevans and unassigned mo-jbeaver Sep 3, 2026
@gavinevans gavinevans assigned bayliffe and unassigned gavinevans Sep 16, 2026

@bayliffe bayliffe 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.

Tiny comments, nearly there.

for template_slice in template_slices
]
elif np.isscalar(self.interpolation_fractions):
fractions = [float(self.interpolation_fractions)] * len(template_slices)

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.

I remain confused. Why do we have multiple template slices if we are simply morphing between two input fields at a fixed validity time?

If supplied, cube1 and cube2 may have the same validity time,
allowing source morphing at a fixed validity time. A scalar applies
the same fraction to every output slice; a sequence provides one
fraction per output slice.

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.

I think I'm confused again (along with the query about multiple template_slices previously) do we ever morph to multiple steps between two fields valid at the same time?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I've modified this text. From the SpatialMorphing plugin, we only ever take two inputs and morph to a single intermediate point. We never morph to multiple points. Just to clarify, the GoogleFilmInterpolation plugin could morph to multiple points, if we wanted to support it, but the GoogleFILMInterpolation plugin is never called in that way from the SpatialMorphing plugin. I think that the confusion arises because the GoogleFILMInterpolation plugin could do things in a more general way than we want to support specifically for the SpatialMorphing plugin.

@bayliffe bayliffe assigned gavinevans and unassigned bayliffe Sep 16, 2026
…learly within the GoogleFILMInterpolation changes.
@gavinevans gavinevans assigned bayliffe and unassigned gavinevans Sep 16, 2026
@gavinevans gavinevans assigned gavinevans and unassigned bayliffe Sep 17, 2026
@gavinevans

gavinevans commented Sep 17, 2026

Copy link
Copy Markdown
Contributor Author

I've now added these two commits: c8381f8 and e4dbf6d. These are all related to this comment: #2441 (comment). I previously tried to address this by making the the selection of the bounding pair of forecast sources cluster-aware, but after testing, I realised that this only worked for "nc_det uk_det" => "uk_det" and "nc_det uk_det" => "uk_ens" and wasn't sufficient for a cluster defined with "nc_det uk_det" => "uk_det" => "uk_ens", because "nc_det uk_det", "uk_det", "uk_ens" were all present in one cluster, so the selection of the bounding pair of forecast sources also needed to be forecast_period aware.

@gavinevans gavinevans assigned bayliffe and unassigned gavinevans Sep 17, 2026
@gavinevans

Copy link
Copy Markdown
Contributor Author

The latest commit (bd2c3b0), I think relates to changes made in relation to this comment: #2441 (comment), where I removed cube.copy()-type lines. In some command line running, I noticed that I was getting some screwy output following this change, as the source cubes were being updated as part of the Google FILM processing, so when these same source cubes were used for the suppression steps in #2451, the output was incorrect.

bayliffe
bayliffe previously approved these changes Sep 17, 2026

@bayliffe bayliffe 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.

Thanks for the changes Gavin. Happy to leave this alone now...

@bayliffe bayliffe assigned mo-jbeaver and unassigned bayliffe Sep 17, 2026
@mo-jbeaver mo-jbeaver assigned gavinevans and unassigned mo-jbeaver Sep 17, 2026
@gavinevans
gavinevans merged commit e3991ba into metoppv:master Sep 18, 2026
13 checks passed
@gavinevans
gavinevans deleted the mobt_1244_spatial_morphing branch September 18, 2026 07:25
gavinevans added a commit to gavinevans/improver that referenced this pull request Sep 18, 2026
…sion

* upstream/master:
  Spatial morphing (metoppv#2441)
  Stochastic noise extensions (metoppv#2442)
  Forecast capping if calibrate forecast is too far from the uncalibrated (metoppv#2449)
  Vicinity metadata from the threshold plugin (metoppv#2439)
  Update cluster sources bookkeeping, so that forecast periods are only stored in one forecast source. (metoppv#2437)
  Correct realization numbering bug in temporal interpolation (metoppv#2436)
  Modify precedence ordering when clustering (metoppv#2435)
MoseleyS added a commit that referenced this pull request Sep 18, 2026
* master:
  Spatial Morphing - refinement of Google FILM output (#2451)
  Spatial morphing (#2441)
  Stochastic noise extensions (#2442)
  Forecast capping if calibrate forecast is too far from the uncalibrated (#2449)
  Vicinity metadata from the threshold plugin (#2439)
  Update cluster sources bookkeeping, so that forecast periods are only stored in one forecast source. (#2437)
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