Skip to content

Add Capella.py Sensor for stripmap workflow#1022

Open
scottstanie wants to merge 17 commits intoisce-framework:mainfrom
scottstanie:claude/add-capella-sensor-Rdsl7
Open

Add Capella.py Sensor for stripmap workflow#1022
scottstanie wants to merge 17 commits intoisce-framework:mainfrom
scottstanie:claude/add-capella-sensor-Rdsl7

Conversation

@scottstanie
Copy link
Member

This PR adds a parser and sensor setup for Capella SLCs (stripmap and spotlight).

  • The ampcor options were added because the defaults for stripmap were taking ~5 minutes for the fine coregistration, which seemed unreasonably slow to estimate a bulk shift

  • The spotlightPhaseCorrection.py performs the re-ramping (Capella spotlight SLCs come with deramped phase). I don't think it's full working with this isce2 metadata, as there are range phase ramps in the mount etna interferograms.

Test cases:

stripmap: https://radiantearth.github.io/stac-browser/#/external/capella-open-data.s3.amazonaws.com/stac/capella-open-data-by-use-case/capella-open-data-insar/capella-open-data-insar-mexico-city/collection.json?.language=en
spotlight: https://radiantearth.github.io/stac-browser/#/external/capella-open-data.s3.us-west-2.amazonaws.com/stac/capella-open-data-by-use-case/capella-open-data-insar/capella-open-data-insar-mount-etna/collection.json?.language=en

claude and others added 17 commits January 23, 2026 00:24
Add support for processing Capella Space SAR SLC data in the stripmapStack
workflow. Capella provides stripmap mode X-band SAR data as GeoTIFF files
with JSON metadata.

New files:
- Capella.py: Sensor class that parses Capella JSON metadata and extracts
  SLC images from GeoTIFF format
- unpackFrame_Capella.py: Script to unpack Capella SLC data for stripmapStack
- prepSlcCapella.py: Script to organize Capella data into date folders and
  generate run files

Updates:
- Register Capella sensor in Sensor/__init__.py
- Add Capella pattern detection in prepSlcSensors.py
Capella does not provide FM rate polynomial in their metadata, so
remove the placeholder zeros. The FM rate is only used by deskewALOS2.py
for ALOS2-specific processing and is not needed for general stripmapStack.
- Read metadata from TIFF ImageDescription tag instead of requiring
  separate JSON files (metadata is embedded in the GeoTIFF)
- Add mode validation to reject Spotlight (SP) and Sliding Spotlight (SL)
  modes which require additional post-processing to reramp phase
- Simplify prepSlcCapella.py to work directly with .tif files
- Update unpackFrame_Capella.py to only need TIFF file path
- Remove JSON file pattern from prepSlcSensors.py auto-detection
- Make scripts executable
Capella provides a 2D Doppler centroid polynomial (function of azimuth and
range), but isce2 expects a 1D polynomial (function of range only).

Fix by evaluating the 2D polynomial at a specific azimuth time (~1 second
from start, or mid-scene for short acquisitions) to extract 1D coefficients
as a function of range pixel.
- State vectors are in collect.state.state_vectors, not top-level
- Radar params are in collect.radar, not top-level
- Handle dict format for position {x,y,z} and velocity {vx,vy,vz}
- Use range_to_first_sample (meters) instead of range_time_origin
Explicitly link against libSystem on Apple platforms to ensure
conda-forge gfortran produces valid shared libraries.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Capella.py: Use image_geometry fields instead of collect-level metadata.
- PRF from 1/delta_line_time (processed SLC line rate ~6209 Hz),
  not raw radar PRF (~9900 Hz)
- Range pixel size from delta_range_sample (slant range ~0.617m),
  not pixel_spacing_column (ground spacing ~0.947m)
- Sensing times from first_line_time, not collect start/stop timestamps
- Sampling frequency derived from slant range pixel spacing

These three fixes improve coherence from ~0.20 to ~0.40 for 3-day pairs.

refineSecondaryTiming.py: Reduce ampcor window sizes and scale grid
to image size for faster processing.
- Window 64x64 (was 128x128), search 20px (was 40)
- Grid count adapts to image size, max 10x10 (was hardcoded 60x60)
- Unconditionally set numberLocationAcross/Down since
  Ampcor.configure() sets defaults that prevent conditional override

Co-Authored-By: Claude Opus 4.6 <[email protected]>
The ampcor window/grid optimization improves Capella processing speed
but could affect other widely-used sensor workflows. Reverting to
upstream defaults. Users processing Capella data with small images
can pass --ao/--ro flags or reduce ampcor settings manually.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
- Add spotlight mode (SP) to Capella.py supported modes and extract
  reference_antenna_position/reference_target_position from metadata
  for post-coregistration phase correction
- Add spotlightPhaseCorrection.py for re-ramping deramped spotlight SLCs
  using geometric phase computation (ECEF-based)
- Add example_capella_stripmap.py jupytext notebook showing full
  Capella stripmapStack workflow from SLC prep through interferograms

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Cropped TIFFs (e.g. from sarlet crop-slc) correctly update timing and
range metadata but may not update the rows/columns fields. Using the
actual TIFF dimensions from GDAL ensures correct image sizing regardless
of whether the metadata dimensions match.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants