GeoscienceAustralia / PyRate

A Python tool for estimating velocity and time-series from Interferometric Synthetic Aperture Radar (InSAR) data.
https://geoscienceaustralia.github.io/PyRate/
Apache License 2.0
199 stars 69 forks source link

Fix and simplify how user supplied reference pixel is validated #367

Closed adeane-ga closed 2 years ago

adeane-ga commented 2 years ago

This is a small PR that simplifies the way that the user supplied reference pixel is validated (confirmed to be within spatial extent). Without this fix, PyRate does not work if trying to crop in combination to supplying reference pixel coordinates - a very common user case.

It is associated with this issue: https://github.com/GeoscienceAustralia/PyRate/issues/360

Recommended Review Strategy On your own testing dataset, run PyRate with the different combinations of cropping and user supplied reference pixel coordinates to confirm it is working for you and has also not broken anything.

The Problem PyRate gives configuration options for the user to determine where the reference pixel will be refx and refy in longitude and latitude. There is also the option to crop the dataset with user defined coordinates so that PyRate only processes a smaller extent with ifgcropopt: 3. It is common for a user to use both of these options. The reference pixel selection is done during the correct step, whilst the cropping is conducted prior, in the prepifg step.

It results in this error:

Traceback (most recent call last):
  File "/home/547/ad6200/PyRateVenv/bin/pyrate", line 11, in <module>
    load_entry_point('Py-Rate==0.6.0', 'console_scripts', 'pyrate')()
  File "/home/547/ad6200/PyRateVenv/lib/python3.7/site-packages/pyrate/main.py", line 116, in main
    correct.main(config)
  File "/home/547/ad6200/PyRateVenv/lib/python3.7/site-packages/pyrate/correct.py", line 142, in main
    return correct_ifgs(config)
  File "/home/547/ad6200/PyRateVenv/lib/python3.7/site-packages/pyrate/correct.py", line 226, in correct_ifgs
    params[C.REFX_FOUND], params[C.REFY_FOUND] = ref_pixel_calc_wrapper(params)
  File "/home/547/ad6200/PyRateVenv/lib/python3.7/site-packages/pyrate/core/refpixel.py", line 423, in ref_pixel_calc_wrapper
    __validate_supplied_lat_lon(params)
  File "/home/547/ad6200/PyRateVenv/lib/python3.7/site-packages/pyrate/core/refpixel.py", line 401, in __validate_supplied_lat_lon
    C.IFG_XLAST], params[C.IFG_YLAST])
  File "/home/547/ad6200/PyRateVenv/lib/python3.7/site-packages/pyrate/core/prepifg_helper.py", line 81, in get_analysis_extent
    return _get_extents(rasters, crop_opt, user_exts)
  File "/home/547/ad6200/PyRateVenv/lib/python3.7/site-packages/pyrate/core/prepifg_helper.py", line 146, in _get_extents
    extents = _custom_bounds(ifgs, *user_exts)
  File "/home/547/ad6200/PyRateVenv/lib/python3.7/site-packages/pyrate/core/prepifg_helper.py", line 332, in _custom_bounds
    raise PreprocessError(msg)
pyrate.core.prepifg_helper.PreprocessError: Cropped image bounds are outside the original image bounds

Solution As the above user supplied cropping coordinates check is not relevant during this step, I have removed the call to the get_analysis_extent() from the prepifg_helper.py and implemented a validation of the user supplied reference pixel by getting dataset extents independently from within the __validate_supplied_lat_lon() function itself.

In Summary

Old code: https://github.com/GeoscienceAustralia/PyRate/blob/8203989e7d9b675491e79610cff04728d8dc3973/pyrate/core/refpixel.py#L389-L411

New code: https://github.com/GeoscienceAustralia/PyRate/blob/73a0d7572f4b785b47f7847890a1c38e06f2eeb9/pyrate/core/refpixel.py#L390-L419

s-m-t-c commented 2 years ago

I have tested this feature with varying combinations of cropping and reference pixel options. Happy to merge this.

Initially I had an issue in the stacking step which implied that the cropping wasn't working correctly but a clean reinstall managed to fix this. Other users weren't able to recreate this.

IndexError: boolean index did not match indexed array along dimension 1; dimension is 60 but corresponding boolean dimension is 50