floodsr 0.0.1__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.
- floodsr-0.0.1/PKG-INFO +118 -0
- floodsr-0.0.1/README.md +97 -0
- floodsr-0.0.1/floodsr/__init__.py +9 -0
- floodsr-0.0.1/floodsr/cache_paths.py +40 -0
- floodsr-0.0.1/floodsr/checksums.py +46 -0
- floodsr-0.0.1/floodsr/cli.py +433 -0
- floodsr-0.0.1/floodsr/dem_sources/__init__.py +6 -0
- floodsr-0.0.1/floodsr/dem_sources/base.py +16 -0
- floodsr-0.0.1/floodsr/dem_sources/catalog.py +32 -0
- floodsr-0.0.1/floodsr/dem_sources/hrdem_stac.py +304 -0
- floodsr-0.0.1/floodsr/engine/__init__.py +8 -0
- floodsr-0.0.1/floodsr/engine/base.py +29 -0
- floodsr-0.0.1/floodsr/engine/ort.py +208 -0
- floodsr-0.0.1/floodsr/engine/providers.py +29 -0
- floodsr-0.0.1/floodsr/io/__init__.py +5 -0
- floodsr-0.0.1/floodsr/io/rasterio_io.py +14 -0
- floodsr-0.0.1/floodsr/model_registry.py +394 -0
- floodsr-0.0.1/floodsr/models/ResUNet_16x_DEM.py +640 -0
- floodsr-0.0.1/floodsr/models/__init__.py +6 -0
- floodsr-0.0.1/floodsr/models/base.py +42 -0
- floodsr-0.0.1/floodsr/models.json +10 -0
- floodsr-0.0.1/floodsr/preprocessing.py +473 -0
- floodsr-0.0.1/floodsr/tiling.py +45 -0
- floodsr-0.0.1/floodsr/tohr.py +43 -0
- floodsr-0.0.1/floodsr.egg-info/PKG-INFO +118 -0
- floodsr-0.0.1/floodsr.egg-info/SOURCES.txt +39 -0
- floodsr-0.0.1/floodsr.egg-info/dependency_links.txt +1 -0
- floodsr-0.0.1/floodsr.egg-info/entry_points.txt +2 -0
- floodsr-0.0.1/floodsr.egg-info/requires.txt +13 -0
- floodsr-0.0.1/floodsr.egg-info/top_level.txt +1 -0
- floodsr-0.0.1/pyproject.toml +37 -0
- floodsr-0.0.1/setup.cfg +4 -0
- floodsr-0.0.1/tests/test_cache_paths.py +25 -0
- floodsr-0.0.1/tests/test_checksums.py +45 -0
- floodsr-0.0.1/tests/test_cli_models.py +113 -0
- floodsr-0.0.1/tests/test_cli_tohr.py +270 -0
- floodsr-0.0.1/tests/test_docs.py +43 -0
- floodsr-0.0.1/tests/test_engine_contracts.py +93 -0
- floodsr-0.0.1/tests/test_model_registry.py +167 -0
- floodsr-0.0.1/tests/test_preprocessing.py +55 -0
- floodsr-0.0.1/tests/test_tohr_regression.py +105 -0
floodsr-0.0.1/PKG-INFO
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: floodsr
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: Flood super-resolution CLI and library using ONNX Runtime.
|
|
5
|
+
Author: floodsr developers
|
|
6
|
+
License: Proprietary
|
|
7
|
+
Requires-Python: >=3.10
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
Requires-Dist: numpy>=1.24
|
|
10
|
+
Requires-Dist: onnxruntime>=1.18
|
|
11
|
+
Requires-Dist: platformdirs>=4.0
|
|
12
|
+
Requires-Dist: pystac-client>=0.9
|
|
13
|
+
Requires-Dist: pydantic>=2.5
|
|
14
|
+
Requires-Dist: rasterio>=1.3
|
|
15
|
+
Requires-Dist: tqdm>=4.0
|
|
16
|
+
Requires-Dist: typer>=0.12
|
|
17
|
+
Provides-Extra: dev
|
|
18
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
19
|
+
Requires-Dist: pytest-cov>=5.0; extra == "dev"
|
|
20
|
+
Requires-Dist: ruff>=0.5; extra == "dev"
|
|
21
|
+
|
|
22
|
+
# floodsr
|
|
23
|
+
[](https://floodsr.readthedocs.io/en/latest/)
|
|
24
|
+
|
|
25
|
+
Super-Resolution for flood hazard rasters.
|
|
26
|
+
Ingests lores water grid and hires DEM and infers a hires water grid using the specified model.
|
|
27
|
+
|
|
28
|
+
Documentation: https://floodsr.readthedocs.io/en/latest/
|
|
29
|
+
|
|
30
|
+
Implemented models (see `floodsr/models.json`):
|
|
31
|
+
- **ResUNet_16x_DEM**: 16x DEM-conditioned ResUNet
|
|
32
|
+
- **CostGrow** (future)
|
|
33
|
+
|
|
34
|
+
Implemented backend:
|
|
35
|
+
- **ONNX Runtime**
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
## Installation
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# recommended: isolated CLI install for users
|
|
42
|
+
python -m pip install --user pipx
|
|
43
|
+
pipx ensurepath
|
|
44
|
+
pipx install floodsr
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
TestPyPI install:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
pipx install --index-url https://test.pypi.org/simple/ --pip-args="--extra-index-url https://pypi.org/simple" floodsr
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Developer install:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
pip install -e ".[dev]"
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
## Use
|
|
61
|
+
|
|
62
|
+
Current CLI surface includes model registry, `tohr` raster execution, and runtime diagnostics.
|
|
63
|
+
|
|
64
|
+
List available model versions:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
# dev shortcut for the CLI
|
|
68
|
+
alias floodsr='python -m floodsr.cli'
|
|
69
|
+
|
|
70
|
+
floodsr models list
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Fetch a model by version into the default cache:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
floodsr models fetch ResUNet_16x_DEM --force
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
tohr using HRDEM as DEM
|
|
80
|
+
```bash
|
|
81
|
+
floodsr tohr -f --in tests/data/2407_FHIMP_tile/lowres032.tif
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Run one ToHR pass from raster inputs:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
# simple tile
|
|
88
|
+
floodsr tohr \
|
|
89
|
+
--in tests/data/2407_FHIMP_tile/lowres032.tif \
|
|
90
|
+
--dem tests/data/2407_FHIMP_tile/hires002_dem.tif
|
|
91
|
+
|
|
92
|
+
# larger raster w/ windowing and tiling and rescaling
|
|
93
|
+
floodsr tohr \
|
|
94
|
+
--in tests/data/rss_mersch_A/lowres030.tif \
|
|
95
|
+
--dem tests/data/rss_mersch_A/hires002_dem.tif \
|
|
96
|
+
--out pred_sr.tif
|
|
97
|
+
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Run ToHR with explicit local model path:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
floodsr tohr \
|
|
104
|
+
--in tests/data/2407_FHIMP_tile/lowres032.tif \
|
|
105
|
+
--dem tests/data/2407_FHIMP_tile/hires002_dem.tif \
|
|
106
|
+
--out ./tmp/pred_sr.tif \
|
|
107
|
+
--model-path _inputs/ResUNet_16x_DEM/model_infer.onnx
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
Doctor diagnostics:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
floodsr doctor
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
|
floodsr-0.0.1/README.md
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# floodsr
|
|
2
|
+
[](https://floodsr.readthedocs.io/en/latest/)
|
|
3
|
+
|
|
4
|
+
Super-Resolution for flood hazard rasters.
|
|
5
|
+
Ingests lores water grid and hires DEM and infers a hires water grid using the specified model.
|
|
6
|
+
|
|
7
|
+
Documentation: https://floodsr.readthedocs.io/en/latest/
|
|
8
|
+
|
|
9
|
+
Implemented models (see `floodsr/models.json`):
|
|
10
|
+
- **ResUNet_16x_DEM**: 16x DEM-conditioned ResUNet
|
|
11
|
+
- **CostGrow** (future)
|
|
12
|
+
|
|
13
|
+
Implemented backend:
|
|
14
|
+
- **ONNX Runtime**
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# recommended: isolated CLI install for users
|
|
21
|
+
python -m pip install --user pipx
|
|
22
|
+
pipx ensurepath
|
|
23
|
+
pipx install floodsr
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
TestPyPI install:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pipx install --index-url https://test.pypi.org/simple/ --pip-args="--extra-index-url https://pypi.org/simple" floodsr
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Developer install:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pip install -e ".[dev]"
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
## Use
|
|
40
|
+
|
|
41
|
+
Current CLI surface includes model registry, `tohr` raster execution, and runtime diagnostics.
|
|
42
|
+
|
|
43
|
+
List available model versions:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
# dev shortcut for the CLI
|
|
47
|
+
alias floodsr='python -m floodsr.cli'
|
|
48
|
+
|
|
49
|
+
floodsr models list
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Fetch a model by version into the default cache:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
floodsr models fetch ResUNet_16x_DEM --force
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
tohr using HRDEM as DEM
|
|
59
|
+
```bash
|
|
60
|
+
floodsr tohr -f --in tests/data/2407_FHIMP_tile/lowres032.tif
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Run one ToHR pass from raster inputs:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
# simple tile
|
|
67
|
+
floodsr tohr \
|
|
68
|
+
--in tests/data/2407_FHIMP_tile/lowres032.tif \
|
|
69
|
+
--dem tests/data/2407_FHIMP_tile/hires002_dem.tif
|
|
70
|
+
|
|
71
|
+
# larger raster w/ windowing and tiling and rescaling
|
|
72
|
+
floodsr tohr \
|
|
73
|
+
--in tests/data/rss_mersch_A/lowres030.tif \
|
|
74
|
+
--dem tests/data/rss_mersch_A/hires002_dem.tif \
|
|
75
|
+
--out pred_sr.tif
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Run ToHR with explicit local model path:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
floodsr tohr \
|
|
83
|
+
--in tests/data/2407_FHIMP_tile/lowres032.tif \
|
|
84
|
+
--dem tests/data/2407_FHIMP_tile/hires002_dem.tif \
|
|
85
|
+
--out ./tmp/pred_sr.tif \
|
|
86
|
+
--model-path _inputs/ResUNet_16x_DEM/model_infer.onnx
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
Doctor diagnostics:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
floodsr doctor
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"""floodsr package."""
|
|
2
|
+
|
|
3
|
+
from importlib.metadata import PackageNotFoundError, version
|
|
4
|
+
|
|
5
|
+
try:
|
|
6
|
+
# Read installed package metadata so version stays tied to pyproject.toml.
|
|
7
|
+
__version__ = version("floodsr")
|
|
8
|
+
except PackageNotFoundError:
|
|
9
|
+
__version__ = "0+unknown"
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"""Cache path helpers for model weights."""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from platformdirs import user_cache_dir
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
APP_NAME = "floodsr"
|
|
9
|
+
APP_AUTHOR = "floodsr"
|
|
10
|
+
log = logging.getLogger(__name__)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def get_cache_dir(cache_dir: str | Path | None = None) -> Path:
|
|
14
|
+
"""Return a writable cache directory and ensure it exists."""
|
|
15
|
+
# Prefer an explicit cache directory when one is supplied.
|
|
16
|
+
if cache_dir is not None:
|
|
17
|
+
path = Path(cache_dir).expanduser().resolve()
|
|
18
|
+
else:
|
|
19
|
+
# Use a stable platform cache path.
|
|
20
|
+
path = Path(user_cache_dir(APP_NAME, APP_AUTHOR))
|
|
21
|
+
path.mkdir(parents=True, exist_ok=True)
|
|
22
|
+
assert path.exists(), f"failed to create cache directory: {path}"
|
|
23
|
+
log.debug(f"resolved cache directory to\n {path}")
|
|
24
|
+
return path
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def get_model_cache_path(
|
|
28
|
+
model_version: str,
|
|
29
|
+
file_name: str,
|
|
30
|
+
cache_dir: str | Path | None = None,
|
|
31
|
+
) -> Path:
|
|
32
|
+
"""Return the cache path for a specific model file."""
|
|
33
|
+
assert model_version, "model_version cannot be empty"
|
|
34
|
+
assert file_name, "file_name cannot be empty"
|
|
35
|
+
|
|
36
|
+
# Group each model version under its own cache subdirectory.
|
|
37
|
+
model_fp = get_cache_dir(cache_dir) / model_version / file_name
|
|
38
|
+
model_fp.parent.mkdir(parents=True, exist_ok=True)
|
|
39
|
+
log.debug(f"resolved model cache path to\n {model_fp}")
|
|
40
|
+
return model_fp
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"""Checksum helpers for model artifacts."""
|
|
2
|
+
|
|
3
|
+
import hashlib
|
|
4
|
+
import logging
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
log = logging.getLogger(__name__)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def compute_sha256(file_path: str | Path, chunk_size: int = 1024 * 1024) -> str:
|
|
12
|
+
"""Compute the SHA256 digest for a file."""
|
|
13
|
+
path = Path(file_path)
|
|
14
|
+
assert path.exists(), f"file does not exist: {path}"
|
|
15
|
+
assert path.is_file(), f"path is not a file: {path}"
|
|
16
|
+
log.debug(f"computing sha256 for\n {path}")
|
|
17
|
+
|
|
18
|
+
# Stream file bytes to avoid loading large model files into memory.
|
|
19
|
+
hasher = hashlib.sha256()
|
|
20
|
+
with path.open("rb") as stream:
|
|
21
|
+
chunk = stream.read(chunk_size)
|
|
22
|
+
while chunk:
|
|
23
|
+
hasher.update(chunk)
|
|
24
|
+
chunk = stream.read(chunk_size)
|
|
25
|
+
return hasher.hexdigest()
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def verify_sha256(file_path: str | Path, expected_sha256: str) -> bool:
|
|
29
|
+
"""Return True when a file digest matches the expected SHA256."""
|
|
30
|
+
assert expected_sha256, "expected_sha256 cannot be empty"
|
|
31
|
+
actual_sha256 = compute_sha256(file_path)
|
|
32
|
+
is_match = actual_sha256.lower() == expected_sha256.strip().lower()
|
|
33
|
+
log.debug(f"sha256 verification result for\n {file_path}\n match={is_match}")
|
|
34
|
+
return is_match
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def assert_sha256(file_path: str | Path, expected_sha256: str) -> None:
|
|
38
|
+
"""Raise ValueError when the file digest mismatches the expected SHA256."""
|
|
39
|
+
assert expected_sha256, "expected_sha256 cannot be empty"
|
|
40
|
+
actual_sha256 = compute_sha256(file_path)
|
|
41
|
+
if actual_sha256.lower() != expected_sha256.strip().lower():
|
|
42
|
+
raise ValueError(
|
|
43
|
+
f"checksum mismatch for {file_path}: "
|
|
44
|
+
f"expected {expected_sha256}, got {actual_sha256}"
|
|
45
|
+
)
|
|
46
|
+
log.debug(f"sha256 assertion passed for\n {file_path}")
|