taco-eo 0.3.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.
- taco_eo-0.3.0/.gitignore +34 -0
- taco_eo-0.3.0/CHANGELOG.md +98 -0
- taco_eo-0.3.0/LICENSE +21 -0
- taco_eo-0.3.0/PKG-INFO +75 -0
- taco_eo-0.3.0/README.md +32 -0
- taco_eo-0.3.0/examples/change_detection.py +78 -0
- taco_eo-0.3.0/examples/geospatial.py +61 -0
- taco_eo-0.3.0/examples/minimal.py +17 -0
- taco_eo-0.3.0/examples/numpy_minimal.py +48 -0
- taco_eo-0.3.0/examples/oceantaco_istac.py +321 -0
- taco_eo-0.3.0/examples/partitioned.py +34 -0
- taco_eo-0.3.0/examples/sequence.py +49 -0
- taco_eo-0.3.0/examples/stac_segmentation.py +209 -0
- taco_eo-0.3.0/examples/time_series.py +65 -0
- taco_eo-0.3.0/pyproject.toml +99 -0
- taco_eo-0.3.0/taco/__init__.py +40 -0
- taco_eo-0.3.0/taco/_graph.py +129 -0
- taco_eo-0.3.0/taco/_parquet.py +15 -0
- taco_eo-0.3.0/taco/_publish.py +97 -0
- taco_eo-0.3.0/taco/_repr.py +303 -0
- taco_eo-0.3.0/taco/_source.py +52 -0
- taco_eo-0.3.0/taco/_view.py +148 -0
- taco_eo-0.3.0/taco/contract/__init__.py +23 -0
- taco_eo-0.3.0/taco/contract/collection.py +410 -0
- taco_eo-0.3.0/taco/contract/contract.py +650 -0
- taco_eo-0.3.0/taco/contract/naming.py +215 -0
- taco_eo-0.3.0/taco/contract/sample.py +151 -0
- taco_eo-0.3.0/taco/contract/structure.py +130 -0
- taco_eo-0.3.0/taco/contract/types.py +279 -0
- taco_eo-0.3.0/taco/cozip.py +9 -0
- taco_eo-0.3.0/taco/dataset.py +88 -0
- taco_eo-0.3.0/taco/errors.py +37 -0
- taco_eo-0.3.0/taco/metadata/__init__.py +3 -0
- taco_eo-0.3.0/taco/metadata/_base.py +68 -0
- taco_eo-0.3.0/taco/metadata/asset.py +59 -0
- taco_eo-0.3.0/taco/metadata/collection.py +70 -0
- taco_eo-0.3.0/taco/metadata/derived.py +244 -0
- taco_eo-0.3.0/taco/metadata/folder.py +15 -0
- taco_eo-0.3.0/taco/metadata/sample.py +5 -0
- taco_eo-0.3.0/taco/metadata/spatiotemporal.py +207 -0
- taco_eo-0.3.0/taco/metadata/split.py +12 -0
- taco_eo-0.3.0/taco/py.typed +0 -0
- taco_eo-0.3.0/taco/reader/__init__.py +194 -0
- taco_eo-0.3.0/taco/reader/engine.py +67 -0
- taco_eo-0.3.0/taco/schema.py +287 -0
- taco_eo-0.3.0/taco/tacocat.py +157 -0
- taco_eo-0.3.0/taco/validate.py +517 -0
- taco_eo-0.3.0/taco/writer/__init__.py +73 -0
- taco_eo-0.3.0/taco/writer/archive.py +367 -0
- taco_eo-0.3.0/taco/writer/core.py +186 -0
- taco_eo-0.3.0/taco/writer/folder.py +211 -0
- taco_eo-0.3.0/taco/writer/metadata_tables.py +233 -0
- taco_eo-0.3.0/taco/writer/progress.py +46 -0
- taco_eo-0.3.0/taco/writer/staging.py +44 -0
- taco_eo-0.3.0/tests/__init__.py +0 -0
- taco_eo-0.3.0/tests/conftest.py +125 -0
- taco_eo-0.3.0/tests/datasets.py +538 -0
- taco_eo-0.3.0/tests/test_collection.py +171 -0
- taco_eo-0.3.0/tests/test_contract.py +220 -0
- taco_eo-0.3.0/tests/test_examples.py +41 -0
- taco_eo-0.3.0/tests/test_metadata.py +407 -0
- taco_eo-0.3.0/tests/test_parquet.py +16 -0
- taco_eo-0.3.0/tests/test_progress.py +64 -0
- taco_eo-0.3.0/tests/test_publish.py +88 -0
- taco_eo-0.3.0/tests/test_reader.py +268 -0
- taco_eo-0.3.0/tests/test_tacocat.py +141 -0
- taco_eo-0.3.0/tests/test_types.py +137 -0
- taco_eo-0.3.0/tests/test_validate.py +145 -0
- taco_eo-0.3.0/tests/test_writer.py +489 -0
- taco_eo-0.3.0/tests/test_writer_cases.py +219 -0
taco_eo-0.3.0/.gitignore
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
|
|
2
|
+
.DS_Store
|
|
3
|
+
|
|
4
|
+
spec/main.md
|
|
5
|
+
|
|
6
|
+
demo.zip
|
|
7
|
+
minimal.zip
|
|
8
|
+
/numpy-demo.zip
|
|
9
|
+
/change-detection/
|
|
10
|
+
/image-sequence.zip
|
|
11
|
+
/time-series.zip
|
|
12
|
+
/geospatial.zip
|
|
13
|
+
/partitioned_*.zip
|
|
14
|
+
/.tacocat/
|
|
15
|
+
.vscode/
|
|
16
|
+
|
|
17
|
+
.pytest_cache/
|
|
18
|
+
.coverage
|
|
19
|
+
__pycache__/
|
|
20
|
+
*.pyc
|
|
21
|
+
build/
|
|
22
|
+
*.egg-info/
|
|
23
|
+
python/.venv/
|
|
24
|
+
python/dist/
|
|
25
|
+
python/uv.lock
|
|
26
|
+
/julia/Manifest.toml
|
|
27
|
+
|
|
28
|
+
*.dylib
|
|
29
|
+
|
|
30
|
+
*.o
|
|
31
|
+
|
|
32
|
+
create-julia-skeleton.sh
|
|
33
|
+
_site/
|
|
34
|
+
numpy_demo.zip
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `taco` are documented here. The format follows
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
5
|
+
|
|
6
|
+
## Unreleased
|
|
7
|
+
|
|
8
|
+
### Changed
|
|
9
|
+
|
|
10
|
+
- Python, R, and Julia now share `open_dataset()` and `read()`. An open dataset
|
|
11
|
+
exposes its sources, collection, and contract in each language.
|
|
12
|
+
- STAC once again represents regular raster chunks with `tensor_shape` and a
|
|
13
|
+
six-value GDAL `geotransform`; it no longer stores a WKB footprint on every
|
|
14
|
+
sample. ISTAC is now a distinct irregular-geometry model instead of an alias
|
|
15
|
+
of STAC. Both retain centroid-based collection summaries, and metadata levels
|
|
16
|
+
must choose one of the two profiles.
|
|
17
|
+
- The reader keeps one DuckDB connection per thread.
|
|
18
|
+
- Collection and nested sample values are validated before writing.
|
|
19
|
+
- Python checks now cover formatting, strict typing, warnings and branch
|
|
20
|
+
coverage.
|
|
21
|
+
- The writer internals now follow the build flow explicitly (`core`, `archive`,
|
|
22
|
+
`folder`, `metadata_tables`, and `staging`) and use descriptive class and
|
|
23
|
+
method names. STAC/ISTAC definitions moved to `metadata.spatiotemporal`,
|
|
24
|
+
while `metadata.sample` remains a compatible import facade.
|
|
25
|
+
|
|
26
|
+
### Removed
|
|
27
|
+
|
|
28
|
+
- The unused `staging_dir` writer option and `writer.ARCHIVE_SUFFIX` constant.
|
|
29
|
+
|
|
30
|
+
## 0.2.0 - 2026-09-04
|
|
31
|
+
|
|
32
|
+
### Changed
|
|
33
|
+
|
|
34
|
+
- The package is laid out as subpackages: `taco.contract` for the contract
|
|
35
|
+
vocabulary, `taco.writer` for the two writers and `taco.reader` for metadata
|
|
36
|
+
access, with `tacocat` and `validate` beside them. The top level exports ten
|
|
37
|
+
names, down from thirty-eight; everything else is imported from the
|
|
38
|
+
subpackage that owns it.
|
|
39
|
+
- `COLLECTION.json` records only the fields the caller declares. Nothing is
|
|
40
|
+
inferred from field names, so the writer no longer guesses an extent from
|
|
41
|
+
`stac:centroid` or `time_start`, and `_extent.py`, `auto_extent`,
|
|
42
|
+
`ExtentSpec`, `compute_extent` and `wkb_bounds` are gone. STAC is not part
|
|
43
|
+
of the core. A TACOCAT still merges the extents its partitions declare,
|
|
44
|
+
which TACO specification 7.5 requires.
|
|
45
|
+
- Archives are written as `.zip`. cozip specification 14.5 makes the profile
|
|
46
|
+
byte in the byte-0 index the only authoritative signal, and the extension
|
|
47
|
+
carries no meaning. Outputs are extensionless or end in `.zip`; any other
|
|
48
|
+
suffix is rejected.
|
|
49
|
+
- Reading a dataset is the `cozip` DuckDB extension's job. `open_dataset`,
|
|
50
|
+
`TacoDataset` and `vsi_subfile` are gone from the top-level API;
|
|
51
|
+
`taco.reader` forwards to the extension and builds no VSI paths itself. The
|
|
52
|
+
old Python mapping covered four URL schemes and the C++ one covers seven,
|
|
53
|
+
so the two had already drifted.
|
|
54
|
+
- The ZIP writer now delegates layout planning and serialization to cozip's
|
|
55
|
+
native TACO ABI through `cozip._taco.plan()` / `write()` instead of driving
|
|
56
|
+
the low-level entry API itself. Archive names, priority ordering, padding
|
|
57
|
+
placement and post-write verification are enforced in C. Local source and
|
|
58
|
+
output paths may contain Unicode.
|
|
59
|
+
- `Contract`, `Collection` and the writers raise `taco.errors.*`
|
|
60
|
+
exceptions (`ContractError`, `SampleError`, `CollectionError`,
|
|
61
|
+
`WriterError`, ...). They still subclass `ValueError` / `RuntimeError`.
|
|
62
|
+
- Metadata levels without fields may be omitted from `Contract(metadata=...)`
|
|
63
|
+
and from `Sample(metadata=...)`.
|
|
64
|
+
- `internal:relative_path` is written in `collection.parquet` too (the sample
|
|
65
|
+
index), matching the normative text of spec section 7.2.
|
|
66
|
+
- Lossy value conversions (floats into integer fields, bytes into strings,
|
|
67
|
+
ISO strings into timestamps) are rejected at `add()` time.
|
|
68
|
+
|
|
69
|
+
### Added
|
|
70
|
+
|
|
71
|
+
- `taco:structure = null` datasets (one file per sample) in every container.
|
|
72
|
+
- Inline `bytes` assets, materialized into the staging directory on `add()`.
|
|
73
|
+
- `FolderWriter` / `open_folder()` for FOLDER mode with `append=True` and
|
|
74
|
+
optional hard links.
|
|
75
|
+
- Partitioned builds (`partition_size`, `partition_by`) producing
|
|
76
|
+
`<stem>_partNNNN.zip` / `<stem>_<value>.zip` plus a `.tacocat` directory;
|
|
77
|
+
`consolidate()` to build a TACOCAT from existing archives.
|
|
78
|
+
- An internal metadata view for ZIP, FOLDER and TACOCAT, used by
|
|
79
|
+
`consolidate` and `validate`.
|
|
80
|
+
- `validate()` for structural and contract checks across all three containers.
|
|
81
|
+
- Type specification parser supporting `timestamp[unit, tz]`, `list<...>`,
|
|
82
|
+
`struct<...>`, `map<...>`, `decimal128(p, s)`, `fixed_size_list<...>`.
|
|
83
|
+
- `parse_size()` and file-name sanitizing for partitioned builds.
|
|
84
|
+
|
|
85
|
+
### Fixed
|
|
86
|
+
|
|
87
|
+
- `overwrite=False` uses an atomic no-replace publication step, so a file
|
|
88
|
+
created by another process during the build is left untouched.
|
|
89
|
+
|
|
90
|
+
### Removed
|
|
91
|
+
|
|
92
|
+
- Direct use of `cozip.profile()` and the entry-based `cozip_plan` /
|
|
93
|
+
`cozip_finalize` calls.
|
|
94
|
+
|
|
95
|
+
## 0.1.0 - 2026-09-02
|
|
96
|
+
|
|
97
|
+
- First prototype: `Contract`, `Asset`, `Sample`, `Collection`, staged
|
|
98
|
+
`TacoWriter` producing profile-2 `.tacozip` archives.
|
taco_eo-0.3.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Asterisk Laboratories Co-operative Limited
|
|
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.
|
taco_eo-0.3.0/PKG-INFO
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: taco-eo
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: Read and write TACO datasets in Python.
|
|
5
|
+
Project-URL: Homepage, https://asterisk.coop/taco
|
|
6
|
+
Project-URL: Specification, https://asterisk.coop/taco/spec
|
|
7
|
+
Project-URL: Repository, https://github.com/asterisk-labs/taco
|
|
8
|
+
Project-URL: Issues, https://github.com/asterisk-labs/taco/issues
|
|
9
|
+
Author-email: Cesar Aybar <cesar@asterisk.coop>
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: cloud-optimized,cozip,earth-observation,geospatial,machine-learning,parquet,taco
|
|
13
|
+
Classifier: Development Status :: 3 - Alpha
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
22
|
+
Classifier: Topic :: Scientific/Engineering :: GIS
|
|
23
|
+
Classifier: Typing :: Typed
|
|
24
|
+
Requires-Python: >=3.10
|
|
25
|
+
Requires-Dist: cozip>=2026.9.4
|
|
26
|
+
Requires-Dist: duckdb>=1.5.5
|
|
27
|
+
Requires-Dist: numpy>=1.24
|
|
28
|
+
Requires-Dist: pyarrow>=14
|
|
29
|
+
Requires-Dist: pydantic>=2.8
|
|
30
|
+
Provides-Extra: dev
|
|
31
|
+
Requires-Dist: mypy>=1.8; extra == 'dev'
|
|
32
|
+
Requires-Dist: pytest-cov>=5; extra == 'dev'
|
|
33
|
+
Requires-Dist: pytest>=8; extra == 'dev'
|
|
34
|
+
Requires-Dist: ruff>=0.5; extra == 'dev'
|
|
35
|
+
Provides-Extra: geoenrich
|
|
36
|
+
Requires-Dist: earthengine-api>=1; extra == 'geoenrich'
|
|
37
|
+
Provides-Extra: progress
|
|
38
|
+
Requires-Dist: tqdm>=4.66; extra == 'progress'
|
|
39
|
+
Provides-Extra: test
|
|
40
|
+
Requires-Dist: pytest-cov>=5; extra == 'test'
|
|
41
|
+
Requires-Dist: pytest>=8; extra == 'test'
|
|
42
|
+
Description-Content-Type: text/markdown
|
|
43
|
+
|
|
44
|
+
# taco
|
|
45
|
+
|
|
46
|
+
Read and write TACO datasets in Python.
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pip install taco-eo
|
|
50
|
+
python examples/minimal.py
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
import taco
|
|
55
|
+
|
|
56
|
+
samples = taco.read("dataset.zip")
|
|
57
|
+
parts = taco.read(["part-0.zip", "part-1.zip"])
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Examples
|
|
61
|
+
|
|
62
|
+
Every example is self-contained, uses synthetic data, and writes its output in
|
|
63
|
+
the current directory.
|
|
64
|
+
|
|
65
|
+
| Example | What it demonstrates |
|
|
66
|
+
| --- | --- |
|
|
67
|
+
| [`minimal.py`](examples/minimal.py) | Smallest possible single-file dataset |
|
|
68
|
+
| [`numpy_minimal.py`](examples/numpy_minimal.py) | NumPy image and mask assets with a train/test split |
|
|
69
|
+
| [`change_detection.py`](examples/change_detection.py) | Metadata on `before/` and `after/` folders |
|
|
70
|
+
| [`sequence.py`](examples/sequence.py) | Variable-length asset sequences |
|
|
71
|
+
| [`time_series.py`](examples/time_series.py) | Per-observation time and cloud metadata |
|
|
72
|
+
| [`geospatial.py`](examples/geospatial.py) | Compact STAC metadata and derived MajorTOM cells |
|
|
73
|
+
| [`stac_segmentation.py`](examples/stac_segmentation.py) | Rich STAC metadata for regular raster chips, labels, bands, scaling, and statistics |
|
|
74
|
+
| [`oceantaco_istac.py`](examples/oceantaco_istac.py) | OceanTACO-inspired ISTAC metadata for irregular SWOT swaths and Argo collocations |
|
|
75
|
+
| [`partitioned.py`](examples/partitioned.py) | ZIP partitions and their TACOCAT catalog |
|
taco_eo-0.3.0/README.md
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# taco
|
|
2
|
+
|
|
3
|
+
Read and write TACO datasets in Python.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
pip install taco-eo
|
|
7
|
+
python examples/minimal.py
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
```python
|
|
11
|
+
import taco
|
|
12
|
+
|
|
13
|
+
samples = taco.read("dataset.zip")
|
|
14
|
+
parts = taco.read(["part-0.zip", "part-1.zip"])
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Examples
|
|
18
|
+
|
|
19
|
+
Every example is self-contained, uses synthetic data, and writes its output in
|
|
20
|
+
the current directory.
|
|
21
|
+
|
|
22
|
+
| Example | What it demonstrates |
|
|
23
|
+
| --- | --- |
|
|
24
|
+
| [`minimal.py`](examples/minimal.py) | Smallest possible single-file dataset |
|
|
25
|
+
| [`numpy_minimal.py`](examples/numpy_minimal.py) | NumPy image and mask assets with a train/test split |
|
|
26
|
+
| [`change_detection.py`](examples/change_detection.py) | Metadata on `before/` and `after/` folders |
|
|
27
|
+
| [`sequence.py`](examples/sequence.py) | Variable-length asset sequences |
|
|
28
|
+
| [`time_series.py`](examples/time_series.py) | Per-observation time and cloud metadata |
|
|
29
|
+
| [`geospatial.py`](examples/geospatial.py) | Compact STAC metadata and derived MajorTOM cells |
|
|
30
|
+
| [`stac_segmentation.py`](examples/stac_segmentation.py) | Rich STAC metadata for regular raster chips, labels, bands, scaling, and statistics |
|
|
31
|
+
| [`oceantaco_istac.py`](examples/oceantaco_istac.py) | OceanTACO-inspired ISTAC metadata for irregular SWOT swaths and Argo collocations |
|
|
32
|
+
| [`partitioned.py`](examples/partitioned.py) | ZIP partitions and their TACOCAT catalog |
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import io
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
from pydantic import BaseModel
|
|
5
|
+
|
|
6
|
+
import taco
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Acquisition(BaseModel):
|
|
10
|
+
year: int
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def encode(array: np.ndarray) -> bytes:
|
|
14
|
+
buffer = io.BytesIO()
|
|
15
|
+
np.save(buffer, array)
|
|
16
|
+
return buffer.getvalue()
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
raster = taco.metadata.asset.Raster
|
|
20
|
+
contract = taco.Contract(
|
|
21
|
+
structure=[
|
|
22
|
+
"before/B02.npy",
|
|
23
|
+
"before/B03.npy",
|
|
24
|
+
"after/B02.npy",
|
|
25
|
+
"after/B03.npy",
|
|
26
|
+
"change.npy",
|
|
27
|
+
],
|
|
28
|
+
metadata=taco.MetadataSchema(
|
|
29
|
+
taco.Level("sample", ml=taco.metadata.sample.Split),
|
|
30
|
+
taco.Level("children", acquisition=Acquisition | None, raster=raster | None),
|
|
31
|
+
taco.Level("children/before", raster=raster),
|
|
32
|
+
taco.Level("children/after", raster=raster),
|
|
33
|
+
),
|
|
34
|
+
)
|
|
35
|
+
collection = taco.Collection(
|
|
36
|
+
contract=contract,
|
|
37
|
+
id="change-detection",
|
|
38
|
+
dataset_version="1.0.0",
|
|
39
|
+
description="Paired observations and their change mask",
|
|
40
|
+
licenses=["MIT"],
|
|
41
|
+
providers=["Asterisk Labs"],
|
|
42
|
+
tasks=["change-detection"],
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
before = np.arange(2 * 16 * 16, dtype=np.uint16).reshape(2, 16, 16)
|
|
46
|
+
after = before.copy()
|
|
47
|
+
after[:, 5:11, 7:13] += 100
|
|
48
|
+
paths = {
|
|
49
|
+
"before/B02.npy": before[0],
|
|
50
|
+
"before/B03.npy": before[1],
|
|
51
|
+
"after/B02.npy": after[0],
|
|
52
|
+
"after/B03.npy": after[1],
|
|
53
|
+
"change.npy": np.any(before != after, axis=0),
|
|
54
|
+
}
|
|
55
|
+
assets = [
|
|
56
|
+
taco.Asset(
|
|
57
|
+
encode(array),
|
|
58
|
+
path=path,
|
|
59
|
+
metadata=taco.Metadata(raster=raster(resolution=10, num_bands=1, data_type=str(array.dtype))),
|
|
60
|
+
)
|
|
61
|
+
for path, array in paths.items()
|
|
62
|
+
]
|
|
63
|
+
sample = taco.Sample(
|
|
64
|
+
assets=assets,
|
|
65
|
+
metadata=taco.Metadata(ml=taco.metadata.sample.Split(split="train")),
|
|
66
|
+
folders=[
|
|
67
|
+
taco.Folder("before", metadata=taco.Metadata(acquisition=Acquisition(year=2020))),
|
|
68
|
+
taco.Folder("after", metadata=taco.Metadata(acquisition=Acquisition(year=2024))),
|
|
69
|
+
],
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
with taco.open_writer(collection, "change-detection", overwrite=True) as writer:
|
|
73
|
+
writer.add(sample)
|
|
74
|
+
writer.run()
|
|
75
|
+
|
|
76
|
+
dataset = taco.open_dataset("change-detection")
|
|
77
|
+
assert taco.read(dataset).num_rows == 1
|
|
78
|
+
assert taco.validate("change-detection").ok
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import struct
|
|
2
|
+
from datetime import datetime, timezone
|
|
3
|
+
|
|
4
|
+
import taco
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def point(longitude: float, latitude: float) -> bytes:
|
|
8
|
+
return struct.pack("<BIdd", 1, 1, longitude, latitude)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
contract = taco.Contract(
|
|
12
|
+
structure=["image.bin"],
|
|
13
|
+
metadata=taco.MetadataSchema(
|
|
14
|
+
taco.Level(
|
|
15
|
+
"sample",
|
|
16
|
+
stac=taco.metadata.sample.STAC,
|
|
17
|
+
majortom=taco.metadata.sample.MajorTOM(
|
|
18
|
+
dist_km=100,
|
|
19
|
+
latitude_range=(-20, 0),
|
|
20
|
+
longitude_range=(-90, -60),
|
|
21
|
+
),
|
|
22
|
+
),
|
|
23
|
+
taco.Level("children", raster=taco.metadata.asset.Raster),
|
|
24
|
+
),
|
|
25
|
+
)
|
|
26
|
+
collection = taco.Collection(
|
|
27
|
+
contract=contract,
|
|
28
|
+
id="peru-sites",
|
|
29
|
+
dataset_version="1.0.0",
|
|
30
|
+
description="Small geospatial dataset with derived MajorTOM cells",
|
|
31
|
+
licenses=["MIT"],
|
|
32
|
+
providers=["Asterisk Labs"],
|
|
33
|
+
tasks=["classification"],
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
sites = [(-77.04, -12.05), (-71.97, -13.53), (-80.63, -5.19)]
|
|
37
|
+
with taco.open_writer(collection, "geospatial.zip", overwrite=True) as writer:
|
|
38
|
+
for index, (longitude, latitude) in enumerate(sites):
|
|
39
|
+
location = point(longitude, latitude)
|
|
40
|
+
stac = taco.metadata.sample.STAC(
|
|
41
|
+
crs="EPSG:4326",
|
|
42
|
+
tensor_shape=(1, 8, 8),
|
|
43
|
+
geotransform=(longitude - 0.05, 0.0125, 0, latitude + 0.05, 0, -0.0125),
|
|
44
|
+
centroid=location,
|
|
45
|
+
time_start=datetime(2024, 1, index + 1, tzinfo=timezone.utc),
|
|
46
|
+
)
|
|
47
|
+
asset = taco.Asset(
|
|
48
|
+
bytes([index + 1]) * 64,
|
|
49
|
+
path="image.bin",
|
|
50
|
+
metadata=taco.Metadata(raster=taco.metadata.asset.Raster(resolution=10, num_bands=1, data_type="uint8")),
|
|
51
|
+
)
|
|
52
|
+
writer.add(taco.Sample(assets=asset, metadata=taco.Metadata(stac=stac)))
|
|
53
|
+
writer.run()
|
|
54
|
+
|
|
55
|
+
dataset = taco.open_dataset("geospatial.zip")
|
|
56
|
+
table = taco.read(dataset)
|
|
57
|
+
assert table.num_rows == 3
|
|
58
|
+
assert "majortom:code" in table.column_names
|
|
59
|
+
assert dataset.collection.extent is not None
|
|
60
|
+
assert dataset.collection.extent.spatial == (-80.63, -13.53, -71.97, -5.19)
|
|
61
|
+
assert taco.validate("geospatial.zip").ok
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import taco
|
|
2
|
+
|
|
3
|
+
collection = taco.Collection(
|
|
4
|
+
contract=taco.Contract(structure=None),
|
|
5
|
+
id="minimal",
|
|
6
|
+
dataset_version="1.0.0",
|
|
7
|
+
description="Minimal TACO dataset",
|
|
8
|
+
licenses=["MIT"],
|
|
9
|
+
providers=["me"],
|
|
10
|
+
tasks=["other"],
|
|
11
|
+
)
|
|
12
|
+
with taco.open_writer(collection, "minimal.zip", overwrite=True) as writer:
|
|
13
|
+
writer.add(taco.Sample(assets=b"hello"))
|
|
14
|
+
writer.run()
|
|
15
|
+
|
|
16
|
+
dataset = taco.open_dataset("minimal.zip")
|
|
17
|
+
assert taco.read(dataset).num_rows == 1
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import io
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
from pydantic import BaseModel
|
|
5
|
+
|
|
6
|
+
import taco
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class ML(BaseModel):
|
|
10
|
+
split: str
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def encode(array: np.ndarray) -> bytes:
|
|
14
|
+
buffer = io.BytesIO()
|
|
15
|
+
np.save(buffer, array)
|
|
16
|
+
return buffer.getvalue()
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
contract = taco.Contract(
|
|
20
|
+
structure=["image.npy", "mask.npy"],
|
|
21
|
+
metadata=taco.MetadataSchema(taco.Level("sample", ml=ML)),
|
|
22
|
+
)
|
|
23
|
+
collection = taco.Collection(
|
|
24
|
+
contract=contract,
|
|
25
|
+
id="numpy-demo",
|
|
26
|
+
dataset_version="1.0.0",
|
|
27
|
+
description="Small NumPy dataset",
|
|
28
|
+
licenses=["MIT"],
|
|
29
|
+
providers=["me"],
|
|
30
|
+
tasks=["segmentation"],
|
|
31
|
+
)
|
|
32
|
+
with taco.open_writer(collection, "numpy-demo.zip", overwrite=True) as writer:
|
|
33
|
+
for index in range(10):
|
|
34
|
+
image = np.random.default_rng(index).random((3, 32, 32), dtype=np.float32)
|
|
35
|
+
writer.add(
|
|
36
|
+
taco.Sample(
|
|
37
|
+
metadata=taco.Metadata(ml=ML(split="train" if index < 8 else "test")),
|
|
38
|
+
assets=[
|
|
39
|
+
taco.Asset(encode(image), path="image.npy"),
|
|
40
|
+
taco.Asset(encode(image[0] > 0.5), path="mask.npy"),
|
|
41
|
+
],
|
|
42
|
+
)
|
|
43
|
+
)
|
|
44
|
+
writer.run()
|
|
45
|
+
|
|
46
|
+
dataset = taco.open_dataset("numpy-demo.zip")
|
|
47
|
+
assert taco.read(dataset).num_rows == 10
|
|
48
|
+
assert taco.validate("numpy-demo.zip").ok
|