Sentinel-1 InSAR baseline stack¶
The only capability that justifies a separate asf backend (rather than reusing earthlens.earthdata): building an InSAR baseline stack from a reference granule, narrowed by perpendicular- and temporal-baseline windows. This walkthrough runs the stack anonymously (no EDL credentials needed) and inspects the resulting acquisitions.
Needs the [asf] extra (pip install earthlens[asf]).
Discover a reference granule¶
An InSAR stack is built around a reference scene — every other product in the stack is a candidate secondary acquisition, characterised by its perpendicular and temporal baselines relative to the reference. The reference must be a stackable product (sentinel-1-slc, sentinel-1-burst, alos-palsar-slc, …).
Hardcoding a granule id is brittle (ASF occasionally retires granules from the live catalog). Instead we run a small search over a SAR-active bbox + time window and pick the first hit as the reference.
from earthlens.earthlens import EarthLens
# San Francisco Bay — Sentinel-1 ascends every few days.
scout = EarthLens(
data_source='asf',
variables=['sentinel-1-slc'],
start='2024-06-01', end='2024-06-30',
lat_lim=[37.0, 37.5],
lon_lim=[-122.5, -122.0],
path='asf_out',
max_results=5,
)
scout_products = scout.datasource._search()
REFERENCE = scout_products[0].id
print(f'reference granule: {REFERENCE}')
Build the baseline stack¶
Setting reference=<granule> switches the backend into stack mode. The bbox is not required in stack mode — the reference scene's footprint defines the area of interest. Pass perpendicular_baseline and temporal_baseline as (min, max) tuples; the backend fetches the full reference-frame stack from ASFProduct.stack() and applies both windows as a client-side post-filter.
el = EarthLens(
data_source='insar', # alias for 'asf'
variables=['sentinel-1-slc'],
reference=REFERENCE, # <-- switches to stack mode
perpendicular_baseline=(-100.0, 100.0), # metres, (min, max)
temporal_baseline=(0, 60), # whole days, (min, max)
start='2024-01-01', # advisory in stack mode
end='2024-12-31',
path='insar_stack',
)
el.datasource._mode
products = el.datasource._search()
print(f'{len(products)} acquisition(s) in the baseline window')
Inspect the baselines¶
Each stacked product carries perpendicularBaseline (metres) and temporalBaseline (days, signed relative to the reference) in its metadata. The reference itself is in the stack with baselines (0, 0).
print(f'{"scene":62s} {"perp (m)":>10s} {"temp (d)":>10s}')
for product in products:
perp = product.metadata.get('perpendicularBaseline')
temp = product.metadata.get('temporalBaseline')
print(f'{product.id:62s} {perp!s:>10s} {temp!s:>10s}')
Tighter windowing¶
If the unfiltered stack returns too many acquisitions, narrow the perpendicular- or temporal-baseline window. Both filter the already-fetched stack client-side, so the request to ASF is unchanged — only the returned list shrinks.
tight = EarthLens(
data_source='insar',
variables=['sentinel-1-slc'],
reference=REFERENCE,
perpendicular_baseline=(-50.0, 50.0), # tighter than before
temporal_baseline=(0, 24), # 24-day repeat cycle
start='2024-01-01',
end='2024-12-31',
path='insar_stack_tight',
)
tight_products = tight.datasource._search()
print(f'tight stack: {len(tight_products)} acquisition(s)')
Downstream processing¶
The backend retrieves SAR products; it does not form interferograms. Hand the downloaded stack to a dedicated InSAR tool:
- HyP3 — ASF's hosted on-demand InSAR / RTC service.
- ISCE2 / ISCE3 — NASA / JPL's InSAR Scientific Computing Environment.
- SNAP — ESA's Sentinel application platform.
- MintPy — time-series InSAR analysis.
To actually fetch the products, set EDL credentials and call el.download() (see Authentication). The download is idempotent — a re-run skips files already on disk.