Skip to content

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

@Dani-Lindsay

Description

@Dani-Lindsay

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions