pygeofetch 2.0.1__tar.gz → 2.0.2__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.0.1 → pygeofetch-2.0.2}/CHANGELOG.md +6 -6
- {pygeofetch-2.0.1/pygeofetch.egg-info → pygeofetch-2.0.2}/PKG-INFO +2 -2
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/__init__.py +2 -2
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/cli/main.py +2 -2
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/insar/__init__.py +1 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/insar/deburst.py +38 -56
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/insar/interferogram.py +688 -783
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/meta.yaml +1 -1
- {pygeofetch-2.0.1 → pygeofetch-2.0.2/pygeofetch.egg-info}/PKG-INFO +2 -2
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch.egg-info/requires.txt +1 -1
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pyproject.toml +2 -2
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/LICENSE +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/MANIFEST.in +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/README.md +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/cli/__init__.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/cli/auth_commands.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/cli/config_commands.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/cli/download_commands.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/cli/index_commands.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/cli/pipeline_process_commands.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/cli/postprocess_commands.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/cli/preprocess_commands.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/cli/sar_commands.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/cli/search_commands.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/config/__init__.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/config/defaults.yaml +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/config/settings.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/core/__init__.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/core/authenticator.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/core/cache_manager.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/core/downloader.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/core/engine.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/core/logging.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/core/orbits.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/core/scheduler.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/core/searcher.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/insar/annotation.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/insar/atmosphere.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/insar/coregister.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/insar/esd.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/insar/extraction.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/insar/flatearth.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/insar/geolocation.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/insar/gpu.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/insar/ionosphere.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/insar/splitspectrum_diagnostic.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/insar/stack_selection.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/insar/synthetic.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/insar/timeseries.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/insar/unwrap.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/insar/validate.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/insar/visualize.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/insar/workflow.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/models/__init__.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/models/download_task.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/models/satellite_data.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/models/search_query.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/models/user_auth.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/processing/__init__.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/processing/base.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/processing/batch.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/processing/indices.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/processing/pipeline.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/processing/postprocessor.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/processing/preprocessor.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/processing/sar.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/processor/__init__.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/processor/indices.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/processor/landsat.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/processor/loader.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/processor/stacker.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/processor/timeseries.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/__init__.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/airbus_oneatlas.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/alaska_satellite_facility.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/aws_earth.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/base.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/copernicus.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/digitalglobe.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/earth_explorer_additional.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/element84.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/eodag_provider.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/esa_scihub.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/geoserver_generic.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/google_earth_engine.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/inpe_cbers.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/isro_bhuvan.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/jaxa_earth.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/maxar_gbdx.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/nasa_earthdata.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/nasa_earthdata_cloud.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/noaa_big_data.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/opentopography.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/planet.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/planetary_computer.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/sentinel_hub.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/terrabotics.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/usgs.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/sar/__init__.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/sar/_native.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/sar/_ost.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/sar/_sarxarray.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/sar/extraction.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/sar/processor.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/utils/__init__.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/utils/file_utils.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/utils/gcp_recovery.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/utils/geo_utils.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/utils/logging_setup.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/utils/retry_handler.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/utils/validators.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/viz/__init__.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/viz/map.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/viz/plot.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch.egg-info/SOURCES.txt +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch.egg-info/dependency_links.txt +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch.egg-info/entry_points.txt +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch.egg-info/not-zip-safe +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch.egg-info/top_level.txt +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/setup.cfg +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_atmospheric_circular_regression (1).py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_atmospheric_circular_regression.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_build_sbas_network.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_burst_metadata.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_burst_processing_integration.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_coregister_integration.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_coregister_upgrades.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_era5_atmospheric_correction.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_extraction.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_flat_earth_phase.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_gcp_reprojection.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_insar.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_ionosphere.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_models.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_pgv_integration_contract.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_provider_geometry_audit (1).py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_provider_geometry_audit.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_provider_scene_disambiguation.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_providers.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_raster_collocation_integration.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_search_download.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_splitspectrum_diagnostic.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_utils.py +0 -0
- {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_viz_plot.py +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
3
|
All notable changes to PyGeoFetch are documented here.
|
|
4
|
-
Format follows [Keep a Changelog](https://keepachangelog.com/en/2.0.
|
|
4
|
+
Format follows [Keep a Changelog](https://keepachangelog.com/en/2.0.2/).
|
|
5
5
|
|
|
6
|
-
## [2.0.
|
|
6
|
+
## [2.0.2] — 2026-07-29
|
|
7
7
|
|
|
8
8
|
### Added
|
|
9
9
|
- Major SNAPHU unwrapping improvements for urban InSAR applications
|
|
@@ -51,7 +51,7 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/2.0.1/).
|
|
|
51
51
|
|
|
52
52
|
### Migration Guide
|
|
53
53
|
```python
|
|
54
|
-
# Before (v2.0.
|
|
54
|
+
# Before (v2.0.2)
|
|
55
55
|
unwrapper = PhaseUnwrapper(cost_mode="defo", init_method="mcf")
|
|
56
56
|
unwrapped = unwrapper.unwrap(phase, coherence, nlooks=2.0)
|
|
57
57
|
|
|
@@ -72,7 +72,7 @@ unwrapped = unwrapper.unwrap(
|
|
|
72
72
|
|
|
73
73
|
---
|
|
74
74
|
|
|
75
|
-
## [2.0.
|
|
75
|
+
## [2.0.2] — 2026-07-12
|
|
76
76
|
|
|
77
77
|
### Added
|
|
78
78
|
- Federated search across 22+ satellite data providers
|
|
@@ -188,8 +188,8 @@ unwrapped = unwrapper.unwrap(
|
|
|
188
188
|
|
|
189
189
|
| Version | Date | Key Changes |
|
|
190
190
|
|---------|------------|-------------|
|
|
191
|
-
| **2.0.
|
|
192
|
-
| **2.0.
|
|
191
|
+
| **2.0.2** | 2026-07-29 | SNAPHU unwrapping fixes, 87.1% reliable pixels |
|
|
192
|
+
| **2.0.2** | 2026-07-12 | 22 providers, 17 indices, Sentinel-1C/D |
|
|
193
193
|
| **1.9.2** | 2026-06-15 | Batch processing, parallel downloads |
|
|
194
194
|
| **1.9.1** | 2026-05-20 | 3D terrain, SNAPHU integration, time series |
|
|
195
195
|
| **1.9.0** | 2026-04-25 | Initial public release |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pygeofetch
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.2
|
|
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
|
|
@@ -85,7 +85,7 @@ Requires-Dist: localtileserver>=1.0.0; extra == "viz"
|
|
|
85
85
|
Requires-Dist: ipysheet>=0.6.0; extra == "viz"
|
|
86
86
|
Requires-Dist: ipyleaflet>=0.17.0; extra == "viz"
|
|
87
87
|
Requires-Dist: ipywidgets>=8.0.0; extra == "viz"
|
|
88
|
-
Requires-Dist: ipyevents>=2.0.
|
|
88
|
+
Requires-Dist: ipyevents>=2.0.2; extra == "viz"
|
|
89
89
|
Requires-Dist: ipyfilechooser>=0.6.0; extra == "viz"
|
|
90
90
|
Requires-Dist: sidecar>=0.6.0; extra == "viz"
|
|
91
91
|
Requires-Dist: bokeh>=3.0.0; extra == "viz"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"""
|
|
2
|
-
PyGeoFetch v2.0.
|
|
2
|
+
PyGeoFetch v2.0.2 — Universal Satellite Data Pipeline.
|
|
3
3
|
|
|
4
4
|
Unified access to 22+ satellite data providers with a consistent
|
|
5
5
|
Python API and CLI. Supports authentication management, federated search,
|
|
@@ -30,7 +30,7 @@ CLI::
|
|
|
30
30
|
pygeofetch doctor
|
|
31
31
|
"""
|
|
32
32
|
|
|
33
|
-
__version__ = "2.0.
|
|
33
|
+
__version__ = "2.0.2"
|
|
34
34
|
__author__ = "PyGeoFetch Contributors"
|
|
35
35
|
__license__ = "MIT"
|
|
36
36
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"""
|
|
2
|
-
PyGeoFetch CLI v2.0.
|
|
2
|
+
PyGeoFetch CLI v2.0.2 main entry point.
|
|
3
3
|
|
|
4
4
|
Full command reference:
|
|
5
5
|
pygeofetch auth — credential management
|
|
@@ -71,7 +71,7 @@ def cli(
|
|
|
71
71
|
) -> None:
|
|
72
72
|
"""
|
|
73
73
|
\b
|
|
74
|
-
PyGeoFetch v2.0.
|
|
74
|
+
PyGeoFetch v2.0.2 — Universal Satellite Data Pipeline
|
|
75
75
|
===========================================================
|
|
76
76
|
Unified access to 22+ satellite data providers.
|
|
77
77
|
|
|
@@ -3,32 +3,27 @@ TOPS deburst — remove real burst-boundary overlap/redundancy, matching
|
|
|
3
3
|
SNAP's own S-1 TOPS Deburst operator.
|
|
4
4
|
|
|
5
5
|
Algorithm confirmed directly against ESA's own STEP documentation for
|
|
6
|
-
TOPSARDeburstOp
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
burst. For each range cell, the merging time is quantised to the
|
|
13
|
-
nearest output azimuth cell."
|
|
6
|
+
TOPSARDeburstOp:
|
|
7
|
+
"In the azimuth direction, bursts are merged according to their
|
|
8
|
+
zero Doppler time... The merge time is determined by the average
|
|
9
|
+
of the last line of the first burst and the first line of the next
|
|
10
|
+
burst. For each range cell, the merging time is quantised to the
|
|
11
|
+
nearest output azimuth cell."
|
|
14
12
|
|
|
15
13
|
Why this matters: without deburst, adjacent bursts' real overlap
|
|
16
14
|
regions both remain in the data, and the SAME ground area gets imaged
|
|
17
15
|
twice by two different (radiometrically and phase-wise inconsistent)
|
|
18
|
-
parts of the antenna beam pattern
|
|
19
|
-
of visible striping and degraded coherence at burst boundaries
|
|
20
|
-
was never being corrected anywhere in this pipeline before this module
|
|
21
|
-
(pygeofetch's own existing ESD refinement docstring already admits this
|
|
22
|
-
directly: "has no effect on already-deburst/stripmap data" -- data
|
|
23
|
-
passed through it was never actually deburst).
|
|
16
|
+
parts of the antenna beam pattern — this is a real, confirmed source
|
|
17
|
+
of visible striping and degraded coherence at burst boundaries.
|
|
24
18
|
"""
|
|
25
|
-
|
|
26
19
|
from __future__ import annotations
|
|
27
20
|
|
|
28
21
|
import logging
|
|
29
22
|
from datetime import timedelta
|
|
30
23
|
from typing import List, Tuple
|
|
31
24
|
|
|
25
|
+
import numpy as np
|
|
26
|
+
|
|
32
27
|
from pygeofetch.insar.annotation import SwathTiming
|
|
33
28
|
|
|
34
29
|
logger = logging.getLogger("pygeofetch.insar.deburst")
|
|
@@ -41,23 +36,9 @@ def compute_burst_row_ranges(
|
|
|
41
36
|
Compute each burst's real, kept (non-overlapping) row range, in
|
|
42
37
|
that burst's own local 0-indexed row coordinates.
|
|
43
38
|
|
|
44
|
-
Verified before use: on a small, controlled synthetic case with
|
|
45
|
-
known burst timing, the computed ranges left no gaps and no
|
|
46
|
-
duplicate coverage, and their total length matched an
|
|
47
|
-
independently-computed expected total (span from the first burst's
|
|
48
|
-
start to the last burst's last line, at one line per
|
|
49
|
-
azimuth_time_interval_s) exactly.
|
|
50
|
-
|
|
51
39
|
Args:
|
|
52
|
-
swath_timing:
|
|
53
|
-
|
|
54
|
-
azimuth_time_interval_s: Real per-line time spacing, from the
|
|
55
|
-
same annotation XML's SLCGeometry
|
|
56
|
-
(imageAnnotation/imageInformation/azimuthTimeInterval)
|
|
57
|
-
-- must be the SAME value used for both, since
|
|
58
|
-
the cut-time calculation converts between the
|
|
59
|
-
two bursts' local row coordinates via this
|
|
60
|
-
shared spacing.
|
|
40
|
+
swath_timing: Real burst metadata from annotation.parse_burst_info().
|
|
41
|
+
azimuth_time_interval_s: Real per-line time spacing.
|
|
61
42
|
|
|
62
43
|
Returns:
|
|
63
44
|
List of (keep_start_row, keep_end_row) inclusive, local to
|
|
@@ -72,23 +53,26 @@ def compute_burst_row_ranges(
|
|
|
72
53
|
if n == 1:
|
|
73
54
|
return [(0, lines_per_burst - 1)]
|
|
74
55
|
|
|
75
|
-
# Real cut row, in each side's own local coordinates
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
cut_in_next = [None] * n # cut row (local to burst i) starting burst i's kept range
|
|
56
|
+
# Real cut row, in each side's own local coordinates
|
|
57
|
+
cut_in_prev = [None] * n
|
|
58
|
+
cut_in_next = [None] * n
|
|
79
59
|
|
|
80
60
|
for i in range(n - 1):
|
|
81
61
|
burst_i_last_line_time = bursts[i].azimuth_time + timedelta(
|
|
82
62
|
seconds=(lines_per_burst - 1) * azimuth_time_interval_s
|
|
83
63
|
)
|
|
84
64
|
burst_next_first_line_time = bursts[i + 1].azimuth_time
|
|
85
|
-
cut_time = burst_i_last_line_time + (
|
|
65
|
+
cut_time = burst_i_last_line_time + (
|
|
66
|
+
burst_next_first_line_time - burst_i_last_line_time
|
|
67
|
+
) / 2
|
|
86
68
|
|
|
87
69
|
cut_row_in_i = round(
|
|
88
|
-
(cut_time - bursts[i].azimuth_time).total_seconds()
|
|
70
|
+
(cut_time - bursts[i].azimuth_time).total_seconds()
|
|
71
|
+
/ azimuth_time_interval_s
|
|
89
72
|
)
|
|
90
73
|
cut_row_in_next = round(
|
|
91
|
-
(cut_time - bursts[i + 1].azimuth_time).total_seconds()
|
|
74
|
+
(cut_time - bursts[i + 1].azimuth_time).total_seconds()
|
|
75
|
+
/ azimuth_time_interval_s
|
|
92
76
|
)
|
|
93
77
|
|
|
94
78
|
cut_in_prev[i] = cut_row_in_i
|
|
@@ -100,11 +84,10 @@ def compute_burst_row_ranges(
|
|
|
100
84
|
keep_end = (lines_per_burst - 1) if i == n - 1 else cut_in_prev[i]
|
|
101
85
|
keep_start = max(0, min(keep_start, lines_per_burst - 1))
|
|
102
86
|
keep_end = max(0, min(keep_end, lines_per_burst - 1))
|
|
87
|
+
|
|
103
88
|
if keep_start > keep_end:
|
|
104
89
|
logger.warning(
|
|
105
|
-
"Burst %d: computed keep range is empty (start=%d > end=%d)
|
|
106
|
-
"— unusually large real overlap or unusual burst timing; "
|
|
107
|
-
"this burst will contribute no rows to the debursted result.",
|
|
90
|
+
"Burst %d: computed keep range is empty (start=%d > end=%d)",
|
|
108
91
|
i, keep_start, keep_end,
|
|
109
92
|
)
|
|
110
93
|
ranges.append((keep_start, keep_end))
|
|
@@ -112,30 +95,27 @@ def compute_burst_row_ranges(
|
|
|
112
95
|
return ranges
|
|
113
96
|
|
|
114
97
|
|
|
115
|
-
def deburst_array(
|
|
98
|
+
def deburst_array(
|
|
99
|
+
data: np.ndarray,
|
|
100
|
+
swath_timing: SwathTiming,
|
|
101
|
+
azimuth_time_interval_s: float,
|
|
102
|
+
row_offset: int = 0,
|
|
103
|
+
) -> Tuple[np.ndarray, int]:
|
|
116
104
|
"""
|
|
117
105
|
Apply real deburst to an array: remove each burst's redundant
|
|
118
106
|
overlap rows and concatenate the kept, non-overlapping portions
|
|
119
|
-
into one continuous array
|
|
120
|
-
image genuinely shrinks; this is not a masking operation).
|
|
107
|
+
into one continuous array.
|
|
121
108
|
|
|
122
109
|
Args:
|
|
123
|
-
data:
|
|
124
|
-
|
|
125
|
-
stack — n_bursts * lines_per_burst rows (or the
|
|
126
|
-
real full-scene extent if row_offset is used).
|
|
127
|
-
swath_timing: Real burst metadata from annotation.parse_burst_info().
|
|
110
|
+
data: 2D array (complex SLC, real-valued raster, etc.)
|
|
111
|
+
swath_timing: Real burst metadata from annotation.parse_burst_info().
|
|
128
112
|
azimuth_time_interval_s: Real per-line time spacing.
|
|
129
|
-
row_offset:
|
|
130
|
-
|
|
131
|
-
burst stack. Default 0 assumes `data` already starts
|
|
132
|
-
at the full-scene burst stack's row 0.
|
|
113
|
+
row_offset: If `data` is an already-cropped extract, the real
|
|
114
|
+
row offset of `data`'s row 0 within the full-scene burst stack.
|
|
133
115
|
|
|
134
116
|
Returns:
|
|
135
117
|
(debursted_data, first_kept_full_scene_row)
|
|
136
118
|
"""
|
|
137
|
-
import numpy as np
|
|
138
|
-
|
|
139
119
|
if not isinstance(swath_timing, SwathTiming):
|
|
140
120
|
raise TypeError(
|
|
141
121
|
f"deburst_array expects a SwathTiming object, got "
|
|
@@ -176,8 +156,10 @@ def deburst_array(data, swath_timing: SwathTiming, azimuth_time_interval_s: floa
|
|
|
176
156
|
)
|
|
177
157
|
|
|
178
158
|
debursted = np.concatenate(chunks, axis=0)
|
|
159
|
+
|
|
179
160
|
logger.info(
|
|
180
161
|
"Deburst: %d bursts -> %d output rows (input was %d rows)",
|
|
181
162
|
len(swath_timing.bursts), debursted.shape[0], data.shape[0],
|
|
182
163
|
)
|
|
183
|
-
|
|
164
|
+
|
|
165
|
+
return debursted, first_kept_full_scene_row
|