isce-framework / isce-framework/dolphin
[Bug]: NISAR GSLC: wavelength not auto-detected, and NISAR_L_FREQUENCY constant is incorrect
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 153
- Forks
- 33
- PR merge metrics
- No merged PRs in 30d
Description
Checked for duplicates
Yes - I've already checked
Describe the bug
When processing NISAR GSLC files without manually setting wavelength in input_options, dolphin silently outputs displacement in radians instead of metres. The existing auto-detection in model_post_init only handles OPERA-S1 (via get_burst_id). NISAR filenames don't match that pattern so it falls through with no warning.
There is also a related bug in constants.py: NISAR_L_FREQUENCY = 1.25e9 is a rounded value that gives a wavelength of 0.23983 m, whereas the correct NISAR L-band centre frequency gives ~0.23840 m (~1.4 mm error, ~0.6%). Note that UAVSAR_WAVELENGTH = 0.238403545 in the same file is already correct — NISAR and UAVSAR share the same L-band frequency.
NISAR GSLC HDF5 files store the mission and radar band under:
science/LSAR/identification/missionId -> b'NISAR'
science/LSAR/identification/radarBand -> b'L'
These fields are present in all tested GSLC products. Since h5py is already a dolphin dependency, a fix requires no new requirements.
Proposed addition to model_post_init in dolphin/workflows/config/_displacement.py, after the existing S1 block:
if self.input_options.wavelength is None and self.cslc_file_list:
try:
import h5py
with h5py.File(self.cslc_file_list[0], "r") as hf:
ident = hf.get("science/LSAR/identification")
if ident is not None:
mission = ident.get("missionId")
band = ident.get("radarBand")
if mission is not None and band is not None:
mission_str = mission[()].decode().upper()
band_str = band[()].decode().upper()
if mission_str == "NISAR":
if band_str == "L":
self.input_options.wavelength = constants.NISAR_L_WAVELENGTH
elif band_str == "S":
self.input_options.wavelength = constants.NISAR_S_WAVELENGTH
except Exception:
pass
And in dolphin/constants.py:
# change from:
NISAR_L_FREQUENCY = 1.25e9
# to:
NISAR_L_FREQUENCY = 1_257_476_312 # actual L-band centre frequency (same as UAVSAR)
Happy to put up a PR for both if useful — the changes are small and self-contained.
What did you expect?
I expected Dolphin to auto-detect the NISAR L-band wavelength from the file metadata and output displacement in metres, consistent with the behaviour for OPERA-S1.
Reproducible steps
1. Download any NISAR GSLC product (tested on v1.4.0 beta, productSpecificationVersion 1.4.0)
2. Run `dolphin config` without setting `--wavelength`
3. Run `dolphin run` — timeseries outputs are in radians, not metres
Environment
dolphin version: 0.42.5
Python deps:
h5py: 3.16.0
jax: 0.7.1
numba: 0.64.0
numpy: 1.26.4
opera-utils: 0.25.6
pydantic: 2.12.5
pyproj: 3.7.2
rasterio: 1.5.0
ruamel_yaml: None
scipy: 1.12.0
snaphu: 0.4.1
threadpoolctl: 3.6.0
tqdm: 4.67.3
tyro: 1.0.10
osgeo.gdal: 3.12.2
System:
python: 3.12.13 | packaged by conda-forge
executable: /Users/dlindsay/miniforge3/envs/dolphin-env/bin/python
machine: macOS-26.3.1-arm64-arm-64bit
Unwrapping packages:
snaphu: 0.4.1
isce3: 0.25.8
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in dolphin/workflows/config/_displacement.py at model_post_init and inspect dolphin/constants.py for the NISAR and UAVSAR wavelength definitions. Reproduce with a NISAR GSLC using dolphin config and dolphin run, then verify metadata-based wavelength detection and metre-scaled displacement while preserving OPERA-S1 behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- data
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100