isce-framework / isce-framework/dolphin

[Bug]: NISAR GSLC: wavelength not auto-detected, and NISAR_L_FREQUENCY constant is incorrect

Open Beginner friendly
#704 7 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.