pygeofetch 2.6.2.2__tar.gz → 2.6.2.4__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.2 → pygeofetch-2.6.2.4}/CHANGELOG.md +7 -7
- {pygeofetch-2.6.2.2/pygeofetch.egg-info → pygeofetch-2.6.2.4}/PKG-INFO +6 -6
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/README.md +4 -4
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/__init__.py +1 -1
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/cli/main.py +3 -1
- pygeofetch-2.6.2.4/pygeofetch/cli/optical_commands.py +105 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/cli/search_commands.py +121 -8
- pygeofetch-2.6.2.4/pygeofetch/core/data_organizer.py +364 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/core/engine.py +7 -2
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/insar/preflight.py +136 -1
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/meta.yaml +1 -1
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/models/satellite_data.py +49 -0
- pygeofetch-2.6.2.4/pygeofetch/optical/__init__.py +27 -0
- pygeofetch-2.6.2.4/pygeofetch/optical/offset_tracking.py +486 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/processor/indices.py +143 -11
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/providers/airbus_oneatlas.py +1 -1
- pygeofetch-2.6.2.4/pygeofetch/providers/alaska_satellite_facility.py +361 -0
- pygeofetch-2.6.2.4/pygeofetch/providers/digitalglobe.py +423 -0
- pygeofetch-2.6.2.4/pygeofetch/providers/earth_explorer_additional.py +104 -0
- pygeofetch-2.6.2.4/pygeofetch/providers/geoserver_generic.py +377 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/providers/inpe_cbers.py +114 -96
- pygeofetch-2.6.2.4/pygeofetch/providers/isro_bhuvan.py +357 -0
- pygeofetch-2.6.2.4/pygeofetch/providers/jaxa_earth.py +276 -0
- pygeofetch-2.6.2.4/pygeofetch/providers/maxar_gbdx.py +298 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/validation/optical_validator.py +69 -33
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/viz/plot.py +24 -5
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4/pygeofetch.egg-info}/PKG-INFO +6 -6
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch.egg-info/SOURCES.txt +19 -0
- pygeofetch-2.6.2.4/pygeofetch.egg-info/top_level.txt +2 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pyproject.toml +3 -3
- pygeofetch-2.6.2.4/tests/test_alaska_satellite_facility.py +217 -0
- pygeofetch-2.6.2.4/tests/test_build_sbas_network.py +191 -0
- pygeofetch-2.6.2.4/tests/test_coregister_upgrades.py +295 -0
- pygeofetch-2.6.2.4/tests/test_data_organizer.py +170 -0
- pygeofetch-2.6.2.4/tests/test_digitalglobe.py +260 -0
- pygeofetch-2.6.2.4/tests/test_earth_explorer_additional.py +94 -0
- pygeofetch-2.6.2.4/tests/test_geology_indices_and_rvi_fix.py +159 -0
- pygeofetch-2.6.2.4/tests/test_geoserver_generic.py +207 -0
- pygeofetch-2.6.2.4/tests/test_inpe_cbers.py +170 -0
- pygeofetch-2.6.2.4/tests/test_isro_bhuvan.py +227 -0
- pygeofetch-2.6.2.4/tests/test_jaxa_earth.py +173 -0
- pygeofetch-2.6.2.4/tests/test_optical_offset_tracking.py +183 -0
- pygeofetch-2.6.2.4/tests/test_optical_validator_stac.py +223 -0
- pygeofetch-2.6.2.4/tests/test_preflight_spatial_baseline.py +152 -0
- pygeofetch-2.6.2.4/tests/test_provider_geometry_audit.py +220 -0
- pygeofetch-2.6.2.2/pygeofetch/providers/alaska_satellite_facility.py +0 -256
- pygeofetch-2.6.2.2/pygeofetch/providers/digitalglobe.py +0 -254
- pygeofetch-2.6.2.2/pygeofetch/providers/earth_explorer_additional.py +0 -254
- pygeofetch-2.6.2.2/pygeofetch/providers/geoserver_generic.py +0 -256
- pygeofetch-2.6.2.2/pygeofetch/providers/isro_bhuvan.py +0 -254
- pygeofetch-2.6.2.2/pygeofetch/providers/jaxa_earth.py +0 -256
- pygeofetch-2.6.2.2/pygeofetch/providers/maxar_gbdx.py +0 -266
- pygeofetch-2.6.2.2/pygeofetch.egg-info/top_level.txt +0 -1
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/LICENSE +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/MANIFEST.in +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/cli/__init__.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/cli/auth_commands.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/cli/config_commands.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/cli/download_commands.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/cli/index_commands.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/cli/monitor_commands.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/cli/pipeline_process_commands.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/cli/postprocess_commands.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/cli/preprocess_commands.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/cli/sar_commands.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/config/__init__.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/config/defaults.yaml +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/config/settings.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/core/__init__.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/core/authenticator.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/core/cache_manager.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/core/downloader.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/core/logging.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/core/monitor.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/core/orbits.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/core/scheduler.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/core/searcher.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/core/state.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/insar/__init__.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/insar/analysis.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/insar/annotation.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/insar/atmosphere.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/insar/coregister.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/insar/deburst.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/insar/esd.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/insar/extraction.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/insar/flatearth.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/insar/geolocation.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/insar/gpu.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/insar/interferogram.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/insar/ionosphere.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/insar/offset_geometry.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/insar/offset_tracking.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/insar/provenance.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/insar/ps_selection.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/insar/splitspectrum_diagnostic.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/insar/stack_selection.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/insar/synthetic.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/insar/timeseries.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/insar/unwrap.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/insar/validate.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/insar/visualize.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/insar/workflow.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/models/__init__.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/models/download_task.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/models/search_query.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/models/user_auth.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/processing/__init__.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/processing/base.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/processing/batch.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/processing/indices.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/processing/pipeline.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/processing/postprocessor.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/processing/preprocessor.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/processing/sar.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/processor/__init__.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/processor/landsat.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/processor/loader.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/processor/stacker.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/processor/timeseries.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/providers/__init__.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/providers/aws_earth.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/providers/base.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/providers/copernicus.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/providers/copernicus_nodes.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/providers/element84.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/providers/eodag_provider.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/providers/esa_scihub.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/providers/google_earth_engine.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/providers/nasa_earthdata.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/providers/nasa_earthdata_cloud.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/providers/noaa_big_data.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/providers/opentopography.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/providers/planet.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/providers/planetary_computer.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/providers/sentinel_hub.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/providers/terrabotics.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/providers/usgs.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/sar/__init__.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/sar/_native.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/sar/_ost.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/sar/_sarxarray.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/sar/extraction.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/sar/processor.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/utils/__init__.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/utils/file_utils.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/utils/gcp_recovery.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/utils/geo_utils.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/utils/logging_setup.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/utils/retry_handler.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/utils/validators.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/validation/__init__.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/viz/__init__.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch/viz/map.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch.egg-info/dependency_links.txt +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch.egg-info/entry_points.txt +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch.egg-info/not-zip-safe +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/pygeofetch.egg-info/requires.txt +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/setup.cfg +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/tests/test_airbus_oneatlas.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/tests/test_atmospheric_circular_regression.py +0 -0
- /pygeofetch-2.6.2.2/tests/test_build_sbas_network.py → /pygeofetch-2.6.2.4/tests/test_build_sbas_network-new.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/tests/test_burst_metadata.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/tests/test_burst_processing_integration.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/tests/test_burst_sync_large_gap.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/tests/test_burst_sync_prescreening.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/tests/test_burst_synchronization.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/tests/test_circuit_breaker_wiring.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/tests/test_cli_optical_validation.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/tests/test_copernicus_nodes.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/tests/test_coregister_integration.py +0 -0
- /pygeofetch-2.6.2.2/tests/test_coregister_upgrades.py → /pygeofetch-2.6.2.4/tests/test_coregister_upgrades (1).py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/tests/test_credential_encryption.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/tests/test_era5_atmospheric_correction.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/tests/test_esa_scihub.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/tests/test_extraction.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/tests/test_flat_earth_phase.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/tests/test_gcp_reprojection.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/tests/test_google_earth_engine.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/tests/test_insar.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/tests/test_ionosphere.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/tests/test_map_preview_consolidation.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/tests/test_models.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/tests/test_monitor.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/tests/test_noaa_big_data.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/tests/test_offset_tracking.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/tests/test_optical_validation_wiring.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/tests/test_optical_validator.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/tests/test_pgv_integration_contract.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/tests/test_pipeline_process_export.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/tests/test_preflight_gate.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/tests/test_provider_geometry_audit (1).py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/tests/test_provider_scene_disambiguation.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/tests/test_providers.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/tests/test_ps_selection.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/tests/test_raster_collocation_integration.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/tests/test_reference_pixel_and_despike.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/tests/test_risk_mapping.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/tests/test_screen_stack_orchestration.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/tests/test_search_download.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/tests/test_sign_convention.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/tests/test_splitspectrum_diagnostic.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/tests/test_stack_selection_consolidation.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/tests/test_state.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/tests/test_topo_r2_bug.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/tests/test_utils.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/tests/test_viz_plot.py +0 -0
- {pygeofetch-2.6.2.2 → pygeofetch-2.6.2.4}/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.4.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.4.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] — 2026-08-24
|
|
152
|
+
## [2.6.2.4] — 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.4.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.4.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.4.4`**, dated
|
|
410
|
+
2026-07-29 and 2026-07-12. **2.6.2.4.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.4
|
|
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
|
|
@@ -26,7 +26,7 @@ License: MIT License
|
|
|
26
26
|
SOFTWARE.
|
|
27
27
|
|
|
28
28
|
Project-URL: Homepage, https://www.eocoreint.com/
|
|
29
|
-
Project-URL: Documentation, https://
|
|
29
|
+
Project-URL: Documentation, https://appiahkubis14.github.io/pygeofetch-docs/
|
|
30
30
|
Project-URL: Repository, https://github.com/EOCoreINT/pygeofetch
|
|
31
31
|
Project-URL: Bug Tracker, https://github.com/EOCoreINT/pygeofetch/issues
|
|
32
32
|
Keywords: satellite,remote-sensing,GIS,earth-observation,geospatial,SAR,Sentinel,Landsat
|
|
@@ -153,9 +153,9 @@ Dynamic: license-file
|
|
|
153
153
|
|
|
154
154
|
[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)
|
|
155
155
|
|
|
156
|
-
<br>
|
|
157
|
-
<img src="icon/concept_a.png" alt="PyGeoFetch Logo" width="350">
|
|
158
|
-
<br>
|
|
156
|
+
<!-- <br>
|
|
157
|
+
<img src="https://raw.githubusercontent.com/EOCoreINT/pygeofetch/refs/heads/main/icon/concept_a.png" alt="PyGeoFetch Logo" width="350">
|
|
158
|
+
<br> -->
|
|
159
159
|
|
|
160
160
|
</div>
|
|
161
161
|
|
|
@@ -386,7 +386,7 @@ If you use PyGeoFetch in your research or operational work, please cite it using
|
|
|
386
386
|
title = {PyGeoFetch: A Unified Python Framework for Multi-Provider Satellite Data Acquisition, Pre-download Quality Control, and Geospatial Processing},
|
|
387
387
|
year = {2026},
|
|
388
388
|
publisher = {Zenodo},
|
|
389
|
-
version = {2.6.2.
|
|
389
|
+
version = {2.6.2.4.1},
|
|
390
390
|
doi = {10.5281/zenodo.22087230},
|
|
391
391
|
url = {https://doi.org/10.5281/zenodo.22087230}
|
|
392
392
|
}
|
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
|
|
12
12
|
[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
13
|
|
|
14
|
-
<br>
|
|
15
|
-
<img src="icon/concept_a.png" alt="PyGeoFetch Logo" width="350">
|
|
16
|
-
<br>
|
|
14
|
+
<!-- <br>
|
|
15
|
+
<img src="https://raw.githubusercontent.com/EOCoreINT/pygeofetch/refs/heads/main/icon/concept_a.png" alt="PyGeoFetch Logo" width="350">
|
|
16
|
+
<br> -->
|
|
17
17
|
|
|
18
18
|
</div>
|
|
19
19
|
|
|
@@ -244,7 +244,7 @@ If you use PyGeoFetch in your research or operational work, please cite it using
|
|
|
244
244
|
title = {PyGeoFetch: A Unified Python Framework for Multi-Provider Satellite Data Acquisition, Pre-download Quality Control, and Geospatial Processing},
|
|
245
245
|
year = {2026},
|
|
246
246
|
publisher = {Zenodo},
|
|
247
|
-
version = {2.6.2.
|
|
247
|
+
version = {2.6.2.4.1},
|
|
248
248
|
doi = {10.5281/zenodo.22087230},
|
|
249
249
|
url = {https://doi.org/10.5281/zenodo.22087230}
|
|
250
250
|
}
|
|
@@ -26,6 +26,7 @@ from pygeofetch.cli.auth_commands import auth
|
|
|
26
26
|
from pygeofetch.cli.config_commands import config
|
|
27
27
|
from pygeofetch.cli.download_commands import download
|
|
28
28
|
from pygeofetch.cli.index_commands import index
|
|
29
|
+
from pygeofetch.cli.optical_commands import optical
|
|
29
30
|
from pygeofetch.cli.pipeline_process_commands import proc_pipeline
|
|
30
31
|
from pygeofetch.cli.postprocess_commands import post
|
|
31
32
|
from pygeofetch.cli.preprocess_commands import preprocess
|
|
@@ -103,6 +104,7 @@ cli.add_command(index)
|
|
|
103
104
|
cli.add_command(post)
|
|
104
105
|
cli.add_command(sar)
|
|
105
106
|
cli.add_command(proc_pipeline)
|
|
107
|
+
cli.add_command(optical)
|
|
106
108
|
|
|
107
109
|
|
|
108
110
|
# ---------------------------------------------------------------------------
|
|
@@ -919,4 +921,4 @@ def main() -> None:
|
|
|
919
921
|
|
|
920
922
|
|
|
921
923
|
if __name__ == "__main__":
|
|
922
|
-
main()
|
|
924
|
+
main()
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"""CLI commands for optical pixel offset tracking (POT)."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import sys
|
|
6
|
+
|
|
7
|
+
import click
|
|
8
|
+
from rich.console import Console
|
|
9
|
+
|
|
10
|
+
console = Console()
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@click.group()
|
|
14
|
+
def optical() -> None:
|
|
15
|
+
"""Optical pixel offset tracking — measures large 2D ground
|
|
16
|
+
displacement via image correlation, complementing InSAR for
|
|
17
|
+
motion that exceeds phase InSAR's coherence limit."""
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@optical.command("offset-track")
|
|
21
|
+
@click.option("--ref", "reference_path", required=True, type=click.Path(exists=True), help="Reference-date raster.")
|
|
22
|
+
@click.option("--sec", "secondary_path", required=True, type=click.Path(exists=True), help="Secondary-date raster.")
|
|
23
|
+
@click.option("--output", "-o", required=True, type=click.Path(), help="Output GeoTIFF (dx/dy/snr, 3 bands).")
|
|
24
|
+
@click.option("--band", default=1, show_default=True, type=int, help="1-based band index to correlate.")
|
|
25
|
+
@click.option("--window-size", default=64, show_default=True, type=int, help="Search window size, pixels.")
|
|
26
|
+
@click.option("--step-size", default=16, show_default=True, type=int, help="Spacing between window centers, pixels.")
|
|
27
|
+
@click.option("--chip-size", default=None, type=int, help="Reference template size, pixels. Default: window-size // 2.")
|
|
28
|
+
@click.option("--snr-threshold", default=3.0, show_default=True, type=float, help="Minimum SNR to mark a window reliable.")
|
|
29
|
+
@click.option("--cloud-mask", default=None, type=click.Path(exists=True), help="Real Sentinel-2 SCL raster, already aligned to --ref.")
|
|
30
|
+
@click.option("--water-mask-threshold", default=None, type=float, help="Mask pixels where NDWI exceeds this value (needs --green-band/--nir-band).")
|
|
31
|
+
@click.option("--green-band", default=None, type=int, help="1-based green band index, for --water-mask-threshold.")
|
|
32
|
+
@click.option("--nir-band", default=None, type=int, help="1-based NIR band index, for --water-mask-threshold.")
|
|
33
|
+
def offset_track_cmd(
|
|
34
|
+
reference_path,
|
|
35
|
+
secondary_path,
|
|
36
|
+
output,
|
|
37
|
+
band,
|
|
38
|
+
window_size,
|
|
39
|
+
step_size,
|
|
40
|
+
chip_size,
|
|
41
|
+
snr_threshold,
|
|
42
|
+
cloud_mask,
|
|
43
|
+
water_mask_threshold,
|
|
44
|
+
green_band,
|
|
45
|
+
nir_band,
|
|
46
|
+
):
|
|
47
|
+
"""
|
|
48
|
+
Measure 2D ground displacement between two optical scenes via
|
|
49
|
+
image correlation.
|
|
50
|
+
|
|
51
|
+
\b
|
|
52
|
+
Examples:
|
|
53
|
+
# Basic: two co-registered scenes, real cloud masking via SCL
|
|
54
|
+
pygeofetch optical offset-track \\
|
|
55
|
+
--ref before.tif --sec after.tif \\
|
|
56
|
+
--cloud-mask before_SCL.tif \\
|
|
57
|
+
--output displacement.tif
|
|
58
|
+
|
|
59
|
+
# Mining-scale displacement, larger search window
|
|
60
|
+
pygeofetch optical offset-track \\
|
|
61
|
+
--ref jan.tif --sec jun.tif \\
|
|
62
|
+
--window-size 96 --step-size 24 \\
|
|
63
|
+
--output mine_displacement.tif
|
|
64
|
+
"""
|
|
65
|
+
from pygeofetch.optical.offset_tracking import compute_pixel_offsets, prepare_optical_pair
|
|
66
|
+
|
|
67
|
+
try:
|
|
68
|
+
ref_arr, sec_arr, ref_profile = prepare_optical_pair(
|
|
69
|
+
reference_path,
|
|
70
|
+
secondary_path,
|
|
71
|
+
band_index=band,
|
|
72
|
+
cloud_mask_path=cloud_mask,
|
|
73
|
+
water_mask_threshold=water_mask_threshold,
|
|
74
|
+
green_band_index=green_band,
|
|
75
|
+
nir_band_index=nir_band,
|
|
76
|
+
)
|
|
77
|
+
except ValueError as exc:
|
|
78
|
+
console.print(f"[red]✗[/] {exc}")
|
|
79
|
+
sys.exit(1)
|
|
80
|
+
|
|
81
|
+
pixel_size_m = abs(ref_profile["transform"].a)
|
|
82
|
+
result = compute_pixel_offsets(
|
|
83
|
+
ref_arr,
|
|
84
|
+
sec_arr,
|
|
85
|
+
pixel_size_m=pixel_size_m,
|
|
86
|
+
window_size=window_size,
|
|
87
|
+
step_size=step_size,
|
|
88
|
+
chip_size=chip_size,
|
|
89
|
+
snr_threshold=snr_threshold,
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
out_transform = ref_profile["transform"] * ref_profile["transform"].scale(step_size, step_size)
|
|
93
|
+
out_profile = dict(ref_profile)
|
|
94
|
+
out_profile.update(
|
|
95
|
+
height=result.dx.shape[0],
|
|
96
|
+
width=result.dx.shape[1],
|
|
97
|
+
transform=out_transform,
|
|
98
|
+
)
|
|
99
|
+
written = result.export_geotiff(output, out_profile)
|
|
100
|
+
|
|
101
|
+
n_reliable = int(result.reliable.sum())
|
|
102
|
+
n_total = int(result.reliable.size)
|
|
103
|
+
console.print(f"[green]✓[/] offset-track → {written}")
|
|
104
|
+
console.print(f" {n_reliable}/{n_total} windows reliable ({100 * n_reliable / n_total:.1f}%)")
|
|
105
|
+
console.print(f" window={window_size}px step={step_size}px pixel_size={pixel_size_m:.2f}m")
|
|
@@ -282,6 +282,7 @@ def search_run(
|
|
|
282
282
|
|
|
283
283
|
sb = PyGeoFetch()
|
|
284
284
|
|
|
285
|
+
optical_config = None
|
|
285
286
|
if validate_optical and (
|
|
286
287
|
optical_max_cloud_cover,
|
|
287
288
|
optical_min_coverage,
|
|
@@ -298,22 +299,48 @@ def search_run(
|
|
|
298
299
|
overrides["required_bands"] = [
|
|
299
300
|
b.strip() for b in optical_required_bands.split(",")
|
|
300
301
|
]
|
|
301
|
-
|
|
302
|
+
optical_config = OpticalValidationConfig(**overrides)
|
|
303
|
+
sb.optical_validation_config = optical_config
|
|
302
304
|
|
|
303
305
|
with console.status(
|
|
304
306
|
f"[cyan]Searching {len(provider_list or [])} provider(s)...[/]"
|
|
305
307
|
):
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
308
|
+
if validate_optical:
|
|
309
|
+
# Real, deliberate choice: search WITHOUT filtering here, then
|
|
310
|
+
# validate directly in this CLI layer, rather than calling
|
|
311
|
+
# search(validate_optical=True) and losing visibility into
|
|
312
|
+
# what got rejected and why. sb.search()'s own contract
|
|
313
|
+
# (returns only the passed scenes) is left untouched for
|
|
314
|
+
# every other caller -- this is a CLI-only reporting path,
|
|
315
|
+
# not a change to the library's real filtering behavior.
|
|
316
|
+
raw_results = sb.search(
|
|
317
|
+
query,
|
|
318
|
+
providers=provider_list,
|
|
319
|
+
use_cache=not no_cache,
|
|
320
|
+
validate_optical=False,
|
|
321
|
+
)
|
|
322
|
+
results, validation_summary = _validate_and_summarize(
|
|
323
|
+
sb, raw_results, query, optical_config
|
|
324
|
+
)
|
|
325
|
+
else:
|
|
326
|
+
results = sb.search(
|
|
327
|
+
query,
|
|
328
|
+
providers=provider_list,
|
|
329
|
+
use_cache=not no_cache,
|
|
330
|
+
validate_optical=False,
|
|
331
|
+
)
|
|
332
|
+
validation_summary = None
|
|
312
333
|
|
|
313
334
|
if not results:
|
|
314
335
|
console.print("[yellow]No results found.[/]")
|
|
315
336
|
return
|
|
316
337
|
|
|
338
|
+
# Real, clean validation info + full results table, organized so the
|
|
339
|
+
# summary always appears before the detailed table -- not interleaved
|
|
340
|
+
# with save/format output below.
|
|
341
|
+
if validation_summary is not None:
|
|
342
|
+
_display_validation_summary(validation_summary)
|
|
343
|
+
|
|
317
344
|
# Save if requested
|
|
318
345
|
if output:
|
|
319
346
|
out_path = Path(output)
|
|
@@ -365,6 +392,92 @@ def search_run(
|
|
|
365
392
|
click.echo(r.id)
|
|
366
393
|
|
|
367
394
|
|
|
395
|
+
def _validate_and_summarize(sb, raw_results, query, optical_config):
|
|
396
|
+
"""
|
|
397
|
+
Real validation pass over every raw candidate, returning both the
|
|
398
|
+
scenes that actually pass and a real, structured summary of what got
|
|
399
|
+
rejected and why -- the information sb.search(validate_optical=True)
|
|
400
|
+
alone discards once it returns only the filtered list.
|
|
401
|
+
"""
|
|
402
|
+
from collections import Counter
|
|
403
|
+
|
|
404
|
+
from pygeofetch.validation import OpticalPreflightValidator, OpticalValidationConfig
|
|
405
|
+
|
|
406
|
+
validator = OpticalPreflightValidator(optical_config or OpticalValidationConfig())
|
|
407
|
+
aoi = sb._derive_aoi_polygon(query)
|
|
408
|
+
|
|
409
|
+
passed_results = []
|
|
410
|
+
rejection_reasons: Counter = Counter()
|
|
411
|
+
warning_reasons: Counter = Counter()
|
|
412
|
+
n_warned_but_passed = 0
|
|
413
|
+
|
|
414
|
+
for scene in raw_results:
|
|
415
|
+
report = validator.validate_scene(scene, aoi, query.start_date, query.end_date)
|
|
416
|
+
if report.passed:
|
|
417
|
+
passed_results.append(scene)
|
|
418
|
+
if report.issues:
|
|
419
|
+
n_warned_but_passed += 1
|
|
420
|
+
for issue in report.issues:
|
|
421
|
+
warning_reasons[issue.code] += 1
|
|
422
|
+
else:
|
|
423
|
+
for issue in report.issues:
|
|
424
|
+
if issue.severity == "ERROR":
|
|
425
|
+
rejection_reasons[issue.code] += 1
|
|
426
|
+
|
|
427
|
+
summary = {
|
|
428
|
+
"n_total": len(raw_results),
|
|
429
|
+
"n_passed": len(passed_results),
|
|
430
|
+
"n_rejected": len(raw_results) - len(passed_results),
|
|
431
|
+
"n_warned_but_passed": n_warned_but_passed,
|
|
432
|
+
"rejection_reasons": rejection_reasons,
|
|
433
|
+
"warning_reasons": warning_reasons,
|
|
434
|
+
}
|
|
435
|
+
return passed_results, summary
|
|
436
|
+
|
|
437
|
+
|
|
438
|
+
def _display_validation_summary(summary: dict) -> None:
|
|
439
|
+
"""Clean, real info block summarizing optical validation -- shown
|
|
440
|
+
before the detailed results table, not interleaved with it."""
|
|
441
|
+
n_total = summary["n_total"]
|
|
442
|
+
n_passed = summary["n_passed"]
|
|
443
|
+
n_rejected = summary["n_rejected"]
|
|
444
|
+
pct = (100 * n_passed / n_total) if n_total else 0.0
|
|
445
|
+
|
|
446
|
+
console.print(
|
|
447
|
+
f"\n[bold]Optical validation:[/] {n_passed}/{n_total} scenes passed "
|
|
448
|
+
f"({pct:.0f}%)"
|
|
449
|
+
+ (f", [yellow]{n_rejected} rejected[/]" if n_rejected else "")
|
|
450
|
+
+ (
|
|
451
|
+
f", [cyan]{summary['n_warned_but_passed']} passed with warnings[/]"
|
|
452
|
+
if summary["n_warned_but_passed"]
|
|
453
|
+
else ""
|
|
454
|
+
)
|
|
455
|
+
)
|
|
456
|
+
|
|
457
|
+
if summary["rejection_reasons"]:
|
|
458
|
+
reasons_table = Table(
|
|
459
|
+
title="Rejection reasons", header_style="bold red", show_lines=False
|
|
460
|
+
)
|
|
461
|
+
reasons_table.add_column("Code", style="red")
|
|
462
|
+
reasons_table.add_column("Count", justify="right")
|
|
463
|
+
for code, count in summary["rejection_reasons"].most_common():
|
|
464
|
+
reasons_table.add_row(code, str(count))
|
|
465
|
+
console.print(reasons_table)
|
|
466
|
+
|
|
467
|
+
if summary["warning_reasons"]:
|
|
468
|
+
warn_table = Table(
|
|
469
|
+
title="Warnings on passed scenes",
|
|
470
|
+
header_style="bold yellow",
|
|
471
|
+
show_lines=False,
|
|
472
|
+
)
|
|
473
|
+
warn_table.add_column("Code", style="yellow")
|
|
474
|
+
warn_table.add_column("Count", justify="right")
|
|
475
|
+
for code, count in summary["warning_reasons"].most_common():
|
|
476
|
+
warn_table.add_row(code, str(count))
|
|
477
|
+
console.print(warn_table)
|
|
478
|
+
console.print() # real spacing before the full results table below
|
|
479
|
+
|
|
480
|
+
|
|
368
481
|
def _display_table(results) -> None:
|
|
369
482
|
table = Table(title=f"{len(results)} Results", header_style="bold blue")
|
|
370
483
|
table.add_column("ID", style="cyan", max_width=30)
|
|
@@ -441,4 +554,4 @@ def _save_csv(results, path: Path) -> None:
|
|
|
441
554
|
)
|
|
442
555
|
writer.writeheader()
|
|
443
556
|
for r in results:
|
|
444
|
-
writer.writerow(_item_to_dict(r))
|
|
557
|
+
writer.writerow(_item_to_dict(r))
|