xcube-eopf


Namexcube-eopf JSON
Version 0.2.0 PyPI version JSON
download
home_pageNone
Summaryxcube datastore for accessing datasets of ESA EOPF data products.
upload_time2025-08-21 14:40:14
maintainerNone
docs_urlNone
authorKonstantin Ntokas (Brockmann Consult GmbH), Norman Fomferra (Brockmann Consult GmbH)
requires_python>=3.10
licenseApache-2.0
keywords copernicus esa eopf sentinel xarray zarr
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            [![Build Status](https://github.com/EOPF-Sample-Service/xcube-eopf/actions/workflows/unit-tests.yml/badge.svg?branch=main)](https://github.com/EOPF-Sample-Service/xcube-eopf/actions)
[![codecov](https://codecov.io/gh/EOPF-Sample-Service/xcube-eopf/branch/main/graph/badge.svg)](https://codecov.io/gh/EOPF-Sample-Service/xcube-eopf)
[![PyPI Version](https://img.shields.io/pypi/v/xcube-eopf)](https://pypi.org/project/xcube-eopf/)
[![Anaconda-Server Badge](https://anaconda.org/conda-forge/xcube-eopf/badges/version.svg)](https://anaconda.org/conda-forge/xcube-eopf)
[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v0.json)](https://github.com/charliermarsh/ruff)
[![License](https://anaconda.org/conda-forge/xcube-eopf/badges/license.svg)](https://anaconda.org/conda-forge/xcube-eopf)


# xcube-eopf

`xcube-eopf` is a Python package and [xcube plugin](https://xcube.readthedocs.io/en/latest/plugins.html) that adds a [data store](https://xcube.readthedocs.io/en/latest/api.html#data-store-framework)
named `eopf-zarr` to xcube. The data store is used to access ESA EOPF data products as an 
analysis-ready datacube (ARDC).

## Features

> **IMPORTANT**  
> `xcube-eopf` is currently under active development.  
> Some features may be partially implemented or still in progress.

The EOPF xcube data store is designed to provide analysis-ready data cubes from the 
EOPF Sentinel Zarr samples for Sentinel-1, Sentinel-2, and Sentinel-3 missions. The
main features are summarized below. A more in depth documentation is given in the 
[User Guide](guide.md). 

Currently, support is focused on **Sentinel-2** products.


### Sentinel-1

Support for Sentinel-1 will be added in an upcoming release.


### Sentinel-2

The current implementation supports two Sentinel-2 product levels, available as 
`data_id` values:

- `sentinel-2-l1c`: Level-1C top-of-atmosphere reflectance
- `sentinel-2-l2a`: Level-2A atmospherically corrected surface reflectance

#### Cube Generation Workflow

The workflow for building 3D analysis-ready cubes from Sentinel-2 products involves 
the following steps:

1. **Query** products using the [EOPF STAC API](https://stac.browser.user.eopf.eodc.eu/) for a given time range and 
   spatial extent.
2. **Retrieve** observations as cloud-optimized Zarr chunks via the 
   [xarray-eopf backend](https://eopf-sample-service.github.io/xarray-eopf/).
3. **Mosaic** spatial tiles into single images per timestamp.
4. **Stack** the mosaicked scenes along the temporal axis to form a 3D cube.

#### Supported Variables

- **Surface reflectance bands**:  
  `b01`, `b02`, `b03`, `b04`, `b05`, `b06`, `b07`, `b08`, `b8a`, `b09`, `b11`, `b12`
- **Classification/Quality layers** (L2A only):  
  `cld`, `scl`, `snw`

**Example: Sentinel-2 L2A**
```python
from xcube.core.store import new_data_store

store = new_data_store("eopf-zarr")
ds = store.open_data(
    data_id="sentinel-2-l2a",
    bbox=[9.7, 53.4, 10.3, 53.7],
    time_range=["2025-05-01", "2025-05-07"],
    spatial_res=10 / 111320,  # meters to degrees (approx.)
    crs="EPSG:4326",
    variables=["b02", "b03", "b04", "scl"],
)
```

### Sentinel-3

Support for Sentinel-3 products will be added in an upcoming release.



## Usage

The `xcube-eopf` package can be installed from PyPI (`pip install xcube-eopf`)
or conda-forge (`conda install -c conda-forge xcube-eopf`).
After installation, you are ready to go and use the `"eopf-zarr"` argument to initiate 
a xcube EOPF data store.

```python
from xcube.core.store import new_data_store

store = new_data_store("eopf-zarr")
ds = store.open_data(
    data_id="sentinel-2-l2a",
    bbox=[9.7, 53.4, 10.3, 53.7],
    time_range=["2025-05-01", "2025-05-07"],
    spatial_res=10 / 111320,  # meters converted to degrees (approx.)
    crs="EPSG:4326",
    variables=["b02", "b03", "b04", "scl"],
)
```

## Development

### Setting up a development environment

The recommended Python distribution for development is 
[miniforge](https://conda-forge.org/download/) which includes 
conda, mamba, and their dependencies.

```shell
git clone https://github.com/EOPF-Sample-Service/xcube-eopf.git
cd xcube-eopf
mamba env create
mamba activate xcube-eopf
pip install -ve .
```

### Install the library locally and test

```shell
mamba activate xcube-eopf
pip install -ve .
pytest
```
By default, this will run all unit tests. To run integration tests, use:  

```shell
pytest integration
```

To run tests and generate a coverage report, use:

```shell
pytest --cov xcube_eopf --cov-report html tests
```

### Some notes on the strategy of unit-testing

The unit test suite uses [pytest-recording](https://pypi.org/project/pytest-recording/)
to mock STAC catalogs. During development an actual HTTP request is performed
to a STAC catalog and the responses are saved in `cassettes/**.yaml` files.
During testing, only the `cassettes/**.yaml` files are used without an actual
HTTP request. During development, to save the responses to `cassettes/**.yaml`, run

```bash
pytest -v -s --record-mode new_episodes
```
Note that `--record-mode new_episodes` overwrites all cassettes. If the user only
wants to write cassettes which are not saved already, `--record-mode once` can be used.
[pytest-recording](https://pypi.org/project/pytest-recording/) supports all records modes given by [VCR.py](https://vcrpy.readthedocs.io/en/latest/usage.html#record-modes).
After recording the cassettes, testing can be performed as usual.


### Setting up a documentation environment

```shell
mamba activate xcube-eopf
pip install .[doc]
```

### Testing documentation changes

```shell
mkdocs serve
```

### Deploying documentation changes

```shell
mkdocs gh-deploy
```

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "xcube-eopf",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.10",
    "maintainer_email": null,
    "keywords": "copernicus, esa, eopf, sentinel, xarray, zarr",
    "author": "Konstantin Ntokas (Brockmann Consult GmbH), Norman Fomferra (Brockmann Consult GmbH)",
    "author_email": null,
    "download_url": "https://files.pythonhosted.org/packages/b3/09/f93786eaf34704d54d8e371f5579cecc558c8fd92c7453f0b318edef65e7/xcube_eopf-0.2.0.tar.gz",
    "platform": null,
    "description": "[![Build Status](https://github.com/EOPF-Sample-Service/xcube-eopf/actions/workflows/unit-tests.yml/badge.svg?branch=main)](https://github.com/EOPF-Sample-Service/xcube-eopf/actions)\n[![codecov](https://codecov.io/gh/EOPF-Sample-Service/xcube-eopf/branch/main/graph/badge.svg)](https://codecov.io/gh/EOPF-Sample-Service/xcube-eopf)\n[![PyPI Version](https://img.shields.io/pypi/v/xcube-eopf)](https://pypi.org/project/xcube-eopf/)\n[![Anaconda-Server Badge](https://anaconda.org/conda-forge/xcube-eopf/badges/version.svg)](https://anaconda.org/conda-forge/xcube-eopf)\n[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v0.json)](https://github.com/charliermarsh/ruff)\n[![License](https://anaconda.org/conda-forge/xcube-eopf/badges/license.svg)](https://anaconda.org/conda-forge/xcube-eopf)\n\n\n# xcube-eopf\n\n`xcube-eopf` is a Python package and [xcube plugin](https://xcube.readthedocs.io/en/latest/plugins.html) that adds a [data store](https://xcube.readthedocs.io/en/latest/api.html#data-store-framework)\nnamed `eopf-zarr` to xcube. The data store is used to access ESA EOPF data products as an \nanalysis-ready datacube (ARDC).\n\n## Features\n\n> **IMPORTANT**  \n> `xcube-eopf` is currently under active development.  \n> Some features may be partially implemented or still in progress.\n\nThe EOPF xcube data store is designed to provide analysis-ready data cubes from the \nEOPF Sentinel Zarr samples for Sentinel-1, Sentinel-2, and Sentinel-3 missions. The\nmain features are summarized below. A more in depth documentation is given in the \n[User Guide](guide.md). \n\nCurrently, support is focused on **Sentinel-2** products.\n\n\n### Sentinel-1\n\nSupport for Sentinel-1 will be added in an upcoming release.\n\n\n### Sentinel-2\n\nThe current implementation supports two Sentinel-2 product levels, available as \n`data_id` values:\n\n- `sentinel-2-l1c`: Level-1C top-of-atmosphere reflectance\n- `sentinel-2-l2a`: Level-2A atmospherically corrected surface reflectance\n\n#### Cube Generation Workflow\n\nThe workflow for building 3D analysis-ready cubes from Sentinel-2 products involves \nthe following steps:\n\n1. **Query** products using the [EOPF STAC API](https://stac.browser.user.eopf.eodc.eu/) for a given time range and \n   spatial extent.\n2. **Retrieve** observations as cloud-optimized Zarr chunks via the \n   [xarray-eopf backend](https://eopf-sample-service.github.io/xarray-eopf/).\n3. **Mosaic** spatial tiles into single images per timestamp.\n4. **Stack** the mosaicked scenes along the temporal axis to form a 3D cube.\n\n#### Supported Variables\n\n- **Surface reflectance bands**:  \n  `b01`, `b02`, `b03`, `b04`, `b05`, `b06`, `b07`, `b08`, `b8a`, `b09`, `b11`, `b12`\n- **Classification/Quality layers** (L2A only):  \n  `cld`, `scl`, `snw`\n\n**Example: Sentinel-2 L2A**\n```python\nfrom xcube.core.store import new_data_store\n\nstore = new_data_store(\"eopf-zarr\")\nds = store.open_data(\n    data_id=\"sentinel-2-l2a\",\n    bbox=[9.7, 53.4, 10.3, 53.7],\n    time_range=[\"2025-05-01\", \"2025-05-07\"],\n    spatial_res=10 / 111320,  # meters to degrees (approx.)\n    crs=\"EPSG:4326\",\n    variables=[\"b02\", \"b03\", \"b04\", \"scl\"],\n)\n```\n\n### Sentinel-3\n\nSupport for Sentinel-3 products will be added in an upcoming release.\n\n\n\n## Usage\n\nThe `xcube-eopf` package can be installed from PyPI (`pip install xcube-eopf`)\nor conda-forge (`conda install -c conda-forge xcube-eopf`).\nAfter installation, you are ready to go and use the `\"eopf-zarr\"` argument to initiate \na xcube EOPF data store.\n\n```python\nfrom xcube.core.store import new_data_store\n\nstore = new_data_store(\"eopf-zarr\")\nds = store.open_data(\n    data_id=\"sentinel-2-l2a\",\n    bbox=[9.7, 53.4, 10.3, 53.7],\n    time_range=[\"2025-05-01\", \"2025-05-07\"],\n    spatial_res=10 / 111320,  # meters converted to degrees (approx.)\n    crs=\"EPSG:4326\",\n    variables=[\"b02\", \"b03\", \"b04\", \"scl\"],\n)\n```\n\n## Development\n\n### Setting up a development environment\n\nThe recommended Python distribution for development is \n[miniforge](https://conda-forge.org/download/) which includes \nconda, mamba, and their dependencies.\n\n```shell\ngit clone https://github.com/EOPF-Sample-Service/xcube-eopf.git\ncd xcube-eopf\nmamba env create\nmamba activate xcube-eopf\npip install -ve .\n```\n\n### Install the library locally and test\n\n```shell\nmamba activate xcube-eopf\npip install -ve .\npytest\n```\nBy default, this will run all unit tests. To run integration tests, use:  \n\n```shell\npytest integration\n```\n\nTo run tests and generate a coverage report, use:\n\n```shell\npytest --cov xcube_eopf --cov-report html tests\n```\n\n### Some notes on the strategy of unit-testing\n\nThe unit test suite uses [pytest-recording](https://pypi.org/project/pytest-recording/)\nto mock STAC catalogs. During development an actual HTTP request is performed\nto a STAC catalog and the responses are saved in `cassettes/**.yaml` files.\nDuring testing, only the `cassettes/**.yaml` files are used without an actual\nHTTP request. During development, to save the responses to `cassettes/**.yaml`, run\n\n```bash\npytest -v -s --record-mode new_episodes\n```\nNote that `--record-mode new_episodes` overwrites all cassettes. If the user only\nwants to write cassettes which are not saved already, `--record-mode once` can be used.\n[pytest-recording](https://pypi.org/project/pytest-recording/) supports all records modes given by [VCR.py](https://vcrpy.readthedocs.io/en/latest/usage.html#record-modes).\nAfter recording the cassettes, testing can be performed as usual.\n\n\n### Setting up a documentation environment\n\n```shell\nmamba activate xcube-eopf\npip install .[doc]\n```\n\n### Testing documentation changes\n\n```shell\nmkdocs serve\n```\n\n### Deploying documentation changes\n\n```shell\nmkdocs gh-deploy\n```\n",
    "bugtrack_url": null,
    "license": "Apache-2.0",
    "summary": "xcube datastore for accessing datasets of ESA EOPF data products.",
    "version": "0.2.0",
    "project_urls": {
        "Changelog": "https://github.com/EOPF-Sample-Service/xcube-eopf/blob/main/CHANGES.md",
        "Documentation": "https://eopf-sample-service.github.io/xcube-eopf",
        "Issues": "https://github.com/EOPF-Sample-Service/xcube-eopf/issues",
        "Repository": "https://github.com/EOPF-Sample-Service/xcube-eopf"
    },
    "split_keywords": [
        "copernicus",
        " esa",
        " eopf",
        " sentinel",
        " xarray",
        " zarr"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "fbf6fdcc68337fdf3f65962eeca9dc93dc454546388bf76e0d9517155464a294",
                "md5": "fd1955ee3415fca4bb9076faa0766d70",
                "sha256": "9fffa9ba3ffd4dce70b71a6e42a2c41e70d71cf71fb3e1f78f287b3ff10e8164"
            },
            "downloads": -1,
            "filename": "xcube_eopf-0.2.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "fd1955ee3415fca4bb9076faa0766d70",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.10",
            "size": 28751,
            "upload_time": "2025-08-21T14:40:12",
            "upload_time_iso_8601": "2025-08-21T14:40:12.775535Z",
            "url": "https://files.pythonhosted.org/packages/fb/f6/fdcc68337fdf3f65962eeca9dc93dc454546388bf76e0d9517155464a294/xcube_eopf-0.2.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "b309f93786eaf34704d54d8e371f5579cecc558c8fd92c7453f0b318edef65e7",
                "md5": "9fae3b73c9d1bb587d6c7cdf6bee9a57",
                "sha256": "3ceeb4c9d516a27e9741eb7a2dcf0b86fea1d446fcdfac47cbdbaaa8ebe03e88"
            },
            "downloads": -1,
            "filename": "xcube_eopf-0.2.0.tar.gz",
            "has_sig": false,
            "md5_digest": "9fae3b73c9d1bb587d6c7cdf6bee9a57",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.10",
            "size": 29335,
            "upload_time": "2025-08-21T14:40:14",
            "upload_time_iso_8601": "2025-08-21T14:40:14.001498Z",
            "url": "https://files.pythonhosted.org/packages/b3/09/f93786eaf34704d54d8e371f5579cecc558c8fd92c7453f0b318edef65e7/xcube_eopf-0.2.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-08-21 14:40:14",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "EOPF-Sample-Service",
    "github_project": "xcube-eopf",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "xcube-eopf"
}
        
Elapsed time: 1.22149s