OPERA Sentinel-1 RTC backscatter (NASA Earthdata)¶
Download OPERA Radiometric-Terrain-Corrected Sentinel-1 backscatter from the ASF DAAC over a small area and map the VV channel in decibels — the kind of SAR layer used for flood and land-surface monitoring. Cloud-Optimized GeoTIFF raster, read with pyramids. Live query — needs the [earthdata] extra and EDL credentials, and the ASF application authorized for your EDL account (see Authentication); wrapped for nbval-lax safety offline.
ASF auth note: ASF's datapool uses an EDL OAuth redirect that drops a bearer token across hosts (HTTP 401). ASF downloads therefore need username/password (or a
~/.netrcentry) soearthaccesscan hold the session — a bareEARTHDATA_TOKENis not enough — or in-region S3. You must also authorize the Alaska Satellite Facility Data Access application for your EDL account (see Authentication).
Setup¶
The imports and the output directory. earthlens provides the unified EarthLens entry point; pyramids reads the Cloud-Optimized GeoTIFF later, and matplotlib/numpy render the VV channel in decibels.
from pathlib import Path
import matplotlib.pyplot as plt
import numpy as np
from pyramids.dataset import Dataset
from earthlens import EarthLens
OUT_DIR = Path('earthdata_output')
OUT_DIR.mkdir(exist_ok=True)
1 · Download the OPERA RTC-S1 scene¶
First describe the request: the earthdata backend, the OPERA RTC-S1 collection, the VV polarization, a short January 2024 window, and a small bounding box near Monterey Bay. Keeping the constructor on its own statement makes the request easy to read and re-run.
scene = EarthLens(
data_source='earthdata',
dataset='OPERA_L2_RTC-S1_V1',
variables=['VV'],
start='2024-01-01',
end='2024-01-13',
aoi=[-121.8, 36.3, -121.5, 36.6],
path=str(OUT_DIR),
)
download() performs the live ASF query and writes the COG file(s) under OUT_DIR, returning the list of written paths. It is wrapped in a try/except so the notebook degrades gracefully offline or without authorized EDL credentials.
paths = None
try:
paths = scene.download(progress_bar=False)
print(len(paths), 'file(s):', [Path(p).name for p in paths][:4])
except Exception as exc:
print(f'skipped live query: {type(exc).__name__}: {exc}')
2 · Read the VV backscatter¶
Pick the _VV.TIF file from the download, read it with pyramids, and mask the non-positive linear-power samples so the log conversion below is well defined. Guarded so it is skipped when the download did not run.
db = None
if paths:
try:
vv = next(p for p in paths if str(p).upper().endswith('_VV.TIF'))
arr = Dataset.read_file(str(vv)).read_array().astype('float32')
arr[arr <= 0] = np.nan
db = 10.0 * np.log10(arr)
except Exception as exc:
print(f'read step skipped: {type(exc).__name__}: {exc}')
Map the VV channel in decibels¶
Convert linear power to decibels (10 · log10) and render it as a grayscale image, the standard way to visualise SAR backscatter for flood and land-surface monitoring.
if db is not None:
fig, ax = plt.subplots(figsize=(8, 7))
im = ax.imshow(db, cmap='gray', vmin=-25, vmax=0)
fig.colorbar(im, ax=ax, label='VV backscatter (dB)')
ax.set_title('OPERA RTC-S1 VV backscatter')
plt.tight_layout()
plt.show()