PyGeoFetch 2.6.2.6__tar.gz → 2.6.2.7__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.
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/CHANGELOG.md +7 -7
- {pygeofetch-2.6.2.6/pygeofetch.egg-info → pygeofetch-2.6.2.7}/PKG-INFO +25 -24
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/README.md +24 -23
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/__init__.py +1 -1
- pygeofetch-2.6.2.7/pygeofetch/geotech/__init__.py +0 -0
- pygeofetch-2.6.2.7/pygeofetch/geotech/risk_mapper.py +276 -0
- pygeofetch-2.6.2.7/pygeofetch/insar/auto_fallback.py +332 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/meta.yaml +1 -1
- pygeofetch-2.6.2.7/pygeofetch/processing/uq_exporter.py +227 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/providers/usgs.py +31 -11
- pygeofetch-2.6.2.7/pygeofetch/stac_compute/__init__.py +0 -0
- pygeofetch-2.6.2.7/pygeofetch/stac_compute/lightweight_prefetch.py +406 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7/pygeofetch.egg-info}/PKG-INFO +25 -24
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch.egg-info/SOURCES.txt +11 -2
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pyproject.toml +1 -1
- pygeofetch-2.6.2.7/tests/test_auto_fallback.py +186 -0
- pygeofetch-2.6.2.7/tests/test_lightweight_prefetch.py +279 -0
- pygeofetch-2.6.2.7/tests/test_risk_mapper.py +200 -0
- pygeofetch-2.6.2.7/tests/test_uq_exporter.py +212 -0
- pygeofetch-2.6.2.6/tests/test_provider_geometry_audit (1).py +0 -204
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/LICENSE +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/MANIFEST.in +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/cli/__init__.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/cli/auth_commands.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/cli/config_commands.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/cli/download_commands.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/cli/index_commands.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/cli/main.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/cli/monitor_commands.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/cli/multisensor_commands.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/cli/optical_commands.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/cli/pipeline_process_commands.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/cli/postprocess_commands.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/cli/preprocess_commands.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/cli/sar_commands.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/cli/search_commands.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/config/__init__.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/config/defaults.yaml +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/config/settings.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/core/__init__.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/core/authenticator.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/core/cache_manager.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/core/data_organizer.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/core/downloader.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/core/engine.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/core/logging.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/core/monitor.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/core/orbits.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/core/scheduler.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/core/searcher.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/core/state.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/insar/__init__.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/insar/advanced_safeguards.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/insar/analysis.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/insar/annotation.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/insar/atmosphere.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/insar/coregister.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/insar/deburst.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/insar/esd.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/insar/extraction.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/insar/flatearth.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/insar/geolocation.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/insar/gpu.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/insar/interferogram.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/insar/ionosphere.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/insar/offset_geometry.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/insar/offset_tracking.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/insar/preflight.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/insar/provenance.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/insar/ps_selection.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/insar/splitspectrum_diagnostic.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/insar/stack_selection.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/insar/synthetic.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/insar/timeseries.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/insar/unwrap.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/insar/validate.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/insar/visualize.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/insar/workflow.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/models/__init__.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/models/download_task.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/models/satellite_data.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/models/search_query.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/models/user_auth.py +0 -0
- /pygeofetch-2.6.2.6/pygeofetch/multisensor/multisensor_init.py → /pygeofetch-2.6.2.7/pygeofetch/multisensor/_init.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/multisensor/dem_differencing.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/multisensor/flood_mapping.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/multisensor/insar_optical_fusion.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/multisensor/terrain_corrected_change.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/multisensor/vegetation_disturbance.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/optical/__init__.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/optical/offset_tracking.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/processing/__init__.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/processing/base.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/processing/batch.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/processing/indices.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/processing/pipeline.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/processing/postprocessor.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/processing/preprocessor.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/processing/sar.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/processor/__init__.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/processor/indices.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/processor/landsat.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/processor/loader.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/processor/stacker.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/processor/timeseries.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/providers/__init__.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/providers/airbus_oneatlas.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/providers/alaska_satellite_facility.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/providers/aws_earth.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/providers/base.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/providers/copernicus.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/providers/copernicus_nodes.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/providers/digitalglobe.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/providers/earth_explorer_additional.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/providers/element84.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/providers/eodag_provider.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/providers/esa_scihub.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/providers/geoserver_generic.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/providers/google_earth_engine.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/providers/inpe_cbers.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/providers/isro_bhuvan.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/providers/jaxa_earth.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/providers/maxar_gbdx.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/providers/nasa_earthdata.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/providers/nasa_earthdata_cloud.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/providers/noaa_big_data.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/providers/opentopography.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/providers/planet.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/providers/planetary_computer.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/providers/sentinel_hub.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/providers/terrabotics.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/sar/__init__.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/sar/_native.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/sar/_ost.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/sar/_sarxarray.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/sar/extraction.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/sar/math.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/sar/pipelines.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/sar/processor.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/utils/__init__.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/utils/file_utils.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/utils/gcp_recovery.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/utils/geo_utils.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/utils/logging_setup.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/utils/retry_handler.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/utils/sar_math.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/utils/validators.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/validation/__init__.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/validation/optical_validator.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/viz/__init__.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/viz/map.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch/viz/plot.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch.egg-info/dependency_links.txt +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch.egg-info/entry_points.txt +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch.egg-info/not-zip-safe +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch.egg-info/requires.txt +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/pygeofetch.egg-info/top_level.txt +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/setup.cfg +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_advanced_safeguards.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_airbus_oneatlas.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_alaska_satellite_facility.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_atmospheric_circular_regression.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_build_sbas_network-new.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_build_sbas_network.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_burst_metadata.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_burst_processing_integration.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_burst_sync_large_gap.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_burst_sync_prescreening.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_burst_synchronization.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_circuit_breaker_wiring.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_cli_optical_validation.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_copernicus_nodes.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_coregister_integration.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_coregister_upgrades (1).py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_coregister_upgrades.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_credential_encryption.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_data_organizer.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_dem_differencing_pipeline.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_digitalglobe.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_earth_explorer_additional.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_era5_atmospheric_correction.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_esa_scihub.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_extraction.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_flat_earth_phase.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_flood_mapping_pipeline.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_gcp_reprojection.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_geology_indices_and_rvi_fix.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_geoserver_generic.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_google_earth_engine.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_inpe_cbers.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_insar.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_insar_optical_fusion_pipeline.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_ionosphere.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_isro_bhuvan.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_jaxa_earth.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_map_preview_consolidation.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_models.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_monitor.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_nasa_earthdata_cloud_s3_fix.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_nasa_earthdata_public_search.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_noaa_big_data.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_offset_tracking.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_opentopography_pointcloud_usgs.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_optical_offset_tracking.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_optical_validation_wiring.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_optical_validator.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_optical_validator_stac.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_pgv_integration_contract.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_pipeline_process_export.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_planet_asset_type_fix.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_preflight_gate.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_preflight_spatial_baseline.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_provider_geometry_audit.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_provider_scene_disambiguation.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_providers.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_ps_selection.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_raster_collocation_integration.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_reference_pixel_and_despike.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_risk_mapping.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_sar_pipelines.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_screen_stack_orchestration.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_search_download.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_sentinel_hub_catalog_fix.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_sign_convention.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_splitspectrum_diagnostic.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_stack_selection_consolidation.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_state.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_strain_and_fusion.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_terrain_corrected_change_pipeline.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_topo_r2_bug.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_utils.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_vegetation_disturbance_pipeline.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_viz_plot.py +0 -0
- {pygeofetch-2.6.2.6 → pygeofetch-2.6.2.7}/tests/test_wls_inversion.py +0 -0
|
@@ -20,7 +20,7 @@ date, and marked accordingly rather than filled in with invented
|
|
|
20
20
|
bullet points.
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
-
## [Unreleased] — v2.6.2.
|
|
23
|
+
## [Unreleased] — v2.6.2.7.4
|
|
24
24
|
|
|
25
25
|
```{note}
|
|
26
26
|
Not yet published to PyPI. This entry documents work completed and
|
|
@@ -130,7 +130,7 @@ audit and remain open for a follow-up pass.
|
|
|
130
130
|
|
|
131
131
|
---
|
|
132
132
|
|
|
133
|
-
## [2.6.2.
|
|
133
|
+
## [2.6.2.7.4] — 2026-08-25 (latest)
|
|
134
134
|
|
|
135
135
|
Confirmed via direct fetch of the current PyPI listing.
|
|
136
136
|
|
|
@@ -149,7 +149,7 @@ Confirmed via direct fetch of the current PyPI listing.
|
|
|
149
149
|
- `SearchQuery.sort_ascending: bool` — earlier examples showed a `sort_order: "asc"/"desc"` string field that doesn't exist on the model (the CLI's `--sort-order` flag does convert to this internally, so CLI docs were unaffected)
|
|
150
150
|
- `DownloadOptions.post_process` requires a list of `PostProcessAction` objects — passing plain strings raises a real `pydantic.ValidationError`
|
|
151
151
|
|
|
152
|
-
## [2.6.2.
|
|
152
|
+
## [2.6.2.7] — 2026-08-24
|
|
153
153
|
Real, verified release. Detailed notes not independently recovered from PyPI's release-history page (no distinct per-version notes exposed for this release specifically).
|
|
154
154
|
|
|
155
155
|
## [2.6.1] — 2026-08-22
|
|
@@ -261,9 +261,9 @@ recovered.
|
|
|
261
261
|
|
|
262
262
|
```{note}
|
|
263
263
|
The previous version of this changelog had an entry labeled
|
|
264
|
-
**"2.6.2.
|
|
264
|
+
**"2.6.2.7.4 — 2026-07-12"** describing 22+ providers, Sentinel-1C/1D
|
|
265
265
|
support, SLC search with provider routing, precise orbit file
|
|
266
|
-
management, 17 spectral indices, and various bug fixes. **2.6.2.
|
|
266
|
+
management, 17 spectral indices, and various bug fixes. **2.6.2.7.4 was
|
|
267
267
|
only ever released once, on 2026-08-25** — it was never released on
|
|
268
268
|
2026-07-12. The date matches this real release, **1.0.8**, exactly.
|
|
269
269
|
That content is reproduced below under the version it actually
|
|
@@ -406,8 +406,8 @@ The version of this file uploaded for this update had **5 entries
|
|
|
406
406
|
covering 5 dates**. PyPI's real release history has **54 releases**.
|
|
407
407
|
Specific issues found and fixed:
|
|
408
408
|
|
|
409
|
-
1. **Two different entries were both labeled `2.6.2.
|
|
410
|
-
2026-07-29 and 2026-07-12. **2.6.2.
|
|
409
|
+
1. **Two different entries were both labeled `2.6.2.7.4`**, dated
|
|
410
|
+
2026-07-29 and 2026-07-12. **2.6.2.7.4 was only ever released once**,
|
|
411
411
|
on 2026-08-25 (confirmed directly from the live PyPI listing).
|
|
412
412
|
2. **The 2026-07-12 entry's date exactly matches a real release**
|
|
413
413
|
— version **1.0.8** — and its content (22+ providers, Sentinel-1C/D,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pygeofetch
|
|
3
|
-
Version: 2.6.2.
|
|
3
|
+
Version: 2.6.2.7
|
|
4
4
|
Summary: Universal satellite data pipeline + geospatial processing platform
|
|
5
5
|
Author-email: Samuel Appiah Kubi <appiahkubis14@gmail.com>
|
|
6
6
|
License: MIT License
|
|
@@ -146,8 +146,9 @@ Dynamic: license-file
|
|
|
146
146
|
[](https://doi.org/10.5281/zenodo.22087230)
|
|
147
147
|
[](https://github.com/EOCoreINT/pygeofetch/actions/workflows/tests.yml)
|
|
148
148
|
[](https://codecov.io/gh/appiahkubis14/pygeofetch)
|
|
149
|
+
[](https://github.com/sponsors/appiahkubis14)
|
|
149
150
|
|
|
150
|
-
**A unified satellite data and geospatial processing platform — one CLI, one Python API,
|
|
151
|
+
**A unified satellite data and geospatial processing platform — one CLI, one Python API, 22 verified providers, and a fully verified InSAR chain.**
|
|
151
152
|
|
|
152
153
|
[Quick Start](#-quick-start) · [Mexico City Case Study](#-case-study-mapping-mexico-city-land-subsidence-with-insar) · [Case Study Repo ↗](https://github.com/EOCoreINT/mexico-subsidence-project) · [Documentation](https://pygeofetch.readthedocs.io/en/latest/) · [Notebooks](#-notebooks)
|
|
153
154
|
|
|
@@ -158,7 +159,7 @@ Dynamic: license-file
|
|
|
158
159
|
|
|
159
160
|
## Overview
|
|
160
161
|
|
|
161
|
-
pygeofetch is a production-ready framework for acquiring and processing Earth observation data. It provides authenticated, unified access to **
|
|
162
|
+
pygeofetch is a production-ready framework for acquiring and processing Earth observation data. It provides authenticated, unified access to **22 verified satellite providers** — Sentinel, Landsat, Planet, Maxar, Airbus, Copernicus, USGS, NASA, JAXA, and more — through a single CLI and Python API, and layers a complete geospatial processing engine on top.
|
|
162
163
|
|
|
163
164
|
Where pygeofetch goes further than most data-access libraries is in its **InSAR chain**: burst-aware coregistration, real flat-earth and topographic phase removal, ERA5 tropospheric and ionospheric correction, phase unwrapping, and SBAS time-series inversion — each stage independently verified against synthetic ground truth or real, published deformation studies, not assumed correct from theory alone. The [Mexico City case study](#-case-study-mapping-mexico-city-land-subsidence-with-insar) below walks through that chain end to end on real Sentinel-1 data.
|
|
164
165
|
|
|
@@ -166,7 +167,7 @@ Where pygeofetch goes further than most data-access libraries is in its **InSAR
|
|
|
166
167
|
|
|
167
168
|
| | |
|
|
168
169
|
|---|---|
|
|
169
|
-
| 🔐 **Authenticated access** |
|
|
170
|
+
| 🔐 **Authenticated access** | 22 verified providers; credentials stored via a Fernet-encrypted local file by default, or the system keyring (Keychain / Credential Manager / Secret Service) as an opt-in alternative |
|
|
170
171
|
| 🔍 **Federated search** | One query across all providers → STAC 1.0 GeoJSON / GeoParquet / CSV, with real footprint geometry where the provider supplies it |
|
|
171
172
|
| 📥 **Resilient downloads** | Parallel, resumable, checksum-verified, band-selective, atomic writes |
|
|
172
173
|
| ⚙️ **Preprocessing** | Atmospheric correction, cloud masking, reprojection, resampling, pan-sharpening, mosaicking |
|
|
@@ -192,7 +193,7 @@ Satellite data access is fragmented — every provider has its own auth scheme,
|
|
|
192
193
|
|
|
193
194
|
| Feature | pygeofetch | EODAG | pystac-client | satpy | sentinelsat |
|
|
194
195
|
|---|---|---|---|---|---|
|
|
195
|
-
| Providers | **
|
|
196
|
+
| Providers | **22** | 10+ | STAC only | Limited | Sentinel only |
|
|
196
197
|
| Processing engine | ✅ Full | ❌ | ❌ | Partial | ❌ |
|
|
197
198
|
| Spectral indices | ✅ 17+ | ❌ | ❌ | ❌ | ❌ |
|
|
198
199
|
| Full InSAR chain | ✅ Verified | ❌ | ❌ | ❌ | ❌ |
|
|
@@ -204,9 +205,9 @@ Satellite data access is fragmented — every provider has its own auth scheme,
|
|
|
204
205
|
|
|
205
206
|
## Providers
|
|
206
207
|
|
|
207
|
-
**
|
|
208
|
+
**22 verified providers total.** Open-access, no login required — including `planetary_computer`, `aws_earth`, `element84`, `noaa_big_data`, `jaxa_earth`, and `geoserver_generic` for any OGC WMS/WFS/WCS endpoint.
|
|
208
209
|
|
|
209
|
-
|
|
210
|
+
Authenticated — USGS, Copernicus CDSE, NASA Earthdata (+ Cloud), Alaska SAR Facility, OpenTopography, Planet Labs, Sentinel Hub, Maxar GBDX, Airbus OneAtlas, and Earth Explorer.
|
|
210
211
|
|
|
211
212
|
Every provider has been directly verified to return at minimum a correct bounding box; several are further confirmed to return real, precise footprint geometry against a live API response (marked in `pygeofetch providers info PROVIDER`). Run `pygeofetch providers list` for the full, current table.
|
|
212
213
|
|
|
@@ -260,23 +261,12 @@ Mexico City sits on a drained lakebed and is subsiding at some of the fastest ra
|
|
|
260
261
|
|
|
261
262
|
**1. Authenticated federated search.** `client.search()` against Copernicus Data Space for SLC scenes over the city (bbox `-99.183, 19.278, -99.003, 19.438`, July 2016 – September 2017) returns a stack of Sentinel-1A/1B candidates in seconds, filterable straight down to a single consistent track.
|
|
262
263
|
|
|
263
|
-
<p align="center"><img src="https://raw.githubusercontent.com/EOCoreINT/mexico-subsidence-project/main/analysis/data-search.png" width="85%" /></p>
|
|
264
|
-
|
|
265
264
|
Results carry real footprint geometry and drop straight onto a map via `MapViewer`, with hover info for scene ID, date, satellite, and provider — useful for spotting swath overlap before committing to a download.
|
|
266
265
|
|
|
267
|
-
<p align="center">
|
|
268
|
-
<img src="https://raw.githubusercontent.com/EOCoreINT/mexico-subsidence-project/main/analysis/search_1.png" width="48%" />
|
|
269
|
-
<img src="https://raw.githubusercontent.com/EOCoreINT/mexico-subsidence-project/main/analysis/search.png" width="48%" />
|
|
270
|
-
</p>
|
|
271
|
-
|
|
272
266
|
**2. DEM acquisition.** A matching search against OpenTopography returns seven DEM products for the AOI; pygeofetch downloads and clips the selected one (SRTM 30 m) automatically for topographic phase removal.
|
|
273
267
|
|
|
274
|
-
<p align="center"><img src="https://raw.githubusercontent.com/EOCoreINT/mexico-subsidence-project/main/analysis/dem_acquisition.png" width="85%" /></p>
|
|
275
|
-
|
|
276
268
|
**3. Preflight validation.** Before anything downloads, the `PreflightGate` checks search truncation, AOI coverage, temporal network connectivity, and burst-timing family compatibility from lightweight annotation XMLs — catching acquisitions that would waste compute before they cost bandwidth. This run avoided roughly 360 GB of downloads by excluding 48 of 115 candidate scenes at this stage alone.
|
|
277
269
|
|
|
278
|
-
<p align="center"><img src="https://raw.githubusercontent.com/EOCoreINT/mexico-subsidence-project/main/analysis/preflight-log.png" width="85%" /></p>
|
|
279
|
-
|
|
280
270
|
Real orbit state vectors then pre-filter the candidate pair list against Sentinel-1's own mission thresholds, rejecting pairs for excess burst-sync error, temporal baseline, or spatial baseline before any interferogram is attempted.
|
|
281
271
|
|
|
282
272
|
<p align="center"><img src="https://raw.githubusercontent.com/EOCoreINT/mexico-subsidence-project/main/analysis/pre-filter-for-interferogram.png" width="85%" /></p>
|
|
@@ -298,8 +288,6 @@ Real orbit state vectors then pre-filter the candidate pair list against Sentine
|
|
|
298
288
|
|
|
299
289
|
**7. SBAS time-series inversion.** The full 58-date descending stack, once low-coherence and unreliable-reference-pixel pairs are excluded, fractures into 17 disconnected network "islands" — a genuine finding about this AOI's data quality, not a bug. The largest connected island (10 dates, 11 pairs) carries the final inversion, referenced near Cerro de la Estrella.
|
|
300
290
|
|
|
301
|
-
<p align="center"><img src="https://raw.githubusercontent.com/EOCoreINT/mexico-subsidence-project/main/analysis/1.png" width="85%" /></p>
|
|
302
|
-
|
|
303
291
|
The resulting velocity field, uncertainty map, reliability mask, and displacement time series recover a 2nd–98th-percentile vertical velocity of **−35.5 to −2.9 cm/year** where reliable pixels exist.
|
|
304
292
|
|
|
305
293
|
<p align="center"><img src="https://raw.githubusercontent.com/EOCoreINT/mexico-subsidence-project/main/analysis/island1_sbas_full_analysis.png" width="90%" /></p>
|
|
@@ -381,7 +369,7 @@ If you use PyGeoFetch in your research or operational work, please cite it using
|
|
|
381
369
|
title = {PyGeoFetch: A Unified Python Framework for Multi-Provider Satellite Data Acquisition, Pre-download Quality Control, and Geospatial Processing},
|
|
382
370
|
year = {2026},
|
|
383
371
|
publisher = {Zenodo},
|
|
384
|
-
version = {2.6.2.
|
|
372
|
+
version = {2.6.2.7.1},
|
|
385
373
|
doi = {10.5281/zenodo.22087230},
|
|
386
374
|
url = {https://doi.org/10.5281/zenodo.22087230}
|
|
387
375
|
}
|
|
@@ -391,15 +379,28 @@ If you use PyGeoFetch in your research or operational work, please cite it using
|
|
|
391
379
|
|
|
392
380
|
Full documentation: **https://pygeofetch.readthedocs.io/en/latest/** — CLI reference, provider auth guides, pipeline configuration, post-processing catalogue, and InSAR verification methodology.
|
|
393
381
|
|
|
382
|
+
## Support this project
|
|
383
|
+
|
|
384
|
+
pygeofetch is built and maintained by a single developer, in the open,
|
|
385
|
+
alongside a full-time workload — the InSAR/optical fusion chain, the
|
|
386
|
+
provider verification work, and the documentation are all real,
|
|
387
|
+
independently-verified engineering, not a side project maintained on
|
|
388
|
+
autopilot. If pygeofetch is useful to your research or your
|
|
389
|
+
organization, sponsoring its development directly funds the time spent
|
|
390
|
+
keeping 22 provider integrations current as their real APIs change, and
|
|
391
|
+
building out the multi-sensor pipelines documented above.
|
|
392
|
+
|
|
393
|
+
[](https://github.com/sponsors/appiahkubis14)
|
|
394
|
+
|
|
394
395
|
## Contributing
|
|
395
396
|
|
|
396
397
|
Contributions are welcome — see [CONTRIBUTING.md](CONTRIBUTING.md). Good first issues include extending real footprint geometry to remaining bbox-only providers, wiring stub providers to full API integrations, and adding new post-processing actions.
|
|
397
398
|
|
|
398
399
|
```bash
|
|
399
400
|
git clone git@github.com:EOCoreINT/pygeofetch.git && cd pygeofetch
|
|
400
|
-
pip install -e ".[
|
|
401
|
-
|
|
401
|
+
pip install -e ".[test]" && pytest tests/ -v
|
|
402
|
+
```
|
|
402
403
|
|
|
403
404
|
## License
|
|
404
405
|
|
|
405
|
-
MIT — see [LICENSE](LICENSE). © 2026 Samuel Appiah Kubi.
|
|
406
|
+
MIT — see [LICENSE](LICENSE). © 2026 Samuel Appiah Kubi.
|
|
@@ -6,8 +6,9 @@
|
|
|
6
6
|
[](https://doi.org/10.5281/zenodo.22087230)
|
|
7
7
|
[](https://github.com/EOCoreINT/pygeofetch/actions/workflows/tests.yml)
|
|
8
8
|
[](https://codecov.io/gh/appiahkubis14/pygeofetch)
|
|
9
|
+
[](https://github.com/sponsors/appiahkubis14)
|
|
9
10
|
|
|
10
|
-
**A unified satellite data and geospatial processing platform — one CLI, one Python API,
|
|
11
|
+
**A unified satellite data and geospatial processing platform — one CLI, one Python API, 22 verified providers, and a fully verified InSAR chain.**
|
|
11
12
|
|
|
12
13
|
[Quick Start](#-quick-start) · [Mexico City Case Study](#-case-study-mapping-mexico-city-land-subsidence-with-insar) · [Case Study Repo ↗](https://github.com/EOCoreINT/mexico-subsidence-project) · [Documentation](https://pygeofetch.readthedocs.io/en/latest/) · [Notebooks](#-notebooks)
|
|
13
14
|
|
|
@@ -18,7 +19,7 @@
|
|
|
18
19
|
|
|
19
20
|
## Overview
|
|
20
21
|
|
|
21
|
-
pygeofetch is a production-ready framework for acquiring and processing Earth observation data. It provides authenticated, unified access to **
|
|
22
|
+
pygeofetch is a production-ready framework for acquiring and processing Earth observation data. It provides authenticated, unified access to **22 verified satellite providers** — Sentinel, Landsat, Planet, Maxar, Airbus, Copernicus, USGS, NASA, JAXA, and more — through a single CLI and Python API, and layers a complete geospatial processing engine on top.
|
|
22
23
|
|
|
23
24
|
Where pygeofetch goes further than most data-access libraries is in its **InSAR chain**: burst-aware coregistration, real flat-earth and topographic phase removal, ERA5 tropospheric and ionospheric correction, phase unwrapping, and SBAS time-series inversion — each stage independently verified against synthetic ground truth or real, published deformation studies, not assumed correct from theory alone. The [Mexico City case study](#-case-study-mapping-mexico-city-land-subsidence-with-insar) below walks through that chain end to end on real Sentinel-1 data.
|
|
24
25
|
|
|
@@ -26,7 +27,7 @@ Where pygeofetch goes further than most data-access libraries is in its **InSAR
|
|
|
26
27
|
|
|
27
28
|
| | |
|
|
28
29
|
|---|---|
|
|
29
|
-
| 🔐 **Authenticated access** |
|
|
30
|
+
| 🔐 **Authenticated access** | 22 verified providers; credentials stored via a Fernet-encrypted local file by default, or the system keyring (Keychain / Credential Manager / Secret Service) as an opt-in alternative |
|
|
30
31
|
| 🔍 **Federated search** | One query across all providers → STAC 1.0 GeoJSON / GeoParquet / CSV, with real footprint geometry where the provider supplies it |
|
|
31
32
|
| 📥 **Resilient downloads** | Parallel, resumable, checksum-verified, band-selective, atomic writes |
|
|
32
33
|
| ⚙️ **Preprocessing** | Atmospheric correction, cloud masking, reprojection, resampling, pan-sharpening, mosaicking |
|
|
@@ -52,7 +53,7 @@ Satellite data access is fragmented — every provider has its own auth scheme,
|
|
|
52
53
|
|
|
53
54
|
| Feature | pygeofetch | EODAG | pystac-client | satpy | sentinelsat |
|
|
54
55
|
|---|---|---|---|---|---|
|
|
55
|
-
| Providers | **
|
|
56
|
+
| Providers | **22** | 10+ | STAC only | Limited | Sentinel only |
|
|
56
57
|
| Processing engine | ✅ Full | ❌ | ❌ | Partial | ❌ |
|
|
57
58
|
| Spectral indices | ✅ 17+ | ❌ | ❌ | ❌ | ❌ |
|
|
58
59
|
| Full InSAR chain | ✅ Verified | ❌ | ❌ | ❌ | ❌ |
|
|
@@ -64,9 +65,9 @@ Satellite data access is fragmented — every provider has its own auth scheme,
|
|
|
64
65
|
|
|
65
66
|
## Providers
|
|
66
67
|
|
|
67
|
-
**
|
|
68
|
+
**22 verified providers total.** Open-access, no login required — including `planetary_computer`, `aws_earth`, `element84`, `noaa_big_data`, `jaxa_earth`, and `geoserver_generic` for any OGC WMS/WFS/WCS endpoint.
|
|
68
69
|
|
|
69
|
-
|
|
70
|
+
Authenticated — USGS, Copernicus CDSE, NASA Earthdata (+ Cloud), Alaska SAR Facility, OpenTopography, Planet Labs, Sentinel Hub, Maxar GBDX, Airbus OneAtlas, and Earth Explorer.
|
|
70
71
|
|
|
71
72
|
Every provider has been directly verified to return at minimum a correct bounding box; several are further confirmed to return real, precise footprint geometry against a live API response (marked in `pygeofetch providers info PROVIDER`). Run `pygeofetch providers list` for the full, current table.
|
|
72
73
|
|
|
@@ -120,23 +121,12 @@ Mexico City sits on a drained lakebed and is subsiding at some of the fastest ra
|
|
|
120
121
|
|
|
121
122
|
**1. Authenticated federated search.** `client.search()` against Copernicus Data Space for SLC scenes over the city (bbox `-99.183, 19.278, -99.003, 19.438`, July 2016 – September 2017) returns a stack of Sentinel-1A/1B candidates in seconds, filterable straight down to a single consistent track.
|
|
122
123
|
|
|
123
|
-
<p align="center"><img src="https://raw.githubusercontent.com/EOCoreINT/mexico-subsidence-project/main/analysis/data-search.png" width="85%" /></p>
|
|
124
|
-
|
|
125
124
|
Results carry real footprint geometry and drop straight onto a map via `MapViewer`, with hover info for scene ID, date, satellite, and provider — useful for spotting swath overlap before committing to a download.
|
|
126
125
|
|
|
127
|
-
<p align="center">
|
|
128
|
-
<img src="https://raw.githubusercontent.com/EOCoreINT/mexico-subsidence-project/main/analysis/search_1.png" width="48%" />
|
|
129
|
-
<img src="https://raw.githubusercontent.com/EOCoreINT/mexico-subsidence-project/main/analysis/search.png" width="48%" />
|
|
130
|
-
</p>
|
|
131
|
-
|
|
132
126
|
**2. DEM acquisition.** A matching search against OpenTopography returns seven DEM products for the AOI; pygeofetch downloads and clips the selected one (SRTM 30 m) automatically for topographic phase removal.
|
|
133
127
|
|
|
134
|
-
<p align="center"><img src="https://raw.githubusercontent.com/EOCoreINT/mexico-subsidence-project/main/analysis/dem_acquisition.png" width="85%" /></p>
|
|
135
|
-
|
|
136
128
|
**3. Preflight validation.** Before anything downloads, the `PreflightGate` checks search truncation, AOI coverage, temporal network connectivity, and burst-timing family compatibility from lightweight annotation XMLs — catching acquisitions that would waste compute before they cost bandwidth. This run avoided roughly 360 GB of downloads by excluding 48 of 115 candidate scenes at this stage alone.
|
|
137
129
|
|
|
138
|
-
<p align="center"><img src="https://raw.githubusercontent.com/EOCoreINT/mexico-subsidence-project/main/analysis/preflight-log.png" width="85%" /></p>
|
|
139
|
-
|
|
140
130
|
Real orbit state vectors then pre-filter the candidate pair list against Sentinel-1's own mission thresholds, rejecting pairs for excess burst-sync error, temporal baseline, or spatial baseline before any interferogram is attempted.
|
|
141
131
|
|
|
142
132
|
<p align="center"><img src="https://raw.githubusercontent.com/EOCoreINT/mexico-subsidence-project/main/analysis/pre-filter-for-interferogram.png" width="85%" /></p>
|
|
@@ -158,8 +148,6 @@ Real orbit state vectors then pre-filter the candidate pair list against Sentine
|
|
|
158
148
|
|
|
159
149
|
**7. SBAS time-series inversion.** The full 58-date descending stack, once low-coherence and unreliable-reference-pixel pairs are excluded, fractures into 17 disconnected network "islands" — a genuine finding about this AOI's data quality, not a bug. The largest connected island (10 dates, 11 pairs) carries the final inversion, referenced near Cerro de la Estrella.
|
|
160
150
|
|
|
161
|
-
<p align="center"><img src="https://raw.githubusercontent.com/EOCoreINT/mexico-subsidence-project/main/analysis/1.png" width="85%" /></p>
|
|
162
|
-
|
|
163
151
|
The resulting velocity field, uncertainty map, reliability mask, and displacement time series recover a 2nd–98th-percentile vertical velocity of **−35.5 to −2.9 cm/year** where reliable pixels exist.
|
|
164
152
|
|
|
165
153
|
<p align="center"><img src="https://raw.githubusercontent.com/EOCoreINT/mexico-subsidence-project/main/analysis/island1_sbas_full_analysis.png" width="90%" /></p>
|
|
@@ -241,7 +229,7 @@ If you use PyGeoFetch in your research or operational work, please cite it using
|
|
|
241
229
|
title = {PyGeoFetch: A Unified Python Framework for Multi-Provider Satellite Data Acquisition, Pre-download Quality Control, and Geospatial Processing},
|
|
242
230
|
year = {2026},
|
|
243
231
|
publisher = {Zenodo},
|
|
244
|
-
version = {2.6.2.
|
|
232
|
+
version = {2.6.2.7.1},
|
|
245
233
|
doi = {10.5281/zenodo.22087230},
|
|
246
234
|
url = {https://doi.org/10.5281/zenodo.22087230}
|
|
247
235
|
}
|
|
@@ -251,15 +239,28 @@ If you use PyGeoFetch in your research or operational work, please cite it using
|
|
|
251
239
|
|
|
252
240
|
Full documentation: **https://pygeofetch.readthedocs.io/en/latest/** — CLI reference, provider auth guides, pipeline configuration, post-processing catalogue, and InSAR verification methodology.
|
|
253
241
|
|
|
242
|
+
## Support this project
|
|
243
|
+
|
|
244
|
+
pygeofetch is built and maintained by a single developer, in the open,
|
|
245
|
+
alongside a full-time workload — the InSAR/optical fusion chain, the
|
|
246
|
+
provider verification work, and the documentation are all real,
|
|
247
|
+
independently-verified engineering, not a side project maintained on
|
|
248
|
+
autopilot. If pygeofetch is useful to your research or your
|
|
249
|
+
organization, sponsoring its development directly funds the time spent
|
|
250
|
+
keeping 22 provider integrations current as their real APIs change, and
|
|
251
|
+
building out the multi-sensor pipelines documented above.
|
|
252
|
+
|
|
253
|
+
[](https://github.com/sponsors/appiahkubis14)
|
|
254
|
+
|
|
254
255
|
## Contributing
|
|
255
256
|
|
|
256
257
|
Contributions are welcome — see [CONTRIBUTING.md](CONTRIBUTING.md). Good first issues include extending real footprint geometry to remaining bbox-only providers, wiring stub providers to full API integrations, and adding new post-processing actions.
|
|
257
258
|
|
|
258
259
|
```bash
|
|
259
260
|
git clone git@github.com:EOCoreINT/pygeofetch.git && cd pygeofetch
|
|
260
|
-
pip install -e ".[
|
|
261
|
-
|
|
261
|
+
pip install -e ".[test]" && pytest tests/ -v
|
|
262
|
+
```
|
|
262
263
|
|
|
263
264
|
## License
|
|
264
265
|
|
|
265
|
-
MIT — see [LICENSE](LICENSE). © 2026 Samuel Appiah Kubi.
|
|
266
|
+
MIT — see [LICENSE](LICENSE). © 2026 Samuel Appiah Kubi.
|
|
File without changes
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Domain-specific geotechnical risk mapping.
|
|
3
|
+
|
|
4
|
+
Extends this project's existing strain calculation
|
|
5
|
+
(`pygeofetch.optical.offset_tracking.compute_horizontal_strain`) with
|
|
6
|
+
curvature -- the real, standard second spatial derivative of a
|
|
7
|
+
displacement field -- and combines both with velocity into a single,
|
|
8
|
+
normalized, physically-capped risk index.
|
|
9
|
+
|
|
10
|
+
Real, standard geotechnical grounding: curvature of the ground surface
|
|
11
|
+
is a real, long-established predictor of structural damage in mining
|
|
12
|
+
subsidence engineering (National Coal Board, 1975, *Subsidence
|
|
13
|
+
Engineering Handbook*) -- a curved ground surface bends whatever rigid
|
|
14
|
+
structure sits on it, and that bending strain is what actually cracks
|
|
15
|
+
foundations and walls, not subsidence magnitude alone. The NCB's own
|
|
16
|
+
real, cited strain-based damage categories are reused here as the real
|
|
17
|
+
reference scale for this module's strain sub-score (see
|
|
18
|
+
`compute_geotechnical_risk_index`'s own docstring).
|
|
19
|
+
|
|
20
|
+
Real, honest note on `compute_curvature`'s two real inputs: the
|
|
21
|
+
standard subsidence-engineering convention computes curvature from a
|
|
22
|
+
*single* vertical displacement/subsidence field, not two horizontal
|
|
23
|
+
components. This module's own `compute_curvature(dx, dy, ...)`
|
|
24
|
+
generalizes that to accept displacement magnitude
|
|
25
|
+
(sqrt(dx^2 + dy^2)) computed from two real horizontal components -- a
|
|
26
|
+
real, honest extension for this project's own broader, multi-modal
|
|
27
|
+
scope (lateral landslide movement, co-seismic horizontal slip), not
|
|
28
|
+
identical to the classic vertical-subsidence-only NCB convention. Pass
|
|
29
|
+
the same real array for both `dx` and `dy=0` (a real zero array, same
|
|
30
|
+
shape) to reproduce standard single-field vertical curvature exactly.
|
|
31
|
+
|
|
32
|
+
Real, direct connection to a previously-found bug, stated explicitly
|
|
33
|
+
rather than left implicit: this project's own real, live Bu'ertai
|
|
34
|
+
validation run produced a genuine 617% strain artifact from a small
|
|
35
|
+
number of spurious optical correlator matches -- caught and fixed with
|
|
36
|
+
real outlier protection in `compute_horizontal_strain` itself. The
|
|
37
|
+
"strict, physically plausible capping" this module applies on top of
|
|
38
|
+
that is a second, independent real safeguard: even a genuinely
|
|
39
|
+
outlier-filtered strain value should never be allowed to dominate a
|
|
40
|
+
risk score computed from it, since real ground strain at the level
|
|
41
|
+
mining-subsidence engineering considers "very severe" is on the order
|
|
42
|
+
of 1% (NCB, 1975) -- several orders of magnitude below any of the
|
|
43
|
+
617%-class artifacts this project has directly, empirically observed.
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
from __future__ import annotations
|
|
47
|
+
|
|
48
|
+
import logging
|
|
49
|
+
from typing import Any
|
|
50
|
+
|
|
51
|
+
from pydantic import BaseModel, Field
|
|
52
|
+
|
|
53
|
+
logger = logging.getLogger("pygeofetch.geotech.risk_mapper")
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class RiskMapperConfig(BaseModel):
|
|
57
|
+
"""
|
|
58
|
+
Real, configurable reference scales for
|
|
59
|
+
`compute_geotechnical_risk_index`.
|
|
60
|
+
|
|
61
|
+
Real, cited defaults for strain (National Coal Board, 1975): the
|
|
62
|
+
NCB's own published damage categories place "very severe" damage
|
|
63
|
+
at real ground strains at or above 1.0% (0.01) -- used here as the
|
|
64
|
+
real strain value that alone saturates this sub-score to 100.
|
|
65
|
+
|
|
66
|
+
Real, honest note on the velocity and curvature defaults: unlike
|
|
67
|
+
strain, there is no single, universally-cited numeric threshold
|
|
68
|
+
for "high-risk" velocity or curvature across all real deformation
|
|
69
|
+
contexts (mining, landslide, urban subsidence each have their own
|
|
70
|
+
real, site-specific conventions) -- the defaults below are
|
|
71
|
+
reasonable, real, commonly-encountered reference points (matching
|
|
72
|
+
the same order of magnitude routinely reported in real InSAR
|
|
73
|
+
mining-subsidence literature this project's own Bu'ertai/Mexico
|
|
74
|
+
City validation work references), not a cited universal standard
|
|
75
|
+
the way the strain threshold is. Override them with a real,
|
|
76
|
+
site-specific reference value whenever one is available.
|
|
77
|
+
"""
|
|
78
|
+
|
|
79
|
+
max_severe_strain: float = Field(
|
|
80
|
+
0.01,
|
|
81
|
+
gt=0,
|
|
82
|
+
description="Real strain (fraction, not %) at which the strain sub-score saturates to 100 -- NCB (1975) 'very severe' threshold.",
|
|
83
|
+
)
|
|
84
|
+
max_severe_velocity_m_per_year: float = Field(
|
|
85
|
+
0.5,
|
|
86
|
+
gt=0,
|
|
87
|
+
description="Real velocity magnitude (m/yr) at which the velocity sub-score saturates to 100 -- a reasonable, site-adjustable reference, not a cited universal standard.",
|
|
88
|
+
)
|
|
89
|
+
max_severe_curvature_per_m: float = Field(
|
|
90
|
+
0.001,
|
|
91
|
+
gt=0,
|
|
92
|
+
description="Real curvature magnitude (1/m) at which the curvature sub-score saturates to 100 -- a reasonable, site-adjustable reference, not a cited universal standard.",
|
|
93
|
+
)
|
|
94
|
+
strain_cap: float = Field(
|
|
95
|
+
0.10,
|
|
96
|
+
gt=0,
|
|
97
|
+
description="Real, hard physical plausibility ceiling (fraction) applied to strain before it enters the risk index at all -- protects against exactly the class of spurious, order-of-magnitude-too-large artifact this project has directly observed (a real 617% strain case), independent of whatever outlier protection already ran upstream.",
|
|
98
|
+
)
|
|
99
|
+
combination: str = Field(
|
|
100
|
+
"max_weighted",
|
|
101
|
+
description="'max_weighted' (default) or 'mean' -- see compute_geotechnical_risk_index's own docstring.",
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def compute_curvature(dx: Any, dy: Any, pixel_size_m: float) -> dict:
|
|
106
|
+
"""
|
|
107
|
+
Real curvature (second spatial derivative) of a displacement
|
|
108
|
+
field -- see this module's own docstring for the real, important
|
|
109
|
+
distinction between this generalized, magnitude-based computation
|
|
110
|
+
and the classic, single-field vertical-subsidence convention.
|
|
111
|
+
|
|
112
|
+
Real, standard central finite-difference implementation: computes
|
|
113
|
+
`np.gradient` twice (first derivative, then the derivative of that)
|
|
114
|
+
on the real displacement magnitude field, matching the exact same
|
|
115
|
+
real numerical approach `compute_horizontal_strain` already uses
|
|
116
|
+
for its own first-derivative strain tensor.
|
|
117
|
+
|
|
118
|
+
Parameters
|
|
119
|
+
----------
|
|
120
|
+
dx, dy : np.ndarray
|
|
121
|
+
Real horizontal displacement components, metres, same shape
|
|
122
|
+
(e.g. from `compute_pixel_offsets`). Pass a real zero array for
|
|
123
|
+
`dy` to compute standard single-field curvature on `dx` alone.
|
|
124
|
+
pixel_size_m : float
|
|
125
|
+
Real ground distance between adjacent grid samples, metres.
|
|
126
|
+
|
|
127
|
+
Returns
|
|
128
|
+
-------
|
|
129
|
+
dict
|
|
130
|
+
Real keys: ``"curvature_xx"``, ``"curvature_yy"`` (the two real
|
|
131
|
+
principal second-derivative components of displacement
|
|
132
|
+
magnitude), and ``"curvature_max"`` (real, per-pixel maximum
|
|
133
|
+
absolute value of the two -- the real, standard single scalar
|
|
134
|
+
used as the risk-relevant curvature magnitude in mining
|
|
135
|
+
subsidence engineering).
|
|
136
|
+
|
|
137
|
+
Raises
|
|
138
|
+
------
|
|
139
|
+
ValueError
|
|
140
|
+
If `dx`/`dy` don't share a real, identical shape.
|
|
141
|
+
"""
|
|
142
|
+
import numpy as np
|
|
143
|
+
|
|
144
|
+
dx = np.asarray(dx, dtype="float64")
|
|
145
|
+
dy = np.asarray(dy, dtype="float64")
|
|
146
|
+
if dx.shape != dy.shape:
|
|
147
|
+
raise ValueError(
|
|
148
|
+
f"compute_curvature: dx/dy shape mismatch {dx.shape} vs {dy.shape}"
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
magnitude = np.sqrt(dx**2 + dy**2)
|
|
152
|
+
|
|
153
|
+
# First derivative (real, same np.gradient convention already
|
|
154
|
+
# verified in compute_horizontal_strain: returns (d/d_row, d/d_col)).
|
|
155
|
+
d_mag_drow, d_mag_dcol = np.gradient(magnitude, pixel_size_m)
|
|
156
|
+
# Second derivative -- the real curvature.
|
|
157
|
+
_, curvature_xx = np.gradient(d_mag_dcol, pixel_size_m)
|
|
158
|
+
curvature_yy, _ = np.gradient(d_mag_drow, pixel_size_m)
|
|
159
|
+
|
|
160
|
+
curvature_max = np.maximum(np.abs(curvature_xx), np.abs(curvature_yy))
|
|
161
|
+
|
|
162
|
+
return {
|
|
163
|
+
"curvature_xx": curvature_xx,
|
|
164
|
+
"curvature_yy": curvature_yy,
|
|
165
|
+
"curvature_max": curvature_max,
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def compute_geotechnical_risk_index(
|
|
170
|
+
velocity: Any,
|
|
171
|
+
max_shear_strain: Any,
|
|
172
|
+
curvature: Any,
|
|
173
|
+
config: "RiskMapperConfig | None" = None,
|
|
174
|
+
) -> dict:
|
|
175
|
+
"""
|
|
176
|
+
Real, normalized (0-100) geotechnical risk index combining
|
|
177
|
+
velocity, strain, and curvature -- with real, physically-plausible
|
|
178
|
+
capping on strain before it enters the index at all.
|
|
179
|
+
|
|
180
|
+
Parameters
|
|
181
|
+
----------
|
|
182
|
+
velocity : np.ndarray
|
|
183
|
+
Real displacement velocity magnitude, m/yr (vertical InSAR
|
|
184
|
+
velocity, fused multi-modal velocity, or horizontal magnitude
|
|
185
|
+
-- whichever real quantity is the relevant risk driver for
|
|
186
|
+
your specific site).
|
|
187
|
+
max_shear_strain : np.ndarray
|
|
188
|
+
Real max shear strain (fraction, not %) -- e.g. from
|
|
189
|
+
`compute_horizontal_strain`'s own `exy` output, or a real,
|
|
190
|
+
independently-computed principal shear strain.
|
|
191
|
+
curvature : np.ndarray
|
|
192
|
+
Real curvature magnitude (1/m) -- e.g.
|
|
193
|
+
`compute_curvature(...)["curvature_max"]`.
|
|
194
|
+
config : RiskMapperConfig, optional
|
|
195
|
+
Real, configurable reference scales and combination method.
|
|
196
|
+
|
|
197
|
+
Returns
|
|
198
|
+
-------
|
|
199
|
+
dict
|
|
200
|
+
Real keys: ``"risk_index"`` (0-100, per-pixel), ``"velocity_score"``,
|
|
201
|
+
``"strain_score"``, ``"curvature_score"`` (each 0-100, the real
|
|
202
|
+
per-factor sub-scores before combination), and
|
|
203
|
+
``"n_strain_capped"`` (real count of pixels where the real,
|
|
204
|
+
physical plausibility cap in `config.strain_cap` actually
|
|
205
|
+
triggered -- inspect this; a large number here means a lot of
|
|
206
|
+
your input strain is implausible and worth investigating at
|
|
207
|
+
its real source before trusting this risk map).
|
|
208
|
+
|
|
209
|
+
Notes
|
|
210
|
+
-----
|
|
211
|
+
Real, deliberate combination logic (`config.combination`):
|
|
212
|
+
|
|
213
|
+
- ``"max_weighted"`` (default): the risk index is dominated by
|
|
214
|
+
whichever single real factor is worst, not diluted by averaging
|
|
215
|
+
it with two moderate ones -- matching real geotechnical practice,
|
|
216
|
+
where one severe factor (e.g. curvature alone, even with modest
|
|
217
|
+
velocity and strain) is a real, standalone reason for concern.
|
|
218
|
+
Computed as `0.6 * max(scores) + 0.4 * mean(scores)`.
|
|
219
|
+
- ``"mean"``: a plain, equal-weighted average of the three real
|
|
220
|
+
sub-scores -- provided as a simpler, real alternative, but will
|
|
221
|
+
understate risk in a real scenario where only one factor is
|
|
222
|
+
severe.
|
|
223
|
+
"""
|
|
224
|
+
import numpy as np
|
|
225
|
+
|
|
226
|
+
config = config or RiskMapperConfig()
|
|
227
|
+
|
|
228
|
+
velocity = np.abs(np.asarray(velocity, dtype="float64"))
|
|
229
|
+
strain = np.asarray(max_shear_strain, dtype="float64")
|
|
230
|
+
curvature = np.abs(np.asarray(curvature, dtype="float64"))
|
|
231
|
+
|
|
232
|
+
# Real, physical plausibility cap -- applied BEFORE strain enters
|
|
233
|
+
# the index at all, independent of whatever outlier protection
|
|
234
|
+
# already ran upstream (see this module's own docstring for the
|
|
235
|
+
# real, directly-observed 617% artifact this specifically guards
|
|
236
|
+
# against).
|
|
237
|
+
strain_capped = np.abs(strain)
|
|
238
|
+
n_strain_capped = int((strain_capped > config.strain_cap).sum())
|
|
239
|
+
strain_capped = np.clip(strain_capped, 0, config.strain_cap)
|
|
240
|
+
|
|
241
|
+
velocity_score = np.clip(
|
|
242
|
+
100 * velocity / config.max_severe_velocity_m_per_year, 0, 100
|
|
243
|
+
)
|
|
244
|
+
strain_score = np.clip(100 * strain_capped / config.max_severe_strain, 0, 100)
|
|
245
|
+
curvature_score = np.clip(
|
|
246
|
+
100 * curvature / config.max_severe_curvature_per_m, 0, 100
|
|
247
|
+
)
|
|
248
|
+
|
|
249
|
+
if config.combination == "max_weighted":
|
|
250
|
+
stacked = np.stack([velocity_score, strain_score, curvature_score])
|
|
251
|
+
risk_index = 0.6 * stacked.max(axis=0) + 0.4 * stacked.mean(axis=0)
|
|
252
|
+
elif config.combination == "mean":
|
|
253
|
+
risk_index = (velocity_score + strain_score + curvature_score) / 3.0
|
|
254
|
+
else:
|
|
255
|
+
raise ValueError(
|
|
256
|
+
f"compute_geotechnical_risk_index: config.combination must be "
|
|
257
|
+
f"'max_weighted' or 'mean', got {config.combination!r}"
|
|
258
|
+
)
|
|
259
|
+
|
|
260
|
+
if n_strain_capped > 0:
|
|
261
|
+
logger.warning(
|
|
262
|
+
"compute_geotechnical_risk_index: %d pixels had strain above the "
|
|
263
|
+
"real physical plausibility cap (%.1f%%) and were clipped -- "
|
|
264
|
+
"investigate the real source of these values before trusting "
|
|
265
|
+
"this risk map at those pixels.",
|
|
266
|
+
n_strain_capped,
|
|
267
|
+
100 * config.strain_cap,
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
return {
|
|
271
|
+
"risk_index": np.clip(risk_index, 0, 100),
|
|
272
|
+
"velocity_score": velocity_score,
|
|
273
|
+
"strain_score": strain_score,
|
|
274
|
+
"curvature_score": curvature_score,
|
|
275
|
+
"n_strain_capped": n_strain_capped,
|
|
276
|
+
}
|