Skip to content

Download data from S3 bucket - #32

Open
treigerm wants to merge 2 commits into
mainfrom
s3-download
Open

Download data from S3 bucket#32
treigerm wants to merge 2 commits into
mainfrom
s3-download

Conversation

@treigerm

@treigerm treigerm commented Sep 2, 2026

Copy link
Copy Markdown
Member

This adds the functionality to download the datasets from the ESIWACE S3 bucket which for some datasets vastly reduces the dataset size that needs to be downloaded. We now also explicitly specify a chunking for each dataset and the downlad verifies that the dataset has the correct chunk sizes and, if not, rechunks the data. So if we just want to change the chunk size in the future we do not have to create separate datasets in the S3 bucket for that.

@juntyr juntyr left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I like many of the changes and left some small suggestions.

My primary concerns is that some new code and comments seem to be AI generated, and if so I'd prefer another human pass to ensure that they don't sound so formulaic and over-engineered. Primarily-AI-generated files (or large parts) should also be marked as such since their authorship is more complicated

Comment thread README.md

To rebuild a dataset from its original data source instead, pass `--reprocess-data`:
```bash
uv run python -m climatebenchpress.data_loader.datasets.cams --reprocess-data\

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why the backslash at the end?

Comment thread pyproject.toml
"intake==0.7.0",
"intake-xarray==0.7.0",
"requests~=2.32.3",
"s3fs>=2024.10.0,<2025.4",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why this specific range? The online lab might support a different version, so perhaps I'd need to patch/update this later


def _differs(mine: object, yours: object) -> bool:
# NaN fill values are not equal to themselves, so compare them by repr.
return mine != yours and repr(mine) != repr(yours)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'd use not ((mine == yours) or (np.isnan(mine) == np.isnan(yours))

@@ -0,0 +1,201 @@
"""Check that the datasets published in the ClimateBenchPress object store are

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This script feels AI generated. Is that the case? If so, I feel like there should be a comment saying who used AI and what AI you used. Maybe you can also do a human pass over the comments

) -> xr.Dataset:
"""Download a given dataset and canonicalize it, i.e. ensure that all the axes names are consistent between different datasets.

By default, the pre-processed dataset is downloaded from the S3 ESIWACE

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

ESiWACE

def open(download_path: Path) -> xr.Dataset:
return xr.open_zarr(download_path / "download.zarr").drop_encoding().chunk(-1)
ds = xr.open_zarr(download_path / "download.zarr").drop_encoding()
return ds.chunk(Cmip6Dataset.chunks(ds))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Open could also be a classmethod to directly call cls.chunks

Since open now also has the contract to call ds.chunk and ds.drop_encoding, I wonder if we shouldn't split the method in two - We could have @Final open() in the abstract class that calls the abstract _open_impl() method in the sub-class; the open() method then applies the chunking and encoding before returning


for v, da in ds.items():
print(f"- {v}: {da.dims}")
main(CamsNitrogenDioxideDataset)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I like the refactoring :)

import xarray as xr
from climatebenchpress.data_loader import s3

DEFAULT_REFERENCE = Path(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Maybe we don't hardcode the default path here?


pbar.update(sizes[key])

with ThreadPoolExecutor(max_workers=_NUM_WORKERS) as pool:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This will not work on Pyodide, we should add an explicit max_workers=0 path that runs everything in a normal loop

@@ -0,0 +1,201 @@
__all__ = [

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The comments also feel a bit AIy here

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