Skip to content

Add alternative source for ERA5 data to eliminate queueing#507

Open
mrmorawski wants to merge 64 commits into
PyPSA:masterfrom
mrmorawski:era5-ncar-thredds
Open

Add alternative source for ERA5 data to eliminate queueing#507
mrmorawski wants to merge 64 commits into
PyPSA:masterfrom
mrmorawski:era5-ncar-thredds

Conversation

@mrmorawski

@mrmorawski mrmorawski commented May 11, 2026

Copy link
Copy Markdown

Closes #495

Changes proposed in this Pull Request

Currently the ERA5 dataset is downloaded from CDS. This requires authentication and users often get stuck in a processing queue for hours.

This PR adds support for downloading ERA5 from a mirror hosted at NCAR via OPeNDAP. This mirror requires no authentication and there is no queue.

The modification is implemented as a new dataset module called era5-ncar, which exposes the same API as the current era5.py module. All the user needs to do is change one line when creating the cutout. Code remains fully backwards-compatible.

cutout = atlite.Cutout(
    path="spain-2024.nc",
    module="era5-ncar",    # <-- only change from "era5"
    x=slice(-10, 5),
    y=slice(35, 44),
    time="2013-01-01
   )

Comparison of era5 vs era5-ncar

The NCAR mirror is stored as NetCDF files at the default 0.25/0.25 deg. resolution used by CDS. This has implications for performance and accuracy.

Performance

Tested on a Germany-sized cutout, 6 months of data, downloaded at the default grid size (CDS files served from CDS server cache, no queuing):

Source Wall time Peak memory usage received files
NCAR THREDDS 239.3 s 865 MB 447.6 MB
CDS 194.2 s 802 MB 186.4 MB

As you can see, we need to download slightly more data from NCAR and do more local processing, but the extra time is typically offset by the CDS queue time (over an hour when this cutout was first requested). Coarser/larger cutouts will benefit CDS, while smaller cutouts will have an even larger speedup on NCAR.

Accuracy

Results on the default grid (and its multiples) are very close, within float32 precision. Results on other grids are slightly off, as we cannot reproduce the exact interpolation logic used by CDS. Details of the interpolation errors are explained in the example notebook examples/comparing_era5_sources_cds_vs_ncar.ipynb

When to use which source

I included the following line in the documentation:

So which source should I use? For very large cutouts (e.g. continents larger than Europe), for workflows that already use CDS, and when you require data at resolution that is not a multiple of the default 0.25/0.25 deg. grid, use CDS. For everything else, NCAR is more convenient.

Communication with UCAR

I asked UCAR, who administer this dataset for NCAR, whether they were OK with the OPeNDAP access. The response was positive. If we experience rate limiting on the server side, we may need to limit the number of simultaneous connections further (I capped it at 8).

LLM use disclosure

I used LLMs to:

  • help me understand the THREDDS API
  • write some of the processing code
  • review the module
  • write the benchmarking and plotting code

I manually wrote all the documentation and most of the docstrings. I hand-checked every line of code in this PR.

Remaining tests

I'd appreciate if someone could test the module on their machine on a large download. I've been test-running it for a week on my own setup, and it was stable (not a single failed download). However, there may still be hidden networking bugs.

Other ERA5 sources

I investigated other sources for ERA5. This is, to my knowledge, the only one fulfills the following criteria:

  • ran by a large organisation
  • easy spatial subsetting
  • no authentication and queueing
  • provides full set of the variables used by atlite

The ARCO datasets stored by Google, Microsoft and Amazon seem to be chunked along the time dimension only, so one always has to download a whole world's worth of data.

Earthmover stores era5 on s3 in Zarr, chunked in yearly, 12x12 spatial chunks, but they only do surface variables.

Checklist

  • Code changes are sufficiently documented; i.e. new functions contain docstrings and further explanations may be given in doc.
  • Unit tests for new features were added (if applicable).
  • Newly introduced dependencies are added to environment.yaml, environment_docs.yaml and setup.py (if applicable). I added dependencies to pyproject.toml, I don't see an environment.yaml
  • A note for the release notes doc/release_notes.rst of the upcoming release is included.
  • I consent to the release of this PR's code under the MIT license.

mrmorawski and others added 30 commits May 9, 2026 00:27
…erpolation if grids are aligned, grid interpolation sanitise only if interpolatingfor consistency with cds
@fneum

fneum commented Jun 1, 2026

Copy link
Copy Markdown
Member

@mrmorawski, let me know when I should give this another review regarding the latest changes.

@mrmorawski

mrmorawski commented Jun 1, 2026 via email

Copy link
Copy Markdown
Author

@mrmorawski

mrmorawski commented Jun 5, 2026

Copy link
Copy Markdown
Author

Profiling memory usage

I did a lot of memory profiling for era5-edh. I fixed some minor issues (chunk sizes, operation order), which brought the memory down to 3.5GB for the 6-month EU cutout I was measuring above. Here is memory usage over time:

image

I think I have identified a key bottleneck - system malloc not releasing small chunks of memory to the OS, which accumulate in the process. It's described in more detail here , and seems to be Linux and MacOS specific. The distributed dask scheduler deals with this by launching workers with an environment variable MALLOC_TRIM_THRESHOLD_=65536, which causes malloc to release memory sooner and avoids accumulation. When I ran the same download as above with this env var, the peak memory usage dropped to 2.35GB.

image

Memory usage conclusions

  • I think that for cutouts in the <50GB range memory usage is acceptable with the default settings.

  • For cutouts above that, I think the users should use the distributed scheduler, as the default threaded one is not memory-aware and may OOM on smaller machines. I wrote an example on how to use the distributed scheduler here . It's two lines of code to give people granular control over memory usage, OOM prevention, nice graphs for monitoring progress etc. In the example notebook, I generate data for the whole world over a year while keeping memory below 12GB.

image
  • Alternatively we could do the memory trimming in the code as done here but IMO we should avoid calling malloc directly from Python if we can help it.

Other issues (support for Python 3.10)

I also fixed issues flagged by the CI, now the tests pass (see here except on Python 3.10. Python 3.10 doesn't work because we need Zarr-3, and 3.10 only supports Zarr-2. I couldy hack around this, but I think we should either:

  • require Python>=3.11, or
  • make era5-edh conditional on having Python>=3.11

Would dropping 3.10 be OK with you @fneum ? It'll reach end-of-life in October 2026 anyway

@mrmorawski

mrmorawski commented Jun 10, 2026

Copy link
Copy Markdown
Author

I updated the branch to pass the new ruff rules checks introduced in 9663808

And one thing that I forgot to mention above - this branch introduces a new secret to the test CI (EARTHDATAHUB_API_KEY), which is needed to download era5-edh cutouts for tests. You'd need to add one to the GitHub Actions config in this repo.

@fneum

fneum commented Jun 23, 2026

Copy link
Copy Markdown
Member

Yes, dropping Python 3.10 is fine (we did this in PyPSA already).

I'll add the earth data hub API key now.

@mrmorawski

mrmorawski commented Jun 24, 2026 via email

Copy link
Copy Markdown
Author

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

did take a look on this as well (just code though, did not try it). Sounds like a good alternative! :)

The history of this PR should be squashed or cleaned up though.

Comment thread examples/create_cutout.ipynb Outdated
Comment thread doc/installation.rst Outdated
Comment thread atlite/resource.py

if TYPE_CHECKING:
from typing import TypedDict
from typing import NotRequired, TypedDict

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 don't have anything against dropping 3.10 support, but I guess that 3.10 would work without this change?

Either remove typing_extensions from pyproject.toml as well, or leave this change as before (and remove python 3.10 in a separate PR)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

this PR needs Python 3.11+ to work because era5-edh relies on Zarr v3's ObjectStore, which is not available for Python 3.10 AFAIK. I could create a separate PR for 3.10->3.11 if you'd like that, but for now I just removed typing_extensions from dependencies. Does this resolve your comment?

@mrmorawski

Copy link
Copy Markdown
Author

thanks for the review @maurerle !

I checked out the CI, and the reason that EDH tests were being skipped is that CI on PRs doesn't have access to secrets. CDS tests are not skipped, but only on Ubuntu, because there are the nightly built cached cutouts for those.

Regarding commit history, I totally agree it should be cleaned up, but I thought you'd just squash merge it @maurerle @fneum?

If you'd prefer that I squash this branch, I'd be happy to do that of course

@fneum

fneum commented Jul 9, 2026

Copy link
Copy Markdown
Member

We just squash at the end.

…out in CI, add a warning

in the CI test job 9x runners simultaneously hammer EDH with the same
API keys, which results in 403s. for now dealt with via long timeouts,
final fix would be a two-step test process, separate creds, or some
other form of rate limiting
@mrmorawski

Copy link
Copy Markdown
Author

Then I think it's ready for merge - CI runs all tests and passes on my fork. The last remaining issue is the Python version bump - would you prefer a separate PR for that, or can we do it here?

@maurerle maurerle 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 think it is fine here.
I do not have commit rights, but I'd approve.

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.

Alternative ERA-5 sources to avoid CDS API queues

3 participants