xarray-spatial 0.10.4__tar.gz → 0.10.6__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.
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.claude/commands/deep-sweep.md +8 -7
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.claude/commands/sweep-accuracy.md +14 -11
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.claude/commands/sweep-api-consistency.md +9 -4
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.claude/commands/sweep-metadata.md +13 -10
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.claude/commands/sweep-performance.md +14 -11
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.claude/commands/sweep-security.md +14 -11
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.claude/commands/sweep-style.md +12 -10
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.claude/commands/sweep-test-coverage.md +9 -4
- xarray_spatial-0.10.6/.claude/sweep-style-state.csv +15 -0
- xarray_spatial-0.10.6/.claude/sweep-test-coverage-state.csv +16 -0
- xarray_spatial-0.10.6/.cursor/rules/backend-parity.mdc +68 -0
- xarray_spatial-0.10.6/.cursor/rules/bench.mdc +51 -0
- xarray_spatial-0.10.6/.cursor/rules/dask-notebook.mdc +58 -0
- xarray_spatial-0.10.6/.cursor/rules/deep-sweep.mdc +49 -0
- xarray_spatial-0.10.6/.cursor/rules/efficiency-audit.mdc +47 -0
- xarray_spatial-0.10.6/.cursor/rules/new-issues.mdc +43 -0
- xarray_spatial-0.10.6/.cursor/rules/ready-to-merge.mdc +45 -0
- xarray_spatial-0.10.6/.cursor/rules/release-major.mdc +85 -0
- xarray_spatial-0.10.6/.cursor/rules/release-minor.mdc +85 -0
- xarray_spatial-0.10.6/.cursor/rules/release-patch.mdc +85 -0
- xarray_spatial-0.10.6/.cursor/rules/review-contributor-pr.mdc +62 -0
- xarray_spatial-0.10.6/.cursor/rules/review-pr.mdc +88 -0
- xarray_spatial-0.10.6/.cursor/rules/rockout.mdc +86 -0
- xarray_spatial-0.10.6/.cursor/rules/sweep-accuracy.mdc +35 -0
- xarray_spatial-0.10.6/.cursor/rules/sweep-api-consistency.mdc +35 -0
- xarray_spatial-0.10.6/.cursor/rules/sweep-metadata.mdc +34 -0
- xarray_spatial-0.10.6/.cursor/rules/sweep-performance.mdc +38 -0
- xarray_spatial-0.10.6/.cursor/rules/sweep-security.mdc +37 -0
- xarray_spatial-0.10.6/.cursor/rules/sweep-style.mdc +41 -0
- xarray_spatial-0.10.6/.cursor/rules/sweep-test-coverage.mdc +35 -0
- xarray_spatial-0.10.6/.cursor/rules/user-guide-notebook.mdc +52 -0
- xarray_spatial-0.10.6/.cursor/rules/validate.mdc +52 -0
- xarray_spatial-0.10.6/.cursorrules +53 -0
- xarray_spatial-0.10.6/.gitattributes +12 -0
- xarray_spatial-0.10.6/.kilo/command/backend-parity.md +159 -0
- xarray_spatial-0.10.6/.kilo/command/bench.md +127 -0
- xarray_spatial-0.10.6/.kilo/command/dask-notebook.md +148 -0
- xarray_spatial-0.10.6/.kilo/command/deep-sweep.md +438 -0
- xarray_spatial-0.10.6/.kilo/command/efficiency-audit.md +274 -0
- xarray_spatial-0.10.6/.kilo/command/new-issues.md +113 -0
- xarray_spatial-0.10.6/.kilo/command/ready-to-merge.md +153 -0
- xarray_spatial-0.10.6/.kilo/command/release-major.md +146 -0
- xarray_spatial-0.10.6/.kilo/command/release-minor.md +146 -0
- xarray_spatial-0.10.6/.kilo/command/release-patch.md +146 -0
- xarray_spatial-0.10.6/.kilo/command/review-contributor-pr.md +332 -0
- xarray_spatial-0.10.6/.kilo/command/review-pr.md +249 -0
- xarray_spatial-0.10.6/.kilo/command/rockout.md +377 -0
- xarray_spatial-0.10.6/.kilo/command/sweep-accuracy.md +335 -0
- xarray_spatial-0.10.6/.kilo/command/sweep-api-consistency.md +291 -0
- xarray_spatial-0.10.6/.kilo/command/sweep-metadata.md +334 -0
- xarray_spatial-0.10.6/.kilo/command/sweep-performance.md +366 -0
- xarray_spatial-0.10.6/.kilo/command/sweep-security.md +334 -0
- xarray_spatial-0.10.6/.kilo/command/sweep-style.md +315 -0
- xarray_spatial-0.10.6/.kilo/command/sweep-test-coverage.md +293 -0
- xarray_spatial-0.10.6/.kilo/command/user-guide-notebook.md +203 -0
- xarray_spatial-0.10.6/.kilo/command/validate.md +216 -0
- xarray_spatial-0.10.6/.kilo/sweep-accuracy-state.csv +39 -0
- xarray_spatial-0.10.6/.kilo/sweep-api-consistency-state.csv +10 -0
- xarray_spatial-0.10.6/.kilo/sweep-metadata-state.csv +12 -0
- xarray_spatial-0.10.6/.kilo/sweep-performance-state.csv +49 -0
- xarray_spatial-0.10.6/.kilo/sweep-security-state.csv +49 -0
- xarray_spatial-0.10.6/.kilo/sweep-test-coverage-state.csv +17 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/CHANGELOG.md +67 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/PKG-INFO +6 -6
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/README.md +5 -5
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xarray_spatial.egg-info/PKG-INFO +6 -6
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xarray_spatial.egg-info/SOURCES.txt +57 -15
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/__init__.py +2 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/_version.py +3 -3
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/accessor.py +92 -34
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/aspect.py +1 -1
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/contour.py +65 -13
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/emerging_hotspots.py +116 -88
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/__init__.py +261 -124
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/_attrs.py +168 -22
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/_backends/_gpu_helpers.py +7 -7
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/_backends/dask.py +83 -48
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/_backends/gpu.py +57 -56
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/_backends/vrt.py +133 -71
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/_cog_http.py +25 -10
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/_coords.py +2 -2
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/_crs.py +3 -3
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/_decode.py +1 -1
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/_errors.py +23 -1
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/_geotags.py +43 -8
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/_gpu_decode.py +11 -2
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/_reader.py +6 -6
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/_runtime.py +17 -9
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/_sidecar.py +38 -20
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/_validation.py +40 -25
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/_vrt.py +57 -6
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/_vrt_validation.py +4 -4
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/_writer.py +111 -40
- xarray_spatial-0.10.6/xrspatial/geotiff/_writers/__init__.py +7 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/_writers/eager.py +185 -157
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/_writers/gpu.py +34 -34
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/_writers/vrt.py +49 -52
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/attrs/test_contract.py +3 -3
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/test_dask_gpu.py +6 -5
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/test_dask_numpy.py +9 -10
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/test_eager_numpy.py +2 -4
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/test_fsspec.py +13 -11
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/test_gpu.py +6 -5
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/test_vrt.py +5 -5
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/gpu/test_codec.py +52 -49
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/gpu/test_kernels_and_kwargs.py +251 -240
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/gpu/test_reader.py +100 -99
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/gpu/test_writer.py +196 -68
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/integration/test_dask_pipeline.py +36 -36
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/integration/test_gpu_pipeline.py +4 -4
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/integration/test_http_sources.py +23 -23
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/integration/test_sidecar.py +172 -9
- xarray_spatial-0.10.6/xrspatial/geotiff/tests/parity/test_api_consolidation.py +143 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/parity/test_backend_matrix.py +14 -13
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/parity/test_finalization.py +67 -67
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/parity/test_pixel_equality.py +34 -34
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/parity/test_reference.py +14 -14
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/parity/test_signature_contract.py +22 -21
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/read/test_basic.py +19 -18
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/read/test_coords.py +2 -2
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/read/test_crs.py +1 -1
- xarray_spatial-0.10.6/xrspatial/geotiff/tests/read/test_degenerate_shapes.py +150 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/read/test_dtypes.py +22 -22
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/read/test_endianness.py +5 -5
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/read/test_georef.py +11 -11
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/read/test_nodata.py +177 -121
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/read/test_overview.py +45 -45
- xarray_spatial-0.10.6/xrspatial/geotiff/tests/read/test_rioxarray_compat_2961.py +494 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/read/test_tiling.py +9 -8
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/release_gates/test_features.py +49 -44
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/release_gates/test_stable_features.py +23 -11
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/test_edge_cases.py +2 -2
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/test_polish.py +16 -16
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/test_round_trip.py +6 -6
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/test_security.py +2 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/test_stable_only_bbox_ordering_2869.py +2 -3
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/test_stable_only_remote_2821.py +10 -10
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/unit/test_codec_roundtrip.py +43 -9
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/unit/test_geotags.py +0 -6
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/unit/test_ifd.py +3 -3
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/unit/test_input_validation.py +59 -59
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/unit/test_metadata.py +19 -19
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/unit/test_photometric.py +22 -22
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/unit/test_predictor.py +4 -4
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/unit/test_safe_xml.py +1 -1
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/unit/test_signatures.py +218 -164
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/vrt/test_dtype_conversion.py +53 -53
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/vrt/test_metadata.py +187 -95
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/vrt/test_missing_sources.py +194 -44
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/vrt/test_parity.py +48 -47
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/vrt/test_source_opt_ins_2672.py +8 -8
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/vrt/test_validation.py +32 -32
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/vrt/test_window.py +36 -36
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/write/test_basic.py +300 -92
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/write/test_bigtiff.py +3 -3
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/write/test_cog.py +10 -10
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/write/test_crs.py +2 -2
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/write/test_nodata.py +58 -33
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/write/test_overview.py +12 -12
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/write/test_streaming.py +99 -1
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/write/test_vrt_atomic.py +46 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/flow_path_dinf.py +9 -2
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/stream_link_mfd.py +44 -32
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/stream_order_mfd.py +72 -56
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/tests/test_flow_path_dinf.py +106 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/tests/test_stream_link_mfd.py +78 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/tests/test_stream_order_mfd.py +79 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/polygonize.py +153 -29
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/reproject/__init__.py +18 -14
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/reproject/_grid.py +10 -3
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/reproject/_itrf.py +1 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/reproject/_merge.py +0 -1
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/reproject/_projections.py +30 -97
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/reproject/_projections_cuda.py +29 -27
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_accessor.py +102 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_aspect.py +8 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_contour.py +363 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_emerging_hotspots.py +94 -0
- xarray_spatial-0.10.6/xrspatial/tests/test_polygonize_issue_2677.py +199 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_reproject.py +52 -44
- xarray_spatial-0.10.6/xrspatial/tests/test_sweep_state_csv_merge_2754.py +142 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_utils.py +30 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_viewshed.py +147 -1
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/utils.py +13 -3
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/viewshed.py +63 -3
- xarray_spatial-0.10.4/.claude/sweep-test-coverage-state.csv +0 -91
- xarray_spatial-0.10.4/.gitattributes +0 -5
- xarray_spatial-0.10.4/xrspatial/geotiff/_writers/__init__.py +0 -7
- xarray_spatial-0.10.4/xrspatial/reproject/_datum_grids.py +0 -386
- xarray_spatial-0.10.4/xrspatial/reproject/grids/at_bev_AT_GIS_GRID.tif +0 -0
- xarray_spatial-0.10.4/xrspatial/reproject/grids/au_icsm_A66_National_13_09_01.tif +0 -0
- xarray_spatial-0.10.4/xrspatial/reproject/grids/be_ign_bd72lb72_etrs89lb08.tif +0 -0
- xarray_spatial-0.10.4/xrspatial/reproject/grids/ch_swisstopo_CHENyx06_ETRS.tif +0 -0
- xarray_spatial-0.10.4/xrspatial/reproject/grids/de_adv_BETA2007.tif +0 -0
- xarray_spatial-0.10.4/xrspatial/reproject/grids/es_ign_SPED2ETV2.tif +0 -0
- xarray_spatial-0.10.4/xrspatial/reproject/grids/nl_nsgi_rdcorr2018.tif +0 -0
- xarray_spatial-0.10.4/xrspatial/reproject/grids/pt_dgt_D73_ETRS89_geo.tif +0 -0
- xarray_spatial-0.10.4/xrspatial/reproject/grids/uk_os_OSTN15_NTv2_OSGBtoETRS.tif +0 -0
- xarray_spatial-0.10.4/xrspatial/reproject/grids/us_noaa_alaska.tif +0 -0
- xarray_spatial-0.10.4/xrspatial/reproject/grids/us_noaa_conus.tif +0 -0
- xarray_spatial-0.10.4/xrspatial/reproject/grids/us_noaa_hawaii.tif +0 -0
- xarray_spatial-0.10.4/xrspatial/reproject/grids/us_noaa_nadcon5_nad27_nad83_1986_conus.tif +0 -0
- xarray_spatial-0.10.4/xrspatial/reproject/grids/us_noaa_prvi.tif +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.claude/commands/backend-parity.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.claude/commands/bench.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.claude/commands/dask-notebook.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.claude/commands/efficiency-audit.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.claude/commands/new-issues.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.claude/commands/ready-to-merge.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.claude/commands/release-major.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.claude/commands/release-minor.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.claude/commands/release-patch.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.claude/commands/review-contributor-pr.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.claude/commands/review-pr.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.claude/commands/rockout.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.claude/commands/user-guide-notebook.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.claude/commands/validate.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.claude/sweep-accuracy-state.csv +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.claude/sweep-api-consistency-state.csv +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.claude/sweep-metadata-state.csv +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.claude/sweep-performance-state.csv +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.claude/sweep-security-state.csv +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.codex/commands/backend-parity.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.codex/commands/bench.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.codex/commands/dask-notebook.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.codex/commands/deep-sweep.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.codex/commands/efficiency-audit.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.codex/commands/new-issues.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.codex/commands/ready-to-merge.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.codex/commands/release-major.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.codex/commands/release-minor.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.codex/commands/release-patch.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.codex/commands/review-contributor-pr.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.codex/commands/review-pr.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.codex/commands/rockout.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.codex/commands/sweep-accuracy.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.codex/commands/sweep-api-consistency.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.codex/commands/sweep-metadata.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.codex/commands/sweep-performance.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.codex/commands/sweep-security.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.codex/commands/sweep-style.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.codex/commands/sweep-test-coverage.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.codex/commands/user-guide-notebook.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.codex/commands/validate.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.codex/sweep-accuracy-state.csv +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.codex/sweep-api-consistency-state.csv +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.codex/sweep-metadata-state.csv +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.codex/sweep-performance-state.csv +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.codex/sweep-security-state.csv +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.codex/sweep-style-state.csv +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.codex/sweep-test-coverage-state.csv +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.efficiency-audit-baseline.json +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.efficiency-audit-baseline.prev.json +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.github/ISSUE_TEMPLATE/feature-proposal.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.github/ISSUE_TEMPLATE/new-contributor.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.github/labeler.yml +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.github/pull_request_template.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.github/workflows/benchmarks.yml +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.github/workflows/copilot-review.yml +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.github/workflows/labeler.yml +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.github/workflows/pypi-publish.yml +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.github/workflows/test-cog-validator.yml +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.github/workflows/test-geotiff-corpus.yml +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.github/workflows/test.yml +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.github/workflows/welcome-contributor.yml +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.gitignore +0 -0
- {xarray_spatial-0.10.4/.claude → xarray_spatial-0.10.6/.kilo}/sweep-style-state.csv +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/.readthedocs.yml +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/AI_POLICY.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/CLAUDE.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/CODE_OF_CONDUCT.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/CONTRIBUTING.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/Citation-styles.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/LICENSE.txt +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/MANIFEST.in +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/RELEASE.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/codecov.yml +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/pyproject.toml +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/setup.cfg +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/setup.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xarray_spatial.egg-info/dependency_links.txt +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xarray_spatial.egg-info/entry_points.txt +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xarray_spatial.egg-info/not-zip-safe +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xarray_spatial.egg-info/requires.txt +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xarray_spatial.egg-info/top_level.txt +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/__main__.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/analytics.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/balanced_allocation.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/bilateral.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/bump.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/classify.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/convolution.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/corridor.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/cost_distance.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/curvature.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/dasymetric.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/dataset_support.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/datasets/__init__.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/datasets/sentinel-2/blue_band.nc +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/datasets/sentinel-2/green_band.nc +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/datasets/sentinel-2/nir_band.nc +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/datasets/sentinel-2/red_band.nc +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/datasets/sentinel-2/swir1_band.nc +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/datasets/sentinel-2/swir2_band.nc +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/diagnostics.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/diffusion.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/edge_detection.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/erosion.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/experimental/__init__.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/experimental/min_observable_height.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/fire.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/flood.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/focal.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geodesic.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/_backends/__init__.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/_compression.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/_dtypes.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/_encode.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/_header.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/_layout.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/_nodata.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/_overview.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/_overview_kernels.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/_safe_xml.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/_sources.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/_write_layout.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/__init__.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/_geotiff_fixtures.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/_helpers/__init__.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/_helpers/markers.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/_helpers/tiff_builders.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/_helpers/tiff_surgery.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/attrs/__init__.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/bench_vs_rioxarray.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/conftest.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/README.md +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/__init__.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/_marks.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/_oracle.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/fixtures/cog_internal_overview_uint16.tif +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/fixtures/compression_deflate_predictor2_uint16.tif +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/fixtures/compression_deflate_predictor3_float32.tif +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/fixtures/compression_jpeg_uint8_ycbcr.tif +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/fixtures/compression_lerc_float32.tif +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/fixtures/compression_lzw_predictor2_int16.tif +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/fixtures/compression_none_uint8.tif +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/fixtures/crs_citation_only.tif +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/fixtures/crs_epsg_3857.tif +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/fixtures/crs_wkt_utm10n.tif +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/fixtures/dtype_float32.tif +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/fixtures/dtype_float64.tif +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/fixtures/dtype_int16.tif +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/fixtures/dtype_int32.tif +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/fixtures/dtype_int8.tif +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/fixtures/dtype_uint16.tif +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/fixtures/dtype_uint32.tif +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/fixtures/dtype_uint8.tif +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/fixtures/extra_tags_uint16.tif +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/fixtures/gdal_metadata_namespaced_uint16.tif +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/fixtures/nodata_int_sentinel_uint16.tif +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/fixtures/nodata_miniswhite_uint8.tif +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/fixtures/nodata_nan_float32.tif +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/fixtures/overview_external_ovr_uint16.tif +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/fixtures/overview_external_ovr_uint16.tif.ovr +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/fixtures/overview_internal_uint16.tif +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/fixtures/planar_separate_uint8_rgb.tif +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/fixtures/sparse_tiled_uint16.tif +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/fixtures/stripped_be_uint16.tif +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/fixtures/stripped_le_uint16.tif +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/fixtures/tiled_be_uint16.tif +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/fixtures/tiled_le_uint16.tif +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/generate.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/manifest.yaml +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/test_compression.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/test_corpus_determinism.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/test_dtype_variants.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/test_http.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/test_layout_endian.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/test_manifest.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/test_metadata_tags.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/test_nodata_sentinels.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/test_oracle.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/golden_corpus/test_overview_cog.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/gpu/__init__.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/integration/__init__.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/parity/__init__.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/read/__init__.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/read/test_bbox_2555.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/read/test_bbox_vrt_2668.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/read/test_compression.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/read/test_streaming.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/release_gates/__init__.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/test_fuzz_hypothesis.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/test_shutdown_cleanup_2486.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/unit/__init__.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/unit/test_compression.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/unit/test_header.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/vrt/__init__.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/geotiff/tests/write/__init__.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/glcm.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/gpu_rtx/__init__.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/gpu_rtx/_memory.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/gpu_rtx/cuda_utils.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/gpu_rtx/hillshade.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/gpu_rtx/mesh_utils.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/gpu_rtx/viewshed.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hillshade.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/__init__.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/_boundary_store.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/basin_d8.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/fill_d8.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/flow_accumulation_d8.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/flow_accumulation_dinf.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/flow_accumulation_mfd.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/flow_direction_d8.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/flow_direction_dinf.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/flow_direction_mfd.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/flow_length_d8.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/flow_length_dinf.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/flow_length_mfd.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/flow_path_d8.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/flow_path_mfd.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/hand_d8.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/hand_dinf.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/hand_mfd.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/sink_d8.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/snap_pour_point_d8.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/stream_link_d8.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/stream_link_dinf.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/stream_order_d8.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/stream_order_dinf.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/tests/__init__.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/tests/conftest.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/tests/test_basin_d8.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/tests/test_fill_d8.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/tests/test_flow_accumulation_d8.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/tests/test_flow_accumulation_dinf.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/tests/test_flow_accumulation_mfd.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/tests/test_flow_direction_d8.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/tests/test_flow_direction_dinf.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/tests/test_flow_direction_mfd.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/tests/test_flow_length_d8.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/tests/test_flow_length_dinf.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/tests/test_flow_length_mfd.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/tests/test_flow_path_d8.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/tests/test_flow_path_mfd.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/tests/test_hand_d8.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/tests/test_hand_dinf.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/tests/test_hand_mfd.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/tests/test_sink_d8.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/tests/test_snap_pour_point_d8.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/tests/test_stream_link_d8.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/tests/test_stream_link_dinf.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/tests/test_stream_order_d8.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/tests/test_stream_order_dinf.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/tests/test_twi_d8.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/tests/test_validate_cellsize.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/tests/test_validate_mfd_companion_shape.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/tests/test_validate_mfd_fractions.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/tests/test_validate_scalar_params.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/tests/test_validate_secondary_args.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/tests/test_watershed_d8.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/tests/test_watershed_dinf.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/tests/test_watershed_mfd.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/twi_d8.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/watershed_d8.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/watershed_dinf.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/hydro/watershed_mfd.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/interpolate/__init__.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/interpolate/_idw.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/interpolate/_kriging.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/interpolate/_spline.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/interpolate/_validation.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/kde.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/mahalanobis.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/mcda/__init__.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/mcda/combine.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/mcda/constrain.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/mcda/sensitivity.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/mcda/standardize.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/mcda/weights.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/morphology.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/multispectral.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/normalize.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/pathfinding.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/perlin.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/polygon_clip.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/preview.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/proximity.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/rasterize.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/reproject/_crs_utils.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/reproject/_interpolate.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/reproject/_lite_crs.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/reproject/_transform.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/reproject/_vertical.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/reproject/grids/us_nga_egm96_15.tif +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/resample.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/sieve.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/sky_view_factor.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/slope.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/surface_distance.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/terrain.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/terrain_metrics.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/__init__.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/bench_reproject_vs_rioxarray.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/conftest.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/general_checks.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_analytics.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_balanced_allocation.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_bilateral.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_bump.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_classify.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_convolution.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_corridor.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_cost_distance.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_curvature.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_dask_cupy_gaps.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_dask_laziness.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_dasymetric.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_dataset_support.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_datasets.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_diagnostics.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_diffusion.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_edge_detection.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_erosion.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_fire.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_flood.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_focal.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_fused_overlap.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_geodesic_aspect.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_geodesic_slope.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_glcm.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_glcm_metric_order.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_gpu_rtx_has_rtx.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_gpu_rtx_memory.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_gpu_rtx_mesh.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_hillshade.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_hypsometric_integral.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_interpolation.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_kde.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_lite_crs.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_mahalanobis.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_mcda.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_min_observable_height.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_morphology.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_morphology_derived.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_multi_overlap.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_multispectral.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_normalize.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_northness_eastness.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_optional_shapely.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_pathfinding.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_perlin.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_polygon_clip.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_polygonize.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_polygonize_atol_rtol_backend_coverage_2026_05_27.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_polygonize_coverage_2026_05_19.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_polygonize_dask_row_batch_2608.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_polygonize_issue_2172.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_polygonize_issue_2583.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_polygonize_issue_2606.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_polygonize_issue_2666.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_polygonize_mask_dtype_coverage_2026_05_29.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_preview.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_proximity.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_rasterize.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_rasterize_accuracy.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_rasterize_all_touched_supercover_2169.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_rasterize_coverage_2026_05_17.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_rasterize_coverage_2026_05_21.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_rasterize_coverage_2026_05_27.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_rasterize_coverage_2026_05_29.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_rasterize_descending_x_2568.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_rasterize_gpu_race_2167.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_rasterize_nan_int_fill_2504.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_rasterize_nan_propagation_2255.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_rasterize_partial_dims_2569.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_rasterize_props_hoist_2506.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_rasterize_resolution_exact_2573.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_rasterize_resolution_validation_2576.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_rasterize_signature_annot_2250.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_rasterize_signed_step_2566.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_rasterize_tile_props_slice_2020.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_rechunk_no_shuffle.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_reproject_coverage_2026_05_27.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_reproject_cupy_gate_2564.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_resample.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_resample_coverage_2026_05_27.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_resample_cupy_agg_fallback_2615.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_resample_input_validation_2574.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_resample_irregular_coords_2663.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_resample_signature_annot_2544.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_sieve.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_sieve_gdal_parity.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_sky_view_factor.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_slope.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_surface_distance.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_terrain.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_terrain_metrics.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_validation.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_visibility.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_zonal.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/tests/test_zonal_backend_coverage_2026_05_27.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/visibility.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/worley.py +0 -0
- {xarray_spatial-0.10.4 → xarray_spatial-0.10.6}/xrspatial/zonal.py +0 -0
|
@@ -120,8 +120,8 @@ with path.open() as f:
|
|
|
120
120
|
header = reader.fieldnames
|
|
121
121
|
rows = [r for r in reader if r["module"] != "{module}"]
|
|
122
122
|
def _oneline(v):
|
|
123
|
-
#
|
|
124
|
-
# the record on
|
|
123
|
+
# Git merges these CSVs line by line, so a newline inside a quoted
|
|
124
|
+
# field splits the record on a merge. Force one physical line per
|
|
125
125
|
# record by collapsing embedded newlines to " | ".
|
|
126
126
|
return "" if v is None else str(v).replace("\r\n", " | ").replace("\r", " | ").replace("\n", " | ")
|
|
127
127
|
|
|
@@ -421,11 +421,12 @@ inspect or push them.
|
|
|
421
421
|
per-sweep worktrees via the subagents.
|
|
422
422
|
- The deliverable from the parent is: validated module, dispatch table,
|
|
423
423
|
parallel agents, results table. Keep parent output concise.
|
|
424
|
-
- Each sweep's state CSV
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
the sweep templates
|
|
424
|
+
- Each sweep's state CSV uses git's default 3-way text merge (no
|
|
425
|
+
`merge=union`; see issue #2754). N concurrent state updates that touch
|
|
426
|
+
the same row surface a normal conflict rather than silently unioning
|
|
427
|
+
duplicate rows. Resolve by keeping one row per module (last write per
|
|
428
|
+
row wins), which is the read-update-write semantics the sweep templates
|
|
429
|
+
already use.
|
|
429
430
|
- If a sweep template later changes its state-file schema or its audit
|
|
430
431
|
categories, deep-sweep picks up the change automatically the next time
|
|
431
432
|
it runs, because each subagent re-reads its sweep file on dispatch.
|
|
@@ -67,11 +67,13 @@ slope,2026-03-28,1042,HIGH,1;3,"optional single-line notes"
|
|
|
67
67
|
- `notes` is CSV-quoted; newlines must be flattened to spaces on write so
|
|
68
68
|
every module stays exactly one line.
|
|
69
69
|
|
|
70
|
-
The file
|
|
71
|
-
parallel sweeps
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
70
|
+
The file uses git's default 3-way text merge (no `merge=union`; see
|
|
71
|
+
issue #2754). Two parallel sweeps that touch the CSV surface a normal
|
|
72
|
+
merge conflict rather than silently unioning duplicate rows. Resolve a
|
|
73
|
+
conflict by keeping one row per `module` (latest `last_inspected` wins),
|
|
74
|
+
a single header, and one physical line per record -- or just re-run the
|
|
75
|
+
read-update-write cycle in step 5, which rewrites the whole canonical
|
|
76
|
+
file.
|
|
75
77
|
|
|
76
78
|
## Step 3 -- Score each module
|
|
77
79
|
|
|
@@ -264,8 +266,8 @@ If CUDA_AVAILABLE is false:
|
|
|
264
266
|
}
|
|
265
267
|
|
|
266
268
|
def _oneline(v):
|
|
267
|
-
#
|
|
268
|
-
# the record on
|
|
269
|
+
# Git merges these CSVs line by line, so a newline inside a quoted
|
|
270
|
+
# field splits the record on a merge. Force one physical line per
|
|
269
271
|
# record by collapsing embedded newlines to " | ".
|
|
270
272
|
return "" if v is None else str(v).replace("\r\n", " | ").replace("\r", " | ").replace("\n", " | ")
|
|
271
273
|
|
|
@@ -324,10 +326,11 @@ To reset all tracking: `/sweep-accuracy --reset-state`
|
|
|
324
326
|
- Do NOT modify any source files directly. Subagents handle fixes via /rockout.
|
|
325
327
|
- Keep the output concise -- the table and agent dispatch are the deliverables.
|
|
326
328
|
- If $ARGUMENTS is empty, use defaults: top 3, no category filter, no exclusions.
|
|
327
|
-
- State file (`.claude/sweep-accuracy-state.csv`) is tracked in git
|
|
328
|
-
`merge=union
|
|
329
|
-
|
|
330
|
-
|
|
329
|
+
- State file (`.claude/sweep-accuracy-state.csv`) is tracked in git and uses git's
|
|
330
|
+
default 3-way text merge (no `merge=union`; see issue #2754), so a
|
|
331
|
+
concurrent change surfaces a conflict instead of silently unioning
|
|
332
|
+
duplicate rows. Subagents must `git add` and commit it so the state
|
|
333
|
+
update lands in the PR.
|
|
331
334
|
- For subpackage modules (geotiff, reproject, hydro), the subagent should read
|
|
332
335
|
ALL `.py` files in the subpackage directory, not just `__init__.py`.
|
|
333
336
|
- Only flag patterns that are ACTUALLY present in the code. Do not report
|
|
@@ -62,7 +62,10 @@ module,last_inspected,issue,severity_max,categories_found,notes
|
|
|
62
62
|
slope,2026-05-01,1042,HIGH,1;3,"optional single-line notes"
|
|
63
63
|
```
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
This file uses git's default 3-way text merge (no `merge=union`; see
|
|
66
|
+
issue #2754), so a concurrent change surfaces a normal conflict instead
|
|
67
|
+
of silently unioning duplicate rows. Keep one row per `module`, a single
|
|
68
|
+
header, and one physical line per record when resolving.
|
|
66
69
|
|
|
67
70
|
## Step 3 -- Score each module
|
|
68
71
|
|
|
@@ -239,8 +242,8 @@ If CUDA_AVAILABLE is false:
|
|
|
239
242
|
}
|
|
240
243
|
|
|
241
244
|
def _oneline(v):
|
|
242
|
-
#
|
|
243
|
-
# the record on
|
|
245
|
+
# Git merges these CSVs line by line, so a newline inside a quoted
|
|
246
|
+
# field splits the record on a merge. Force one physical line per
|
|
244
247
|
# record by collapsing embedded newlines to " | ".
|
|
245
248
|
return "" if v is None else str(v).replace("\r\n", " | ").replace("\r", " | ").replace("\n", " | ")
|
|
246
249
|
|
|
@@ -285,7 +288,9 @@ To reset: `/sweep-api-consistency --reset-state`
|
|
|
285
288
|
- If $ARGUMENTS is empty, use defaults: top 3, no category filter, no
|
|
286
289
|
exclusions.
|
|
287
290
|
- State file (`.claude/sweep-api-consistency-state.csv`) is tracked in
|
|
288
|
-
git
|
|
291
|
+
git and uses git's default 3-way text merge (no `merge=union`; see
|
|
292
|
+
issue #2754), so a concurrent change surfaces a conflict instead of
|
|
293
|
+
silently unioning duplicate rows.
|
|
289
294
|
- Renames are breaking. The fix path is a deprecation shim, not a
|
|
290
295
|
hard rename, unless the function has a clearly orphan/private status.
|
|
291
296
|
- False positives are worse than missed issues.
|
|
@@ -68,11 +68,13 @@ slope,2026-05-01,1042,HIGH,1;3,"optional single-line notes"
|
|
|
68
68
|
- `notes` is CSV-quoted; newlines must be flattened to spaces on write so
|
|
69
69
|
every module stays exactly one line.
|
|
70
70
|
|
|
71
|
-
The file
|
|
72
|
-
parallel sweeps
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
71
|
+
The file uses git's default 3-way text merge (no `merge=union`; see
|
|
72
|
+
issue #2754). Two parallel sweeps that touch the CSV surface a normal
|
|
73
|
+
merge conflict rather than silently unioning duplicate rows. Resolve a
|
|
74
|
+
conflict by keeping one row per `module` (latest `last_inspected` wins),
|
|
75
|
+
a single header, and one physical line per record -- or just re-run the
|
|
76
|
+
read-update-write cycle in step 5, which rewrites the whole canonical
|
|
77
|
+
file.
|
|
76
78
|
|
|
77
79
|
## Step 3 -- Score each module
|
|
78
80
|
|
|
@@ -267,8 +269,8 @@ If CUDA_AVAILABLE is false:
|
|
|
267
269
|
}
|
|
268
270
|
|
|
269
271
|
def _oneline(v):
|
|
270
|
-
#
|
|
271
|
-
# the record on
|
|
272
|
+
# Git merges these CSVs line by line, so a newline inside a quoted
|
|
273
|
+
# field splits the record on a merge. Force one physical line per
|
|
272
274
|
# record by collapsing embedded newlines to " | ".
|
|
273
275
|
return "" if v is None else str(v).replace("\r\n", " | ").replace("\r", " | ").replace("\n", " | ")
|
|
274
276
|
|
|
@@ -325,9 +327,10 @@ To reset all tracking: `/sweep-metadata --reset-state`
|
|
|
325
327
|
the deliverables.
|
|
326
328
|
- If $ARGUMENTS is empty, use defaults: top 3, no category filter, no
|
|
327
329
|
exclusions.
|
|
328
|
-
- State file (`.claude/sweep-metadata-state.csv`) is tracked in git
|
|
329
|
-
`merge=union
|
|
330
|
-
|
|
330
|
+
- State file (`.claude/sweep-metadata-state.csv`) is tracked in git and uses
|
|
331
|
+
git's default 3-way text merge (no `merge=union`; see issue #2754), so a
|
|
332
|
+
concurrent change surfaces a conflict instead of silently unioning
|
|
333
|
+
duplicate rows.
|
|
331
334
|
- For subpackage modules (geotiff, reproject, hydro), the subagent should
|
|
332
335
|
read ALL `.py` files in the subpackage directory, not just `__init__.py`.
|
|
333
336
|
- Only flag patterns that are ACTUALLY present in the code.
|
|
@@ -89,11 +89,13 @@ slope,2026-04-15,SAFE,compute-bound,0,,"optional single-line notes"
|
|
|
89
89
|
- `notes` is CSV-quoted; newlines must be flattened to spaces on write so
|
|
90
90
|
every module stays exactly one line.
|
|
91
91
|
|
|
92
|
-
The file
|
|
93
|
-
parallel sweeps
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
92
|
+
The file uses git's default 3-way text merge (no `merge=union`; see
|
|
93
|
+
issue #2754). Two parallel sweeps that touch the CSV surface a normal
|
|
94
|
+
merge conflict rather than silently unioning duplicate rows. Resolve a
|
|
95
|
+
conflict by keeping one row per `module` (latest `last_inspected` wins),
|
|
96
|
+
a single header, and one physical line per record -- or just re-run the
|
|
97
|
+
read-update-write cycle in the agent prompt, which rewrites the whole
|
|
98
|
+
canonical file.
|
|
97
99
|
|
|
98
100
|
### Compute scores
|
|
99
101
|
|
|
@@ -290,8 +292,8 @@ If CUDA_AVAILABLE is false:
|
|
|
290
292
|
}
|
|
291
293
|
|
|
292
294
|
def _oneline(v):
|
|
293
|
-
#
|
|
294
|
-
# the record on
|
|
295
|
+
# Git merges these CSVs line by line, so a newline inside a quoted
|
|
296
|
+
# field splits the record on a merge. Force one physical line per
|
|
295
297
|
# record by collapsing embedded newlines to " | ".
|
|
296
298
|
return "" if v is None else str(v).replace("\r\n", " | ").replace("\r", " | ").replace("\n", " | ")
|
|
297
299
|
|
|
@@ -353,10 +355,11 @@ To reset all tracking: `/sweep-performance --reset-state`
|
|
|
353
355
|
the deliverables.
|
|
354
356
|
- If $ARGUMENTS is empty, use defaults: top 3, no category filter, no
|
|
355
357
|
exclusions.
|
|
356
|
-
- State file (`.claude/sweep-performance-state.csv`) is tracked in git
|
|
357
|
-
`merge=union
|
|
358
|
-
|
|
359
|
-
|
|
358
|
+
- State file (`.claude/sweep-performance-state.csv`) is tracked in git and uses git's
|
|
359
|
+
default 3-way text merge (no `merge=union`; see issue #2754), so a
|
|
360
|
+
concurrent change surfaces a conflict instead of silently unioning
|
|
361
|
+
duplicate rows. Subagents must `git add` and commit it so the state
|
|
362
|
+
update lands in the PR.
|
|
360
363
|
- For subpackage modules (geotiff, reproject, hydro), the subagent reads ALL
|
|
361
364
|
`.py` files in the subpackage directory, not just `__init__.py`.
|
|
362
365
|
- Only flag patterns that are ACTUALLY present in the code. Do not report
|
|
@@ -71,11 +71,13 @@ cost_distance,2026-04-10,1150,HIGH,1;2,,"optional single-line notes"
|
|
|
71
71
|
- `notes` is CSV-quoted; newlines must be flattened to spaces on write so
|
|
72
72
|
every module stays exactly one line.
|
|
73
73
|
|
|
74
|
-
The file
|
|
75
|
-
parallel sweeps
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
74
|
+
The file uses git's default 3-way text merge (no `merge=union`; see
|
|
75
|
+
issue #2754). Two parallel sweeps that touch the CSV surface a normal
|
|
76
|
+
merge conflict rather than silently unioning duplicate rows. Resolve a
|
|
77
|
+
conflict by keeping one row per `module` (latest `last_inspected` wins),
|
|
78
|
+
a single header, and one physical line per record -- or just re-run the
|
|
79
|
+
read-update-write cycle in step 5, which rewrites the whole canonical
|
|
80
|
+
file.
|
|
79
81
|
|
|
80
82
|
## Step 3 -- Score each module
|
|
81
83
|
|
|
@@ -265,8 +267,8 @@ If CUDA_AVAILABLE is false:
|
|
|
265
267
|
}
|
|
266
268
|
|
|
267
269
|
def _oneline(v):
|
|
268
|
-
#
|
|
269
|
-
# the record on
|
|
270
|
+
# Git merges these CSVs line by line, so a newline inside a quoted
|
|
271
|
+
# field splits the record on a merge. Force one physical line per
|
|
270
272
|
# record by collapsing embedded newlines to " | ".
|
|
271
273
|
return "" if v is None else str(v).replace("\r\n", " | ").replace("\r", " | ").replace("\n", " | ")
|
|
272
274
|
|
|
@@ -323,10 +325,11 @@ To reset all tracking: `/sweep-security --reset-state`
|
|
|
323
325
|
- Do NOT modify any source files directly. Subagents handle fixes via /rockout.
|
|
324
326
|
- Keep the output concise -- the table and agent dispatch are the deliverables.
|
|
325
327
|
- If $ARGUMENTS is empty, use defaults: top 3, no category filter, no exclusions.
|
|
326
|
-
- State file (`.claude/sweep-security-state.csv`) is tracked in git
|
|
327
|
-
`merge=union
|
|
328
|
-
|
|
329
|
-
|
|
328
|
+
- State file (`.claude/sweep-security-state.csv`) is tracked in git and uses
|
|
329
|
+
git's default 3-way text merge (no `merge=union`; see issue #2754), so a
|
|
330
|
+
concurrent change surfaces a conflict instead of silently unioning
|
|
331
|
+
duplicate rows. Subagents must `git add` and commit it so the state
|
|
332
|
+
update lands in the PR.
|
|
330
333
|
- For subpackage modules (geotiff, reproject, hydro), the subagent should read
|
|
331
334
|
ALL `.py` files in the subpackage directory, not just `__init__.py`.
|
|
332
335
|
- Only flag patterns that are ACTUALLY present in the code. Do not report
|
|
@@ -58,12 +58,13 @@ slope,2026-05-01,1042,MEDIUM,1;4,"optional single-line notes"
|
|
|
58
58
|
- `notes` is CSV-quoted; newlines must be flattened to spaces on write so
|
|
59
59
|
every module stays exactly one line.
|
|
60
60
|
|
|
61
|
-
The file
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
61
|
+
The file uses git's default 3-way text merge (no `merge=union`; see
|
|
62
|
+
issue #2754). Two parallel sweeps that touch the CSV surface a normal
|
|
63
|
+
merge conflict rather than silently unioning duplicate rows. Resolve a
|
|
64
|
+
conflict by keeping one row per `module` (latest `last_inspected` wins),
|
|
65
|
+
a single header, and one physical line per record -- or just re-run the
|
|
66
|
+
read-update-write cycle in step 5, which rewrites the whole canonical
|
|
67
|
+
file.
|
|
67
68
|
|
|
68
69
|
## Step 3 -- Score each module
|
|
69
70
|
|
|
@@ -302,10 +303,11 @@ To reset all tracking: `/sweep-style --reset-state`
|
|
|
302
303
|
- Do NOT modify any source files directly. Subagents handle fixes via /rockout.
|
|
303
304
|
- Keep the output concise -- the table and agent dispatch are the deliverables.
|
|
304
305
|
- If $ARGUMENTS is empty, use defaults: top 3, no category filter, no exclusions.
|
|
305
|
-
- State file (`.claude/sweep-style-state.csv`) is tracked in git
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
`git add` and commit it so the state
|
|
306
|
+
- State file (`.claude/sweep-style-state.csv`) is tracked in git and uses
|
|
307
|
+
git's default 3-way text merge (no `merge=union`; see issue #2754), so a
|
|
308
|
+
concurrent change surfaces a conflict instead of silently unioning
|
|
309
|
+
duplicate rows. Subagents must `git add` and commit it so the state
|
|
310
|
+
update lands in the PR.
|
|
309
311
|
- For subpackage modules (geotiff, reproject, hydro), the subagent should run
|
|
310
312
|
flake8 + isort across ALL `.py` files in the subpackage directory, not
|
|
311
313
|
just `__init__.py`.
|
|
@@ -63,7 +63,10 @@ module,last_inspected,issue,severity_max,categories_found,notes
|
|
|
63
63
|
slope,2026-05-01,1042,HIGH,1;3,"optional single-line notes"
|
|
64
64
|
```
|
|
65
65
|
|
|
66
|
-
`merge=union
|
|
66
|
+
This file uses git's default 3-way text merge (no `merge=union`; see
|
|
67
|
+
issue #2754), so a concurrent change surfaces a normal conflict instead
|
|
68
|
+
of silently unioning duplicate rows. Keep one row per `module`, a single
|
|
69
|
+
header, and one physical line per record when resolving.
|
|
67
70
|
|
|
68
71
|
## Step 3 -- Score each module
|
|
69
72
|
|
|
@@ -240,8 +243,8 @@ If CUDA_AVAILABLE is false:
|
|
|
240
243
|
}
|
|
241
244
|
|
|
242
245
|
def _oneline(v):
|
|
243
|
-
#
|
|
244
|
-
# the record on
|
|
246
|
+
# Git merges these CSVs line by line, so a newline inside a quoted
|
|
247
|
+
# field splits the record on a merge. Force one physical line per
|
|
245
248
|
# record by collapsing embedded newlines to " | ".
|
|
246
249
|
return "" if v is None else str(v).replace("\r\n", " | ").replace("\r", " | ").replace("\n", " | ")
|
|
247
250
|
|
|
@@ -287,7 +290,9 @@ To reset: `/sweep-test-coverage --reset-state`
|
|
|
287
290
|
- Keep parent output concise.
|
|
288
291
|
- Default: top 3, no filter.
|
|
289
292
|
- State file `.claude/sweep-test-coverage-state.csv` is tracked in git
|
|
290
|
-
|
|
293
|
+
and uses git's default 3-way text merge (no `merge=union`; see issue
|
|
294
|
+
#2754), so a concurrent change surfaces a conflict instead of silently
|
|
295
|
+
unioning duplicate rows.
|
|
291
296
|
- The "fix" is *tests, not source*. If a test reveals a bug, file a
|
|
292
297
|
separate issue — do not change source in this sweep's PRs.
|
|
293
298
|
- False positives are worse than missed issues.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module,last_inspected,issue,severity_max,categories_found,notes
|
|
2
|
+
aspect,2026-05-29,2683,MEDIUM,1,E402+E305 line 38: from xrspatial.geodesic import block sat below _geodesic_cuda_dims; moved up with top-of-file imports. E501 lines 219/263: wrapped two _run_gpu_geodesic_aspect kernel-launch calls (101/109 chars). Cat 4 isort reviewed but NOT applied: slope.py/curvature.py use one-import-per-line for xrspatial.utils so raw isort would make aspect inconsistent. Cat 2/3/5 grep clean. PR #2740. 82 aspect+geodesic tests pass.
|
|
3
|
+
contour,2026-05-29,2698,HIGH,3,"F821 line 557: contours() return annotation ""gpd.GeoDataFrame"" referenced gpd not bound at module scope (only imported inside _to_geopandas). Fixed via TYPE_CHECKING-guarded import geopandas as gpd, matching polygonize.py. No runtime change; geopandas stays optional. isort clean. Cat 1/2/4/5 clean. 24 contour tests pass. PR open."
|
|
4
|
+
focal,2026-05-29,2731,HIGH,3;4;5,"F401 not_implemented_func (import line 36, unused, not re-exported). isort: stdlib reorder (import math before from-imports), dropped stray blank lines in import groups, alphabetised+rewrapped convolution/utils from-imports, moved dataset_support import into order. Cat 5: mutable default excludes=[np.nan] in mean() (line 238) -> None sentinel, resolved to [np.nan] in body; never mutated so behaviour preserved; regression test test_mean_default_excludes_does_not_leak added. Cat 1/2 clean. 115 focal tests pass. PR pending."
|
|
5
|
+
geotiff,2026-05-27,2481,HIGH,1;3;4,"Bundled 387 flake8 + ~30 isort fixes since #2285/#2430. F401 x9, F811 x6, F841 x3. E501 x250 (mostly wrapped, 3 file-scope imports keep noqa: E402+E501). E252 x62, blank-line cluster, E128/E127 indents. importorskip imports use # noqa: E402. Cat 5 grep clean."
|
|
6
|
+
hydro-d8,2026-05-29,2705,HIGH,1;3;4,"flake8+isort over the 13 D8 files only (dinf/mfd out of scope). Cat 3 HIGH: F401 x2 (flow_length_d8 function-local _compute_accum_seeds never called; snap_pour_point_d8 module-level cuda_args unused) - both confirmed dead, no re-export. Cat 1: E127/E128 continuation-indent x90 (mostly multi-line def signatures); E302/E303 blank-line cluster in watershed_d8; E501 x4 (flow_path_d8 + snap_pour_point_d8, wrapped ternaries). Cat 4: isort import-block reordering on all 13 files. No Cat 2 (W-codes), no Cat 5 (grep clean: no bare except, mutable defaults, ==None/==True, or shadowed builtins). flake8+isort clean after fix; 385 D8 tests pass. flow_direction_d8 needed manual blank-line placement to satisfy both isort and E302."
|
|
7
|
+
interpolate-kriging,2026-06-04,2916,MEDIUM,1;4,"flake8 E128 x2: continuation-line under-indent at the _chunk_var kriging-predict calls in _kriging_dask_numpy (L234) and _kriging_dask_cupy (L324); re-indented to visual-indent column. Cat 4 isort: 5-line from xrspatial.utils (...) block collapses to one 88-char line under line_length=100. Cat 2/3/5 grep clean (no W-codes, F-codes, bare except, mutable defaults, ==None/True, or shadowed builtins). flake8+isort clean after fix; 14 kriging tests pass. PR open."
|
|
8
|
+
polygonize,2026-05-27,2534,HIGH,1;3;4,"F401 line 58 (is_cupy_array unused, not re-exported). E127 lines 83/88 (overload continuation indent in generated_jit). isort: 5-line .utils import block collapses to one line at 100-char limit. Cat 2 clean. Cat 5 grep clean."
|
|
9
|
+
proximity,2026-05-29,2725,HIGH,1;3;4;5,"F841 line 1274 original_chunks dead local in unbounded dask+cupy branch (refactor leftover). Cat 5 mutable default target_values: list = [] in proximity/allocation/direction -> None sentinel, normalized to [] in body (never mutated, behaviour preserved). E128 line 291 np.where continuation under-indent in _vectorized_calc_direction. isort: re-sorted xrspatial import block + blank line after inline import cupy as cp. flake8+isort clean after fix; 69 proximity tests pass + new parametrized regression test. Pre-existing E127 (test_proximity.py 726/752) + test-file isort drift left untouched (out of module scope)."
|
|
10
|
+
rasterize,2026-05-27,2503,HIGH,1;3,F401 line 15 + F811 line 1193 (paired: local import warnings shadowed unused module-level import); E306 line 1775 (nested @cuda.jit). isort clean. Cat 5 grep clean. Fix in PR #2507.
|
|
11
|
+
reproject,2026-06-08,3049,HIGH,1;2;3;4,"flake8 baseline 57 across the 10 reproject files. Cat 3 HIGH: F401 'numpy as np' unused in _projections_cuda.py; F841 nine dead locals in _projections.py (e12, m2 chained-assign, phi_approx, a, two half_e, t_90, south_f, Q) - all assigned-never-read, math unchanged. Cat 1: E702 semicolon statements split (_projections.py + _projections_cuda.py Clenshaw loops); E127/E128 continuation indents fixed across both files; E302 blank line added in _itrf.py and _projections.py; E501 x3 wrapped. Two dense polynomial-coefficient continuation lines in _projections.py keep noqa: E128 (visual-indent alignment hits col 60 -> E501). Cat 2: W391 trailing blank removed from _projections.py. Cat 4 isort: _grid.py/_merge.py blank-line trim + deferred-import re-sort in _projections_cuda.py. Cat 5 grep clean (d: dict annotation is not a shadow; no bare except / mutable defaults / ==None,True,False). flake8+isort clean after fix; 435 reproject tests pass on numpy/dask/cupy. PR open."
|
|
12
|
+
resample,2026-05-27,2543,MEDIUM,4,isort drift only: 4 multi-line parenthesised imports collapsed to single/one-per-line under line_length=100 (top-of-file scipy.ndimage + xrspatial.utils; local cupyx imports in _nan_aware_interp_cupy and _interp_block_cupy); two blank-line nits after import math in _run_dask_numpy/_run_dask_cupy. flake8 clean. Cat 5 grep clean. 169 resample tests pass.
|
|
13
|
+
slope,2026-05-29,2685,HIGH,1;3;4,"F401 line 26 (VALID_BOUNDARY_MODES unused, not re-exported). E402+E305 line 48 (geodesic import block sat after _geodesic_cuda_dims; moved up to top-of-file imports). E501 line 260 (cupy kernel launch, 108 chars) wrapped. isort: consolidated/regrouped xrspatial imports (dataset_support, geodesic, utils). Cat 2 clean. Cat 5 grep clean. 41 slope + 21 geodesic_slope tests pass."
|
|
14
|
+
viewshed,2026-05-29,2690,HIGH,1;4;5,"flake8 E127 x2 (L2013-2014 _viewshed_distance_sweep sig); isort .utils import reflow; shadowed builtin id->node_id (L1409,1474). Fixed via /rockout PR. No behavioural change."
|
|
15
|
+
zonal,2026-05-27,2522,HIGH,1;3;4,"F401 not_implemented_func (line 42, only present on import line). E501 line 455 (dd.concat one-liner, 117 chars) wrapped across 3 lines. isort: consolidated xrspatial.utils block (merged has_dask_array, dropped not_implemented_func, alphabetised, trimmed extra blank line). Cat 5 grep clean. 125 zonal tests pass."
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module,last_inspected,issue,severity_max,categories_found,notes
|
|
2
|
+
aspect,2026-06-02,2742;2829,HIGH,3;4,"#2742: degenerate shapes (1x1/Nx1/1xN) + geodesic boundary modes; tests added all 4 backends, GPU-validated. #2829: northness/eastness method='geodesic' branch was untested (planar only); added correctness (diagonal surface where planar!=geodesic) + 4-backend parity, GPU-validated. all-NaN planar/geodesic returns all-NaN (correct). Inf input -> silent -1/flat on spike cell: possible source bug, out of scope for test-only sweep, not filed. Dedup: rectangular-cell oracle #2781 + cell-size #2780 already merged, not duplicated."
|
|
3
|
+
contour,2026-06-08,2704;2710;3044,MEDIUM,1;2,"Pass 2 (2026-06-08, deep-sweep test-coverage): re-swept on a CUDA host. Verified issue #2704 is CLOSED (fixed 2026-06-01 via #2749, kernel now uses np.isfinite at contour.py:73-74); the two prior xfail(strict) #2704 pins were already flipped to plain passing assertions in TestInfHandling (test_inf_corner_no_nan_coords / test_neg_inf_corner_no_nan_coords) -- no stale xfail remained. Found one MEDIUM Cat 1+2 gap: no cross-backend parity test fed NaN input -- TestBackendEquivalence uses elevation_raster_no_nans and test_partial_nan is numpy-only, so numpy-interior NaN-skip vs dask NaN-halo (da.overlap) parity at chunk edges was unpinned. Filed #3044, added TestNaNBackendParity (3 tests: dask, cupy, dask+cupy each assert _segments_by_level equality vs numpy on a partial-NaN ramp with a NaN edge row + interior NaN cell inside a non-edge chunk). All 3 RAN and PASSED on a CUDA host; full file 89 passed, 0 skipped. Probed and verified now-resolved: the prior-pass LOW items are no longer real gaps -- the levels=None all-NaN early-return IS asserted (result==[]) on all 4 backends (numpy L148/dask L163/cupy L178/dask+cupy L194) plus geopandas (test_geopandas_all_nan_keeps_crs). LOW (documented, NOT fixed): non-square cellsize (res[0]!=res[1]) still never exercised -- all tests use create_test_raster res (0.5,0.5); probed live that anisotropic coords transform correctly (y scaled 2.0, x scaled 0.5 -> crossing x=1.25, y spans 0..8), works, so it is a LOW coverage gap not a bug. Cat 3 1x1/Nx1/1xN remain rejected by the >=2x2 guard (tested). Test-only PR for #3044; contour.py untouched. | Pass 1 (2026-05-29): added TestInfHandling, TestCRSPropagation, TestNonDefaultDims to test_contour.py (5 passed + 2 strict-xfail on a CUDA host; full file 29 passed, 2 xfailed). All four backends (numpy / cupy / dask+numpy / dask+cupy) were already exercised with cross-backend segment-equality assertions (TestBackendEquivalence), and ran green locally on the CUDA host -- Cat 1 well covered, no new backend tests needed. Cat 2 HIGH (Inf): the marching-squares NaN-skip guard at contour.py:67 uses x!=x which does not catch infinity, so a finite level near a +/-inf corner leaks NaN coordinates into the output. Filed source bug #2704 and added two xfail(strict=True) tests pinning it (+inf and -inf) plus test_inf_far_level_no_crossing covering the safe path where the inf quad classifies as all-above (idx 15) and is skipped before any interpolation. Cat 5 MEDIUM: no test asserted gdf.crs propagation from agg.attrs['crs'] (contour.py:660) -- added test_geopandas_crs_from_attrs (to_epsg()==5070) + test_geopandas_no_crs_attr. Cat 5 MEDIUM: the index-to-coordinate transform (contour.py:644-654) reads agg.dims[0]/[1] coords but no test used non-y/x dims -- added test_lat_lon_dims_coordinate_transform + test_lat_lon_matches_yx_equivalent. PR #2710 (test-only, source untouched). LOW (documented, not fixed): non-square cellsize (cellsize_x != cellsize_y) never exercised -- all tests use res (0.5,0.5); levels=None early-return on all-NaN/all-equal works (probed) but only the explicit-levels all-NaN path is asserted. Cat 3 1x1/Nx1/1xN are rejected by the >=2x2 validation guard and that rejection is already tested (test_too_small, test_minimum_raster)."
|
|
4
|
+
focal,2026-05-29,2732,HIGH,1,"Pass (2026-05-29): added test_hotspots_dask_cupy to test_focal.py closing Cat 1 HIGH backend-coverage gap. hotspots() registers dask_cupy_func=_hotspots_dask_cupy (focal.py L1414) but no test invoked it, while mean/apply/focal_stats each have a dedicated dask+cupy test. New test compares dask+cupy vs numpy on chunk interior (matches test_apply_dask_cupy/test_focal_stats_dask_cupy style). RUN on CUDA host: passes; spy confirmed routing through _hotspots_dask_cupy; path matches numpy exactly so no source fix needed. LOW (documented not fixed): Inf/-Inf inputs untested across focal funcs; 1x1 raster not explicitly tested for mean/apply/hotspots (focal_stats 1x1 covered by test_variety_single_cell). Issue #2732."
|
|
5
|
+
geotiff,2026-06-06,2984,MEDIUM,1;3,"Pass 20 (2026-06-06, deep-sweep test-coverage): filed #2984 and added test_writer.py degenerate-shape GPU write coverage (Cat 1 backend + Cat 3 geometric edge). Read side already covers 1x1/1xN/Nx1 on all 4 backends (read/test_degenerate_shapes.py) and the dask streaming writer covers them (integration/test_dask_pipeline.py); the GPU write path was the gap (smallest shape in gpu/test_writer.py was 2x2). Added test_write_geotiff_gpu_degenerate_round_trip (1x1/1xN/Nx1 x none/deflate) + test_to_geotiff_dask_gpu_degenerate_round_trip (dask+cupy via gpu=True). 9 new tests RUN+passing on a CUDA host. Verified paths work first (not a source bug); transform supplied explicitly via attrs. Wider tree audit (~92k test LOC vs ~33k source): rioxarray-compat (#2961), bbox NaN/Inf/rotated, 8-backend parity matrix, codec round-trips already covered -- no other real gaps. | Pass (2026-06-05 test-coverage sweep): mature module (~31k src / ~124k test LOC, 9 test dirs). Exhaustive existing coverage -- parity/test_backend_matrix.py runs all 4 backends + VRT + HTTP + fsspec; golden_corpus full-manifest parity; read_rioxarray_compat_2961 covers masked/mask_and_scale/parse_coordinates/default_name on eager+dask. Cat1+Cat3 gap found (MEDIUM): degenerate-shape READS (1x1/1xN/Nx1) were tested only on the eager numpy reader (test_edge_cases.py) and the dask streaming WRITE path (integration/test_dask_pipeline.py); the windowed dask READ (chunks=) and GPU READ (gpu=True) on a single-pixel dimension were never exercised (smallest dask-read source in read/test_tiling is 8x8/2x32, parity fixtures 32x32/64x64). Probed: paths work today, no source bug -- pure coverage gap. Added read/test_degenerate_shapes.py (18 tests): dask read x{chunks 1,3,4} x{1x1,1xN,Nx1} + coord/transform/crs parity + GPU read + dask+gpu read. GPU cells RAN and PASSED on this CUDA host (grid-size-1 launch validated). Fixture supplies explicit attrs['transform'] (writer cannot infer pixel size from a 1-element coord axis). Branch deep-sweep-test-coverage-geotiff-degenerate-read-01. NOTE: pre-existing union-merge CRLF/duplicate-record corruption in this CSV left untouched -- appended one clean record; DictReader last-write-wins picks this one."
|
|
6
|
+
idw,2026-06-04,2919,HIGH,1;4,"cupy/dask+cupy backends untested (Cat1 HIGH); GPU k-reject error path untested (Cat4 MED). Added 6 GPU tests, validated on CUDA host. Inf-in-points (Cat2) and attrs-preservation (Cat5) are LOW, documented not fixed."
|
|
7
|
+
interpolate-kriging,2026-06-04,2920;2921,HIGH,1;2;3;4;5,"Single public fn kriging(); all 4 backends already had cross-backend parity tests (numpy/cupy/dask+numpy/dask+cupy) incl. cupy & dask+cupy variance -- ran green on CUDA host. Gaps closed (test-only, #2921): Cat1 dask+numpy return_variance branch (_chunk_var) was untested -> added test_dask_return_variance_matches_numpy (atol=1e-12, var ~1e-14). Cat4 nlags only default(15) tested -> added non-default nlags=5 + invalid paths (nlags=0/-1 ValueError, nlags=2.5 TypeError). Cat2/3 two-point <3-lag-bins UserWarning branch -> test_two_point_warns_few_lag_bins. Cat2 all-NaN kriging input -> test_kriging_all_nan_points (only idw covered before). Cat5 output metadata (coords/dims/attrs/name) untested -> added test_output_metadata. Single-point kriging CRASHES (zero-size array reduction in _experimental_variogram, N=1) -- real source bug filed #2920; added xfail(strict, raises=ValueError) test_single_point documenting expected graceful behavior; source fix left to #2920 (test-only PR). LOW/not filed: singular-matrix K_inv-is-None all-NaN branch is defensive and unreachable via public API. GPU-validated."
|
|
8
|
+
interpolate_spline,2026-06-04,,HIGH,1;3;5,scope=spline-only; cupy+dask_cupy spline backends untested (_tps_cuda_kernel) | n==2 affine branch + metadata untested | added 4 tests to TestSpline all pass on CUDA host | issue-create denied by classifier no GH issue
|
|
9
|
+
polygonize,2026-05-29,2623,MEDIUM,4,"Pass 3 (2026-05-29): added test_polygonize_mask_dtype_coverage_2026_05_29.py (41 passed, 8 xfailed on a CUDA host). Closes Cat 4 MEDIUM parameter-coverage gap: mask= is documented to accept bool/integer/float values but every prior test passed only a bool mask. Integer masks (int32/int64) now pinned against the same-backend bool-mask output on all four backends x both raster dtypes x connectivity 4/8; float-mask-on-integer-raster also pinned. Each backend is compared to its OWN bool reference to isolate mask-dtype from the unrelated numpy-vs-dask hole-vs-single-ring representation difference. Mutation (drop the not-mask[ij] exclusion in _calculate_regions) flips 11 tests red incl. the pixel-exclusion sanity anchor; clean md5 restore. Surfaced source bug #2623: a float-dtype mask on a float-dtype raster raises TypeError at polygonize.py:918 (mask & nan_mask; bitwise_and undefined for float&bool; cupy/dask route floats through _polygonize_numpy so they crash too; int masks coerce fine). 8 float-mask cases marked xfail(strict, raises=TypeError) referencing #2623. Test-only; source untouched. | Pass 2 (2026-05-27): added test_polygonize_atol_rtol_backend_coverage_2026_05_27.py with 15 tests, all passing on a CUDA host. Closes Cat 4 MEDIUM parameter-coverage gap on atol/rtol forwarding through the cupy and dask+cupy backends. atol/rtol were exposed by #2173 / #2194 and thread through _polygonize_cupy (polygonize.py:808) and _polygonize_dask (polygonize.py:1719); the dask path further plumbs them into dask.delayed(_polygonize_chunk)(...) at lines 1748-1754 and into _bucket_key_for_value for cross-chunk merge bucketing at lines 1757-1758. Pre-existing tests covered non-default atol/rtol only on numpy and dask+numpy. The cupy and dask+cupy dispatchers were untested -- a regression dropping the kwargs there would silently change the float polygon count and would not be caught. Same dispatcher-silently-drops-kwarg pattern fixed by #1561 / #1605 / #1685 / #1810 / #1974 on adjacent GeoTIFF surfaces. 15 tests: cupy strict-equality + default-tolerance pin on _REPRO_2173, dask+cupy strict-equality single-chunk + multi-chunk (engages cross-chunk merge bucket) + default-tolerance multi-chunk pin, cupy intermediate-atol small/large pair, dask+cupy intermediate-atol single/multi-chunk small + single-chunk large, cupy integer atol-ignored matrix, dask+cupy integer atol-ignored single-chunk + multi-chunk, cupy rtol-only large/small matrix. Mutation against _polygonize_cupy float branch (drop atol/rtol kwargs in the _polygonize_numpy forward call at polygonize.py:823-825) flips 3 of 5 cupy tests red; mutation against dask.delayed(_polygonize_chunk)(...) at polygonize.py:1748-1754 (drop atol, rtol args) flips 2 of 6 dask+cupy tests red. Confirmed clean restore via md5sum. Source untouched. Filed issue #2537 (test-only). Cat 4 MEDIUM (parameter coverage on cupy + dask+cupy atol/rtol forwarding). Pass 1 (2026-05-19): added test_polygonize_coverage_2026_05_19.py with 58 tests, all passing on a CUDA host. Closes Cat 3 HIGH 1x1 / Nx1 single-column geometric gaps (Nx1 exercises the nx==1 padding path at polygonize.py:565 and the cupy nx==1 numpy-fallback at polygonize.py:671), Cat 3 MEDIUM 1xN single-row and all-equal-value rasters on all four backends. Closes Cat 2 HIGH NaN parity for cupy + dask+cupy (numpy/dask were already covered by test_polygonize_nan_pixels_excluded*), Cat 2 MEDIUM all-NaN raster on all four backends, Cat 2 HIGH +/-Inf pins on all four backends. Filed source-bug issue #2155: numpy/dask/dask+cupy backends silently absorb Inf cells into adjacent finite polygons because _is_close reduces abs(inf-inf) to nan; cupy backend handles Inf correctly. Pins lock the asymmetric behaviour so the fix is visible. Closes Cat 1 MEDIUM simplify_tolerance + mask= parity gaps on dask+cupy backend (numpy/cupy/dask were already covered). Closes Cat 4 MEDIUM column_name non-default value across geopandas/spatialpandas/geojson return types and Cat 4 MEDIUM validation error paths (bad connectivity, bad transform length, mask shape mismatch, mask underlying-type mismatch). Cat 5 N/A: polygonize returns lists/dataframes, not a DataArray with attrs to propagate."
|
|
10
|
+
proximity,2026-06-02,2692,HIGH,1;2;3;4;5,"Pass 2 (2026-06-02): added 18 tests to test_proximity.py closing the two MEDIUM gaps Pass 1 left open, all RUN and passing on a CUDA host across numpy/cupy/dask+numpy/dask+cupy (15 cross-backend + 3 error-path). Source untouched. Cat 4 MEDIUM (error path): _process raises ValueError when raster.dims != (y, x) (proximity.py:1043) but no test exercised the swapped x/y guard; test_wrong_dim_order_raises pins it for proximity/allocation/direction. Cat 2 MEDIUM (all-NaN input): Pass 1 noted all-NaN/all-zero on eager numpy+cupy was unpinned; test_all_nan_raster_all_nan_output pins an all-NaN 6x6 raster -> all-NaN float32 output on all four backends x three functions. Remaining LOW (documented): invalid distance_metric string silently falls back to EUCLIDEAN (proximity.py:1049-1051). || PREVIOUS: Pass 1 (2026-05-29): added 65 tests to test_proximity.py closing three coverage gaps, all RUN and passing on a CUDA host (numpy/cupy/dask+numpy/dask+cupy). Issue #2692, PR opened. Source untouched. Cat 3 HIGH: degenerate raster shapes (1x1 single pixel, Nx1 column strip, 1xN row strip) had zero coverage for proximity/allocation/direction on any backend; they stress the line-sweep kernel boundaries (_process_proximity_line) and the GPU brute-force kernel grid sizing (_proximity_cuda_kernel via cuda_args). Pinned all three shapes x three functions x four backends against hand-checked expected values; mutation of a pinned direction expectation confirms teeth. Cat 1/4 HIGH: allocation and direction only ran EUCLIDEAN across backends; MANHATTAN and GREAT_CIRCLE were cross-backend-tested for proximity only. Pinned both metrics x two functions x four backends against the numpy baseline (all match). Cat 5 MEDIUM: no test set non-empty res/crs attrs so the attrs-preservation assertion in general_output_checks compared two empty dicts. proximity reads attrs['res'] via get_dataarray_resolution for bounded-dask chunk padding, so added attrs round-trip tests on four backends plus a bounded-dask test where a res attr matching the coordinate spacing must equal the numpy baseline. A res attr that lies about the spacing mis-sizes the map_overlap depth; source fragility, not a test gap, left for a separate accuracy issue. Cat 2 (NaN/Inf input) already covered by the shared test_raster fixture (embeds np.inf and np.nan, runs on four backends). Remaining LOW: all-NaN / all-zero input on eager numpy+cupy not directly pinned."
|
|
11
|
+
rasterize,2026-05-29,2614,MEDIUM,4,"Pass 4 (2026-05-29): added test_rasterize_coverage_2026_05_29.py with 11 tests, all passing (pure-Python validation paths, no CUDA needed); filed issue #2614 and opened a test-only PR. Closes Cat 4 MEDIUM error-path gaps that all three prior passes left untouched. (1) Partial width/height: the (width is None) != (height is None) guard in rasterize() raises ValueError naming the given and missing dimension, documented in the docstring, but neither the width-only nor height-only branch had a test; pin both directions plus the width-only+resolution case proving the guard fires before the resolution branch. (2) resolution= input type/shape validation: the type/shape branches (non-number/non-sequence string|dict; wrong-ndim numpy array; wrong-length sequence len 1|3|4; non-numeric elements) had no coverage -- test_rasterize.py's test_invalid_resolution_scalar/tuple only exercise non-finite/non-positive VALUES, not these type/shape guards, so a regression loosening or reordering them would ship silently; pin each branch to its message plus a positive control that a 1-D length-2 numpy array is still accepted. Source untouched."
|
|
12
|
+
reproject,2026-06-08,2618;3050,HIGH,3;4,"Pass 2026-06-08 (deep-sweep test-coverage): #3050 closes the one live gap found this pass. reproject()'s dask+cupy backend was parity-tested only with resampling='cubic' (TestCupyPyprojFallbackParity::test_projected_to_projected_dask_cupy_match); nearest/bilinear were covered on numpy (end-to-end) and eager cupy (parametrized test_projected_to_projected_numpy_cupy_match) but never on the dask+cupy chunk-assembly path. Parametrized that test over ['nearest','bilinear','cubic']; all 3 RUN+PASS on a CUDA host. Cat 4 MEDIUM (resampling-mode parameter coverage on the dask+cupy backend). Test-only, source untouched. Re-confirmed _merge.merge() has NO genuine cupy/dask+cupy backend (_merge_inmemory/_merge_dask use _merge_arrays_numpy + raster.values; _merge_arrays_cupy is imported but never dispatched = dead code, not a test gap) matching the prior pass's observation. reproject() otherwise saturated across all 4 backends, NaN/Inf/all-NaN, degenerate shapes, metadata, vertical, bounds_policy, integer nodata. LOW (documented, not filed): dask+cupy resampling-mode parity is the only per-mode-per-backend cell that had been missing. || PREVIOUS: Pass 2026-05-29: reproject already has a deep suite (369 tests in test_reproject.py + coverage/gate files) covering all 4 backends, NaN/Inf/all-NaN/all-Inf, 1x1/2x2, metadata, vertical shift, bounds_policy x backends, integer nodata x backends. Gaps found: Cat 3 HIGH single-row (1xN) and single-col (Nx1) strip rasters never tested (hit size<2 branch of _validate_regular_axis + degenerate resampling axis); Cat 3 MEDIUM constant-value/zero-gradient raster never reprojected. Added TestDegenerateShapeReproject (12 tests): 1xN+Nx1 strips x numpy/dask/cupy/dask+cupy, constant raster numpy value-preservation + cross-backend parity. All 12 executed and passed on a CUDA host. Test-only, no source change (#2618). LOW (documented only): _merge._merge_arrays_cupy imported but never called by merge() (host-bounces via _merge_arrays_numpy) - dead-code source observation not a test gap; non-square cellsize reproject only covered via resolution-tuple validation errors not a successful anisotropic run."
|
|
13
|
+
resample,2026-05-29,2547;2615,HIGH,1;2;3;5,"Pass 2 (2026-05-29): added test_resample_cupy_agg_fallback_2615.py (6 tests, all passing on CUDA host). Closes Cat 1 MEDIUM backend-coverage gap: the cupy eager aggregate CPU fallback for average/min/max at a NON-integer downsample factor (_run_cupy fy==int(fy) branch in resample.py ~L957-973) was never exercised; existing TestCuPyParity used 12x12 scale 0.5 (integer factor 2 -> GPU reshape path) and only median/mode hit the host fallback. New tests use 10x10 scale 0.3 (factor 3.33) for average/min/max parity vs numpy plus a NaN-masked variant. Issue #2615. Module is otherwise very thoroughly covered (test_resample.py + 3 supplementary files); no remaining HIGH gaps found. Pass 1 (2026-05-27): added test_resample_coverage_2026_05_27.py with 70 tests (68 passing, 2 skipped). Closes Cat 3 HIGH Nx1 single-column gap across numpy/cupy/dask+numpy/dask+cupy x 8 methods (nearest/bilinear/cubic/average/min/max/median/mode) plus Nx1 upsample-nearest parity and Nx1 cross-backend aggregate parity. Closes Cat 2 MEDIUM NaN-parity gap on cupy and dask+cupy (existing TestCuPyParity/TestDaskCuPyParity used random data without NaN; the weight-mask gate and spline-prepad had no GPU NaN coverage). Closes Cat 3 MEDIUM all-equal-value raster across 8 methods (downsample) and 3 interp methods (upsample) plus a constant-with-NaN aggregate variant. Closes Cat 5 MEDIUM non-default dim-name propagation: lat/lon, latitude/longitude, and (channel, lat, lon) 3D round-trip without being renamed to y/x; per-dim attrs (units) preserved. Closes Cat 3 MEDIUM empty-raster behaviour pin: 0-row and 0-col rasters raise (currently IndexError) -- contract covered. Filed source-bug issue #2547: cubic on dask backends fails for Nx1 / arrays smaller than depth=16; the 2 skipped tests in this file gate on that fix landing. Source untouched."
|
|
14
|
+
slope,2026-05-29,2697,MEDIUM,3,"PR #2703: added degenerate-shape tests (1x1/1xN/Nx1) for all 4 planar backends + geodesic; no live bug, pins all-NaN+shape contract. CUDA host: cupy/dask+cupy ran. Backend/NaN/param/metadata coverage already complete."
|
|
15
|
+
viewshed,2026-05-29,2693,HIGH,1;2;5,"Pass 1 (2026-05-29): added 4 new test groups to test_viewshed.py (13 new tests + 1 xfail, all passing/xfailing on a CUDA+RTX host). Closes Cat 1 HIGH backend-coverage gap: the dask+cupy dispatch path in _viewshed_dask (Tier B) and _viewshed_windowed (max_distance) was registered but never invoked by any test -- added test_viewshed_dask_cupy_flat (analytical-angle parity, atol 0.03) and test_viewshed_dask_cupy_max_distance (windowed GPU run; observer cell 180, corners INVISIBLE). Both use non-zero flat terrain (1.3) because the RTX mesh builder rejects an all-zero raster (#1378). Closes Cat 5 HIGH metadata-preservation gap: only the numpy test_viewshed called general_output_checks; the cupy/dask/dask+cupy and max_distance paths never asserted attrs/coords/dims/array-type preservation. Added parametrised test_viewshed_metadata_preserved over {numpy,cupy,dask+numpy,dask+cupy} x {full, max_distance=2.0}: asserts attrs==, dims==, shape==, x/y coords allclose; runs general_output_checks (full type parity) for all backends except dask+cupy. Closes Cat 2 HIGH NaN-input gap and surfaced source bug #2693: viewshed on a numpy raster crashes with ValueError 'node not found' from _delete_from_tree when a NaN cell sits at certain positions (e.g. (2,4) in a 5x5 with observer at (2,2)), while NaN at (1,1)/(0,0)/(4,4) runs fine. Added test_viewshed_nan_input_supported_positions (parametrised working positions, asserts observer=180 and NaN cell is INVISIBLE/NaN) plus test_viewshed_nan_input_crashing_position (xfail strict, raises, links #2693). Noted but NOT fixed (source change out of scope for test sweep): the dask+cupy backend does not preserve the cupy backing -- _viewshed_dask computes then rewraps via da.from_array(result_np), so the output computes to numpy not cupy; general_output_checks is skipped for dask+cupy for that reason (candidate for the metadata/backend-parity sweep). LOW (documented only): non-square cell sizes; 1x1 and 1xN geometry covered behaviourally by probing (run without error). Test-only PR; viewshed.py untouched."
|
|
16
|
+
zonal,2026-05-29,2619,MEDIUM,1,"Pass 2 (2026-05-29): one Cat 1 MEDIUM backend-coverage gap remained after pass 1 -- 3D crosstab on cupy / dask+cupy. The 3D GPU paths (_crosstab_cupy / _crosstab_dask_cupy with a 3D categorical values array, layer=, agg='count') were reachable and correct but untested; the existing 3D crosstab tests (test_crosstab_3d_count, test_crosstab_3d_agg_method, test_nodata_values_crosstab_3d) only parametrize numpy / dask+numpy. Added 3 parity tests to test_zonal_backend_coverage_2026_05_27.py (test_crosstab_3d_count_cupy_matches_numpy, test_crosstab_3d_count_dask_cupy_matches_numpy, test_crosstab_3d_nodata_cupy_matches_numpy) asserting cupy and dask+cupy results match numpy for agg='count' including a nodata_values case. All passed live on a CUDA host. Issue #2619, PR #2625. Test-only, no source change. Remaining LOW (documented, not fixed): get_full_extent has no direct unit test (exercised indirectly via suggest_zonal_canvas); non-square cellsize handling not exercised. Pass 1 (2026-05-27): added test_zonal_backend_coverage_2026_05_27.py with 32 tests, all passing on a CUDA host. Closes Cat 1 HIGH backend-coverage gaps: crosstab cupy + dask+cupy (_crosstab_cupy / _crosstab_dask_cupy were dispatched but never invoked by tests), regions cupy + dask+cupy (_regions_cupy via cupyx.scipy.ndimage + _regions_dask_cupy), trim dask+numpy + cupy + dask+cupy (_trim_bounds_dask isnan path and cupy data.get() path), crop dask+numpy + cupy + dask+cupy (_crop_bounds_dask + cupy data.get() path), apply 3D cupy + dask+cupy (per-layer kernel launch over the third axis in _apply_cupy and _apply_dask_cupy). Existing test_zonal.py covered only numpy + dask+numpy for crosstab/regions/trim/crop and 2D-only for cupy apply. Closes Cat 3 MEDIUM 1x1 / 1xN / Nx1 strip edge cases for trim, crop, and regions. Closes Cat 4 LOW pins: regions(neighborhood=6) ValueError, suggest_zonal_canvas(crs='Geographic') aspect-ratio pin and invalid-crs KeyError, crosstab cupy zone_ids/cat_ids filter, crosstab cupy agg='percentage'. Closes Cat 5 MEDIUM: regions coords/attrs propagation across numpy + dask+numpy, trim/crop name='trim'/'crop' default + attrs preservation. Also pins the documented numpy-vs-dask trim asymmetry on NaN sentinel (numpy _trim does equality which never matches NaN; dask _trim_bounds_dask has dedicated isnan branch). Mutation against the cupy.asnumpy() conversion in _crosstab_cupy flipped test_crosstab_cupy_matches_numpy red. Source untouched."
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Verify that all implemented backends produce consistent results for a given function or set of functions"
|
|
3
|
+
globs: "*.py"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Backend Parity: Cross-Backend Consistency Audit
|
|
7
|
+
|
|
8
|
+
Verify that all implemented backends produce consistent results for a given function or set of functions.
|
|
9
|
+
|
|
10
|
+
## Step 1 -- Identify targets
|
|
11
|
+
|
|
12
|
+
1. If the prompt names specific functions (e.g. `slope`, `aspect`), use those.
|
|
13
|
+
2. If the prompt names a category (e.g. `hydrology`, `surface`, `focal`), read `README.md` to find all functions in that category.
|
|
14
|
+
3. If the prompt is empty, scan the full feature matrix in `README.md` and test every function that claims support for 2+ backends.
|
|
15
|
+
4. For each function, read its source file and find the `ArrayTypeFunctionMapping` call to determine which backends are actually implemented.
|
|
16
|
+
|
|
17
|
+
## Step 2 -- Build test inputs
|
|
18
|
+
|
|
19
|
+
For each target function, create test rasters at three scales:
|
|
20
|
+
|
|
21
|
+
| Name | Size | Purpose |
|
|
22
|
+
|---------|---------|--------------------------------------------------|
|
|
23
|
+
| tiny | 8x6 | Fast, easy to inspect cell-by-cell |
|
|
24
|
+
| medium | 64x64 | Catches chunk-boundary artifacts in dask |
|
|
25
|
+
| large | 256x256 | Stress test, exposes numerical accumulation drift |
|
|
26
|
+
|
|
27
|
+
For each size, generate two variants:
|
|
28
|
+
- **Clean:** no NaN, realistic value range for the function
|
|
29
|
+
- **Dirty:** 5-10% random NaN, some extreme values near dtype limits
|
|
30
|
+
|
|
31
|
+
Use `np.random.default_rng(42)` for reproducibility. Test with at least `float32` and `float64`.
|
|
32
|
+
|
|
33
|
+
## Step 3 -- Run every backend
|
|
34
|
+
|
|
35
|
+
1. **NumPy:** `create_test_raster(data, backend='numpy')` -- always the baseline.
|
|
36
|
+
2. **Dask+NumPy:** test with two chunk configurations: even split and ragged remainder.
|
|
37
|
+
3. **CuPy:** `create_test_raster(data, backend='cupy')` -- skip if CUDA unavailable.
|
|
38
|
+
4. **Dask+CuPy:** `create_test_raster(data, backend='dask+cupy')` -- skip if CUDA unavailable.
|
|
39
|
+
|
|
40
|
+
## Step 4 -- Pairwise comparison
|
|
41
|
+
|
|
42
|
+
For every non-NumPy result, compare against the NumPy baseline. Extract data:
|
|
43
|
+
- Dask: `.data.compute()`
|
|
44
|
+
- CuPy: `.data.get()`
|
|
45
|
+
- Dask+CuPy: `.data.compute().get()`
|
|
46
|
+
|
|
47
|
+
Compute: absolute difference, relative difference, NaN mask agreement, metadata preservation.
|
|
48
|
+
|
|
49
|
+
Pass/fail thresholds:
|
|
50
|
+
- NumPy vs Dask+NumPy: rtol=1e-5, atol=0
|
|
51
|
+
- NumPy vs CuPy: rtol=1e-6, atol=1e-6
|
|
52
|
+
- NumPy vs Dask+CuPy: rtol=1e-6, atol=1e-6
|
|
53
|
+
|
|
54
|
+
A comparison fails if max_abs > atol AND max_rel > rtol, or if NaN masks disagree.
|
|
55
|
+
|
|
56
|
+
## Step 5 -- Chunk boundary analysis
|
|
57
|
+
|
|
58
|
+
For any Dask comparison that fails, identify which cells diverge and map them to chunk boundaries. Report what percentage of divergent cells are at chunk boundaries vs interior.
|
|
59
|
+
|
|
60
|
+
## Step 6 -- Generate the report
|
|
61
|
+
|
|
62
|
+
Print a structured report with: functions tested, parity matrix table, failures with root cause analysis, and summary counts.
|
|
63
|
+
|
|
64
|
+
## General rules
|
|
65
|
+
|
|
66
|
+
- Do not modify any source or test files. This rule is read-only.
|
|
67
|
+
- Use `create_test_raster` from `general_checks.py` for all raster construction.
|
|
68
|
+
- If CUDA is unavailable, skip CuPy and Dask+CuPy gracefully. Report as SKIPPED, not FAIL.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Run ASV benchmarks for the current branch against main and report regressions and improvements"
|
|
3
|
+
globs: "benchmarks/**/*.py"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Bench: Local Performance Comparison
|
|
7
|
+
|
|
8
|
+
Run ASV benchmarks for the current branch against main and report regressions and improvements.
|
|
9
|
+
|
|
10
|
+
## Step 1 -- Identify what changed
|
|
11
|
+
|
|
12
|
+
1. If the prompt names specific benchmark classes or functions, use those directly.
|
|
13
|
+
2. If the prompt is empty or says "auto", run `git diff origin/main --name-only` to find changed source files under `xrspatial/`. Map each changed file to the corresponding benchmark module in `benchmarks/benchmarks/`.
|
|
14
|
+
3. If no benchmark exists for the changed code, note this and suggest whether one should be added.
|
|
15
|
+
|
|
16
|
+
## Step 2 -- Check prerequisites
|
|
17
|
+
|
|
18
|
+
1. Verify ASV is installed: `python -c "import asv"`. If missing, tell the user to install it.
|
|
19
|
+
2. Verify the benchmarks directory exists at `benchmarks/`.
|
|
20
|
+
3. Read `benchmarks/asv.conf.json` to confirm the project name and branch settings.
|
|
21
|
+
|
|
22
|
+
## Step 3 -- Run the comparison
|
|
23
|
+
|
|
24
|
+
Run ASV in continuous-comparison mode from the `benchmarks/` directory:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
cd benchmarks && asv continuous origin/main HEAD -b "<regex>" -e
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Where `<regex>` is a pattern matching the benchmark classes identified in Step 1.
|
|
31
|
+
|
|
32
|
+
## Step 4 -- Parse and interpret results
|
|
33
|
+
|
|
34
|
+
Classify each result:
|
|
35
|
+
- REGRESSION: Ratio > 1.2x
|
|
36
|
+
- IMPROVED: Ratio < 0.8x
|
|
37
|
+
- UNCHANGED: Between 0.8x and 1.2x
|
|
38
|
+
|
|
39
|
+
## Step 5 -- Generate the report
|
|
40
|
+
|
|
41
|
+
Print a table with benchmark name, main time, HEAD time, ratio, and status. List regressions with likely causes, improvements, missing benchmarks, and a recommendation.
|
|
42
|
+
|
|
43
|
+
## Step 6 -- Suggest benchmark additions
|
|
44
|
+
|
|
45
|
+
If changed functions have no benchmark coverage, describe what a new benchmark should test and ask the user whether to write it.
|
|
46
|
+
|
|
47
|
+
## General rules
|
|
48
|
+
|
|
49
|
+
- Always run benchmarks from the `benchmarks/` directory.
|
|
50
|
+
- The regression threshold is 1.2x, matching `.github/workflows/benchmarks.yml`.
|
|
51
|
+
- Do not modify any source, test, or benchmark files unless explicitly asked to write a benchmark.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Create a Jupyter notebook that sets up a Dask distributed LocalCluster and walks through an ETL workflow"
|
|
3
|
+
globs: "*.ipynb"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Dask ETL Notebook
|
|
7
|
+
|
|
8
|
+
Create a Jupyter notebook that sets up a Dask distributed LocalCluster and walks through an ETL (Extract, Transform, Load) workflow.
|
|
9
|
+
|
|
10
|
+
## Notebook structure
|
|
11
|
+
|
|
12
|
+
1. Title + one-line description
|
|
13
|
+
2. Overview (what the pipeline does, what you'll learn)
|
|
14
|
+
3. Imports
|
|
15
|
+
4. Cluster Setup -- create and inspect a LocalCluster + Client
|
|
16
|
+
5. Extract -- load or generate source data as lazy Dask arrays
|
|
17
|
+
6. Transform -- apply transformations (filtering, rechunking, computation)
|
|
18
|
+
7. Load -- write results to disk (Zarr, Parquet, GeoTIFF)
|
|
19
|
+
8. Cleanup -- close the client and cluster
|
|
20
|
+
9. Summary + next steps
|
|
21
|
+
|
|
22
|
+
## Cluster Setup
|
|
23
|
+
|
|
24
|
+
Always use this pattern:
|
|
25
|
+
```python
|
|
26
|
+
from dask.distributed import Client, LocalCluster
|
|
27
|
+
|
|
28
|
+
cluster = LocalCluster(
|
|
29
|
+
n_workers=4,
|
|
30
|
+
threads_per_worker=2,
|
|
31
|
+
memory_limit="2GB",
|
|
32
|
+
)
|
|
33
|
+
client = Client(cluster)
|
|
34
|
+
client
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Include a markdown cell noting the dashboard link and that n_workers/memory_limit should be tuned.
|
|
38
|
+
|
|
39
|
+
## Code conventions
|
|
40
|
+
|
|
41
|
+
- **Lazy by default**: build the computation graph before calling .compute().
|
|
42
|
+
- **Chunking**: explain chunk choices. Use explicit chunks=.
|
|
43
|
+
- **Avoid full materialization mid-pipeline**: no .values or .compute() until the Load phase.
|
|
44
|
+
- **Persist when reused**: if an intermediate result is used in multiple downstream steps, call client.persist().
|
|
45
|
+
- **Cleanup**: always close the client and cluster at the end.
|
|
46
|
+
|
|
47
|
+
## Data handling
|
|
48
|
+
|
|
49
|
+
- Generate or load data lazily. Wrap numpy arrays with da.from_array(..., chunks=...).
|
|
50
|
+
- For file-based sources, prefer xr.open_dataset with explicit chunks=.
|
|
51
|
+
- For Load phase, prefer Zarr (to_zarr()) as default output format.
|
|
52
|
+
|
|
53
|
+
## Checklist
|
|
54
|
+
|
|
55
|
+
1. Pick a data domain from the prompt (or default to geospatial raster).
|
|
56
|
+
2. Write the full cell sequence following the structure.
|
|
57
|
+
3. Verify all code cells are syntactically correct and self-contained.
|
|
58
|
+
4. Ensure the notebook cleans up after itself (cluster closed, temp files noted).
|