cubedynamics 0.1.0rc1__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.
- cubedynamics-0.1.0rc1/CITATION.cff +23 -0
- cubedynamics-0.1.0rc1/LICENSE +21 -0
- cubedynamics-0.1.0rc1/MANIFEST.in +5 -0
- cubedynamics-0.1.0rc1/PKG-INFO +434 -0
- cubedynamics-0.1.0rc1/README.md +329 -0
- cubedynamics-0.1.0rc1/pyproject.toml +115 -0
- cubedynamics-0.1.0rc1/setup.cfg +4 -0
- cubedynamics-0.1.0rc1/src/climate_cube_math/__init__.py +33 -0
- cubedynamics-0.1.0rc1/src/climate_cube_math/data/__init__.py +10 -0
- cubedynamics-0.1.0rc1/src/climate_cube_math/data/gridmet.py +24 -0
- cubedynamics-0.1.0rc1/src/climate_cube_math/data/prism.py +41 -0
- cubedynamics-0.1.0rc1/src/climate_cube_math/data/sentinel2.py +3 -0
- cubedynamics-0.1.0rc1/src/climate_cube_math/demo.py +80 -0
- cubedynamics-0.1.0rc1/src/climate_cube_math/hulls.py +175 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/__init__.py +207 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/biology/__init__.py +6 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/biology/align.py +50 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/biology/rasterize.py +72 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/config.py +12 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/correlation_cubes.py +30 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/data/__init__.py +101 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/data/_ranges.py +88 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/data/_transport.py +272 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/data/catalog.py +319 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/data/certification.py +116 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/data/daymet.py +92 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/data/gridmet.py +536 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/data/lifecycle.py +410 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/data/nouns.py +467 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/data/prism.py +927 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/data/qa.py +328 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/data/revisions.py +147 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/data/roads.py +236 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/data/schema.py +256 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/data/sentinel2.py +166 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/data/serving_history.json +16 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/data/three_dep.py +115 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/data/usgs.py +260 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/demo.py +80 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/demo_vase.py +105 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/deprecations.py +33 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/events/__init__.py +6 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/events/detection.py +182 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/events/matching.py +76 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/events/schemas.py +21 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/fire_time_hull.py +1894 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/fire_vase_lakehouse/__init__.py +49 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/fire_vase_lakehouse/cache.py +174 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/fire_vase_lakehouse/manifest.py +78 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/fire_vase_lakehouse/partitioning.py +65 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/fire_vase_lakehouse/qc.py +56 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/fire_vase_lakehouse/query.py +76 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/fire_vase_lakehouse/schemas.py +57 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/grammar.py +949 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/hulls.py +175 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/indices/__init__.py +1 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/indices/vegetation.py +39 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/ops/__init__.py +18 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/ops/io.py +18 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/ops/ndvi.py +33 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/ops/stats.py +103 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/ops/transforms.py +50 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/ops/viz.py +53 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/ops_fire/__init__.py +1 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/ops_fire/climate_hull_extract.py +52 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/ops_fire/fired_api.py +78 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/ops_fire/fired_io.py +46 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/ops_fire/time_hull.py +113 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/ops_io/__init__.py +1 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/ops_io/gridmet_api.py +72 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/ops_io/gridmet_loader.py +13 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/piping.py +296 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/plotting/__init__.py +29 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/plotting/axis_rig.py +746 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/plotting/cube_plot.py +1008 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/plotting/cube_viewer.py +1345 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/plotting/geom.py +16 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/plotting/progress.py +43 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/plotting/stats.py +33 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/plotting/tail_association.py +482 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/plotting/viewer.py +46 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/prism_streaming.py +35 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/progress.py +45 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/sentinel.py +271 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/stats/__init__.py +1 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/stats/anomalies.py +83 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/stats/correlation.py +53 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/stats/rolling.py +65 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/stats/spatial.py +67 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/stats/spatial_units.py +386 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/stats/tails.py +172 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/streaming/__init__.py +12 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/streaming/global_climate.py +177 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/streaming/gridmet.py +379 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/streaming/virtual.py +222 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/synchrony/__init__.py +21 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/synchrony/coupling.py +99 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/synchrony/occurrence.py +210 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/synchrony/severity.py +188 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/synchrony/spatial.py +413 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/synchrony/states.py +283 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/synchrony/timing.py +243 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/tubes.py +277 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/utils/__init__.py +8 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/utils/chunking.py +31 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/utils/cube_css.py +446 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/utils/dims.py +90 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/utils/drift_centering.py +137 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/utils/drop_bad_assets.py +108 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/utils/provenance.py +57 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/utils/reference.py +29 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/variables.py +491 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/vase.py +289 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/vase_viz.py +211 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/verbs/__init__.py +804 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/verbs/biology.py +55 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/verbs/combine.py +108 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/verbs/custom.py +29 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/verbs/diagnostics.py +407 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/verbs/events.py +34 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/verbs/fire.py +871 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/verbs/flatten.py +51 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/verbs/landsat_mpc.py +344 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/verbs/models.py +12 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/verbs/plot.py +252 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/verbs/plot_mean.py +75 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/verbs/states.py +127 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/verbs/stats.py +794 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/verbs/synchrony.py +189 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/verbs/tubes.py +107 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/verbs/vase.py +202 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/version.py +5 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/viewers/__init__.py +11 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/viewers/cube_viewer.py +186 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/viewers/simple_plot.py +162 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/viewers/templates/cube_viewer_template.html +546 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/viz/__init__.py +8 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/viz/lexcube_viz.py +70 -0
- cubedynamics-0.1.0rc1/src/cubedynamics/viz/qa_plots.py +97 -0
- cubedynamics-0.1.0rc1/src/cubedynamics.egg-info/PKG-INFO +434 -0
- cubedynamics-0.1.0rc1/src/cubedynamics.egg-info/SOURCES.txt +142 -0
- cubedynamics-0.1.0rc1/src/cubedynamics.egg-info/dependency_links.txt +1 -0
- cubedynamics-0.1.0rc1/src/cubedynamics.egg-info/requires.txt +66 -0
- cubedynamics-0.1.0rc1/src/cubedynamics.egg-info/top_level.txt +2 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
cff-version: 1.2.0
|
|
2
|
+
title: "CubeDynamics: A Composable Grammar for Spatiotemporal Science"
|
|
3
|
+
message: "If you use CubeDynamics, please cite it as described here."
|
|
4
|
+
type: software
|
|
5
|
+
authors:
|
|
6
|
+
- family-names: Tuff
|
|
7
|
+
given-names: Ty
|
|
8
|
+
version: 0.1.0rc1
|
|
9
|
+
repository-code: "https://github.com/CU-ESIIL/cubedynamics"
|
|
10
|
+
url: "https://cu-esiil.github.io/cubedynamics/"
|
|
11
|
+
keywords:
|
|
12
|
+
- climate
|
|
13
|
+
- streaming
|
|
14
|
+
- data cubes
|
|
15
|
+
- xarray
|
|
16
|
+
- dask
|
|
17
|
+
license: MIT
|
|
18
|
+
abstract: |
|
|
19
|
+
CubeDynamics is an early scientific Python software release centered on
|
|
20
|
+
pipe(value) | verb() composition over labeled spatiotemporal objects.
|
|
21
|
+
It includes documented source loaders, provenance and QA interfaces,
|
|
22
|
+
visualization, and project-specific vocabularies. Version 0.1.0rc1 is alpha;
|
|
23
|
+
source suitability and operational maturity are documented separately.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Environmental Data Science Innovation and Inclusion Lab (ESIIL)
|
|
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.
|
|
@@ -0,0 +1,434 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: cubedynamics
|
|
3
|
+
Version: 0.1.0rc1
|
|
4
|
+
Summary: A composable grammar of verbs for streaming spatiotemporal cubes
|
|
5
|
+
Author: Ty Tuff
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2023 Environmental Data Science Innovation and Inclusion Lab (ESIIL)
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
|
|
28
|
+
Project-URL: Homepage, https://github.com/CU-ESIIL/cubedynamics
|
|
29
|
+
Project-URL: Repository, https://github.com/CU-ESIIL/cubedynamics
|
|
30
|
+
Project-URL: Documentation, https://cu-esiil.github.io/cubedynamics/
|
|
31
|
+
Project-URL: Issues, https://github.com/CU-ESIIL/cubedynamics/issues
|
|
32
|
+
Keywords: climate,data-cubes,xarray,dask,geospatial
|
|
33
|
+
Classifier: Development Status :: 3 - Alpha
|
|
34
|
+
Classifier: Intended Audience :: Science/Research
|
|
35
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
36
|
+
Classifier: Operating System :: OS Independent
|
|
37
|
+
Classifier: Programming Language :: Python :: 3
|
|
38
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
39
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
40
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
41
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
42
|
+
Classifier: Topic :: Scientific/Engineering
|
|
43
|
+
Classifier: Topic :: Scientific/Engineering :: GIS
|
|
44
|
+
Requires-Python: >=3.9
|
|
45
|
+
Description-Content-Type: text/markdown
|
|
46
|
+
License-File: LICENSE
|
|
47
|
+
Requires-Dist: numpy<2
|
|
48
|
+
Requires-Dist: xarray
|
|
49
|
+
Requires-Dist: pandas
|
|
50
|
+
Requires-Dist: rasterio
|
|
51
|
+
Requires-Dist: rioxarray
|
|
52
|
+
Requires-Dist: pystac-client
|
|
53
|
+
Requires-Dist: planetary-computer
|
|
54
|
+
Requires-Dist: pyproj
|
|
55
|
+
Requires-Dist: requests
|
|
56
|
+
Requires-Dist: dask
|
|
57
|
+
Requires-Dist: h5netcdf
|
|
58
|
+
Requires-Dist: h5py
|
|
59
|
+
Requires-Dist: cubo
|
|
60
|
+
Requires-Dist: matplotlib
|
|
61
|
+
Requires-Dist: Pillow
|
|
62
|
+
Requires-Dist: crc32c
|
|
63
|
+
Requires-Dist: plotly
|
|
64
|
+
Requires-Dist: geopandas
|
|
65
|
+
Requires-Dist: shapely
|
|
66
|
+
Requires-Dist: scipy
|
|
67
|
+
Requires-Dist: ipython
|
|
68
|
+
Provides-Extra: roads
|
|
69
|
+
Requires-Dist: pyarrow<22,>=17; extra == "roads"
|
|
70
|
+
Provides-Extra: browser
|
|
71
|
+
Requires-Dist: playwright==1.58.0; python_version >= "3.10" and extra == "browser"
|
|
72
|
+
Requires-Dist: pytest-playwright==0.7.2; python_version >= "3.10" and extra == "browser"
|
|
73
|
+
Provides-Extra: viz
|
|
74
|
+
Requires-Dist: lexcube; extra == "viz"
|
|
75
|
+
Provides-Extra: test
|
|
76
|
+
Requires-Dist: pytest; extra == "test"
|
|
77
|
+
Requires-Dist: build; extra == "test"
|
|
78
|
+
Requires-Dist: twine; extra == "test"
|
|
79
|
+
Provides-Extra: docs
|
|
80
|
+
Requires-Dist: mkdocs>=1.6; extra == "docs"
|
|
81
|
+
Requires-Dist: mkdocs-material; extra == "docs"
|
|
82
|
+
Requires-Dist: mkdocstrings[python]; extra == "docs"
|
|
83
|
+
Requires-Dist: mkdocs-git-revision-date-plugin; extra == "docs"
|
|
84
|
+
Requires-Dist: mkdocs-jupyter; extra == "docs"
|
|
85
|
+
Requires-Dist: nbclient; extra == "docs"
|
|
86
|
+
Requires-Dist: nbformat; extra == "docs"
|
|
87
|
+
Provides-Extra: vignettes
|
|
88
|
+
Requires-Dist: nbclient; extra == "vignettes"
|
|
89
|
+
Requires-Dist: nbformat; extra == "vignettes"
|
|
90
|
+
Requires-Dist: ipykernel; extra == "vignettes"
|
|
91
|
+
Provides-Extra: dev
|
|
92
|
+
Requires-Dist: pytest; extra == "dev"
|
|
93
|
+
Requires-Dist: build; extra == "dev"
|
|
94
|
+
Requires-Dist: twine; extra == "dev"
|
|
95
|
+
Requires-Dist: mkdocs>=1.6; extra == "dev"
|
|
96
|
+
Requires-Dist: mkdocs-material; extra == "dev"
|
|
97
|
+
Requires-Dist: mkdocstrings[python]; extra == "dev"
|
|
98
|
+
Requires-Dist: mkdocs-git-revision-date-plugin; extra == "dev"
|
|
99
|
+
Requires-Dist: mkdocs-jupyter; extra == "dev"
|
|
100
|
+
Requires-Dist: nbclient; extra == "dev"
|
|
101
|
+
Requires-Dist: nbformat; extra == "dev"
|
|
102
|
+
Requires-Dist: ipykernel; extra == "dev"
|
|
103
|
+
Requires-Dist: lexcube; extra == "dev"
|
|
104
|
+
Dynamic: license-file
|
|
105
|
+
|
|
106
|
+
# CubeDynamics
|
|
107
|
+
|
|
108
|
+
<p align="center">
|
|
109
|
+
<img src="https://raw.githubusercontent.com/CU-ESIIL/cubedynamics/main/docs/assets/img/cubedynamics_logo.png" alt="CubeDynamics" width="520">
|
|
110
|
+
</p>
|
|
111
|
+
|
|
112
|
+
 
|
|
113
|
+
|
|
114
|
+
CubeDynamics is an inspectable grammar for spatiotemporal environmental data:
|
|
115
|
+
**source-qualified nouns describe observations, semantic verbs describe
|
|
116
|
+
operations, and pipes preserve authored order.** Its core is deliberately small:
|
|
117
|
+
`pipe(cube) | verb() | verb()`. It builds on xarray, NumPy, Dask, and geospatial
|
|
118
|
+
tools rather than replacing them.
|
|
119
|
+
|
|
120
|
+
Rerunnable code is not automatically a recoverable scientific argument. A pipe
|
|
121
|
+
retains semantic state and an ordered trace so a reader can inspect what object
|
|
122
|
+
each transformation produced, while source records and bounded QA keep the
|
|
123
|
+
evidence beneath a concise noun reachable. A common noun does not make sources
|
|
124
|
+
interchangeable, a trace is not complete workflow provenance, and validation
|
|
125
|
+
does not choose or certify the scientific question. See the
|
|
126
|
+
[scientific framing](docs/concepts/scientific_inspectability.md).
|
|
127
|
+
|
|
128
|
+
The checkout currently declares **version 0.1.0rc1, alpha**, with Python **3.9+**
|
|
129
|
+
support. Development and documentation CI use Python 3.11; the offline test
|
|
130
|
+
matrix covers 3.9–3.12. These are repository metadata and CI targets, not a claim
|
|
131
|
+
that an installed PyPI release contains every change on `main`.
|
|
132
|
+
|
|
133
|
+
For the first public alpha release candidate, see the [0.1 support contract](docs/project/api_support_0_1.md),
|
|
134
|
+
[release-note draft](docs/project/release_0_1_0.md), and [non-publishing release checklist](RELEASING.md).
|
|
135
|
+
The candidate artifact targets `0.1.0rc1`; it is not a published release or tag.
|
|
136
|
+
|
|
137
|
+
## Start here
|
|
138
|
+
|
|
139
|
+
The [website](https://cu-esiil.github.io/cubedynamics/) has five entry points:
|
|
140
|
+
|
|
141
|
+
- [Home](https://cu-esiil.github.io/cubedynamics/) — what the grammar is for.
|
|
142
|
+
- [Learn](https://cu-esiil.github.io/cubedynamics/learn/) — a progressive introduction.
|
|
143
|
+
- [Library](https://cu-esiil.github.io/cubedynamics/library/) — environmental nouns and source flavors.
|
|
144
|
+
- [Documents](https://cu-esiil.github.io/cubedynamics/documentation/) — operations, arguments, and return values.
|
|
145
|
+
- [Vignettes](https://cu-esiil.github.io/cubedynamics/vignettes/) — real-data analysis stories with runnable notebooks and figures.
|
|
146
|
+
|
|
147
|
+
[Developer documentation](https://cu-esiil.github.io/cubedynamics/developer/)
|
|
148
|
+
separates architecture, CI, source maintenance, and audits from user reference.
|
|
149
|
+
|
|
150
|
+
## Install
|
|
151
|
+
|
|
152
|
+
**Current state: preparing the first public release candidate; not published.**
|
|
153
|
+
There is no installable CubeDynamics distribution on PyPI or in the existing
|
|
154
|
+
GitHub Releases. Do not substitute a source clone for outside-user acceptance
|
|
155
|
+
testing. A reviewer can install a maintainer-supplied, checksum-verified
|
|
156
|
+
`cubedynamics-0.1.0rc1-py3-none-any.whl` directly with pip today.
|
|
157
|
+
|
|
158
|
+
**After the v0.1.0rc1 GitHub Release is published**, the external install command
|
|
159
|
+
will be (this URL is not available yet):
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
python -m pip install "https://github.com/CU-ESIIL/cubedynamics/releases/download/v0.1.0rc1/cubedynamics-0.1.0rc1-py3-none-any.whl"
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
After a separate PyPI publication, `python -m pip install cubedynamics==0.1.0rc1`
|
|
166
|
+
will install the same version. Plain `pip install cubedynamics` is reserved for
|
|
167
|
+
the future final release. See the [installation guide](docs/getting_started/install.md)
|
|
168
|
+
and [package-only quickstart](docs/quickstart.md); neither requires a clone.
|
|
169
|
+
|
|
170
|
+
### Developer checkout (not the release-candidate install)
|
|
171
|
+
|
|
172
|
+
Contributors who need this checkout's code, real-data fixtures, and notebooks
|
|
173
|
+
can clone and install from its root. This uses the Python 3.11 development target:
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
git clone https://github.com/CU-ESIIL/cubedynamics.git
|
|
177
|
+
cd cubedynamics
|
|
178
|
+
python3.11 -m venv .venv
|
|
179
|
+
source .venv/bin/activate
|
|
180
|
+
python -m pip install -e ".[dev]"
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
On Windows, activate with `.venv\Scripts\activate` instead. For an exact
|
|
184
|
+
reproduction, check out a recorded commit or release tag before installing.
|
|
185
|
+
`make install` and `make test` provide the existing local development shortcuts.
|
|
186
|
+
|
|
187
|
+
Optional extras in [pyproject.toml](pyproject.toml):
|
|
188
|
+
|
|
189
|
+
| Extra | Adds |
|
|
190
|
+
| --- | --- |
|
|
191
|
+
| `test` | Pytest and distribution-checking tools |
|
|
192
|
+
| `docs` | MkDocs, reference rendering, and notebook rendering |
|
|
193
|
+
| `vignettes` | Notebook execution and a Python kernel |
|
|
194
|
+
| `viz` | Optional Lexcube widget support; not required for the custom HTML cube viewer |
|
|
195
|
+
| `dev` | Test, docs, vignette, and Lexcube tooling |
|
|
196
|
+
| `browser` | Playwright and its pytest plugin, Python 3.10+; install Chromium separately |
|
|
197
|
+
| `roads` | Optional PyArrow reader for the bounded Overture roads candidate |
|
|
198
|
+
|
|
199
|
+
The former `climate_cube_math` namespace remains a deprecated compatibility
|
|
200
|
+
path. Use `cubedynamics` for new code.
|
|
201
|
+
|
|
202
|
+
## A short pipe, a visible result
|
|
203
|
+
|
|
204
|
+
Run this from the repository root after installation. It uses a small,
|
|
205
|
+
checksum-controlled **real PRISM extract**, not generated observations, and
|
|
206
|
+
requires no network request. The input contains January 1–30, 2024 daily
|
|
207
|
+
maximum temperatures near Boulder, Colorado, in degrees Celsius.
|
|
208
|
+
|
|
209
|
+
<!-- readme-example: offline -->
|
|
210
|
+
```python
|
|
211
|
+
import matplotlib.pyplot as plt
|
|
212
|
+
import xarray as xr
|
|
213
|
+
from cubedynamics import pipe, verbs as v
|
|
214
|
+
|
|
215
|
+
# Load only the small, reviewed fixture; the file closes after loading.
|
|
216
|
+
with xr.open_dataset(
|
|
217
|
+
"tests/fixtures/real_data/prism_boulder_january_2024.nc", engine="scipy"
|
|
218
|
+
) as observations:
|
|
219
|
+
cube = observations["tmax"].load()
|
|
220
|
+
|
|
221
|
+
# Average daily maximum temperature over these dates at each grid cell.
|
|
222
|
+
result = pipe(cube) | v.mean(over="time", keep_dim=False)
|
|
223
|
+
result.unwrap().plot(cmap="magma", cbar_kwargs={"label": "Temperature (°C)"})
|
|
224
|
+
plt.title("Boulder region · Mean daily maximum · January 1–30, 2024")
|
|
225
|
+
plt.show()
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
This describes the observed period, not a long-term climate normal. The
|
|
229
|
+
[fixture provenance](tests/fixtures/real_data/prism_boulder_january_2024.provenance.json)
|
|
230
|
+
records its source and checksum; [validation](https://cu-esiil.github.io/cubedynamics/validation/)
|
|
231
|
+
documents the checks.
|
|
232
|
+
|
|
233
|
+
Pipes also expose `explain()`, `suggest()`, `validate()`, `semantic_state`, and
|
|
234
|
+
`semantic_trace`. These inspect metadata and analytical order; they do not
|
|
235
|
+
certify the scientific question or independently validate source observations.
|
|
236
|
+
`|` invokes each stage when composed; Dask-backed stages can retain deferred
|
|
237
|
+
computation. `unwrap()` returns the current value, not a forced computation.
|
|
238
|
+
|
|
239
|
+
## Choose observations by scientific noun
|
|
240
|
+
|
|
241
|
+
The current catalog contains these implemented source flavors:
|
|
242
|
+
|
|
243
|
+
<!-- readme-catalog: start -->
|
|
244
|
+
| Noun | Source flavors |
|
|
245
|
+
| --- | --- |
|
|
246
|
+
| `temperature` | `gridmet`, `prism` |
|
|
247
|
+
| `precipitation` | `gridmet`, `prism` |
|
|
248
|
+
| `vpd` | `gridmet` |
|
|
249
|
+
| `wind` | `gridmet` |
|
|
250
|
+
| `humidity` | `gridmet` |
|
|
251
|
+
| `radiation` | `gridmet` |
|
|
252
|
+
| `surface_reflectance` | `sentinel2` |
|
|
253
|
+
| `vegetation_index` | `sentinel2` |
|
|
254
|
+
<!-- readme-catalog: end -->
|
|
255
|
+
|
|
256
|
+
Inspect support without downloading observations:
|
|
257
|
+
|
|
258
|
+
<!-- readme-example: discovery -->
|
|
259
|
+
```python
|
|
260
|
+
from cubedynamics import data
|
|
261
|
+
|
|
262
|
+
print(data.list_sources())
|
|
263
|
+
print(data.describe("temperature", "prism"))
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
For a live request, choose a source and statistic explicitly. This example
|
|
267
|
+
requires provider access and may fail if the remote service is unavailable:
|
|
268
|
+
|
|
269
|
+
<!-- readme-example: live -->
|
|
270
|
+
```python
|
|
271
|
+
import matplotlib.pyplot as plt
|
|
272
|
+
from cubedynamics import data, pipe, verbs as v
|
|
273
|
+
|
|
274
|
+
cube = data.temperature(
|
|
275
|
+
source="prism", statistic="maximum",
|
|
276
|
+
bbox=[-105.55, 39.85, -105.05, 40.15],
|
|
277
|
+
start="2024-01-01", end="2024-01-03",
|
|
278
|
+
)
|
|
279
|
+
(pipe(cube) | v.mean(over="time", keep_dim=False)).unwrap().plot(cmap="magma")
|
|
280
|
+
plt.show()
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
The same noun does **not** make sources interchangeable. gridMET temperature
|
|
284
|
+
uses kelvin and provides maximum/minimum; PRISM uses degrees Celsius and also
|
|
285
|
+
provides a mean statistic. These climate sources cover the contiguous United
|
|
286
|
+
States. Sentinel-2 has different spatial, spectral, acquisition, and quality
|
|
287
|
+
constraints. Inspect units, CRS, coordinates, missingness, and source provenance
|
|
288
|
+
before combining observations; CubeDynamics does not silently harmonize them.
|
|
289
|
+
|
|
290
|
+
Noun loaders reject synthetic fallback. Provider-specific loaders remain
|
|
291
|
+
available for lower-level access. Landsat and FIRED integrations are additional
|
|
292
|
+
workflows, not extra registered noun flavors. `stream_global_climate_cube`
|
|
293
|
+
adapts an already-open xarray object; it is not a global-data downloader.
|
|
294
|
+
|
|
295
|
+
Lazy output is not proof of bounded remote access: PRISM uses daily THREDDS
|
|
296
|
+
NcSS subsets; gridMET can use OPeNDAP with an optional compatible engine, but
|
|
297
|
+
falls back to fetching annual HTTPS files. A long record can still be expensive.
|
|
298
|
+
Source QA separates a serving revision's scientific validity from live endpoint
|
|
299
|
+
health. See the [source reference](https://cu-esiil.github.io/cubedynamics/library/sources/).
|
|
300
|
+
|
|
301
|
+
## Built-in vocabulary and your own verbs
|
|
302
|
+
|
|
303
|
+
| Layer | Role |
|
|
304
|
+
| --- | --- |
|
|
305
|
+
| Core grammar | `pipe`, `Pipe`, callable stages, and semantic contracts |
|
|
306
|
+
| Shared vocabulary | Transformations, summaries, states/events, comparison, and alignment |
|
|
307
|
+
| Integrations | Source adapters, plotting/viewers, and output helpers |
|
|
308
|
+
| Project extensions | Synchrony, biological workflows, tubes, Fire VASE, and your own methods |
|
|
309
|
+
|
|
310
|
+
Project vocabularies currently ship in the same distribution for compatibility;
|
|
311
|
+
their scientific assumptions are not part of the minimal grammar contract.
|
|
312
|
+
|
|
313
|
+
A project-owned operation can be an ordinary callable factory. Continuing with
|
|
314
|
+
the **offline Celsius cube** above, ask what fraction of observed days exceeded
|
|
315
|
+
a chosen temperature. The threshold is an analytical choice, not a provider fact:
|
|
316
|
+
|
|
317
|
+
<!-- readme-example: custom -->
|
|
318
|
+
```python
|
|
319
|
+
def fraction_above(threshold):
|
|
320
|
+
def _op(cube):
|
|
321
|
+
# Count only observed days; missing values must not become cool days.
|
|
322
|
+
observed = cube.notnull().sum("time")
|
|
323
|
+
return ((cube > threshold).sum("time") / observed.where(observed > 0)).rename(
|
|
324
|
+
"fraction_above"
|
|
325
|
+
).assign_attrs(units="1")
|
|
326
|
+
return _op
|
|
327
|
+
|
|
328
|
+
warm_days = (pipe(cube) | fraction_above(10)).unwrap()
|
|
329
|
+
warm_days.plot(vmin=0, vmax=1, cbar_kwargs={"label": "Fraction of observed days"})
|
|
330
|
+
plt.title("Boulder region · Daily maximum above 10°C")
|
|
331
|
+
plt.show()
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
No registration or subclass is required. Start from the
|
|
335
|
+
[custom-verb scaffold](examples/custom_verb_project/README.md) and test direct
|
|
336
|
+
and piped use before presenting a method as reviewed.
|
|
337
|
+
|
|
338
|
+
[Browse operations by purpose](https://cu-esiil.github.io/cubedynamics/reference/verbs/)
|
|
339
|
+
or use the [full A–Z inventory](https://cu-esiil.github.io/cubedynamics/reference/verbs/a-z/).
|
|
340
|
+
Not every callable in `v` is a pipe-stage factory: `v.fire_plot`, for example,
|
|
341
|
+
is a direct visualization helper. `v.correlation_cube` and `v.fit_model` are
|
|
342
|
+
reserved placeholders, not implemented analysis operations. Compatibility
|
|
343
|
+
aliases are labeled separately in the reference. `v.month_filter` is a
|
|
344
|
+
supported stage; only its legacy `cubedynamics.ops` import warns.
|
|
345
|
+
|
|
346
|
+
`v.plot()` uses the custom HTML/CSS/JavaScript cube viewer. Fire plotting still
|
|
347
|
+
has a Plotly renderer; it has not been fully migrated to that viewer.
|
|
348
|
+
`FireEventDaily` and `FireHull` are the canonical fire object names;
|
|
349
|
+
`TimeHull` is retained for compatibility.
|
|
350
|
+
|
|
351
|
+
## Reproduce and validate
|
|
352
|
+
|
|
353
|
+
There are **twelve supported offline notebooks**: eight core lessons and three
|
|
354
|
+
real-data noun lessons (elevation, roads, streamflow) under
|
|
355
|
+
`docs/vignettes/` and the Working Lands analysis under `docs/decision_vignettes/`.
|
|
356
|
+
They cover arrays, tidy tables, Datasets, composition, transformations,
|
|
357
|
+
states/events, custom verbs, lazy computation, and a two-noun decision story.
|
|
358
|
+
Each has real-data provenance, executable code, and required static plots.
|
|
359
|
+
The runner checks those outputs without modifying notebook sources:
|
|
360
|
+
|
|
361
|
+
```bash
|
|
362
|
+
python scripts/run_vignettes.py
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
Use these checks from an installed development checkout:
|
|
366
|
+
|
|
367
|
+
```bash
|
|
368
|
+
python -m pytest -m "not integration and not online" -q
|
|
369
|
+
python scripts/run_validation.py --run-vignettes
|
|
370
|
+
python scripts/run_source_qa.py
|
|
371
|
+
python scripts/run_decision_qa.py
|
|
372
|
+
python scripts/build_reference_docs.py --check
|
|
373
|
+
python -m mkdocs build --strict
|
|
374
|
+
python scripts/check_site_links.py site
|
|
375
|
+
python scripts/check_repository_size.py --mode tracked
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
QA evidence is written under ignored `artifacts/`. Passing a bounded fixture
|
|
379
|
+
does not certify every product, location, period, or current provider endpoint.
|
|
380
|
+
Online checks and live-source certification are separate from offline tests.
|
|
381
|
+
|
|
382
|
+
For website changes, also run the opt-in browser suite (Python 3.10+):
|
|
383
|
+
|
|
384
|
+
```bash
|
|
385
|
+
python -m pip install -e ".[browser]"
|
|
386
|
+
python -m playwright install chromium
|
|
387
|
+
python -m pytest tests/browser -m browser --site-dir site --browser chromium \
|
|
388
|
+
--tracing retain-on-failure --output artifacts/browser/playwright -q
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
It checks built-page links and anchors, decoded images, deferred embeds,
|
|
392
|
+
desktop/mobile journeys, and cube interaction. CI gates documentation and Pages
|
|
393
|
+
publication on browser failures; external-link availability is advisory.
|
|
394
|
+
See [CI and testing](docs/dev/ci_testing.md) for evidence and platform setup.
|
|
395
|
+
|
|
396
|
+
## Repository and contribution guide
|
|
397
|
+
|
|
398
|
+
The main noun library includes [elevation](docs/library/nouns/elevation.md),
|
|
399
|
+
[roads](docs/library/nouns/roads.md), and [streamflow](docs/library/nouns/streamflow.md),
|
|
400
|
+
with source-specific installed imports, complete references, and offline
|
|
401
|
+
real-data lessons. Their bounded QA status is documented separately from their
|
|
402
|
+
place in the grammar; `data.list_sources()` and production serving histories
|
|
403
|
+
are unchanged. Historical acquisition reports live in
|
|
404
|
+
[developer source engineering](docs/data/source_projects/index.md).
|
|
405
|
+
|
|
406
|
+
- `src/cubedynamics/` is the installed package; `code/cubedynamics/` is a legacy mirror.
|
|
407
|
+
- `docs/` holds the website, generated references, and supported notebooks.
|
|
408
|
+
- `tests/fixtures/real_data/` holds small observational fixtures and provenance.
|
|
409
|
+
- `scripts/` holds reference/notebook builders and QA runners.
|
|
410
|
+
- [paper/](paper/README.md) holds manuscript working material, including the
|
|
411
|
+
supplied citation-map draft; draft markers are not completed references.
|
|
412
|
+
|
|
413
|
+
Large scientific products and runtime manifests belong outside Git. Use
|
|
414
|
+
[config/storage.example.yml](config/storage.example.yml) for local/object-store
|
|
415
|
+
paths. The size policy permits small reviewed fixtures under `tests/fixtures/`;
|
|
416
|
+
do not remove their NetCDF files merely because bulk NetCDF output is blocked.
|
|
417
|
+
Historical Fire VASE outputs still in Git require an explicit archival plan,
|
|
418
|
+
not automatic deletion. See [data policy](data/README.md) and the
|
|
419
|
+
[publication plan](docs/project/publication_plan.md).
|
|
420
|
+
|
|
421
|
+
Read [CONTRIBUTING.md](CONTRIBUTING.md) and [AGENTS.md](AGENTS.md) before changing
|
|
422
|
+
the package. Edit reference generators, not files marked generated. Keep the
|
|
423
|
+
five website entry points and distinguish implemented, compatibility, and
|
|
424
|
+
reserved APIs. See the [public API policy](docs/project/public_api.md).
|
|
425
|
+
|
|
426
|
+
## Citation and license
|
|
427
|
+
|
|
428
|
+
Use [CITATION.cff](CITATION.cff), recording the package version/commit and the
|
|
429
|
+
source products used. Its DOI field is not populated; manuscript citation
|
|
430
|
+
markers do not supply a release DOI. Release publishing is handled by
|
|
431
|
+
[publish.yml](.github/workflows/publish.yml) on `v*` tags or manual dispatch;
|
|
432
|
+
tagging/publishing and completing manuscript references are separate tasks.
|
|
433
|
+
|
|
434
|
+
CubeDynamics is distributed under the [MIT License](LICENSE).
|