Skip to content

Add NISAR geometry, mask, and tropo match utilities#220

Open
mgovorcin wants to merge 3 commits into
opera-adt:mainfrom
mgovorcin:reapply-nisar-utilities
Open

Add NISAR geometry, mask, and tropo match utilities#220
mgovorcin wants to merge 3 commits into
opera-adt:mainfrom
mgovorcin:reapply-nisar-utilities

Conversation

@mgovorcin
Copy link
Copy Markdown
Contributor

Reapply NISAR geometry, mask, and tropo match utilities

Re-introduces the utilities removed in #218 (revert of #214). Same code as #214, applied cleanly on top of current main.

What's added

Three modules to support the DISP-NISAR processing chain:

Module Public API Purpose
opera_utils.nisar._mask get_gslc_mask, get_gunw_mask Extract validity masks from NISAR GSLC / GUNW HDF5 products
opera_utils.nisar._geometry prepare_incidence_angle Compute incidence-angle and LOS unit-vector rasters from a GSLC radarGrid datacube interpolated to a DEM
opera_utils.tropo._match apply_tropo_correction, match_and_apply_tropo, read_reference_point Subtract a tropospheric correction from interferograms, with optional reference-point re-referencing and secondary-date matching

Also exported from opera_utils.nisar and opera_utils.tropo __init__.py.

Basic usage

Validity masks

from opera_utils.nisar import get_gslc_mask, get_gunw_mask

# GSLC: returns xr.DataArray (uint8, 1=valid, 0=invalid) with CRS attached
mask = get_gslc_mask("NISAR_L2_PR_GSLC_*.h5", frequency="frequencyA")

# Optionally write to GeoTIFF (uint8, nodata=255)
get_gslc_mask("gslc.h5", output_path="gslc_mask.tif")

# GUNW: decodes the 3-digit bitfield (water flag + ref/sec subswath)
gunw_mask = get_gunw_mask("gunw.h5", layer="unwrappedInterferogram")

Incidence angle / LOS unit vectors

from opera_utils.nisar import prepare_incidence_angle

inc_tif, los_tif = prepare_incidence_angle(
    gslc_path="gslc.h5",
    dem_path="dem.tif",
    ref_tif="reference.tif",          # output grid is matched to this
    output_path="incidence_angle.tif",
    los_output_path="los_unit_vector.tif",
    chunk_size=200,
    n_workers=8,
)

Tropospheric correction

from pathlib import Path
from opera_utils.tropo import (
    apply_tropo_correction,
    match_and_apply_tropo,
    read_reference_point,
)

# Single interferogram, with re-referencing
ref = read_reference_point("reference_point.txt")  # -> (row, col)
apply_tropo_correction(
    ifg_path="20260101_20260113.iono_corrected.tif",
    tropo_path="tropo_correction_20260113T000000.tif",
    output_path="20260101_20260113.iono_tropo_corrected.tif",
    reference_point=ref,
)

# Batch: match each ifg to its secondary-date tropo file and apply
match_and_apply_tropo(
    ifg_files=sorted(Path("ifgs").glob("*.iono_corrected.tif")),
    tropo_dir="tropo",
    reference_point_file="reference_point.txt",
)
image

- nisar/_geometry.py: prepare_incidence_angle — interpolates radarGrid datacube
  to DEM surface using multiprocessing, writes incidence angle and LOS unit vector rasters
- nisar/_mask.py: get_gslc_mask / get_gunw_mask — extract boolean validity masks
  from GSLC (subswath mask) and GUNW (water+subswath bitfield) products
- tropo/_match.py: apply_tropo_correction / match_and_apply_tropo / read_reference_point
  — match and subtract tropospheric delay corrections by secondary date
- Update nisar/__init__.py and tropo/__init__.py exports
- Resolve merge conflict in nisar/_download.py (keep both numpy and requests imports)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@mgovorcin mgovorcin requested a review from mirzaees May 28, 2026 23:40
if auth is None:
msg = "No .netrc entry found for urs.earthdata.nasa.gov"
raise ValueError(msg)
username, _, password = auth
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might be good to use the existing function: credentials.get_earthdata_username_password

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants