> Create Earth2Studio prognostic (time-stepping forecast) model wrappers. Do NOT use for diagnostic models, data sources, or installation.
npx skills add https://github.com/NVIDIA/skills --skill earth2studio-create-prognostic
Do these steps IN ORDER. Do not skip any step.
earth2studio/models/px/<name>.py with triple inheritancetest/models/px/test_<name>.py with mock testsuv run pytest test/models/px/test_<name>.py -vmake format && make lint> ⚠️ CRITICAL: Always use uv run for Python commands:
> - ✅ uv run pytest ... / uv run python ...
> - ❌ pytest ... / python ... (missing dependencies)
>
> Stuck or wrong output: Do not keep retrying the same fix. Follow
> Self-Improvement to patch this skill before continuing.
Implement a prognostic model wrapper connecting third-party ML weather models
to Earth2Studio. Prognostic models time-integrate forward—given initial state,
they predict future states by stepping through time (e.g., 6-hour increments).
| Context | Location |
|---------|----------|
| Harbor eval | Write to /workspace/output/earth2studio/models/px/... |
| Harbor + --copy-repo | Full checkout at /workspace/repo |
| Local clone | Directory with pyproject.toml |
Never read evals/targets/ — grader references only.
Load on demand during the matching step:
| File | Content | Load at |
|------|---------|---------|
| references/skeleton-template.py | Full model skeleton with FILL comments | Steps 3–6 |
| references/method-templates.py | Canonical method implementations | Steps 4–6 |
| references/testing-guide.py | Test skeleton and mock patterns | Step 7 |
| references/validation-guide.md | Comparison scripts, PR, code review | Steps 10–11 |
If $ARGUMENTS provided, use it. Otherwise ask:
> Please provide a reference inference script URL/path.
Analyze: packages, architecture, I/O shapes, time step, resolution, checkpoint.
Propose pyproject.toml group (alphabetical, add to all). Every
prognostic model must have an optional dependency extra, even when no packages
are required:
model-name = ["package1>=version", "package2"]
# or, when no additional packages are required:
model-name = []
[CONFIRM] Present dependencies and ask user to approve.
Edit pyproject.toml: add the model extra alphabetically, even if it is
empty, and update the all aggregate.
File: earth2studio/models/px/<lowercase>.py
Required inheritance (all three):
class ModelName(torch.nn.Module, AutoModelMixin, PrognosticMixin):
Required imports:
import numpy as np
import torch
from earth2studio.models.auto import AutoModelMixin, Package
from earth2studio.models.batch import batch_coords, batch_func
from earth2studio.models.px.base import PrognosticMixin
from earth2studio.models.utils import create_coords_from_lat_lon, handshake_dim
from earth2studio.lexicon import E2STUDIO_VOCAB
from earth2studio.utils import check_optional_dependencies
from loguru import logger
SPDX header (required at top of every .py file):
# SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES.
# SPDX-License-Identifier: Apache-2.0
Canonical method order:
__init__ 2. input_coords 3. output_coords (@batch_coords)load_default_package 5. load_model 6. to (optional)__call__ (@batch_func) 9. _default_generator10. create_iterator
input_coords rules:
batch: np.empty(0)time: np.empty(0) (dynamic)lead_time: starts at np.timedelta64(0, "h")lat: 90 to -90 (north to south); this is the public Earth2Studio convention even if the source model uses the opposite orderlon: 0 to 360input_coords or output_coordsE2STUDIO_VOCAB (282 entries in earth2studio/lexicon/base.py)output_coords: Use handshake_dim/handshake_coords for input validation, then increment lead_time. Prefer a shared coordinate-check helper and call it from output_coords, __call__, and iterator setup before model execution.
__call__: @batch_func decorated, shape (batch, time, lead_time, var, lat, lon).
Reshape to model format → call model → reshape back.
create_iterator: MUST yield initial condition first (step 0).
Use front_hook/rear_hook for perturbation injection.
load_default_package: Lock HuggingFace URLs: hf://org/repo@commit
load_model: Use package.resolve(), map_location="cpu", eval() mode,
decorate with @check_optional_dependencies().
File: test/models/px/test_<name>.py
Required tests:
| Function | Purpose |
|----------|---------|
| test_<model>_call | Single forward pass (parametrize device/time) |
| test_<model>_iter | Iterator produces sequence |
| test_<model>_exceptions | Invalid coords raise errors |
| test_<model>_package | Real weights (@pytest.mark.package) |
Create PhooModelName dummy matching interface for mock tests.
Run tests:
uv run pytest test/models/px/test_<name>.py -m "not package" -v
uv run pytest test/models/px/test_<name>.py::test_<model>_package --package -v
Do not omit the package test. If arbitrary random inputs are not physically
valid for the real checkpoint, use a stable model-appropriate synthetic input
while still loading real weights and running a forward pass.
earth2studio/models/px/__init__.py (alphabetical)docs/modules/models_px.rst (alphabetical). This is required forevery new prognostic model so the API docs include the generated page.
docs/userguide/about/install.md (alphabetical tab) for themodel extra, even when the extra is empty. Include model-specific notes plus
both pip install earth2studio[model-name] and
uv add earth2studio --extra model-name instructions.
CHANGELOG.md under ### Added. This is required for every newprognostic model.
Format and lint:
make format && make lint && make license
Follow references/validation-guide.md. Create uncommitted vanilla, E2S,
comparison, and sanity-check scripts; do not commit generated outputs or images.
Use PR-safe placeholders for plots so the user can upload images manually.
[CONFIRM] User must visually inspect plots before proceeding.
Follow references/validation-guide.md and use:
references/pr-body-template.mdreferences/pr-comment-template.mdBefore creating the PR, verify pyproject.toml has the model extra, the
all extra includes it, install docs include both pip and uv commands, and
docs/modules/models_px.rst plus CHANGELOG.md are updated.
Do not include machine names, absolute paths, device inventory, or uploaded image
links in PR text. Use plot placeholders instead.
User: Create IdentityModel - returns input unchanged, 6h step, 181x360, vars: t2m, u10m, v10m, msl
Agent: [reads SKILL.md, creates identity.py with triple inheritance,
creates test_identity.py, runs pytest, runs make format && lint]
User: Add Pangu-Weather wrapper
GitHub: https://github.com/198808xc/Pangu-Weather
Agent: [reads SKILL.md, fetches inference.py, creates pangu.py,
creates test_pangu.py, runs pytest]
@property
def input_coords(self) -> CoordSystem:
return CoordSystem({
"batch": np.empty(0),
"time": np.empty(0),
"lead_time": np.array([np.timedelta64(0, "h")]),
"variable": np.array(["t2m", "u10m", ...]),
# Public Earth2Studio convention is north-to-south latitude.
"lat": np.linspace(90, -90, 181),
"lon": np.linspace(0, 359, 360),
})
@batch_coords()
def output_coords(self, input_coords: CoordSystem) -> CoordSystem:
output = input_coords.copy()
output["lead_time"] = input_coords["lead_time"] + np.timedelta64(6, "h")
return output
def create_iterator(self, x, coords):
yield x, coords # Initial condition (step 0)
while True:
x, coords = self.front_hook(x, coords)
x, coords = self(x, coords)
x, coords = self.rear_hook(x, coords)
yield x, coords
| Error | Solution |
|-------|----------|
| OptionalDependencyFailure | uv add --optional <group> <pkg> |
| Coordinate handshake fails | Check handshake_dim indices match dim position |
| Iterator wrong shapes | Debug reshape logic with random input |
| ModuleNotFoundError: pytest | Use uv run pytest not pytest |
DO:
uv run python for ALL Python commandsloguru.logger, never print()torch.nn.Module + AutoModelMixin + PrognosticMixincreate_iteratorfront_hook()/rear_hook() in _default_generatorDON'T:
evals/targets/Integration with protocols.io API for managing scientific protocols. This skill should be used when working with protocols.io to search, create, update, or publish protocols; manage protocol steps and materials; handle discussions and comments; organize workspaces; upload and manage files; or integrate protocols.io functionality into workflows. Applicable for protocol discovery, collaborative protocol development, experiment tracking, lab protocol management, and scientific documentation.
Analyzes job descriptions and generates tailored resumes that highlight relevant experience, skills, and achievements to maximize interview chances
Generate Excalidraw diagrams from natural language descriptions. Use when asked to "create a diagram", "make a flowchart", "visualize a process", "draw a system architecture", "create a mind map", or "generate an Excalidraw file". Supports flowcharts, relationship diagrams, mind maps, and system architecture diagrams. Outputs .excalidraw JSON files that can be opened directly in Excalidraw.
Build and distribute Expo development clients locally or via TestFlight
Use when you have a written implementation plan to execute in a separate session with review checkpoints
Data structure for annotated matrices in single-cell analysis. Use when working with .h5ad files or integrating with the scverse ecosystem. This is the data format skill—for analysis workflows use scanpy; for probabilistic models use scvi-tools; for population-scale queries use cellxgene-census.
Benchling R&D platform integration. Access registry (DNA, proteins), inventory, ELN entries, workflows via API, build Benchling Apps, query Data Warehouse, for lab data management automation.
Comprehensive molecular biology toolkit. Use for sequence manipulation, file parsing (FASTA/GenBank/PDB), phylogenetics, and programmatic NCBI/PubMed access (Bio.Entrez). Best for batch processing, custom bioinformatics pipelines, BLAST automation. For quick lookups use gget; for multi-service integration use bioservices.
Take nvidia/earth2studio-create-prognostic from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.
The instructions reference pip.
Without those the skill loads but fails at the first command.