dhidb 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- dhidb-0.1.0/.github/workflows/ci-release.yml +123 -0
- dhidb-0.1.0/.github/workflows/docs.yml +50 -0
- dhidb-0.1.0/.gitignore +12 -0
- dhidb-0.1.0/LICENSE +22 -0
- dhidb-0.1.0/PKG-INFO +106 -0
- dhidb-0.1.0/README.md +64 -0
- dhidb-0.1.0/assetts/DHIDB_logo.png +0 -0
- dhidb-0.1.0/assetts/DHIDB_logo_white.png +0 -0
- dhidb-0.1.0/docs/_config.yml +35 -0
- dhidb-0.1.0/docs/_static/DHIDB_logo.png +0 -0
- dhidb-0.1.0/docs/_static/custom.css +75 -0
- dhidb-0.1.0/docs/_toc.yml +10 -0
- dhidb-0.1.0/docs/api.md +11 -0
- dhidb-0.1.0/docs/contributing.md +22 -0
- dhidb-0.1.0/docs/data-model.md +31 -0
- dhidb-0.1.0/docs/getting-started.md +41 -0
- dhidb-0.1.0/docs/index.md +37 -0
- dhidb-0.1.0/docs/quality.md +16 -0
- dhidb-0.1.0/docs/queries.md +60 -0
- dhidb-0.1.0/pyproject.toml +76 -0
- dhidb-0.1.0/setup.cfg +4 -0
- dhidb-0.1.0/src/dhidb/__init__.py +14 -0
- dhidb-0.1.0/src/dhidb/config.py +33 -0
- dhidb-0.1.0/src/dhidb/grid.py +79 -0
- dhidb-0.1.0/src/dhidb/provider.py +350 -0
- dhidb-0.1.0/src/dhidb/py.typed +1 -0
- dhidb-0.1.0/src/dhidb.egg-info/PKG-INFO +106 -0
- dhidb-0.1.0/src/dhidb.egg-info/SOURCES.txt +32 -0
- dhidb-0.1.0/src/dhidb.egg-info/dependency_links.txt +1 -0
- dhidb-0.1.0/src/dhidb.egg-info/requires.txt +19 -0
- dhidb-0.1.0/src/dhidb.egg-info/top_level.txt +1 -0
- dhidb-0.1.0/tests/conftest.py +45 -0
- dhidb-0.1.0/tests/test_config.py +14 -0
- dhidb-0.1.0/tests/test_provider.py +57 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
name: CI and release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
workflow_dispatch:
|
|
9
|
+
|
|
10
|
+
permissions:
|
|
11
|
+
contents: read
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
versioning:
|
|
15
|
+
name: Compute semantic version
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
outputs:
|
|
18
|
+
version: ${{ steps.semver.outputs.version-string }}
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@v4
|
|
21
|
+
with:
|
|
22
|
+
fetch-depth: 0
|
|
23
|
+
fetch-tags: true
|
|
24
|
+
- name: Compute version from Git history
|
|
25
|
+
id: semver
|
|
26
|
+
uses: bitshifted/git-auto-semver@v2
|
|
27
|
+
with:
|
|
28
|
+
create_tag: false
|
|
29
|
+
main_branch: main
|
|
30
|
+
initial_version: 0.1.0
|
|
31
|
+
- name: Display version
|
|
32
|
+
run: echo "Candidate version is ${{ steps.semver.outputs.version-string }}"
|
|
33
|
+
|
|
34
|
+
test:
|
|
35
|
+
name: Test Python ${{ matrix.python-version }}
|
|
36
|
+
runs-on: ubuntu-latest
|
|
37
|
+
strategy:
|
|
38
|
+
fail-fast: false
|
|
39
|
+
matrix:
|
|
40
|
+
python-version: ["3.10", "3.11", "3.12", "3.13"]
|
|
41
|
+
steps:
|
|
42
|
+
- uses: actions/checkout@v4
|
|
43
|
+
- uses: actions/setup-python@v5
|
|
44
|
+
with:
|
|
45
|
+
python-version: ${{ matrix.python-version }}
|
|
46
|
+
cache: pip
|
|
47
|
+
- name: Install package and test dependencies
|
|
48
|
+
run: python -m pip install -e ".[test]"
|
|
49
|
+
- name: Lint
|
|
50
|
+
run: ruff check src tests
|
|
51
|
+
- name: Test
|
|
52
|
+
run: pytest --cov=dhidb --cov-report=term-missing
|
|
53
|
+
|
|
54
|
+
build:
|
|
55
|
+
name: Build distributions
|
|
56
|
+
runs-on: ubuntu-latest
|
|
57
|
+
needs: [versioning, test]
|
|
58
|
+
env:
|
|
59
|
+
SETUPTOOLS_SCM_PRETEND_VERSION_FOR_DHIDB: ${{ needs.versioning.outputs.version }}
|
|
60
|
+
steps:
|
|
61
|
+
- uses: actions/checkout@v4
|
|
62
|
+
with:
|
|
63
|
+
fetch-depth: 0
|
|
64
|
+
- uses: actions/setup-python@v5
|
|
65
|
+
with:
|
|
66
|
+
python-version: "3.12"
|
|
67
|
+
- name: Build wheel and source distribution
|
|
68
|
+
run: |
|
|
69
|
+
python -m pip install build
|
|
70
|
+
python -m build
|
|
71
|
+
- name: Check distributions
|
|
72
|
+
run: |
|
|
73
|
+
python -m pip install twine
|
|
74
|
+
twine check dist/*
|
|
75
|
+
- uses: actions/upload-artifact@v4
|
|
76
|
+
with:
|
|
77
|
+
name: python-distributions
|
|
78
|
+
path: dist/
|
|
79
|
+
if-no-files-found: error
|
|
80
|
+
|
|
81
|
+
release:
|
|
82
|
+
name: Tag, release, and publish
|
|
83
|
+
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
|
84
|
+
runs-on: ubuntu-latest
|
|
85
|
+
needs: [versioning, build]
|
|
86
|
+
environment:
|
|
87
|
+
name: pypi
|
|
88
|
+
url: https://pypi.org/project/dhidb/
|
|
89
|
+
permissions:
|
|
90
|
+
contents: write
|
|
91
|
+
id-token: write
|
|
92
|
+
steps:
|
|
93
|
+
- uses: actions/checkout@v4
|
|
94
|
+
with:
|
|
95
|
+
fetch-depth: 0
|
|
96
|
+
fetch-tags: true
|
|
97
|
+
- uses: actions/download-artifact@v4
|
|
98
|
+
with:
|
|
99
|
+
name: python-distributions
|
|
100
|
+
path: dist
|
|
101
|
+
- name: Create semantic version tag
|
|
102
|
+
env:
|
|
103
|
+
VERSION: ${{ needs.versioning.outputs.version }}
|
|
104
|
+
run: |
|
|
105
|
+
set -euo pipefail
|
|
106
|
+
git config user.name "github-actions[bot]"
|
|
107
|
+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
|
108
|
+
if git rev-parse "v${VERSION}" >/dev/null 2>&1; then
|
|
109
|
+
echo "Tag v${VERSION} already exists"
|
|
110
|
+
else
|
|
111
|
+
git tag -a "v${VERSION}" -m "Release v${VERSION}"
|
|
112
|
+
git push origin "v${VERSION}"
|
|
113
|
+
fi
|
|
114
|
+
- name: Create GitHub release
|
|
115
|
+
uses: softprops/action-gh-release@v2
|
|
116
|
+
with:
|
|
117
|
+
tag_name: v${{ needs.versioning.outputs.version }}
|
|
118
|
+
generate_release_notes: true
|
|
119
|
+
files: dist/*
|
|
120
|
+
- name: Publish to PyPI using trusted publishing
|
|
121
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
122
|
+
with:
|
|
123
|
+
password: ${{ secrets.PYPI }}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
name: Documentation
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
paths:
|
|
7
|
+
- "docs/**"
|
|
8
|
+
- "src/**"
|
|
9
|
+
- "assetts/**"
|
|
10
|
+
- "pyproject.toml"
|
|
11
|
+
- ".github/workflows/docs.yml"
|
|
12
|
+
workflow_dispatch:
|
|
13
|
+
|
|
14
|
+
permissions:
|
|
15
|
+
contents: read
|
|
16
|
+
pages: write
|
|
17
|
+
id-token: write
|
|
18
|
+
|
|
19
|
+
concurrency:
|
|
20
|
+
group: pages
|
|
21
|
+
cancel-in-progress: true
|
|
22
|
+
|
|
23
|
+
jobs:
|
|
24
|
+
build:
|
|
25
|
+
runs-on: ubuntu-latest
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@v4
|
|
28
|
+
- uses: actions/setup-python@v5
|
|
29
|
+
with:
|
|
30
|
+
python-version: "3.12"
|
|
31
|
+
cache: pip
|
|
32
|
+
- name: Install package and documentation dependencies
|
|
33
|
+
run: python -m pip install -e ".[docs]"
|
|
34
|
+
- name: Build Jupyter Book
|
|
35
|
+
run: jupyter-book build docs
|
|
36
|
+
- uses: actions/upload-pages-artifact@v3
|
|
37
|
+
with:
|
|
38
|
+
path: docs/_build/html
|
|
39
|
+
|
|
40
|
+
deploy:
|
|
41
|
+
environment:
|
|
42
|
+
name: github-pages
|
|
43
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
44
|
+
runs-on: ubuntu-latest
|
|
45
|
+
needs: build
|
|
46
|
+
steps:
|
|
47
|
+
- name: Deploy to GitHub Pages
|
|
48
|
+
id: deployment
|
|
49
|
+
uses: actions/deploy-pages@v4
|
|
50
|
+
|
dhidb-0.1.0/.gitignore
ADDED
dhidb-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Helmholtz Centre for Environmental Research - UFZ
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
dhidb-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: dhidb
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Read-only Python access to the global 300 m Dynamic Habitat Indices database
|
|
5
|
+
Author: Julian Oeser, Ingolf Kühn
|
|
6
|
+
Author-email: Taimur Khan <taimur.khan@ufz.de>
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
Project-URL: Homepage, https://github.com/thisistaimur/dhidb
|
|
9
|
+
Project-URL: Documentation, https://thisistaimur.github.io/dhidb/
|
|
10
|
+
Project-URL: Repository, https://github.com/thisistaimur/dhidb
|
|
11
|
+
Project-URL: Issues, https://github.com/thisistaimur/dhidb/issues
|
|
12
|
+
Keywords: biodiversity,DHI,remote sensing,S3,TileDB
|
|
13
|
+
Classifier: Development Status :: 3 - Alpha
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering :: GIS
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: affine>=2.4
|
|
25
|
+
Requires-Dist: numpy<3,>=1.26
|
|
26
|
+
Requires-Dist: pandas>=2.1
|
|
27
|
+
Requires-Dist: pyproj>=3.6
|
|
28
|
+
Requires-Dist: rasterio>=1.3
|
|
29
|
+
Requires-Dist: shapely>=2.0
|
|
30
|
+
Requires-Dist: tiledb<0.38,>=0.35
|
|
31
|
+
Requires-Dist: xarray>=2024.1
|
|
32
|
+
Provides-Extra: docs
|
|
33
|
+
Requires-Dist: jupyter-book<2,>=1.0; extra == "docs"
|
|
34
|
+
Requires-Dist: matplotlib>=3.8; extra == "docs"
|
|
35
|
+
Requires-Dist: sphinx-copybutton>=0.5; extra == "docs"
|
|
36
|
+
Provides-Extra: test
|
|
37
|
+
Requires-Dist: build>=1.2; extra == "test"
|
|
38
|
+
Requires-Dist: pytest>=8; extra == "test"
|
|
39
|
+
Requires-Dist: pytest-cov>=5; extra == "test"
|
|
40
|
+
Requires-Dist: ruff>=0.9; extra == "test"
|
|
41
|
+
Dynamic: license-file
|
|
42
|
+
|
|
43
|
+
<p align="center">
|
|
44
|
+
<img src="https://raw.githubusercontent.com/thisistaimur/dhidb/main/assetts/DHIDB_logo_white.png" alt="DHIDB" width="720">
|
|
45
|
+
</p>
|
|
46
|
+
|
|
47
|
+
# dhidb
|
|
48
|
+
|
|
49
|
+
`dhidb` provides read-only Python access to the global 300 m Dynamic Habitat
|
|
50
|
+
Indices database stored as a dense TileDB array on public S3-compatible object
|
|
51
|
+
storage. It supports point, bounding-box, and polygon queries without first
|
|
52
|
+
downloading the complete database.
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
## Installation
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
pip install dhidb
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
For development:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
python -m pip install -e ".[test,docs]"
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Quick start
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
from dhidb import DHIProvider
|
|
71
|
+
|
|
72
|
+
with DHIProvider() as db:
|
|
73
|
+
print(db.years)
|
|
74
|
+
print(db.variables)
|
|
75
|
+
|
|
76
|
+
germany = db.query_bbox(
|
|
77
|
+
bounds=(5.8, 47.2, 15.1, 55.1),
|
|
78
|
+
years=[2020, 2021, 2022],
|
|
79
|
+
variables=["dhi_cum", "dhi_min", "dhi_var", "valid_count"],
|
|
80
|
+
)
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Documentation
|
|
84
|
+
|
|
85
|
+
The Jupyter Book source is in [`docs/`](docs/). Build it locally with:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
jupyter-book build docs
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Data variables
|
|
92
|
+
|
|
93
|
+
| Variable | Meaning | Unit |
|
|
94
|
+
|---|---|---|
|
|
95
|
+
| `dhi_cum` | Cumulative productivity from LSP TPROD | PPI integral (`m2 m-2 day`) |
|
|
96
|
+
| `dhi_min` | Minimum seasonal productivity baseline from LSP MINV | PPI (`m2 m-2`) |
|
|
97
|
+
| `dhi_var` | Inter-period GPP coefficient of variation | dimensionless |
|
|
98
|
+
| `dhi_combined` | Normalized combined DHI, where available | dimensionless |
|
|
99
|
+
| `observed_count` | Number of available 10-day observations | scenes |
|
|
100
|
+
| `valid_count` | Number of accepted 10-day observations | scenes |
|
|
101
|
+
| `qflag_any_count` | Observations carrying any source quality flag | scenes |
|
|
102
|
+
| `qflag_rejected_count` | Observations rejected by quality filtering | scenes |
|
|
103
|
+
|
|
104
|
+
## License
|
|
105
|
+
|
|
106
|
+
MIT
|
dhidb-0.1.0/README.md
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/thisistaimur/dhidb/main/assetts/DHIDB_logo_white.png" alt="DHIDB" width="720">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
# dhidb
|
|
6
|
+
|
|
7
|
+
`dhidb` provides read-only Python access to the global 300 m Dynamic Habitat
|
|
8
|
+
Indices database stored as a dense TileDB array on public S3-compatible object
|
|
9
|
+
storage. It supports point, bounding-box, and polygon queries without first
|
|
10
|
+
downloading the complete database.
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pip install dhidb
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
For development:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
python -m pip install -e ".[test,docs]"
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Quick start
|
|
26
|
+
|
|
27
|
+
```python
|
|
28
|
+
from dhidb import DHIProvider
|
|
29
|
+
|
|
30
|
+
with DHIProvider() as db:
|
|
31
|
+
print(db.years)
|
|
32
|
+
print(db.variables)
|
|
33
|
+
|
|
34
|
+
germany = db.query_bbox(
|
|
35
|
+
bounds=(5.8, 47.2, 15.1, 55.1),
|
|
36
|
+
years=[2020, 2021, 2022],
|
|
37
|
+
variables=["dhi_cum", "dhi_min", "dhi_var", "valid_count"],
|
|
38
|
+
)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Documentation
|
|
42
|
+
|
|
43
|
+
The Jupyter Book source is in [`docs/`](docs/). Build it locally with:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
jupyter-book build docs
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Data variables
|
|
50
|
+
|
|
51
|
+
| Variable | Meaning | Unit |
|
|
52
|
+
|---|---|---|
|
|
53
|
+
| `dhi_cum` | Cumulative productivity from LSP TPROD | PPI integral (`m2 m-2 day`) |
|
|
54
|
+
| `dhi_min` | Minimum seasonal productivity baseline from LSP MINV | PPI (`m2 m-2`) |
|
|
55
|
+
| `dhi_var` | Inter-period GPP coefficient of variation | dimensionless |
|
|
56
|
+
| `dhi_combined` | Normalized combined DHI, where available | dimensionless |
|
|
57
|
+
| `observed_count` | Number of available 10-day observations | scenes |
|
|
58
|
+
| `valid_count` | Number of accepted 10-day observations | scenes |
|
|
59
|
+
| `qflag_any_count` | Observations carrying any source quality flag | scenes |
|
|
60
|
+
| `qflag_rejected_count` | Observations rejected by quality filtering | scenes |
|
|
61
|
+
|
|
62
|
+
## License
|
|
63
|
+
|
|
64
|
+
MIT
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
title: DHIDB
|
|
2
|
+
author: Taimur Khan, Julian Oeser, and Ingolf Kühn
|
|
3
|
+
copyright: "2026, Helmholtz Centre for Environmental Research - UFZ"
|
|
4
|
+
logo: _static/DHIDB_logo.png
|
|
5
|
+
only_build_toc_files: true
|
|
6
|
+
execute:
|
|
7
|
+
execute_notebooks: "off"
|
|
8
|
+
parse:
|
|
9
|
+
myst_enable_extensions:
|
|
10
|
+
- colon_fence
|
|
11
|
+
- deflist
|
|
12
|
+
- dollarmath
|
|
13
|
+
- linkify
|
|
14
|
+
repository:
|
|
15
|
+
url: https://github.com/thisistaimur/dhidb
|
|
16
|
+
branch: main
|
|
17
|
+
html:
|
|
18
|
+
favicon: _static/DHIDB_logo.png
|
|
19
|
+
use_issues_button: true
|
|
20
|
+
use_repository_button: true
|
|
21
|
+
home_page_in_navbar: true
|
|
22
|
+
extra_footer: >-
|
|
23
|
+
DHIDB is developed at the Helmholtz Centre for Environmental Research - UFZ.
|
|
24
|
+
sphinx:
|
|
25
|
+
extra_extensions:
|
|
26
|
+
- sphinx.ext.autodoc
|
|
27
|
+
- sphinx.ext.napoleon
|
|
28
|
+
- sphinx_copybutton
|
|
29
|
+
config:
|
|
30
|
+
html_css_files:
|
|
31
|
+
- custom.css
|
|
32
|
+
html_theme_options:
|
|
33
|
+
logo:
|
|
34
|
+
text: DHIDB
|
|
35
|
+
show_nav_level: 2
|
|
Binary file
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--dhidb-black: #050505;
|
|
3
|
+
--dhidb-panel: #111416;
|
|
4
|
+
--dhidb-purple: #440154;
|
|
5
|
+
--dhidb-blue: #31688e;
|
|
6
|
+
--dhidb-green: #35b779;
|
|
7
|
+
--dhidb-yellow: #fde725;
|
|
8
|
+
--pst-color-primary: #35b779;
|
|
9
|
+
--pst-color-link: #35b779;
|
|
10
|
+
--pst-color-link-hover: #fde725;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
html[data-theme="light"],
|
|
14
|
+
html[data-theme="dark"] {
|
|
15
|
+
--pst-color-background: var(--dhidb-black);
|
|
16
|
+
--pst-color-on-background: #f4f7f5;
|
|
17
|
+
--pst-color-surface: var(--dhidb-panel);
|
|
18
|
+
--pst-color-on-surface: #e8efec;
|
|
19
|
+
--pst-color-text-base: #eef4f1;
|
|
20
|
+
--pst-color-text-muted: #aab8b2;
|
|
21
|
+
--pst-color-border: #27302d;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
body,
|
|
25
|
+
.bd-header,
|
|
26
|
+
.bd-sidebar-primary,
|
|
27
|
+
.bd-sidebar-secondary,
|
|
28
|
+
.bd-main .bd-content .bd-article-container {
|
|
29
|
+
background: var(--dhidb-black);
|
|
30
|
+
color: #eef4f1;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.bd-header {
|
|
34
|
+
border-bottom: 1px solid #27302d;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
a,
|
|
38
|
+
.toc-entry a.nav-link.active,
|
|
39
|
+
.bd-links .current > a {
|
|
40
|
+
color: var(--dhidb-green);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
a:hover {
|
|
44
|
+
color: var(--dhidb-yellow);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
code {
|
|
48
|
+
color: #9be26d;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
pre,
|
|
52
|
+
div.highlight {
|
|
53
|
+
background: #0d1110;
|
|
54
|
+
border: 1px solid #27302d;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.hero-logo {
|
|
58
|
+
margin: 1rem auto 2rem;
|
|
59
|
+
max-height: 300px;
|
|
60
|
+
object-fit: contain;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
table {
|
|
64
|
+
border-color: #27302d;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
thead {
|
|
68
|
+
background: linear-gradient(90deg, var(--dhidb-purple), var(--dhidb-blue));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.admonition {
|
|
72
|
+
background: var(--dhidb-panel);
|
|
73
|
+
border-left-color: var(--dhidb-green);
|
|
74
|
+
}
|
|
75
|
+
|
dhidb-0.1.0/docs/api.md
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Contributing and releases
|
|
2
|
+
|
|
3
|
+
Install the development environment and run the checks locally:
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
python -m pip install -e ".[test,docs]"
|
|
7
|
+
ruff check src tests
|
|
8
|
+
pytest
|
|
9
|
+
python -m build
|
|
10
|
+
jupyter-book build docs
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Versioning
|
|
14
|
+
|
|
15
|
+
The CI workflow derives a semantic version from Git history. It computes the
|
|
16
|
+
candidate version for pull requests and pushes, but creates a tag, GitHub
|
|
17
|
+
release, and PyPI distribution only after the test matrix and package build
|
|
18
|
+
have succeeded on `main`.
|
|
19
|
+
|
|
20
|
+
PyPI publication uses GitHub trusted publishing. Configure the `pypi`
|
|
21
|
+
environment for this repository on PyPI before enabling the first release.
|
|
22
|
+
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Data model
|
|
2
|
+
|
|
3
|
+
DHIDB v1 is a dense TileDB array with dimensions `(time, y, x)`.
|
|
4
|
+
|
|
5
|
+
| Dimension | Size | Meaning |
|
|
6
|
+
|---|---:|---|
|
|
7
|
+
| `time` | 12 | Annual layers from 2014 through 2025 |
|
|
8
|
+
| `y` | 47,040 | Global raster rows |
|
|
9
|
+
| `x` | 120,960 | Global raster columns |
|
|
10
|
+
|
|
11
|
+
Each annual layer contains 5,689,958,400 grid cells. The complete logical
|
|
12
|
+
array contains 68,279,500,800 cells before compression and exclusion of
|
|
13
|
+
unwritten fragments.
|
|
14
|
+
|
|
15
|
+
## Variables
|
|
16
|
+
|
|
17
|
+
| Variable | Definition | Unit |
|
|
18
|
+
|---|---|---|
|
|
19
|
+
| `dhi_cum` | Sum of LSP TPROD over two growing seasons | PPI integral (`m2 m-2 day`) |
|
|
20
|
+
| `dhi_min` | Minimum of scaled LSP MINV over two growing seasons | PPI (`m2 m-2`) |
|
|
21
|
+
| `dhi_var` | Coefficient of variation of accepted 10-day GPP | dimensionless |
|
|
22
|
+
| `dhi_combined` | Sum of normalized component layers | dimensionless |
|
|
23
|
+
| `observed_count` | Available GPP observations | scenes |
|
|
24
|
+
| `valid_count` | Accepted GPP observations | scenes |
|
|
25
|
+
| `qflag_any_count` | Observations carrying any source QFLAG | scenes |
|
|
26
|
+
| `qflag_rejected_count` | Rejected observations | scenes |
|
|
27
|
+
|
|
28
|
+
`dhi_cum` and `dhi_min` summarize the smoothed Plant Phenology Index
|
|
29
|
+
trajectory represented by Copernicus LSP. They are not direct annual GPP sums
|
|
30
|
+
or minima. `dhi_var` is calculated from the 10-day GPP time series.
|
|
31
|
+
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Getting started
|
|
2
|
+
|
|
3
|
+
## Install
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
pip install dhidb
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Connect to public QAS storage
|
|
10
|
+
|
|
11
|
+
Public reads use unsigned S3 requests. No access key is required.
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
from dhidb import DHIProvider
|
|
15
|
+
|
|
16
|
+
db = DHIProvider()
|
|
17
|
+
print(db.years)
|
|
18
|
+
print(db.variables)
|
|
19
|
+
db.close()
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
The provider uses the public endpoint and array defaults, so Python needs no
|
|
23
|
+
connection arguments:
|
|
24
|
+
|
|
25
|
+
```python
|
|
26
|
+
from dhidb import DHIProvider
|
|
27
|
+
|
|
28
|
+
with DHIProvider() as db:
|
|
29
|
+
print(db.metadata)
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
## Query safety
|
|
34
|
+
|
|
35
|
+
The default client refuses a request containing more than 50 million
|
|
36
|
+
space-time cells. This protects laptops from accidentally materializing a
|
|
37
|
+
global array. Raise the limit deliberately when appropriate:
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
db = DHIProvider(max_cells=100_000_000)
|
|
41
|
+
```
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Global habitat dynamics, queried where you need them
|
|
2
|
+
|
|
3
|
+
```{image} _static/DHIDB_logo.png
|
|
4
|
+
:alt: DHIDB logo
|
|
5
|
+
:class: hero-logo
|
|
6
|
+
:width: 760px
|
|
7
|
+
:align: center
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
DHIDB provides direct, read-only access to annual global Dynamic Habitat
|
|
11
|
+
Indices at 300 m resolution. The data remain in a dense TileDB array on public
|
|
12
|
+
S3-compatible object storage; the Python package retrieves only the years,
|
|
13
|
+
variables, and spatial window requested by the user.
|
|
14
|
+
|
|
15
|
+
The indices describe three complementary dimensions of vegetation dynamics:
|
|
16
|
+
|
|
17
|
+
- cumulative productivity (`dhi_cum`),
|
|
18
|
+
- the minimum seasonal productivity baseline (`dhi_min`), and
|
|
19
|
+
- inter-period variability in gross primary production (`dhi_var`).
|
|
20
|
+
|
|
21
|
+
```python
|
|
22
|
+
from dhidb import DHIProvider
|
|
23
|
+
|
|
24
|
+
with DHIProvider() as db:
|
|
25
|
+
point = db.query_point(12.37, 51.34, years=range(2014, 2026))
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
:::{important}
|
|
29
|
+
The provider uses the public QAS endpoint and production array defaults
|
|
30
|
+
automatically. Public reads do not require credentials.
|
|
31
|
+
:::
|
|
32
|
+
|
|
33
|
+
## Why TileDB?
|
|
34
|
+
|
|
35
|
+
The database contains 12 annual layers over a grid of 47,040 by 120,960 cells,
|
|
36
|
+
or 68,279,500,800 dense array cells. TileDB exposes this as `(time, y, x)` and
|
|
37
|
+
allows small spatial subsets to be read without transferring the full array.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Quality information
|
|
2
|
+
|
|
3
|
+
The database retains observation counts alongside the DHI components so that
|
|
4
|
+
users can evaluate temporal support for each pixel.
|
|
5
|
+
|
|
6
|
+
`observed_count` records how many 10-day GPP scenes were present.
|
|
7
|
+
`valid_count` records how many contributed after source-quality screening.
|
|
8
|
+
`qflag_any_count` and `qflag_rejected_count` summarize the original
|
|
9
|
+
Copernicus QFLAG observations.
|
|
10
|
+
|
|
11
|
+
For annual products, a maximum `valid_count` of 36 is expected. The TileDB
|
|
12
|
+
fill value for an unwritten `uint16` cell is 65,535; clients should not
|
|
13
|
+
interpret that value as an observation count. Query only production-complete
|
|
14
|
+
years and use finite DHI values together with plausible count values when
|
|
15
|
+
validating an analysis.
|
|
16
|
+
|