Skip to content

StormScope MeteoSat Europe - #981

Open
jleinonen wants to merge 19 commits into
NVIDIA:mainfrom
jleinonen:stormscope-mtg-euro
Open

StormScope MeteoSat Europe#981
jleinonen wants to merge 19 commits into
NVIDIA:mainfrom
jleinonen:stormscope-mtg-euro

Conversation

@jleinonen

@jleinonen jleinonen commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator

Earth2Studio Pull Request

Description

Adds the European StormScope MeteoSat model.

  1. Model wrapper: earth2studio.models.px.stormscope_meteosat.StormScopeMeteosatEU
  2. Example in examples/04_nowcasting/05_stormscope_meteosat_example.py
  3. Unit tests
  4. Some fixes/improvements to the MeteosatFCI data source:
    • Fix projection_extent to account for FCI coordinate convention
    • available_variables to list the variables available at the selected resolution
    • Recycle opened data files (this speeds up data loading in the example by ~5x on my system)

Depends on NVIDIA/physicsnemo#1848.

Checklist

  • I am familiar with the Contributing Guidelines.
  • New or existing tests cover these changes.
  • The documentation is up to date with these changes.
  • The CHANGELOG.md is up to date with these changes.
  • An issue is linked to this pull request.
  • Assess and address Greptile feedback (AI code review bot for guidance; use discretion, addressing all feedback is not required).

Dependencies

@jleinonen
jleinonen requested a review from pzharrington July 20, 2026 19:51
@jleinonen jleinonen self-assigned this Jul 20, 2026
@greptile-apps

greptile-apps Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds StormScopeMeteosatEU, a two-stage EDM diffusion nowcasting model for MTG-I1 FCI satellite imagery, along with supporting data-source helpers, an example script, and unit tests.

  • The new StormScopeMeteosatEU model predicts the next 10-minute FCI frame from a sliding window of recent observations using a high-sigma/low-sigma denoiser split; it also introduces available_variables() and pixel_bbox-aware projection_extent() improvements to MeteosatFCI.
  • The autoregressive generator (create_generator) has a rolling loop for solar angles that uses range(L-1) instead of range(L), leaving the second-to-last solar-angle slot stale from the second iteration onward — the model is conditioned on incorrect angles for all steps after the first.
  • The example file and cache key carry "stormcast" naming (copy-paste from the StormCast example), and the docstring for num_diffusion_steps reports a default of 18 while the code defaults to 48.

Confidence Score: 3/5

Safe to merge after fixing the solar-angle rolling bug in create_generator; the single-step call path is unaffected, but multi-step autoregressive rollout will silently produce wrong conditioning from step 2 onward.

The autoregressive generator accumulates incorrect solar-angle conditioning because the zen_azi rolling loop is one iteration short. Every rollout step after the first conditions on a stale angle at slot L-1, which grows worse the longer the rollout runs. The fix is a one-character change (range(L-1) to range(L)), but without it multi-step nowcasts will be subtly incorrect in a way the tests do not catch — the unit tests use a spoofed model that ignores conditioning tensors.

earth2studio/models/px/stormscope_meteosat.py — specifically the zen_azi rolling loop inside create_generator (~line 762).

Important Files Changed

Filename Overview
earth2studio/models/px/stormscope_meteosat.py New StormScopeMeteosatEU diffusion nowcasting model; rolling loop for solar angles in create_generator uses range(L-1) instead of range(L), leaving slot L-1 stale after the first autoregressive step. Minor: docstring default for num_diffusion_steps says 18 but code defaults to 48; a comment refers to StormCastMTG.
earth2studio/data/meteosat_fci.py Adds available_variables() helper and pixel_bbox support to projection_extent(); logic is correct and the east-west axis sign swap in projection_extent is intentional.
examples/04_nowcasting/05_stormcast_meteosat_example.py Example file is named stormcast instead of stormscope, and references Package.default_cache(stormcast-conus) — copy-paste leftovers from the StormCast example that point to the wrong cache directory.
test/models/px/test_stormscope_meteosat.py Comprehensive unit tests covering coords, forward pass, batching, AMP, autoregressive iterator, sub-region slicing, raw/physical/normalized conversions, ir_38 warm scaling, off-earth masking, and solar angle computation.
earth2studio/models/px/init.py Adds StormScopeMeteosatEU to the public px model exports; straightforward one-line change.
test/conftest.py Registers stormscope-meteosat optional-dependency gate for the new test file; correct and minimal.
docs/modules/models_px.rst Adds StormScopeMeteosatEU to the documentation toctree in alphabetical order.

Comments Outside Diff (1)

  1. examples/04_nowcasting/05_stormcast_meteosat_example.py, line 1021-1026 (link)

    P2 Wrong cache key and file naming

    The example file is named 05_stormcast_meteosat_example.py (and references "stormcast" in the saved output filename and cache key) but should use "stormscope-meteosat" throughout. The Package.default_cache("stormcast-conus") call will resolve to the StormCast cache directory rather than one appropriate for this model, which could cause checkpoints to be stored or read from the wrong location.

Reviews (1): Last reviewed commit: "Add model to __init__.py" | Re-trigger Greptile

Comment thread earth2studio/models/px/stormscope_meteosat.py
Comment thread earth2studio/models/px/stormscope_meteosat.py Outdated
Comment thread earth2studio/models/px/stormscope_meteosat.py Outdated
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.

2 participants