Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ FROM build-deps AS build-app
# * .git: Required for setuptools-git-versioning
COPY src /opt/app/src
COPY .git /opt/app/.git
COPY uv.lock /opt/app/uv.lock
RUN uv sync --no-dev --no-editable --index-strategy unsafe-best-match

# --- Runtime image (use distroless if feasible for 100MB saving) --- #
Expand All @@ -49,5 +50,24 @@ COPY --from=build-app --chown=app:app /opt/app/.venv /opt/app/.venv

ENV _TYPER_STANDARD_TRACEBACK=1

ENTRYPOINT ["/opt/app/.venv/bin/cloudcasting-app"]
COPY <<EOF /opt/app/entrypoint.sh
#!/bin/bash
set -e

case "\$1" in
inference)
/opt/app/.venv/bin/cloudcasting-inference
;;
metrics)
/opt/app/.venv/bin/cloudcasting-metrics
;;
*)
exit 1
;;
esac
EOF

RUN chmod +x /opt/app/entrypoint.sh

ENTRYPOINT ["/opt/app/entrypoint.sh"]

41 changes: 13 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,56 +6,42 @@
[![contributors badge](https://img.shields.io/github/contributors/openclimatefix/cloudcasting-app?color=FFFFFF)](https://github.com/openclimatefix/cloudcasting-app/graphs/contributors)
[![ease of contribution: hard](https://img.shields.io/badge/ease%20of%20contribution:%20hard-bb2629)](https://github.com/openclimatefix#how-easy-is-it-to-get-involved)

This repo is used to run the OCF-ATI cloudcasting model live in production. This model takes
previous frames of EUMETSAT satellite images and forecasts the future frames to come.
This repo is used to run the OCF-ATI cloudcasting model live in production and meausure its
performance. The model takes previous frames of EUMETSAT satellite images and forecasts the future
frames to come.

The repo associated with training the models run here is https://github.com/openclimatefix/sat_pred

The model checkpoints are hosted at:
https://huggingface.co/openclimatefix/cloudcasting_uk

## Environment Variables

The following environment variables are used in the app:

- `SATELLITE_ZARR_PATH`: The path to the satellite data in Zarr format.
- `OUTPUT_PREDICTION_DIRECTORY`: The directory where results are saved.

### Optional Environment Variables

- `SATELLITE_SCALE_FACTOR`: The scale factor for the satellite data. Defaults to 1023.
- `SATELLITE_15_ZARR_PATH`: The path to the 15 minute satellite data in Zarr format. If
this is not set then the `SATELLITE_ZARR_PATH` is used by `.zarr` is repalced with `_15.zarr`
This repo contains two different packages:
- `cloudcasting_inference`: Used to run inference
- `cloudcasting_metrics`: Used to score the predictions against ground truth

## Installation

## Setup / Installation

Both packages will be installed simultaneously using:

```bash
git clone https://github.com/openclimatefix/cloudcasting-app
cd cloudcasting-app
pip install .
```

## Usage and environmental variables

## Example usage

### Running the app locally

It is possbile to run the app locally by setting the required environment variables listed at the top of the [app](src/cloudcasting_app/app.py), these should point to the relevant paths for loading satellite data
and saving predicitons.
See the READMEs in `src/cloudcasting_inference` and `src/cloudcasting_metrics`.

## Development

### Running the test suite

The test suite is via pytest and can be run from command line using
The test suite is via pytest and can be run from command line using:

```
pytest
```


This will run tests for both packages.

## Contributing and community

[![issues badge](https://img.shields.io/github/issues/openclimatefix/cloudcasting-app?color=FFAC5F)](https://github.com/openclimatefix/cloudcasting-app/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc)
Expand All @@ -65,7 +51,6 @@ pytest
- Check out the [OCF blog](https://openclimatefix.org/blog) for updates
- Follow OCF on [LinkedIn](https://uk.linkedin.com/company/open-climate-fix)


## Contributors

<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
Expand Down
38 changes: 15 additions & 23 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,23 @@ classifiers = [
]
dependencies = [
"fsspec==2025.7.0",
"huggingface-hub==0.28.1",
"hydra-core==1.3.2",
"loguru == 0.7.3",
"numpy==2.1.2",
"huggingface-hub",
"hydra-core",
"icechunk",
"loguru",
"numpy",
"ocf-data-sampler==0.5.27",
"pandas==2.2.3",
"s3fs==2025.7.0",
"safetensors==0.5.2",
"pandas",
"s3fs",
"safetensors",
"sat_pred @ git+https://github.com/openclimatefix/sat_pred.git@main",
# Since torch distributes CPU only packages as wheels, have to specify the target platform in order to pull the wheel compiled for that specific platform
"torch @ https://download.pytorch.org/whl/cpu/torch-2.3.1-cp312-none-macosx_11_0_arm64.whl ; platform_system == 'Darwin' and platform_machine == 'arm64'",
"torchvision @ https://download.pytorch.org/whl/cpu/torchvision-0.18.1-cp312-cp312-macosx_11_0_arm64.whl ; platform_system == 'Darwin' and platform_machine == 'arm64'",
"torch @ https://download.pytorch.org/whl/cpu/torch-2.3.1%2Bcpu-cp312-cp312-linux_x86_64.whl ; platform_system == 'Linux' and platform_machine == 'x86_64'",
"torchvision @ https://download.pytorch.org/whl/cpu/torchvision-0.18.1%2Bcpu-cp312-cp312-linux_x86_64.whl ; platform_system == 'Linux' and platform_machine == 'x86_64'",
"typer==0.15.1",
"xarray==2025.7.1",
"zarr==3.1.1",
"xarray",
"zarr",
]

[dependency-groups]
Expand All @@ -52,11 +52,15 @@ dev = [

[project.scripts]
# Put entrypoints in here
cloudcasting-app = "cloudcasting_app.app:main"
cloudcasting-inference = "cloudcasting_inference.app:app"
cloudcasting-metrics = "cloudcasting_metrics.app:app"

[project.urls]
repository = "https://github.com/openclimatefix/cloudcasting-app"

[tool.setuptools.packages.find]
where = ["src"]

[tool.setuptools]
include-package-data = false

Expand Down Expand Up @@ -122,18 +126,6 @@ line-ending = "auto"
docstring-code-format = true
docstring-code-line-length = 100

# --- DOCUMENTATION CONFIGURATION --- #

[tool.pydoctor]
add-package = ["src/cloudcasting_app"]
project-base-dir = "src/cloudcasting_app"
docformat = "google"
html-output = "docs"
theme = "classic"
privacy = [
"HIDDEN:**.test_*",
]

[[tool.uv.index]]
url = "https://pypi.org/simple"

Expand Down
31 changes: 31 additions & 0 deletions src/cloudcasting_inference/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# cloudcasting-inference

This package is used to run inference on the model. This model takes previous frames of EUMETSAT
satellite images and forecasts the future frames to come.

The repo associated with training the models run here is https://github.com/openclimatefix/sat_pred

The model checkpoints are hosted at:
https://huggingface.co/openclimatefix/cloudcasting_uk

## Environment Variables

The following environment variables are used in the app:

- `SATELLITE_ZARR_PATH`: The path to the satellite data in Zarr format.
- `PREDICTION_SAVE_DIRECTORY`: The directory where predictions will be saved.

### Optional Environment Variables

- `SATELLITE_15_ZARR_PATH`: The path to the 15 minute satellite data in Zarr format. If
this is not set then the `SATELLITE_ZARR_PATH` is used by `.zarr` is repalced with `_15.zarr`

## Example usage

### Running the app locally

It is possible to run the app locally by setting the required environment variables listed at the
top of the [inference app](src/cloudcasting_inference/app.py), these should point to the relevant
paths for loading satellite data and saving predicitons.

You can then run the app using `uv run cloudcasting-inference`.s
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,4 @@ def structured_formatter(record: "loguru.Record") -> str:
loguru.logger.add(
sys.stdout, format=structured_formatter, backtrace=True,
level=os.getenv("LOGLEVEL", "INFO").upper(),
)

# Uncomment and change the list to quieten external libraries
# for logger in ["aiobotocore", "cfgrib"]:
# logging.getLogger(logger).setLevel(logging.WARNING)

)
21 changes: 5 additions & 16 deletions src/cloudcasting_app/app.py → src/cloudcasting_inference/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

This app expects these environmental variables to be available:
SATELLITE_ZARR_PATH (str): The path of the input satellite data
OUTPUT_PREDICTION_DIRECTORY (str): The path of the directory to save the predictions to
PREDICTION_SAVE_DIRECTORY (str): The path of the directory to save the predictions to
"""

import os
Expand All @@ -12,18 +12,17 @@
import hydra
import pandas as pd
import torch
import typer
import xarray as xr
import yaml
from huggingface_hub import snapshot_download
from safetensors.torch import load_model
from loguru import logger

from cloudcasting_app.data import SatelliteDownloader, sat_path, get_input_data
from cloudcasting_inference.data import SatelliteDownloader, sat_path, get_input_data

# Get package version
try:
__version__ = version("cloudcasting-app")
__version__ = version("cloudcasting-inference")
except PackageNotFoundError:
__version__ = "v?"

Expand All @@ -33,20 +32,18 @@
# Model will use GPU if available
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")


# Model revision on huggingface
REPO_ID = "openclimatefix/cloudcasting_uk"
REVISION = "47643e89000e64e0150f7359ccc0cb6524948712"



def app(t0=None):
"""Inference function for production

Args:
t0 (datetime): Datetime at which forecast is made
"""
logger.info(f"Using `cloudcasting_app` version: {__version__}", version=__version__)
logger.info(f"Using `cloudcasting-app` version: {__version__}", version=__version__)

# ---------------------------------------------------------------------------
# 0. If inference datetime is None, round down to last 30 minutes
Expand Down Expand Up @@ -123,7 +120,7 @@ def app(t0=None):
ds_y_hat.sat_pred.attrs.update(ds.data.attrs)

# Save predictions to the latest path and to path with timestring
out_dir = os.environ["OUTPUT_PREDICTION_DIRECTORY"]
out_dir = os.environ["PREDICTION_SAVE_DIRECTORY"]

if satellite_downloader.use_5_minute:
latest_zarr_path = f"{out_dir}/latest.zarr"
Expand All @@ -141,11 +138,3 @@ def app(t0=None):
fs.rm(path, recursive=True)

ds_y_hat.to_zarr(path)


def main() -> None:
"""Entrypoint to the application."""
typer.run(app)

if __name__ == "__main__":
main()
File renamed without changes.
14 changes: 14 additions & 0 deletions src/cloudcasting_metrics/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# cloudcasting-metrics

This package is used to score the predictions made by the cloudcasting model and save the scores to
a zarr store at the location `METRIC_ZARR_PATH`. By default, the scoring is run for all init-times
made the day before running.

## Environment Variables

The following environment variables are used in the app:

- `SATELLITE_ICECHUNK_ARCHIVE`: The path to the satellite archive in icechunk formast
- `PREDICTION_SAVE_DIRECTORY`: The directory where the cloudcasting predictions are saved.
i.e. set to the same as `PREDICTION_SAVE_DIRECTORY` in `cloudcasting_inference`.
- `METRIC_ZARR_PATH`: Where to save metrics zarr
Empty file.
Loading
Loading