Skip to content

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

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions