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.
Files changed (144) hide show
  1. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/CHANGELOG.md +6 -6
  2. {pygeofetch-2.0.1/pygeofetch.egg-info → pygeofetch-2.0.2}/PKG-INFO +2 -2
  3. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/__init__.py +2 -2
  4. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/cli/main.py +2 -2
  5. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/insar/__init__.py +1 -0
  6. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/insar/deburst.py +38 -56
  7. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/insar/interferogram.py +688 -783
  8. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/meta.yaml +1 -1
  9. {pygeofetch-2.0.1 → pygeofetch-2.0.2/pygeofetch.egg-info}/PKG-INFO +2 -2
  10. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch.egg-info/requires.txt +1 -1
  11. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pyproject.toml +2 -2
  12. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/LICENSE +0 -0
  13. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/MANIFEST.in +0 -0
  14. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/README.md +0 -0
  15. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/cli/__init__.py +0 -0
  16. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/cli/auth_commands.py +0 -0
  17. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/cli/config_commands.py +0 -0
  18. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/cli/download_commands.py +0 -0
  19. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/cli/index_commands.py +0 -0
  20. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/cli/pipeline_process_commands.py +0 -0
  21. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/cli/postprocess_commands.py +0 -0
  22. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/cli/preprocess_commands.py +0 -0
  23. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/cli/sar_commands.py +0 -0
  24. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/cli/search_commands.py +0 -0
  25. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/config/__init__.py +0 -0
  26. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/config/defaults.yaml +0 -0
  27. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/config/settings.py +0 -0
  28. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/core/__init__.py +0 -0
  29. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/core/authenticator.py +0 -0
  30. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/core/cache_manager.py +0 -0
  31. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/core/downloader.py +0 -0
  32. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/core/engine.py +0 -0
  33. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/core/logging.py +0 -0
  34. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/core/orbits.py +0 -0
  35. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/core/scheduler.py +0 -0
  36. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/core/searcher.py +0 -0
  37. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/insar/annotation.py +0 -0
  38. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/insar/atmosphere.py +0 -0
  39. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/insar/coregister.py +0 -0
  40. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/insar/esd.py +0 -0
  41. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/insar/extraction.py +0 -0
  42. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/insar/flatearth.py +0 -0
  43. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/insar/geolocation.py +0 -0
  44. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/insar/gpu.py +0 -0
  45. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/insar/ionosphere.py +0 -0
  46. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/insar/splitspectrum_diagnostic.py +0 -0
  47. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/insar/stack_selection.py +0 -0
  48. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/insar/synthetic.py +0 -0
  49. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/insar/timeseries.py +0 -0
  50. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/insar/unwrap.py +0 -0
  51. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/insar/validate.py +0 -0
  52. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/insar/visualize.py +0 -0
  53. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/insar/workflow.py +0 -0
  54. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/models/__init__.py +0 -0
  55. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/models/download_task.py +0 -0
  56. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/models/satellite_data.py +0 -0
  57. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/models/search_query.py +0 -0
  58. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/models/user_auth.py +0 -0
  59. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/processing/__init__.py +0 -0
  60. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/processing/base.py +0 -0
  61. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/processing/batch.py +0 -0
  62. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/processing/indices.py +0 -0
  63. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/processing/pipeline.py +0 -0
  64. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/processing/postprocessor.py +0 -0
  65. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/processing/preprocessor.py +0 -0
  66. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/processing/sar.py +0 -0
  67. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/processor/__init__.py +0 -0
  68. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/processor/indices.py +0 -0
  69. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/processor/landsat.py +0 -0
  70. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/processor/loader.py +0 -0
  71. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/processor/stacker.py +0 -0
  72. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/processor/timeseries.py +0 -0
  73. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/__init__.py +0 -0
  74. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/airbus_oneatlas.py +0 -0
  75. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/alaska_satellite_facility.py +0 -0
  76. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/aws_earth.py +0 -0
  77. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/base.py +0 -0
  78. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/copernicus.py +0 -0
  79. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/digitalglobe.py +0 -0
  80. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/earth_explorer_additional.py +0 -0
  81. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/element84.py +0 -0
  82. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/eodag_provider.py +0 -0
  83. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/esa_scihub.py +0 -0
  84. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/geoserver_generic.py +0 -0
  85. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/google_earth_engine.py +0 -0
  86. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/inpe_cbers.py +0 -0
  87. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/isro_bhuvan.py +0 -0
  88. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/jaxa_earth.py +0 -0
  89. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/maxar_gbdx.py +0 -0
  90. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/nasa_earthdata.py +0 -0
  91. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/nasa_earthdata_cloud.py +0 -0
  92. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/noaa_big_data.py +0 -0
  93. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/opentopography.py +0 -0
  94. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/planet.py +0 -0
  95. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/planetary_computer.py +0 -0
  96. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/sentinel_hub.py +0 -0
  97. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/terrabotics.py +0 -0
  98. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/providers/usgs.py +0 -0
  99. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/sar/__init__.py +0 -0
  100. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/sar/_native.py +0 -0
  101. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/sar/_ost.py +0 -0
  102. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/sar/_sarxarray.py +0 -0
  103. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/sar/extraction.py +0 -0
  104. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/sar/processor.py +0 -0
  105. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/utils/__init__.py +0 -0
  106. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/utils/file_utils.py +0 -0
  107. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/utils/gcp_recovery.py +0 -0
  108. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/utils/geo_utils.py +0 -0
  109. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/utils/logging_setup.py +0 -0
  110. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/utils/retry_handler.py +0 -0
  111. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/utils/validators.py +0 -0
  112. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/viz/__init__.py +0 -0
  113. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/viz/map.py +0 -0
  114. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch/viz/plot.py +0 -0
  115. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch.egg-info/SOURCES.txt +0 -0
  116. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch.egg-info/dependency_links.txt +0 -0
  117. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch.egg-info/entry_points.txt +0 -0
  118. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch.egg-info/not-zip-safe +0 -0
  119. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/pygeofetch.egg-info/top_level.txt +0 -0
  120. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/setup.cfg +0 -0
  121. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_atmospheric_circular_regression (1).py +0 -0
  122. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_atmospheric_circular_regression.py +0 -0
  123. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_build_sbas_network.py +0 -0
  124. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_burst_metadata.py +0 -0
  125. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_burst_processing_integration.py +0 -0
  126. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_coregister_integration.py +0 -0
  127. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_coregister_upgrades.py +0 -0
  128. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_era5_atmospheric_correction.py +0 -0
  129. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_extraction.py +0 -0
  130. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_flat_earth_phase.py +0 -0
  131. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_gcp_reprojection.py +0 -0
  132. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_insar.py +0 -0
  133. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_ionosphere.py +0 -0
  134. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_models.py +0 -0
  135. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_pgv_integration_contract.py +0 -0
  136. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_provider_geometry_audit (1).py +0 -0
  137. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_provider_geometry_audit.py +0 -0
  138. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_provider_scene_disambiguation.py +0 -0
  139. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_providers.py +0 -0
  140. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_raster_collocation_integration.py +0 -0
  141. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_search_download.py +0 -0
  142. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_splitspectrum_diagnostic.py +0 -0
  143. {pygeofetch-2.0.1 → pygeofetch-2.0.2}/tests/test_utils.py +0 -0
  144. {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.1/).
4
+ Format follows [Keep a Changelog](https://keepachangelog.com/en/2.0.2/).
5
5
 
6
- ## [2.0.1] — 2026-07-29
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.1)
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.1] — 2026-07-12
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.1** | 2026-07-29 | SNAPHU unwrapping fixes, 87.1% reliable pixels |
192
- | **2.0.1** | 2026-07-12 | 22 providers, 17 indices, Sentinel-1C/D |
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.1
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.1; extra == "viz"
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.1 — Universal Satellite Data Pipeline.
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.1"
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.1 main entry point.
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.1 — Universal Satellite Data Pipeline
74
+ PyGeoFetch v2.0.2 — Universal Satellite Data Pipeline
75
75
  ===========================================================
76
76
  Unified access to 22+ satellite data providers.
77
77
 
@@ -158,4 +158,5 @@ __all__ = [
158
158
  "collocate_by_geocoding",
159
159
  "CoregistrationQuality",
160
160
  "select_consistent_geometry",
161
+
161
162
  ]
@@ -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 (step.esa.int/main/wp-content/help/.../TOPSARDeburstOp.html),
7
- not inferred or guessed:
8
-
9
- "In the azimuth direction, bursts are merged according to their
10
- zero Doppler time... The merge time is determined by the average
11
- of the last line of the first burst and the first line of the next
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 -- this is a real, confirmed source
19
- of visible striping and degraded coherence at burst boundaries, and it
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: Real burst metadata from
53
- annotation.parse_burst_info().
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, for every
76
- # adjacent burst pair
77
- cut_in_prev = [None] * n # cut row (local to burst i) ending burst i's kept range
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 + (burst_next_first_line_time - burst_i_last_line_time) / 2
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() / azimuth_time_interval_s
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() / azimuth_time_interval_s
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(data, swath_timing: SwathTiming, azimuth_time_interval_s: float, row_offset: int = 0):
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 — matching SNAP's real behaviour (the
120
- image genuinely shrinks; this is not a masking operation).
107
+ into one continuous array.
121
108
 
122
109
  Args:
123
- data: 2D array (complex SLC, real-valued raster,
124
- whatever a caller needs debursted), full burst
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: If `data` is an already-cropped extract, the real
130
- row offset of `data`'s row 0 within the full-scene
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
- return debursted, first_kept_full_scene_row
164
+
165
+ return debursted, first_kept_full_scene_row