PyGeoFetch 2.0.6__tar.gz → 2.0.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.0.6 → pygeofetch-2.0.7}/CHANGELOG.md +6 -6
- {pygeofetch-2.0.6/pygeofetch.egg-info → pygeofetch-2.0.7}/PKG-INFO +1 -1
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/__init__.py +2 -2
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/cli/main.py +2 -2
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/insar/unwrap.py +83 -21
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/meta.yaml +1 -1
- {pygeofetch-2.0.6 → pygeofetch-2.0.7/pygeofetch.egg-info}/PKG-INFO +1 -1
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pyproject.toml +1 -1
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/LICENSE +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/MANIFEST.in +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/README.md +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/cli/__init__.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/cli/auth_commands.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/cli/config_commands.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/cli/download_commands.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/cli/index_commands.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/cli/pipeline_process_commands.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/cli/postprocess_commands.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/cli/preprocess_commands.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/cli/sar_commands.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/cli/search_commands.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/config/__init__.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/config/defaults.yaml +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/config/settings.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/core/__init__.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/core/authenticator.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/core/cache_manager.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/core/downloader.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/core/engine.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/core/logging.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/core/orbits.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/core/scheduler.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/core/searcher.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/insar/__init__.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/insar/annotation.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/insar/atmosphere.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/insar/coregister.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/insar/deburst.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/insar/esd.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/insar/extraction.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/insar/flatearth.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/insar/geolocation.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/insar/gpu.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/insar/interferogram.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/insar/ionosphere.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/insar/splitspectrum_diagnostic.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/insar/stack_selection.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/insar/synthetic.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/insar/timeseries.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/insar/validate.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/insar/visualize.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/insar/workflow.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/models/__init__.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/models/download_task.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/models/satellite_data.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/models/search_query.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/models/user_auth.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/processing/__init__.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/processing/base.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/processing/batch.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/processing/indices.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/processing/pipeline.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/processing/postprocessor.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/processing/preprocessor.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/processing/sar.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/processor/__init__.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/processor/indices.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/processor/landsat.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/processor/loader.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/processor/stacker.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/processor/timeseries.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/providers/__init__.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/providers/airbus_oneatlas.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/providers/alaska_satellite_facility.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/providers/aws_earth.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/providers/base.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/providers/copernicus.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/providers/digitalglobe.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/providers/earth_explorer_additional.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/providers/element84.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/providers/eodag_provider.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/providers/esa_scihub.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/providers/geoserver_generic.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/providers/google_earth_engine.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/providers/inpe_cbers.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/providers/isro_bhuvan.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/providers/jaxa_earth.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/providers/maxar_gbdx.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/providers/nasa_earthdata.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/providers/nasa_earthdata_cloud.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/providers/noaa_big_data.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/providers/opentopography.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/providers/planet.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/providers/planetary_computer.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/providers/sentinel_hub.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/providers/terrabotics.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/providers/usgs.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/sar/__init__.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/sar/_native.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/sar/_ost.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/sar/_sarxarray.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/sar/extraction.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/sar/processor.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/utils/__init__.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/utils/file_utils.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/utils/gcp_recovery.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/utils/geo_utils.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/utils/logging_setup.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/utils/retry_handler.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/utils/validators.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/viz/__init__.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/viz/map.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch/viz/plot.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch.egg-info/SOURCES.txt +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch.egg-info/dependency_links.txt +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch.egg-info/entry_points.txt +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch.egg-info/not-zip-safe +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch.egg-info/requires.txt +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/pygeofetch.egg-info/top_level.txt +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/setup.cfg +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/tests/test_atmospheric_circular_regression (1).py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/tests/test_atmospheric_circular_regression.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/tests/test_build_sbas_network.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/tests/test_burst_metadata.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/tests/test_burst_processing_integration.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/tests/test_coregister_integration.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/tests/test_coregister_upgrades.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/tests/test_era5_atmospheric_correction.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/tests/test_extraction.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/tests/test_flat_earth_phase.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/tests/test_gcp_reprojection.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/tests/test_insar.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/tests/test_ionosphere.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/tests/test_models.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/tests/test_pgv_integration_contract.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/tests/test_provider_geometry_audit (1).py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/tests/test_provider_geometry_audit.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/tests/test_provider_scene_disambiguation.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/tests/test_providers.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/tests/test_raster_collocation_integration.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/tests/test_search_download.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/tests/test_splitspectrum_diagnostic.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/tests/test_utils.py +0 -0
- {pygeofetch-2.0.6 → pygeofetch-2.0.7}/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.7/).
|
|
5
5
|
|
|
6
|
-
## [2.0.
|
|
6
|
+
## [2.0.7] — 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.6/).
|
|
|
51
51
|
|
|
52
52
|
### Migration Guide
|
|
53
53
|
```python
|
|
54
|
-
# Before (v2.0.
|
|
54
|
+
# Before (v2.0.7)
|
|
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.7] — 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.7** | 2026-07-29 | SNAPHU unwrapping fixes, 87.1% reliable pixels |
|
|
192
|
+
| **2.0.7** | 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,5 +1,5 @@
|
|
|
1
1
|
"""
|
|
2
|
-
PyGeoFetch v2.0.
|
|
2
|
+
PyGeoFetch v2.0.7 — 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.7"
|
|
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.7 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.7 — Universal Satellite Data Pipeline
|
|
75
75
|
===========================================================
|
|
76
76
|
Unified access to 22+ satellite data providers.
|
|
77
77
|
|
|
@@ -452,13 +452,14 @@ class PhaseUnwrapper:
|
|
|
452
452
|
"""
|
|
453
453
|
Fallback unwrapping using the SNAPHU CLI executable.
|
|
454
454
|
Bypasses Python C-extension compilation issues on Windows entirely.
|
|
455
|
+
Includes auto-repair for the infamous 0xC0000135 (STATUS_DLL_NOT_FOUND) error.
|
|
455
456
|
"""
|
|
456
457
|
import numpy as np
|
|
457
458
|
|
|
458
459
|
cli_path = _ensure_snaphu_cli()
|
|
459
460
|
height, width = igram.shape
|
|
460
461
|
|
|
461
|
-
|
|
462
|
+
def _run_snaphu(tmp_dir):
|
|
462
463
|
tmp = Path(tmp_dir)
|
|
463
464
|
igram_path = tmp / "igram.cpx"
|
|
464
465
|
corr_path = tmp / "corr.cor"
|
|
@@ -473,29 +474,47 @@ class PhaseUnwrapper:
|
|
|
473
474
|
# Write config file using relative paths to avoid Windows space issues
|
|
474
475
|
nlooks_int = max(1, int(nlooks))
|
|
475
476
|
conf_text = f"""INFILE igram.cpx
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
477
|
+
INFILEFORMAT COMPLEX_DATA
|
|
478
|
+
CORRFILE corr.cor
|
|
479
|
+
CORRFILEFORMAT FLOAT_DATA
|
|
480
|
+
OUTFILE unw.unw
|
|
481
|
+
OUTFILEFORMAT FLOAT_DATA
|
|
482
|
+
CONNCOMPFILE conncomp.cc
|
|
483
|
+
CONNCOMPOUTFORMAT UINT_DATA
|
|
484
|
+
LINELENGTH {width}
|
|
485
|
+
STATCOSTMODE {self._cost_mode.upper()}
|
|
486
|
+
INITMETHOD {self._init_method.upper()}
|
|
487
|
+
NLOOKSRANGE {nlooks_int}
|
|
488
|
+
NLOOKSAZ {nlooks_int}
|
|
489
|
+
"""
|
|
489
490
|
conf_path.write_text(conf_text)
|
|
490
491
|
|
|
491
492
|
# Run SNAPHU from within the temp directory
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
493
|
+
cmd = [cli_path, "-f", "snaphu.conf"]
|
|
494
|
+
result = subprocess.run(cmd, capture_output=True, text=True, cwd=str(tmp), timeout=3600)
|
|
495
|
+
return result, unw_path, cc_path
|
|
496
|
+
|
|
497
|
+
with tempfile.TemporaryDirectory() as tmp_dir:
|
|
498
|
+
result, unw_path, cc_path = _run_snaphu(tmp_dir)
|
|
499
|
+
|
|
500
|
+
# ═══════════════════════════════════════════════════════════════
|
|
501
|
+
# AUTO-REPAIR: Catch Windows STATUS_DLL_NOT_FOUND (0xC0000135)
|
|
502
|
+
# 3221225781 is the unsigned int representation of 0xC0000135
|
|
503
|
+
# -1073741515 is the signed int representation. We check both.
|
|
504
|
+
# ═══════════════════════════════════════════════════════════════
|
|
505
|
+
if result.returncode in (3221225781, -1073741515):
|
|
506
|
+
logger.warning(
|
|
507
|
+
"SNAPHU crashed with STATUS_DLL_NOT_FOUND (0xC0000135). "
|
|
508
|
+
"This means the Microsoft Visual C++ Redistributable is missing."
|
|
509
|
+
)
|
|
510
|
+
self._ensure_msvc_runtime()
|
|
511
|
+
|
|
512
|
+
# Retry after installation
|
|
513
|
+
logger.info("Retrying SNAPHU after MSVC runtime installation...")
|
|
514
|
+
result, unw_path, cc_path = _run_snaphu(tmp_dir)
|
|
515
|
+
|
|
516
|
+
if result.returncode != 0:
|
|
517
|
+
raise RuntimeError(f"SNAPHU CLI failed with code {result.returncode}: {result.stderr}")
|
|
499
518
|
|
|
500
519
|
# Read outputs
|
|
501
520
|
unw = np.fromfile(str(unw_path), dtype=np.float32).reshape((height, width))
|
|
@@ -512,6 +531,49 @@ class PhaseUnwrapper:
|
|
|
512
531
|
|
|
513
532
|
return unw, conncomp.astype(np.int32)
|
|
514
533
|
|
|
534
|
+
def _ensure_msvc_runtime(self):
|
|
535
|
+
"""
|
|
536
|
+
Fixes the 0xC0000135 (STATUS_DLL_NOT_FOUND) error by ensuring the
|
|
537
|
+
Microsoft Visual C++ Redistributable is installed.
|
|
538
|
+
"""
|
|
539
|
+
import ctypes
|
|
540
|
+
|
|
541
|
+
# Check if vcruntime140.dll is already available in the system PATH
|
|
542
|
+
try:
|
|
543
|
+
ctypes.WinDLL("vcruntime140.dll")
|
|
544
|
+
return # Already installed
|
|
545
|
+
except OSError:
|
|
546
|
+
pass
|
|
547
|
+
|
|
548
|
+
logger.info("Downloading official Microsoft Visual C++ Redistributable...")
|
|
549
|
+
vc_url = "https://aka.ms/vs/17/release/vc_redist.x64.exe"
|
|
550
|
+
|
|
551
|
+
with tempfile.TemporaryDirectory() as tmp_dir:
|
|
552
|
+
installer_path = Path(tmp_dir) / "vc_redist.x64.exe"
|
|
553
|
+
try:
|
|
554
|
+
urllib.request.urlretrieve(vc_url, str(installer_path))
|
|
555
|
+
except Exception as e:
|
|
556
|
+
raise RuntimeError(
|
|
557
|
+
f"Failed to download MSVC installer: {e}\n"
|
|
558
|
+
"Please install manually: https://aka.ms/vs/17/release/vc_redist.x64.exe"
|
|
559
|
+
)
|
|
560
|
+
|
|
561
|
+
logger.info("Installing MSVC runtime (this may prompt for Administrator permission)...")
|
|
562
|
+
try:
|
|
563
|
+
# /quiet = no UI, /norestart = no reboot prompt, /install = install
|
|
564
|
+
result = subprocess.run(
|
|
565
|
+
[str(installer_path), "/install", "/quiet", "/norestart"],
|
|
566
|
+
timeout=120
|
|
567
|
+
)
|
|
568
|
+
# Return code 0 = success, 3010 = success but reboot required
|
|
569
|
+
if result.returncode not in (0, 3010):
|
|
570
|
+
logger.warning(f"Installer returned code {result.returncode}. You may need to install manually.")
|
|
571
|
+
except Exception as e:
|
|
572
|
+
raise RuntimeError(
|
|
573
|
+
f"Failed to run MSVC installer: {e}\n"
|
|
574
|
+
"Please install manually: https://aka.ms/vs/17/release/vc_redist.x64.exe"
|
|
575
|
+
)
|
|
576
|
+
|
|
515
577
|
def unwrap(
|
|
516
578
|
self,
|
|
517
579
|
interferogram: Any,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|