Skip to content

Update prep_nisar.py#1478

Closed
Alex-Lewandowski wants to merge 1 commit intoinsarlab:mainfrom
ASFOpenSARlab:update_prep_nisar
Closed

Update prep_nisar.py#1478
Alex-Lewandowski wants to merge 1 commit intoinsarlab:mainfrom
ASFOpenSARlab:update_prep_nisar

Conversation

@Alex-Lewandowski
Copy link
Copy Markdown
Contributor

@Alex-Lewandowski Alex-Lewandowski commented Mar 16, 2026

  • update slantRange attr name to referenceSlantRange
  • path handling
  • gdal.warp options to creationOptions
  • gdal.UseExceptions()

Description of proposed changes

Reminders

  • Fix #xxxx
  • Pass Pre-commit check (green)
  • Pass Codacy code review (green)
  • Pass Circle CI test (green)
  • Make sure that your code follows our style. Use the other functions/files as a basis.
  • If modifying functionality, describe changes to function behavior and arguments in a comment below the function declaration.
  • If adding new functionality, add a detailed description to the documentation and/or an example.

Summary by Sourcery

Update NISAR preparation to use the correct reference slant range attribute and more robust DEM file handling while improving GDAL usage and logging.

Enhancements:

  • Switch NISAR radar grid slant range attribute to use referenceSlantRange instead of slantRange.
  • Resolve DEM paths via the current working directory and ensure all GDAL operations use resolved filesystem paths and creationOptions for compression.
  • Add lightweight logging/prints for input glob pattern, current working directory, and DEM subset dimensions to aid debugging.

…al.warp options to creationOptions, gdal.UseExceptions()
@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai bot commented Mar 16, 2026

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Aligns NISAR preparation script with updated product metadata and improves DEM path resolution and GDAL warp usage, while adding minimal debug output for geometry prep.

Sequence diagram for updated DEM handling in prepare_geometry

sequenceDiagram
    actor User
    participant prep_nisar as prep_nisar_module
    participant prepare_geometry
    participant read_subset
    participant read_and_interpolate_geometry
    participant GDAL as gdal
    User->>prep_nisar: run script with demFile and input_glob
    prep_nisar->>prepare_geometry: prepare_geometry(metaFile, demFile, ...)
    prepare_geometry->>read_subset: read_subset(metaFile, bbox, geometry=True)
    read_subset-->>prepare_geometry: geo_ds (includes xybbox)
    prepare_geometry->>read_and_interpolate_geometry: read_and_interpolate_geometry(metaFile, demFile, geo_ds[xybbox], mask_file)
    read_and_interpolate_geometry->>prep_nisar: Path.cwd()
    read_and_interpolate_geometry->>prep_nisar: Path.cwd().rglob(demFile)
    prep_nisar-->>read_and_interpolate_geometry: dem_path (absolute)
    read_and_interpolate_geometry->>GDAL: Open(dem_path, GA_ReadOnly)
    GDAL-->>read_and_interpolate_geometry: dem_dataset (projection, EPSG)
    read_and_interpolate_geometry->>GDAL: Warp(output_dem, dem_path, outputBounds=bounds, format=GTiff, srcSRS=input_projection, dstSRS=output_projection, resampleAlg=GRA_Bilinear, width=subset_cols, height=subset_rows, creationOptions=[COMPRESS=DEFLATE])
    read_and_interpolate_geometry->>GDAL: Open(output_dem, GA_ReadOnly).ReadAsArray()
    GDAL-->>read_and_interpolate_geometry: dem_subset_array
    read_and_interpolate_geometry-->>prepare_geometry: dem_subset_array, slant_range, incidence_angle, mask
    prepare_geometry-->>prep_nisar: geometry datasets
    prep_nisar-->>User: prepared NISAR geometry products
Loading

File-Level Changes

Change Details Files
Update radar grid slant range attribute to match current NISAR product metadata.
  • Change DATASETS mapping for rdr_slant_range from slantRange to referenceSlantRange in the RADARGRID metadata path
src/mintpy/prep_nisar.py
Make DEM handling more robust by resolving an absolute path from the current working directory and normalizing usage in GDAL calls.
  • Resolve dem_file to an absolute path via Path.cwd().rglob before opening with GDAL
  • Use dem_path consistently for computing the transformed DEM output location
  • Pass output_dem and dem_path to gdal.Warp as strings and use the resolved output_dem when reopening the warped DEM
src/mintpy/prep_nisar.py
Adjust GDAL warp configuration to use creationOptions and ensure compatibility with current GDAL API.
  • Replace options=['COMPRESS=DEFLATE'] with creationOptions=['COMPRESS=DEFLATE'] in gdal.Warp invocation
src/mintpy/prep_nisar.py
Add lightweight debug logging around input discovery and geometry preparation.
  • Print the input_glob pattern used to discover unwrapped files
  • Print the current working directory before geometry preparation
  • Print the DEM subset array length after interpolation
src/mintpy/prep_nisar.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@yunjunz yunjunz marked this pull request as ready for review March 25, 2026 06:04
Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey - I've found 2 issues, and left some high level feedback:

  • The DEM resolution logic dem_path = list(Path.cwd().rglob(dem_file))[0].resolve() is brittle and potentially expensive (no match, multiple matches, large trees); consider respecting the provided path first and only falling back to a controlled search with explicit error handling when the file is not found.
  • The new print statements for debugging (e.g., inps.input_glob, Path.cwd(), length) should be replaced with the existing logging/verbosity mechanism or removed to avoid noisy stdout in normal runs.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The DEM resolution logic `dem_path = list(Path.cwd().rglob(dem_file))[0].resolve()` is brittle and potentially expensive (no match, multiple matches, large trees); consider respecting the provided path first and only falling back to a controlled search with explicit error handling when the file is not found.
- The new `print` statements for debugging (e.g., `inps.input_glob`, `Path.cwd()`, `length`) should be replaced with the existing logging/verbosity mechanism or removed to avoid noisy stdout in normal runs.

## Individual Comments

### Comment 1
<location path="src/mintpy/prep_nisar.py" line_range="62" />
<code_context>
     print(f'update mode: {inps.update_mode}')

     input_files = sorted(glob.glob(inps.input_glob))
+    print(inps.input_glob)
     print(f"Found {len(input_files)} unwrapped files")

</code_context>
<issue_to_address>
**suggestion:** Avoid unconditional debug `print` in `load_nisar`, prefer logging or remove it.

This call will run on every execution and may clutter stdout or expose sensitive path info. If it’s only for debugging, please remove it or send it through the logger at debug level instead.

Suggested implementation:

```python
    input_files = sorted(glob.glob(inps.input_glob))
    logger.debug("Input glob pattern: %s", inps.input_glob)
    print(f"Found {len(input_files)} unwrapped files")

```

If `logger` is not already defined in `prep_nisar.py`, you should also:
1. Add `import logging` near the top of the file.
2. Define a module-level logger, e.g.:
   ```python
   logger = logging.getLogger(__name__)
   ```
This will ensure the `logger.debug(...)` call works correctly and respects the configured logging level.
</issue_to_address>

### Comment 2
<location path="src/mintpy/prep_nisar.py" line_range="251-252" />
<code_context>
     """Read the DEM and mask, change projection and interpolate to data grid,
        interpolate slant range and incidence angle to data grid"""
-    dem_dataset = gdal.Open(dem_file, gdal.GA_ReadOnly)
+    dem_path = list(Path.cwd().rglob(dem_file))[0].resolve()
+    dem_dataset = gdal.Open(dem_path, gdal.GA_ReadOnly)
     proj = gdal.osr.SpatialReference(wkt=dem_dataset.GetProjection())
     dem_src_epsg = int(proj.GetAttrValue('AUTHORITY', 1))
</code_context>
<issue_to_address>
**issue:** Using `Path.cwd().rglob(dem_file)[0]` is brittle and can fail or be slow; consider resolving the provided path directly.

This has two problems: it raises an unhelpful `IndexError` when no match is found, and it may be slow and pick an unintended file if multiple matches exist. If `dem_file` is already a path or relative to a known base, prefer resolving it directly, e.g. `dem_path = Path(dem_file).expanduser().resolve()` (or joining with an explicit base dir), then explicitly check it exists and raise a clear error if not.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +251 to +252
dem_path = list(Path.cwd().rglob(dem_file))[0].resolve()
dem_dataset = gdal.Open(dem_path, gdal.GA_ReadOnly)
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.

issue: Using Path.cwd().rglob(dem_file)[0] is brittle and can fail or be slow; consider resolving the provided path directly.

This has two problems: it raises an unhelpful IndexError when no match is found, and it may be slow and pick an unintended file if multiple matches exist. If dem_file is already a path or relative to a known base, prefer resolving it directly, e.g. dem_path = Path(dem_file).expanduser().resolve() (or joining with an explicit base dir), then explicitly check it exists and raise a clear error if not.

@yunjunz
Copy link
Copy Markdown
Member

yunjunz commented Mar 25, 2026

@Alex-Lewandowski Looks good to me in general, could you fix a few minor issues flagged by pre-comit and sourcery-ai?

Normally, I would fix these minor issues myself, but it seems that I do not have permission to modify the PR changes here.

@Alex-Lewandowski
Copy link
Copy Markdown
Contributor Author

@Alex-Lewandowski Looks good to me in general, could you fix a few minor issues flagged by pre-comit and sourcery-ai?

Hi @yunjunz, Yes, I just started this as a draft PR and still plan to work on it a bit more. I'd like to add tests now that some NISAR data has been released.

Normally, I would fix these minor issues myself, but it seems that I do not have permission to modify the PR changes here.

I bet that's because I submitted the PR from a fork. I can move it into a branch if you'd like access.

@yunjunz
Copy link
Copy Markdown
Member

yunjunz commented Mar 29, 2026

Sounds good @Alex-Lewandowski, take your time.

I bet that's because I submitted the PR from a fork. I can move it into a branch if you'd like access.

Strangely, I could modify other PRs from forks but not this one. Not a big deal, as long as quality checks are all passed. :)

@ehavazli
Copy link
Copy Markdown
Contributor

ehavazli commented Mar 29, 2026

@Alex-Lewandowski @yunjunz
there is a currently working version we are working with in this fork: https://github.com/nisar-solid/MintPy/blob/prep_nisar/src/mintpy/prep_nisar.py

@yunjunz
Copy link
Copy Markdown
Member

yunjunz commented Mar 30, 2026

@Alex-Lewandowski @yunjunz there is a currently working version we are working with in this fork: https://github.com/nisar-solid/MintPy/blob/prep_nisar/src/mintpy/prep_nisar.py

Thank you for letting us know @ehavazli. Please consider issuing a PR whenever it's ready.

@Alex-Lewandowski
Copy link
Copy Markdown
Contributor Author

Closing in favor of this more comprehensive PR: #1487

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.

3 participants