fix(isce2): repair no-ionosphere resume and sync env example

This commit is contained in:
2026-04-30 10:13:28 +08:00
parent 6696fe90fa
commit 6513ff1623
2 changed files with 72 additions and 0 deletions
+15
View File
@@ -23,9 +23,11 @@ DB_SCHEMA_RESET_CONFIRM=false
AUTH_SESSION_COOKIE_NAME=ims_session AUTH_SESSION_COOKIE_NAME=ims_session
AUTH_COOKIE_SAMESITE=lax AUTH_COOKIE_SAMESITE=lax
AUTH_COOKIE_SECURE=false AUTH_COOKIE_SECURE=false
AUTH_PBKDF2_ITERATIONS=240000
AUTH_LOGIN_MAX_FAILURES=5 AUTH_LOGIN_MAX_FAILURES=5
AUTH_LOGIN_WINDOW_SECONDS=300 AUTH_LOGIN_WINDOW_SECONDS=300
AUTH_LOGIN_LOCK_SECONDS=600 AUTH_LOGIN_LOCK_SECONDS=600
TRUSTED_PROXY_IPS=127.0.0.1
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
@@ -41,10 +43,12 @@ CONDA_ENV_NAME=
NGINX_PATH=C:\nginx\nginx.exe NGINX_PATH=C:\nginx\nginx.exe
NGINX_HEALTH_URL=http://127.0.0.1/ NGINX_HEALTH_URL=http://127.0.0.1/
LICENSE_PATH=
CORS_ORIGINS=http://127.0.0.1:5173,http://localhost CORS_ORIGINS=http://127.0.0.1:5173,http://localhost
CORS_ALLOW_CREDENTIALS=true CORS_ALLOW_CREDENTIALS=true
CORS_STRICT_MODE=false CORS_STRICT_MODE=false
ALLOWED_EXPORT_DIRS=
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
@@ -61,6 +65,8 @@ GF3_STORAGE_DIRS=D:\GF3_L2_Image
HAZARD_POINTS_DIR=D:\Code\Insar_management_system_v2\backend\Point HAZARD_POINTS_DIR=D:\Code\Insar_management_system_v2\backend\Point
HAZARD_POINTS_FILENAME=Point.shp HAZARD_POINTS_FILENAME=Point.shp
AOI_REGION_INDEX_FILE=
AOI_REGION_GEOJSON_FILE=
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
@@ -69,6 +75,7 @@ HAZARD_POINTS_FILENAME=Point.shp
RESULT_PUBLISH_ROOT=D:\production_results RESULT_PUBLISH_ROOT=D:\production_results
DINSAR_PRODUCT_DIR=D:\production_results\dinsar DINSAR_PRODUCT_DIR=D:\production_results\dinsar
TIMESERIES_PRODUCT_DIR=D:\production_results\timeseries TIMESERIES_PRODUCT_DIR=D:\production_results\timeseries
PSINSAR_PRODUCT_DIR=D:\production_results\timeseries
RESULT_QUARANTINE_ROOT=D:\production_results\_quarantine RESULT_QUARANTINE_ROOT=D:\production_results\_quarantine
RESULT_CATALOG_AUTO_REBUILD_ON_STARTUP=true RESULT_CATALOG_AUTO_REBUILD_ON_STARTUP=true
@@ -80,6 +87,7 @@ RESULT_CATALOG_AUTO_REBUILD_ON_STARTUP=true
ORBIT_POOL_ENVI=D:\orbit_pools\envi ORBIT_POOL_ENVI=D:\orbit_pools\envi
ORBIT_POOL_ISCE2=D:\orbit_pools\isce2 ORBIT_POOL_ISCE2=D:\orbit_pools\isce2
ORBIT_POOL_LANDSAR= ORBIT_POOL_LANDSAR=
ORBIT_QUARANTINE_DIR=
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
@@ -112,6 +120,7 @@ IDL_DINSAR_CUSTOM_GEOCODING_COH_THRESHOLD=0.0
IDL_DINSAR_CUSTOM_GEOCODING_PIXEL_SIZE_M=10.0 IDL_DINSAR_CUSTOM_GEOCODING_PIXEL_SIZE_M=10.0
ENVI_TASK_TIMEOUT_SECONDS=21600 ENVI_TASK_TIMEOUT_SECONDS=21600
ENVI_PER_TASK_TIMEOUT=21600
ENVI_FILE_STALE_SECONDS=43200 ENVI_FILE_STALE_SECONDS=43200
ENVI_STABILITY_CHECK_INTERVAL=15 ENVI_STABILITY_CHECK_INTERVAL=15
ENVI_STABILITY_ROUNDS=3 ENVI_STABILITY_ROUNDS=3
@@ -169,6 +178,7 @@ PYINT_FABDEM_ROOT=
# When PYINT_DEM_MODE=prepared_file, point this to the same prepared WGS84 DEM. # When PYINT_DEM_MODE=prepared_file, point this to the same prepared WGS84 DEM.
PYINT_PREPARED_DEM_PATH= PYINT_PREPARED_DEM_PATH=
PYINT_OPENTOPO_DEM_TYPE=SRTMGL1 PYINT_OPENTOPO_DEM_TYPE=SRTMGL1
PYINT_OPENTOPO_API_KEY=
PYINT_DEM_STRICT=true PYINT_DEM_STRICT=true
PYINT_ORBIT_POLICY=require_txt PYINT_ORBIT_POLICY=require_txt
PYINT_ORBIT_POOL_TXT=D:\orbit_pools\envi PYINT_ORBIT_POOL_TXT=D:\orbit_pools\envi
@@ -202,8 +212,13 @@ TIMESERIES_STACK_RUNNER_SCRIPT=
TIMESERIES_MINTPY_SBAS_SCRIPT= TIMESERIES_MINTPY_SBAS_SCRIPT=
TIMESERIES_EXPORT_PUBLISH_SCRIPT= TIMESERIES_EXPORT_PUBLISH_SCRIPT=
TIMESERIES_STACK_WORKFLOW=interferogram TIMESERIES_STACK_WORKFLOW=interferogram
TIMESERIES_DEFAULT_PROCESSOR_CODE=isce2_stack_mintpy
TIMESERIES_WSL_STEP_TIMEOUT_SECONDS=7200 TIMESERIES_WSL_STEP_TIMEOUT_SECONDS=7200
TIMESERIES_ALLOW_SYNTHETIC_WATER_MASK=true TIMESERIES_ALLOW_SYNTHETIC_WATER_MASK=true
SARSCAPE_SBAS_PARAMETER_TEMPLATE_PATH=
SARSCAPE_SBAS_ALLOW_EXECUTION=false
SARSCAPE_SBAS_DISCOVERY_TIMEOUT_SECONDS=120
SARSCAPE_SBAS_STEP_TIMEOUT_SECONDS=21600
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
@@ -968,6 +968,59 @@ def has_pickle_state(work_dir: Path, state_name: str) -> bool:
return (pickle_dir / state_name).exists() and (pickle_dir / f"{state_name}.xml").exists() return (pickle_dir / state_name).exists() and (pickle_dir / f"{state_name}.xml").exists()
def copy_pickle_state(work_dir: Path, source_state: str, target_state: str) -> Path:
pickle_dir = work_dir / "PICKLE"
src = pickle_dir / source_state
src_xml = pickle_dir / f"{source_state}.xml"
dst = pickle_dir / target_state
dst_xml = pickle_dir / f"{target_state}.xml"
if not src.exists() or not src_xml.exists():
raise FileNotFoundError(
f"PICKLE/{source_state} state is missing; cannot prepare PICKLE/{target_state}."
)
shutil.copy2(src, dst)
shutil.copy2(src_xml, dst_xml)
return dst_xml
def prepare_no_ionosphere_snaphu_resume(work_dir: Path, bbox: list[float] | None) -> None:
dst_xml = copy_pickle_state(work_dir, "filter", "filter_high_band")
root = ET.fromstring(dst_xml.read_text(encoding="utf-8"))
props = {prop.attrib.get("name"): prop for prop in root.findall("property")}
required = {
"referenceslccroppedproduct": "reference_slc.xml",
"secondaryslccroppedproduct": "secondary_slc.xml",
"referenceslcproduct": "reference_slc.xml",
"secondaryslcproduct": "secondary_slc.xml",
"referencegeometrysystem": "Zero Doppler",
"secondarygeometrysystem": "Zero Doppler",
}
if bbox is not None:
required["estimatedboundingbox"] = str(bbox)
for name, value in required.items():
if name in props:
node = props[name].find("value")
if node is None:
node = ET.SubElement(props[name], "value")
node.text = value
continue
prop = ET.SubElement(root, "property", {"name": name})
ET.SubElement(prop, "value").text = value
dst_xml.write_text(ET.tostring(root, encoding="unicode"), encoding="utf-8")
print("Prepared no-ionosphere SNAPHU resume state: PICKLE/filter_high_band", flush=True)
def prepare_no_ionosphere_geocode_resume(work_dir: Path) -> None:
copy_pickle_state(work_dir, "unwrap", "ionosphere")
print("Prepared no-ionosphere geocode resume state: PICKLE/ionosphere", flush=True)
def resolve_unwrap_start_step(work_dir: Path, *, ionosphere_correction: bool) -> str: def resolve_unwrap_start_step(work_dir: Path, *, ionosphere_correction: bool) -> str:
if ionosphere_correction: if ionosphere_correction:
if has_pickle_state(work_dir, "ionosphere"): if has_pickle_state(work_dir, "ionosphere"):
@@ -1181,6 +1234,8 @@ def main() -> int:
write_stripmap_xml(xml_path, config) write_stripmap_xml(xml_path, config)
if should_run_stage(start_stage, "unwrap"): if should_run_stage(start_stage, "unwrap"):
if not config.ionosphere_correction:
prepare_no_ionosphere_snaphu_resume(work_dir, config.bbox)
unwrap_start_step = resolve_unwrap_start_step( unwrap_start_step = resolve_unwrap_start_step(
work_dir, work_dir,
ionosphere_correction=config.ionosphere_correction, ionosphere_correction=config.ionosphere_correction,
@@ -1202,6 +1257,8 @@ def main() -> int:
) )
if should_run_stage(start_stage, "geocode"): if should_run_stage(start_stage, "geocode"):
if not config.ionosphere_correction:
prepare_no_ionosphere_geocode_resume(work_dir)
geocode_start_step = resolve_geocode_start_step( geocode_start_step = resolve_geocode_start_step(
work_dir, work_dir,
ionosphere_correction=config.ionosphere_correction, ionosphere_correction=config.ionosphere_correction,