587 lines
22 KiB
Markdown
587 lines
22 KiB
Markdown
# Time-Series SBAS And SARscape Integration Design
|
|
|
|
## 1. Problem Statement
|
|
|
|
The current time-series route can find and run a scene stack, but the system does not yet treat SBAS as a first-class production input. The main gaps are:
|
|
|
|
- `find-ps-timeseries` returns scenes, not a durable SBAS network.
|
|
- `PsTaskBatch` is used as a production input even though it is a thin list of paths.
|
|
- Planning context is partly duplicated in `PsTaskItem.remark`.
|
|
- `copy-ps-stack` copies source folders, but does not create a stack-level production package.
|
|
- The managed time-series runner reconstructs input state at run time.
|
|
- SARscape is currently integrated only as a D-InSAR pair processor.
|
|
|
|
The design goal is to make one immutable stack manifest the source of truth for every SBAS run, then let ISCE2/MintPy and SARscape consume the same contract.
|
|
|
|
## 2. Target Workflow
|
|
|
|
```text
|
|
AOI + filters
|
|
-> time-series stack search
|
|
-> SBAS network plan
|
|
-> user review and commit
|
|
-> immutable stack package
|
|
-> processor workflow
|
|
-> publish bundle
|
|
-> psinsar catalog
|
|
```
|
|
|
|
The stack plan and the production package are separate states. A plan is a previewable proposal; a package is a committed production input.
|
|
|
|
## 3. Planning Contract
|
|
|
|
### 3.1 Search API
|
|
|
|
Add or evolve the current `find-ps-timeseries` route toward:
|
|
|
|
```text
|
|
POST /timeseries/plans/search
|
|
```
|
|
|
|
Core request fields:
|
|
|
|
- AOI source: uploaded shapefile, region geometry, or GeoJSON.
|
|
- Scene compatibility filters: satellite, orbit direction, imaging mode, polarization, date range.
|
|
- Scene thresholds: `initial_overlap_threshold`, `final_overlap_threshold`.
|
|
- Network thresholds: `time_baseline_min`, `time_baseline_max`, `spatial_baseline_max_meters`, later `perpendicular_baseline_max_meters`.
|
|
- Network policy: `strategy`, `num_connections`, `reference_image_id`.
|
|
- Processor hint: optional `processor_target`, for example `isce2_stack_mintpy` or `sarscape_sbas`.
|
|
|
|
### 3.2 Plan Tables
|
|
|
|
Existing:
|
|
|
|
- `timeseries_stack_plans`
|
|
- `timeseries_stack_plan_items`
|
|
|
|
New:
|
|
|
|
- `timeseries_stack_plan_edges`
|
|
|
|
The edge table stores the selected SBAS graph:
|
|
|
|
- plan reference
|
|
- master/slave plan item references
|
|
- master/slave radar scene references
|
|
- optional `pairing_metric_cache` reference
|
|
- temporal baseline
|
|
- spatial/perpendicular baseline
|
|
- scene overlap ratio
|
|
- AOI pair overlap ratio
|
|
- selection reason and score
|
|
- enabled flag
|
|
|
|
This lets the system answer: which pairs were selected, why were they selected, and what graph was actually submitted.
|
|
|
|
## 4. Production Input Package
|
|
|
|
Committed production input is represented by a prepared stack manifest. In the
|
|
current backend this file is:
|
|
|
|
```text
|
|
backend/runtime/timeseries_work/<run_id>/input/selected_stack_manifest.json
|
|
```
|
|
|
|
This file is not the same thing as a `TimeseriesStackPlan`. The plan is the
|
|
candidate pool and audit graph. The prepared stack is the smaller frozen set
|
|
submitted to a processor.
|
|
|
|
Schema:
|
|
|
|
```json
|
|
{
|
|
"schema": "insar.timeseries-stack/v1",
|
|
"prepared_stack_schema": "insar.prepared-sbas-stack/v1",
|
|
"manifest_role": "prepared_sbas_stack",
|
|
"mode": "sbas",
|
|
"plan_id": "tsp_...",
|
|
"prepared_stack_id": "pss_...",
|
|
"source_plan_id": "tsp_...",
|
|
"source_batch_id": "...",
|
|
"processor_code": "sarscape_sbas",
|
|
"aoi": {},
|
|
"candidate_pool_source": {},
|
|
"selection_params": {},
|
|
"scenes": [],
|
|
"network_edges": [],
|
|
"reference_date": "YYYYMMDD",
|
|
"production_contract": {
|
|
"input_policy": "prepared_stack_only",
|
|
"catalog_scan_allowed_after_prepare": false,
|
|
"scene_selection_frozen": true
|
|
},
|
|
"artifacts": {
|
|
"selected_network_edges_path_windows": "..."
|
|
},
|
|
"prepared_stack_validation": {},
|
|
"prepared_at_utc": "...",
|
|
"manifest_checksum": "..."
|
|
}
|
|
```
|
|
|
|
Rules:
|
|
|
|
- A production run consumes the prepared manifest, not `PsTaskItem.remark` and
|
|
not a fresh scan of the full radar catalog.
|
|
- The manifest is immutable after `prepare` completes, except for explicit
|
|
retry/re-prepare workflows.
|
|
- Processor-specific materialization is recorded in a separate processor manifest.
|
|
- Source data copying must include the manifest and graph.
|
|
|
|
### 4.1 Layered SBAS Input Model
|
|
|
|
The production model is now four layers:
|
|
|
|
1. Full radar inventory
|
|
- The long-lived scene catalog and pairing metric cache.
|
|
- It can be large and dirty/rebuilt over time.
|
|
|
|
2. Candidate time-series pool
|
|
- `TimeseriesStackPlanORM`, plan items, and plan edges.
|
|
- This is the large pool selected by AOI, date, orbit, baseline, overlap,
|
|
and network policy.
|
|
- It records why each scene and edge was selected.
|
|
|
|
3. Prepared SBAS stack
|
|
- `selected_stack_manifest.json` with
|
|
`prepared_stack_schema=insar.prepared-sbas-stack/v1`.
|
|
- Contains only the frozen scenes for this run.
|
|
- Writes `input/selected_network_edges.json` as a standalone artifact.
|
|
- Records validation results for scene files, graph count/date consistency,
|
|
DEM availability when required, and the no-catalog-scan production policy.
|
|
|
|
4. Processor execution
|
|
- SARscape `wf_sbas` consumes the prepared scene stack.
|
|
- System `network_edges` are mandatory as the planning/audit graph, but the
|
|
native `wf_sbas` path may rebuild the executable graph internally.
|
|
- When SARscape's actual graph can be extracted, it should be saved as
|
|
`actual_network_edges.json` and compared with `selected_network_edges.json`.
|
|
|
|
Backend enforcement:
|
|
|
|
- `prepare_run()` creates the prepared stack contract and validates it.
|
|
- `build_sarscape_processor_preflight()` refuses non-prepared manifests.
|
|
- `run_sarscape_sbas()` refuses non-prepared manifests and missing
|
|
`selected_network_edges.json`.
|
|
- `execute_template_workflow()` in the SARscape service has a second guard so
|
|
lower-level execution cannot accidentally run from a candidate pool.
|
|
|
|
## 5. Processor Boundary
|
|
|
|
Introduce a time-series processor interface:
|
|
|
|
```text
|
|
TimeseriesProcessor
|
|
check_available()
|
|
preflight(manifest)
|
|
build_workflow(run)
|
|
prepare_inputs(run)
|
|
execute_step(run, step_id)
|
|
export_publish_bundle(run)
|
|
```
|
|
|
|
Processor codes:
|
|
|
|
- `isce2_stack_mintpy`
|
|
- `sarscape_sbas`
|
|
|
|
The existing `timeseries_service` can remain the orchestration service, but processor-specific logic should move behind this interface.
|
|
|
|
## 6. SARscape SBAS Processor
|
|
|
|
SARscape SBAS should be a stack-level processor, not an extension of the D-InSAR pair engine.
|
|
|
|
Suggested steps:
|
|
|
|
1. `sarscape_preflight`
|
|
- Check ENVI, SARscape, taskengine, license, DEM, orbit pool, and output roots.
|
|
- Enumerate available SARscape SBAS/E-SBAS task names via `envipyengine`.
|
|
|
|
2. `sarscape_import`
|
|
- Import LT-1 scenes.
|
|
- Write `sarscape_import_manifest.json`.
|
|
|
|
3. `sarscape_connection_graph`
|
|
- Prefer the system-selected `network_edges`.
|
|
- If SARscape internally rebuilds the graph, export the actual graph as `actual_network_edges.json`.
|
|
|
|
4. `sarscape_interferogram_generation`
|
|
|
|
5. `sarscape_inversion`
|
|
- Generate time-series, velocity, coherence, and quality products.
|
|
|
|
6. `sarscape_geocode_export`
|
|
|
|
7. `export_publish_bundle`
|
|
|
|
8. `register_psinsar_product`
|
|
|
|
## 7. Result Contract
|
|
|
|
One SBAS run registers one `psinsar` product bundle.
|
|
|
|
Required bundle roles:
|
|
|
|
- stack manifest
|
|
- processor manifest
|
|
- selected network edges
|
|
- actual network edges if processor modified them
|
|
- velocity product
|
|
- time-series product
|
|
- temporal coherence or equivalent quality product
|
|
- geocoded rasters
|
|
- quicklooks
|
|
- logs
|
|
- processor reports
|
|
- product manifest
|
|
|
|
The catalog registers the publish manifest, not the transient work directory.
|
|
|
|
## 8. Delivery Phases
|
|
|
|
### Phase 1: Planning Boundary
|
|
|
|
- Stop auto-creating PS batches after search.
|
|
- Persist `TimeseriesStackPlanEdge`.
|
|
- Return edges from `/timeseries-plans/{plan_id}`.
|
|
- Add network thresholds to `PsRequest` with backward-compatible defaults.
|
|
|
|
### Phase 2: Manifest Boundary
|
|
|
|
- Add committed stack package creation.
|
|
- Generate immutable `stack_manifest.json`.
|
|
- Make the existing ISCE2/MintPy route consume the manifest.
|
|
|
|
### Phase 3: SARscape Discovery
|
|
|
|
- Add a SARscape SBAS task verifier script.
|
|
- Capture task names and required parameters per installed SARscape version.
|
|
- Add `sarscape_sbas` preflight endpoint.
|
|
|
|
Initial implementation points:
|
|
|
|
- `scripts/verify_sarscape_sbas_tasks.py`
|
|
- `POST /idl/inspect/sarscape-sbas`
|
|
- `POST /timeseries-production/sarscape-sbas/preflight`
|
|
- `python -m backend.app.services.envi_runner_cli --inspect-sarscape-sbas`
|
|
|
|
These entry points must stay read-only. They instantiate ENVI task definitions
|
|
and inspect parameters, but do not execute SBAS processing.
|
|
|
|
The time-series SARscape preflight endpoint builds a processor manifest from
|
|
the committed PS batch/stack plan context. It reports the selected network
|
|
edges, the SARscape task sequence, required publish roles, and current blockers.
|
|
At this phase it must return `ready_for_pipeline_design=true` when ENVI/SARscape
|
|
is discoverable, but `ready_for_execution=false` until a checked-in parameter
|
|
template and job handler are implemented.
|
|
|
|
Current implementation status:
|
|
|
|
- `sarscape_sbas` is a selectable time-series processor.
|
|
- The production UI defaults to `ENVI/SARscape SBAS` with `Preflight only`.
|
|
- `POST /timeseries-production/runs` accepts `processor_code` and
|
|
`execution_mode`.
|
|
- SARscape runs use workflow `psinsar_sarscape_sbas_chain`.
|
|
- Preflight-only SARscape runs execute `prepare` plus
|
|
`sarscape_processor_preflight`, then complete the task without launching the
|
|
long SARscape stack execution.
|
|
- Full execution is gated by `SARSCAPE_SBAS_ALLOW_EXECUTION=true` and a
|
|
`validated=true` parameter template at
|
|
`SARSCAPE_SBAS_PARAMETER_TEMPLATE_PATH`.
|
|
- The checked-in template at
|
|
`backend/templates/sarscape_sbas_parameter_template.example.json` is a
|
|
placeholder contract and is intentionally not executable.
|
|
|
|
Observed on the target workstation:
|
|
|
|
- Lightweight `Engine.tasks()` discovery succeeds.
|
|
- Static `.task` extraction succeeds without starting taskengine. The extractor is:
|
|
- `scripts/extract_sarscape_sbas_task_templates.py`
|
|
- The installed SARscape exposes native workflow metatasks:
|
|
- `wf_sbas`
|
|
- `wf_esbas`
|
|
- `wf_sbas` is an ENVI metatask at
|
|
`C:\Program Files\Harris\ENVI56\user_custom_code\wf_sbas.task`.
|
|
It is not listed by `Engine.tasks()` on this workstation, but
|
|
`Engine("ENVI").task("wf_sbas")` can instantiate it successfully. Discovery
|
|
therefore combines `Engine.tasks()` with static `.task` file detection.
|
|
It contains an embedded 11-node DAG:
|
|
- `SARscape_setting_output_folders`
|
|
- `SARsLoadPreferences`
|
|
- `SARsImportSarSelector`
|
|
- `ENVIEXTRACTELEMENTSFROMARRAYTASK`
|
|
- `SARscapeSuggestLooks`
|
|
- `SARsInSARStackSBASGenerateConnectionGraph`
|
|
- `SARsInSARStackSBASInterferogramGeneration`
|
|
- `SARsInSARStackSBASInversionStep1`
|
|
- `SARsInSARStackSBASInversionStep2`
|
|
- `SARsInSARStackSBASGeocode`
|
|
- `SARscapeEnviuriToShape`
|
|
- The static `wf_sbas.task` file contains 18 parameter entries including the
|
|
embedded `DAG` default. Live taskengine `QueryTask` exposes 17 callable
|
|
parameters; it does not require the caller to pass `DAG`.
|
|
- The core production inputs are:
|
|
- `INPUT_FILE_LIST`
|
|
- `SARSCAPE_PREFERENCE`
|
|
- `DEM_SARSCAPEDATA`
|
|
- `OUTPUT_FOLDER`
|
|
- `GEOCODE_RG_GRID_SIZE`
|
|
- `ESTIMATE_RESIDUAL_HEIGHT`
|
|
- `DISPLACEMENT_MODEL_TYPE`
|
|
- `OUTPUT_ENVI_CARTOGRAPHIC_SYSTEM`
|
|
- `wf_sbas` returns SBAS product handles:
|
|
- `DISPLACEMENT_SARSCAPEDATA`
|
|
- `DEM_OUT_SARSCAPEDATA`
|
|
- `CORRECTION_H_SARSCAPEDATA`
|
|
- `COHERENCE_SARSCAPEDATA`
|
|
- `ALOS_SARSCAPEDATA`
|
|
- `ILOS_SARSCAPEDATA`
|
|
- `VELOCITY_SARSCAPEDATA`
|
|
- `OUTPUT_SHAPES`
|
|
- The installed SARscape also exposes these stack tasks:
|
|
- `SARsInSARStackSBASGenerateConnectionGraph`
|
|
- `SARsInSARStackSBASInterferogramGeneration`
|
|
- `SARsInSARStackSBASInversionStep1`
|
|
- `SARsInSARStackSBASInversionStep2`
|
|
- `SARsInSARStackSBASGeocode`
|
|
- `SARsInSARStackSBASVariogram`
|
|
- `SARsInSARStackESBASInterferogramGeneration`
|
|
- `SARsInSARStackESBASInversion`
|
|
- `SARsInSARStackESBASGeocode`
|
|
- `SARsInSARConnectionGraphESBAS`
|
|
- Reading `.parameters` for stack SBAS tasks can hang taskengine. Parameter
|
|
discovery must therefore be optional, subprocess-isolated, and timeout-bound.
|
|
Processor implementation should use a checked-in task template or SARscape
|
|
help/SML-derived parameter contract rather than relying on live parameter
|
|
introspection at run time.
|
|
- Timeout cleanup must remove only taskengine processes spawned by the timed-out
|
|
inspection subprocess. Existing user-launched ENVI/taskengine sessions should
|
|
not be killed by name.
|
|
- SARscape/taskengine can create zero-byte `env_*.xyz` and `IDL*.tmp` files in
|
|
the process current working directory. ENVI runner cwd and temp variables must
|
|
point at `backend/runtime/idl_worker/envi_cwd`, not the repository root.
|
|
Root-level `env_*.xyz` and `IDL*.tmp` are disposable taskengine leftovers.
|
|
|
|
### Phase 3.5: SARscape Native Workflow Strategy
|
|
|
|
The short-term production strategy is to integrate SARscape through `wf_sbas`.
|
|
This is the lowest-risk ENVI/SARscape path because SARscape already wires import,
|
|
connection graph generation, interferogram generation, inversion, geocoding, and
|
|
shape export in one metatask DAG.
|
|
|
|
The backend template contract now supports two execution strategies:
|
|
|
|
- `native_workflow_metatask`
|
|
- Preferred first implementation.
|
|
- Executes `wf_sbas` once with the committed stack manifest converted into
|
|
`INPUT_FILE_LIST`, configured DEM, output folder, and basic SBAS options.
|
|
- Does not directly consume the system-selected `network_edges`.
|
|
- Requires post-run extraction of SARscape's actual connection graph for audit.
|
|
|
|
- `explicit_stack_tasks`
|
|
- Future controllable implementation.
|
|
- Executes `SARsInSARStackSBASGenerateConnectionGraph`,
|
|
`InterferogramGeneration`, `InversionStep1`, `InversionStep2`, and
|
|
`Geocode` as separate tasks.
|
|
- May allow tighter control of graph settings, but direct injection of the
|
|
system-selected edge list is not verified yet.
|
|
|
|
Current rule:
|
|
|
|
- `network_edges` remain mandatory in the stack manifest because they are the
|
|
system planning decision and task-dispatch audit record.
|
|
- When using `wf_sbas`, SARscape may rebuild the graph internally. The output
|
|
bundle must therefore contain both:
|
|
- `selected_network_edges.json`
|
|
- `actual_network_edges.json`, when it can be extracted from SARscape outputs
|
|
|
|
Current code points:
|
|
|
|
- `backend/app/services/envi_service.py`
|
|
- Discovers `wf_sbas`, `wf_esbas`, support tasks, and stack tasks.
|
|
- Cleans up only newly spawned `taskengine.exe` PIDs on timeout.
|
|
- Runs subprocess and in-process envipyengine calls from
|
|
`backend/runtime/idl_worker/envi_cwd` so taskengine temp files do not pollute
|
|
the project root.
|
|
- `backend/app/services/sarscape_sbas_service.py`
|
|
- Builds processor manifests with `execution_strategy`.
|
|
- Reports both native and explicit strategy availability.
|
|
- Requires `insar.prepared-sbas-stack/v1` before execution.
|
|
- Executes `native_workflow_metatask` only when the template is validated and
|
|
execution is explicitly enabled.
|
|
- `backend/app/services/timeseries_service.py`
|
|
- Treats `TimeseriesStackPlan` as the candidate pool.
|
|
- Creates `selected_stack_manifest.json` as the prepared stack in
|
|
`prepare_run()`.
|
|
- Writes `input/selected_network_edges.json` before SARscape preflight or
|
|
execution.
|
|
- Refuses SARscape preflight/execution when the prepared stack validation
|
|
fails.
|
|
- `backend/templates/sarscape_sbas_parameter_template.example.json`
|
|
- Records the `wf_sbas` parameter contract and DAG summary.
|
|
- Keeps `validated=false` until a controlled run validates parameters and
|
|
output capture.
|
|
- `scripts/extract_sarscape_sbas_task_templates.py`
|
|
- Regenerates the static parameter report from installed `.task` files.
|
|
|
|
Open engineering items:
|
|
|
|
- Confirm `wf_sbas.INPUT_FILE_LIST` accepts the same LT-1 `*.meta.xml` list used
|
|
by current SARscape import tasks.
|
|
- Confirm whether `DAG` must be passed explicitly or SARscape uses the embedded
|
|
default from `wf_sbas.task`.
|
|
- Locate SARscape's written connection graph or auxiliary processing file and
|
|
convert it into `actual_network_edges.json`.
|
|
- Map `VELOCITY_SARSCAPEDATA`, `DISPLACEMENT_SARSCAPEDATA`,
|
|
`COHERENCE_SARSCAPEDATA`, and `OUTPUT_SHAPES` into the unified `psinsar`
|
|
publish bundle.
|
|
- Decide later whether to invest in `explicit_stack_tasks` for strict graph
|
|
injection, depending on whether SARscape exposes a supported graph import or
|
|
connection-list parameter.
|
|
|
|
Smoke test on 2026-04-30:
|
|
|
|
- Applied the non-destructive `008_timeseries_stack_plan_edges.sql` migration.
|
|
- Backfilled two edges for test plan `tsp_d89bfc5bded744e6bf9b60c1` from
|
|
`pairing_metric_cache` because the plan was created before the edge table
|
|
existed.
|
|
- Ran SARscape SBAS preflight for batch
|
|
`e240a63a-5941-4a86-8aae-182a6bc95dae`.
|
|
- Result:
|
|
- `scene_count=3`
|
|
- `network_edge_count=2`
|
|
- `ready_for_pipeline_design=true`
|
|
- `ready_for_execution=false`
|
|
- `execution_strategy=native_workflow_metatask`
|
|
- `missing_required_tasks=[]`
|
|
- blockers are only `Template is not marked validated=true` and
|
|
`SARSCAPE_SBAS_ALLOW_EXECUTION is false`.
|
|
- Created a `preflight_only` run
|
|
`b7c2df45-a891-4ff7-b106-013e8d285fbd` and executed its `prepare` plus
|
|
`sarscape_processor_preflight` steps. This wrote
|
|
`selected_stack_manifest.json` and `sarscape_sbas_processor_manifest.json`
|
|
without launching the full SARscape SBAS pipeline.
|
|
- Dispatch verification for workflow
|
|
`eeaf1d82-7268-490c-9fb5-911a00a475c6` exposed a real workflow bug:
|
|
`workflow_service.mark_step_completed()` advanced downstream steps to
|
|
`READY`, but the database session has `autoflush=False`, so the immediate
|
|
`enqueue_ready_steps()` query did not see the new `READY` status.
|
|
`sarscape_processor_preflight` therefore stayed `READY` without a job.
|
|
- Fixed the dispatcher by flushing after `_advance_ready_steps()` and before
|
|
`enqueue_ready_steps()`.
|
|
- Verified the dispatcher fix in a rollback-only two-step workflow regression
|
|
check: completing step `a` immediately advanced step `b` to `RUNNING` and
|
|
created its queued job.
|
|
- Re-ran the controlled dispatch path for only this workflow:
|
|
- `TIMESERIES_PREPARE`: `COMPLETED`
|
|
- `TIMESERIES_SARSCAPE_PREFLIGHT`: `COMPLETED`
|
|
- workflow status: `COMPLETED`
|
|
- task status: `COMPLETED`, progress `100`
|
|
- run status: `PREPARED`
|
|
- no `TIMESERIES_RUN_SARSCAPE_SBAS` job or `run_sarscape_sbas` step was
|
|
created because execution mode was `preflight_only`.
|
|
- Root-level taskengine leftovers after the run:
|
|
- `env_*.xyz`: `0`
|
|
- `IDL*.tmp`: `0`
|
|
ENVI status now reports runner cwd as
|
|
`backend/runtime/idl_worker/envi_cwd`.
|
|
|
|
Parameter template validation on 2026-04-30:
|
|
|
|
- Initial live `Engine("ENVI").task("wf_sbas")` parameter inspection failed
|
|
with `ENVITASK: No task matches: wf_sbas`, even though the static
|
|
`wf_sbas.task` file was present.
|
|
- Root cause: SARscape installed `wf_sbas.task` under
|
|
`C:\Program Files\Harris\ENVI56\user_custom_code`, while taskengine only
|
|
auto-loads deployed custom tasks from `ENVI_CUSTOM_CODE`, the ENVI
|
|
`custom_code` directory, the application user directory, or IDL packages.
|
|
- Backend runner now sets `ENVI_CUSTOM_CODE` to the discovered SARscape
|
|
`user_custom_code` directory. This is process-local to the runner and does
|
|
not modify the machine-level environment.
|
|
- After the fix, live `wf_sbas` parameter inspection succeeds:
|
|
- `available=true`
|
|
- `parameter_count=17`
|
|
- required inputs: `INPUT_FILE_LIST`
|
|
- outputs: `OUTPUT_SHAPES`, `DISPLACEMENT_SARSCAPEDATA`,
|
|
`DEM_OUT_SARSCAPEDATA`, `CORRECTION_H_SARSCAPEDATA`,
|
|
`COHERENCE_SARSCAPEDATA`, `ALOS_SARSCAPEDATA`,
|
|
`ILOS_SARSCAPEDATA`, `VELOCITY_SARSCAPEDATA`
|
|
- Added repeatable validation script:
|
|
`scripts/validate_sarscape_sbas_template.py`.
|
|
- Validation report:
|
|
`backend/runtime/sarscape_sbas_template_validation_latest.json`.
|
|
- Current 3-scene validation result:
|
|
- `ok=true`
|
|
- validation scope: template contract only, no `task.execute()`
|
|
- manifest scene count: `3`
|
|
- network edge count: `2`
|
|
- `INPUT_FILE_LIST_count=3`
|
|
- scene `meta_path`, `tiff_path`, and folders all exist
|
|
- DEM base, `.sml`, and `.hdr` all exist
|
|
- remaining execution gate issue: checked-in template is still
|
|
`validated=false`
|
|
|
|
Prepared stack boundary implementation on 2026-04-30:
|
|
|
|
- Added `prepared_stack_schema=insar.prepared-sbas-stack/v1` to
|
|
`selected_stack_manifest.json`.
|
|
- Added `prepared_stack_id`, `source_plan_id`, `source_batch_id`,
|
|
`candidate_pool_source`, and `production_contract`.
|
|
- Added `input/selected_network_edges.json` as the frozen planning/audit graph
|
|
artifact.
|
|
- Added prepared stack validation for:
|
|
- scene count and dates
|
|
- required scene folder, TIFF, and metadata XML paths
|
|
- zero-size source files
|
|
- network edge count and edge date consistency
|
|
- SARscape DEM dependency when SARscape is the selected processor
|
|
- missing `selected_network_edges.json`
|
|
- SARscape processor preflight and execution now reject manifests that are not
|
|
prepared stacks. The lower-level SARscape executor repeats this guard before
|
|
calling any ENVI task.
|
|
|
|
Prepared stack UI/API update on 2026-04-30:
|
|
|
|
- Added read-only backend summary endpoint:
|
|
`GET /timeseries-production/runs/{run_id}/prepared-stack`.
|
|
- The endpoint reads only existing run artifacts and does not trigger catalog
|
|
scans, preflight, or SARscape execution.
|
|
- The summary reports:
|
|
- prepared stack state
|
|
- `prepared_stack_id`
|
|
- manifest and selected network edge artifact paths
|
|
- scene count and network edge count
|
|
- prepared stack validation result
|
|
- SARscape processor manifest readiness and blockers
|
|
- `TimeseriesProductionPanel` now shows a dedicated `Prepared SBAS Stack`
|
|
section in run details.
|
|
- The SARscape preflight card now states that batch preflight is against the
|
|
candidate pool, while production freezes a prepared stack before processor
|
|
execution.
|
|
- `usePairingLogic` now marks created PS batches as candidate time-series pools
|
|
in the planning context and logs that production will freeze a prepared SBAS
|
|
stack during `prepare`.
|
|
|
|
### Phase 4: SARscape Execution
|
|
|
|
- Implement the SARscape SBAS processor steps.
|
|
- Serialize taskengine execution through the existing ENVI lock.
|
|
- Persist step manifests and logs.
|
|
|
|
Initial execution skeleton is in place:
|
|
|
|
- `TIMESERIES_SARSCAPE_PREFLIGHT`
|
|
- `TIMESERIES_RUN_SARSCAPE_SBAS`
|
|
- `backend/app/services/sarscape_sbas_service.py`
|
|
|
|
The execution handler resolves template macros and calls `execute_envi_task`
|
|
only after the template is readable, structurally valid, marked
|
|
`validated=true`, required tasks are discoverable, and execution is explicitly
|
|
enabled.
|
|
|
|
### Phase 5: Unified Result Management
|
|
|
|
- Normalize ISCE2/MintPy and SARscape outputs into the same publish bundle roles.
|
|
- Keep processor-specific files as secondary assets.
|
|
- Show products by role in the UI, not by processor-specific filenames.
|