insarlab / MintPy

Miami InSAR time-series software in Python
https://mintpy.readthedocs.io
Other
596 stars 255 forks source link

multiple GNSS/GPS sources support #1173

Closed rzinke closed 5 months ago

rzinke commented 6 months ago

Description of proposed changes

SUMMARY

I have redefined the GPS class to be a dedicated parent class, and have defined several child classes (e.g., UNR_GPS, ESESES_GPS) that will inherit the existing GPS processing routines. Doing so has the dual benefit of providing a straightforward structure for adding new GPS data formats, while requiring as few changes as possible to the existing MintPy code base. Related to https://github.com/nisar-solid/ATBD/issues/3.

RATIONALE

The best way of implementing plugins for multiple GNSS sources is, as far as I can tell, using parent and child classes. This will provide a structured format for ingesting potential new data, maximizes reuse of existing code when new data sources are introduced, and minimizes the number of modifications to the existing code base.

The class GPS is now a parent class, which maintains the functions one would want to apply to all GPS time series, regardless of where they were processed or how they are archived. Once loaded, the three-component displacement data can be cropped, projected, displayed, and fit with mathematical models as a function of time:

# Parent class
class GPS:
    """These subroutines apply to ALL types of GPS time series.
    """
    def __init__(...)
    def open(...)
    def displacement_enu2los(...)
    def get_los_geometry(...)
    def read_gps_los_displacement(...)
    def get_gps_los_velocity(...)

The funcitons for loading and formatting the displacement time series should follow a common set of operations (e.g., load, format, etc., ...) and return the same attributes (e.g., dates, displacement components, etc.), but will obviously differ depending on the format of the source data. To account for this, one should define "child" classes, which inherit the properites and subroutines of the parent class, but for which the methods can be redefined.

# Child classes

class UNR_GPS:
    """These subroutines follow the same workflow, but work for only 
    a specific format of data UNR).
    """
    def dload_site(...):
        download UNR data
    def get_stat_lat_lon(...):
        get geographic info for UNR data
    def read_displacement(...):
    get displacement values for UNR data

# OR

class ESESES_GPS:
    """These subroutines follow the same workflow, but work for only 
    a specific format of data ESESES).
    """
    def dload_site(...):
        download ESESES data
    def get_stat_lat_lon(...):
        get geographic info for ESESES data
    def read_displacement(...):
    get displacement values for ESESES data

That way, all one would need to do to get the data into the proper format for all subsequent operations, is to define a new child class, e.g., class MyGPS with the same sequence of subroutines, rewritten for a specific data format.

Once a child class has been defined, it can easily be recalled by the parent class using the static method GPS.get_gps_obj_by_source(<processing_source>). This offers both convenience and structure, and reduces the number of if statements in the broader code base. For example

from mintpy.objects import gps
gps_source = 'UNR'
GPS = gps.GPS.get_gps_obj_by_source(gps_source)

is all one needs to add in order to not break the existing libraries.

Reminders

New functionality

The user can now specify GPS processing source. If not specified, the default source is UNR NGL -- the only source supported currently -- and all functions can be used as before, as if no changes were made.

rzinke commented 6 months ago

pre-commit.ci autofix

rzinke commented 6 months ago

pre-commit.ci autofix

yunjunz commented 6 months ago

I always wanted to rename the GPS naming into GNSS, for a more generic purpose. This includes all the related functions, variables, and option names, and code comments/documentation. As for the view.py options, we could support both gps and gnss for back-ward compatibility. @rzinke Shall we do it in this PR?

rzinke commented 6 months ago

I always wanted to rename the GPS naming into GNSS, for a more generic purpose. This includes all the related functions, variables, and option names, and code comments/documentation. As for the view.py options, we could support both gps and gnss for back-ward compatibility. @rzinke Shall we do it in this PR?

Sure! And I agree philosophically.

yunjunz commented 6 months ago

@rzinke Could you go for this change?

I will check more at the PR later this week.

rzinke commented 6 months ago

@rzinke Could you go for this change?

I will check more at the PR later this week.

Yes. I am working on it right now. Would you like the whole module gps.py renamed to gnss.py?

yunjunz commented 6 months ago

Yes please.

rzinke commented 6 months ago

pre-commit.ci autofix

rzinke commented 6 months ago

pre-commit.ci autofix

rzinke commented 6 months ago

pre-commit.ci autofix

rzinke commented 6 months ago

I have added support for two other GNSS processing "sources": The JPL-SIDESHOW daily solutions computed with GipsyX, and a "Generic" format for which the use could provide any data of their choosing, formatted in space-separated columns.

We need to sort out how the site_lat and site_lon for each station of calculated see https://github.com/insarlab/MintPy/discussions/1167#discussioncomment-9002091, and then I think the revised GNSS module is ready for incorporation into MintPy.

rzinke commented 5 months ago

Who should I talk to about resolving the difference between MintPy's station lat/lon computation performed here, and the nominal station lat/lon reported in the UNR tenv3 file?

Is there a specific reason the nominal lat/lon numbers where not used?

rzinke commented 5 months ago

Also, what does "Fix #xxxx" mean? Otherwise, all check have been passed for this PR.

yunjunz commented 5 months ago

Thank you @rzinke for the PR, and sorry for the late response. As for the site_lat/lon, let's just use the nominal lat/lon directly, which makes more sense, and I could not recall why I was not using them before. Could you please change the code for it?

rzinke commented 5 months ago

Hi @yunjunz, thanks for the feedback. I have incorporated the proposed changes into the gnss.py module. Please have a look when you get the chance. Cheers.