Full Code of GeoscienceAustralia/PyRate for AI

master 3579612cbfec cached
856 files
5.7 MB
1.5M tokens
1108 symbols
1 requests
Download .txt
Showing preview only (6,072K chars total). Download the full file or copy to clipboard to get everything.
Repository: GeoscienceAustralia/PyRate
Branch: master
Commit: 3579612cbfec
Files: 856
Total size: 5.7 MB

Directory structure:
gitextract_ml4uzp09/

├── .coveragerc
├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   └── feature_request.md
│   └── workflows/
│       └── build.yml
├── .gitignore
├── .pylintrc
├── Dockerfile
├── LICENSE
├── README.rst
├── __init__.py
├── docs/
│   ├── Makefile
│   ├── algorithm.rst
│   ├── aps.rst
│   ├── authors.rst
│   ├── conf.py
│   ├── configuration.rst
│   ├── contributing.rst
│   ├── covariance.rst
│   ├── demerror.rst
│   ├── dependencies.rst
│   ├── docker.rst
│   ├── gamma.rst
│   ├── gdal_python.rst
│   ├── geometry.rst
│   ├── history.rst
│   ├── hpc.rst
│   ├── ifgconstants.rst
│   ├── index.rst
│   ├── installation.rst
│   ├── logger.rst
│   ├── make.bat
│   ├── modules.rst
│   ├── mpiops.rst
│   ├── mst.rst
│   ├── orbital.rst
│   ├── phase_closure.rst
│   ├── prepifg_helper.rst
│   ├── pyrate.conv2tif.rst
│   ├── pyrate.correct.rst
│   ├── pyrate.main.rst
│   ├── pyrate.merge.rst
│   ├── pyrate.prepifg.rst
│   ├── ref_phs_est.rst
│   ├── refpixel.rst
│   ├── roipac.rst
│   ├── scripts.rst
│   ├── shared.rst
│   ├── stack.rst
│   ├── timeseries.rst
│   ├── troubleshooting.rst
│   ├── ubuntu.rst
│   └── usage.rst
├── input_parameters.conf
├── pyrate/
│   ├── __init__.py
│   ├── configuration.py
│   ├── constants.py
│   ├── conv2tif.py
│   ├── core/
│   │   ├── .coveragerc
│   │   ├── __init__.py
│   │   ├── algorithm.py
│   │   ├── aps.py
│   │   ├── covariance.py
│   │   ├── dem_error.py
│   │   ├── gamma.py
│   │   ├── gdal_python.py
│   │   ├── geometry.py
│   │   ├── ifgconstants.py
│   │   ├── logger.py
│   │   ├── mpiops.py
│   │   ├── mst.py
│   │   ├── orbital.py
│   │   ├── phase_closure/
│   │   │   ├── __init__.py
│   │   │   ├── closure_check.py
│   │   │   ├── collect_loops.py
│   │   │   ├── correct_phase.py
│   │   │   ├── mst_closure.py
│   │   │   ├── plot_closure.py
│   │   │   └── sum_closure.py
│   │   ├── prepifg_helper.py
│   │   ├── ref_phs_est.py
│   │   ├── refpixel.py
│   │   ├── roipac.py
│   │   ├── shared.py
│   │   ├── stack.py
│   │   └── timeseries.py
│   ├── correct.py
│   ├── default_parameters.py
│   ├── main.py
│   ├── merge.py
│   └── prepifg.py
├── pytest.ini
├── requirements-dev.txt
├── requirements-plot.txt
├── requirements-test.txt
├── requirements.txt
├── scripts/
│   ├── apt_install.sh
│   ├── ci_gdal_install.sh
│   ├── ci_proj_install.sh
│   ├── create_html_documentation.sh
│   ├── gdal_calc_local.py
│   ├── nci_install.sh
│   ├── nci_load_modules.sh
│   ├── nci_run_tests.sh
│   ├── plot_ifgs.py
│   └── prepifg.sh
├── setup.cfg
├── setup.py
├── tests/
│   ├── __init__.py
│   ├── common.py
│   ├── conftest.py
│   ├── phase_closure/
│   │   ├── __init__.py
│   │   ├── common.py
│   │   ├── conftest.py
│   │   ├── test_closure_check.py
│   │   ├── test_collect_loops.py
│   │   ├── test_mst_closure.py
│   │   ├── test_plot_closure.py
│   │   └── test_sum_closure.py
│   ├── test_algorithm.py
│   ├── test_aps.py
│   ├── test_constants.py
│   ├── test_conv2tif.py
│   ├── test_correct.py
│   ├── test_covariance.py
│   ├── test_data/
│   │   ├── cropA/
│   │   │   ├── baseline_30
│   │   │   ├── coherence_30
│   │   │   ├── coherence_stats/
│   │   │   │   ├── coh_mean.tif
│   │   │   │   ├── coh_median.tif
│   │   │   │   └── coh_std.tif
│   │   │   ├── dem_error_result/
│   │   │   │   ├── 20180106-20180319_ifg_20_dem_error.npy
│   │   │   │   ├── 20180130-20180412_ifg_20_dem_error.npy
│   │   │   │   ├── 20180412-20180518_ifg_20_dem_error.npy
│   │   │   │   └── dem_error.tif
│   │   │   ├── geometry/
│   │   │   │   ├── 20180106-20180130_VV_8rlks_base.par
│   │   │   │   ├── 20180106-20180130_VV_8rlks_bperp.par
│   │   │   │   ├── 20180106-20180319_VV_8rlks_base.par
│   │   │   │   ├── 20180106-20180319_VV_8rlks_bperp.par
│   │   │   │   ├── 20180106-20180412_VV_8rlks_base.par
│   │   │   │   ├── 20180106-20180412_VV_8rlks_bperp.par
│   │   │   │   ├── 20180106-20180518_VV_8rlks_base.par
│   │   │   │   ├── 20180106-20180518_VV_8rlks_bperp.par
│   │   │   │   ├── 20180106_VV_8rlks_eqa_to_rdc.lt
│   │   │   │   ├── 20180130-20180307_VV_8rlks_base.par
│   │   │   │   ├── 20180130-20180307_VV_8rlks_bperp.par
│   │   │   │   ├── 20180130-20180412_VV_8rlks_base.par
│   │   │   │   ├── 20180130-20180412_VV_8rlks_bperp.par
│   │   │   │   ├── 20180307-20180319_VV_8rlks_base.par
│   │   │   │   ├── 20180307-20180319_VV_8rlks_bperp.par
│   │   │   │   ├── 20180307-20180331_VV_8rlks_base.par
│   │   │   │   ├── 20180307-20180331_VV_8rlks_bperp.par
│   │   │   │   ├── 20180307-20180506_VV_8rlks_base.par
│   │   │   │   ├── 20180307-20180506_VV_8rlks_bperp.par
│   │   │   │   ├── 20180307-20180530_VV_8rlks_base.par
│   │   │   │   ├── 20180307-20180530_VV_8rlks_bperp.par
│   │   │   │   ├── 20180307-20180611_VV_8rlks_base.par
│   │   │   │   ├── 20180307-20180611_VV_8rlks_bperp.par
│   │   │   │   ├── 20180319-20180331_VV_8rlks_base.par
│   │   │   │   ├── 20180319-20180331_VV_8rlks_bperp.par
│   │   │   │   ├── 20180319-20180506_VV_8rlks_base.par
│   │   │   │   ├── 20180319-20180506_VV_8rlks_bperp.par
│   │   │   │   ├── 20180319-20180518_VV_8rlks_base.par
│   │   │   │   ├── 20180319-20180518_VV_8rlks_bperp.par
│   │   │   │   ├── 20180319-20180530_VV_8rlks_base.par
│   │   │   │   ├── 20180319-20180530_VV_8rlks_bperp.par
│   │   │   │   ├── 20180319-20180623_VV_8rlks_base.par
│   │   │   │   ├── 20180319-20180623_VV_8rlks_bperp.par
│   │   │   │   ├── 20180331-20180412_VV_8rlks_base.par
│   │   │   │   ├── 20180331-20180412_VV_8rlks_bperp.par
│   │   │   │   ├── 20180331-20180506_VV_8rlks_base.par
│   │   │   │   ├── 20180331-20180506_VV_8rlks_bperp.par
│   │   │   │   ├── 20180331-20180518_VV_8rlks_base.par
│   │   │   │   ├── 20180331-20180518_VV_8rlks_bperp.par
│   │   │   │   ├── 20180331-20180530_VV_8rlks_base.par
│   │   │   │   ├── 20180331-20180530_VV_8rlks_bperp.par
│   │   │   │   ├── 20180331-20180623_VV_8rlks_base.par
│   │   │   │   ├── 20180331-20180623_VV_8rlks_bperp.par
│   │   │   │   ├── 20180331-20180717_VV_8rlks_base.par
│   │   │   │   ├── 20180331-20180717_VV_8rlks_bperp.par
│   │   │   │   ├── 20180412-20180506_VV_8rlks_base.par
│   │   │   │   ├── 20180412-20180506_VV_8rlks_bperp.par
│   │   │   │   ├── 20180412-20180518_VV_8rlks_base.par
│   │   │   │   ├── 20180412-20180518_VV_8rlks_bperp.par
│   │   │   │   ├── 20180506-20180518_VV_8rlks_base.par
│   │   │   │   ├── 20180506-20180518_VV_8rlks_bperp.par
│   │   │   │   ├── 20180506-20180530_VV_8rlks_base.par
│   │   │   │   ├── 20180506-20180530_VV_8rlks_bperp.par
│   │   │   │   ├── 20180506-20180611_VV_8rlks_base.par
│   │   │   │   ├── 20180506-20180611_VV_8rlks_bperp.par
│   │   │   │   ├── 20180506-20180623_VV_8rlks_base.par
│   │   │   │   ├── 20180506-20180623_VV_8rlks_bperp.par
│   │   │   │   ├── 20180506-20180705_VV_8rlks_base.par
│   │   │   │   ├── 20180506-20180705_VV_8rlks_bperp.par
│   │   │   │   ├── 20180506-20180717_VV_8rlks_base.par
│   │   │   │   └── 20180506-20180717_VV_8rlks_bperp.par
│   │   │   ├── geotiffs/
│   │   │   │   ├── cropA_20180106-20180130_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180106-20180130_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180106-20180319_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180106-20180319_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180106-20180412_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180106-20180412_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180106-20180518_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180106-20180518_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180130-20180307_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180130-20180307_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180130-20180412_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180130-20180412_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180307-20180319_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180307-20180319_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180307-20180331_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180307-20180331_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180307-20180506_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180307-20180506_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180307-20180530_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180307-20180530_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180307-20180611_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180307-20180611_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180319-20180331_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180319-20180331_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180319-20180506_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180319-20180506_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180319-20180518_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180319-20180518_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180319-20180530_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180319-20180530_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180319-20180623_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180319-20180623_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180331-20180412_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180331-20180412_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180331-20180506_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180331-20180506_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180331-20180518_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180331-20180518_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180331-20180530_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180331-20180530_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180331-20180623_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180331-20180623_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180331-20180717_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180331-20180717_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180412-20180506_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180412-20180506_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180412-20180518_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180412-20180518_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180506-20180518_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180506-20180518_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180506-20180530_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180506-20180530_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180506-20180611_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180506-20180611_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180506-20180623_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180506-20180623_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180506-20180705_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180506-20180705_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180506-20180717_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180506-20180717_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   └── cropA_T005A_dem.tif
│   │   │   ├── headers/
│   │   │   │   ├── cropA_20180106_VV_8rlks_eqa_dem.par
│   │   │   │   ├── r20180106_VV_8rlks_mli.par
│   │   │   │   ├── r20180106_VV_slc.par
│   │   │   │   ├── r20180130_VV_8rlks_mli.par
│   │   │   │   ├── r20180130_VV_slc.par
│   │   │   │   ├── r20180307_VV_8rlks_mli.par
│   │   │   │   ├── r20180307_VV_slc.par
│   │   │   │   ├── r20180319_VV_8rlks_mli.par
│   │   │   │   ├── r20180319_VV_slc.par
│   │   │   │   ├── r20180331_VV_8rlks_mli.par
│   │   │   │   ├── r20180331_VV_slc.par
│   │   │   │   ├── r20180412_VV_8rlks_mli.par
│   │   │   │   ├── r20180412_VV_slc.par
│   │   │   │   ├── r20180506_VV_8rlks_mli.par
│   │   │   │   ├── r20180506_VV_slc.par
│   │   │   │   ├── r20180518_VV_8rlks_mli.par
│   │   │   │   ├── r20180518_VV_slc.par
│   │   │   │   ├── r20180530_VV_8rlks_mli.par
│   │   │   │   ├── r20180530_VV_slc.par
│   │   │   │   ├── r20180611_VV_8rlks_mli.par
│   │   │   │   ├── r20180611_VV_slc.par
│   │   │   │   ├── r20180623_VV_8rlks_mli.par
│   │   │   │   ├── r20180623_VV_slc.par
│   │   │   │   ├── r20180705_VV_8rlks_mli.par
│   │   │   │   ├── r20180705_VV_slc.par
│   │   │   │   ├── r20180717_VV_8rlks_mli.par
│   │   │   │   └── r20180717_VV_slc.par
│   │   │   ├── headers_13
│   │   │   ├── ifg_30
│   │   │   └── pyrate_mexico_cropa.conf
│   │   ├── cropB/
│   │   │   └── 20180106-20180130_ifg.tif
│   │   ├── gamma/
│   │   │   ├── 16x20_20090713-20090817_VV_4rlks_utm.tif
│   │   │   ├── 16x20_20090713-20090817_VV_4rlks_utm.unw
│   │   │   ├── 20160114-20160126_base.par
│   │   │   ├── 20160114-20160126_base_init.par
│   │   │   ├── cropped_lookup_table.lt
│   │   │   ├── dem16x20_subset_from_gamma.tif
│   │   │   ├── dem16x20raw.dem
│   │   │   ├── dem16x20raw.dem.par
│   │   │   ├── r20090713_VV.slc.par
│   │   │   └── r20090817_VV.slc.par
│   │   ├── geotiffs/
│   │   │   ├── cropA_20180106-20180130_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180106-20180130_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180106-20180319_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180106-20180319_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180106-20180412_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180106-20180412_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180106-20180518_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180106-20180518_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180106_VV_8rlks_eqa_dem.par
│   │   │   ├── cropA_20180130-20180307_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180130-20180307_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180130-20180412_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180130-20180412_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180307-20180319_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180307-20180319_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180307-20180331_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180307-20180331_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180307-20180506_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180307-20180506_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180307-20180530_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180307-20180530_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180307-20180611_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180307-20180611_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180319-20180331_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180319-20180331_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180319-20180506_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180319-20180506_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180319-20180518_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180319-20180518_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180319-20180530_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180319-20180530_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180319-20180623_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180319-20180623_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180331-20180412_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180331-20180412_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180331-20180506_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180331-20180506_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180331-20180518_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180331-20180518_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180331-20180530_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180331-20180530_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180331-20180623_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180331-20180623_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180331-20180717_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180331-20180717_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180412-20180506_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180412-20180506_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180412-20180518_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180412-20180518_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180506-20180518_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180506-20180518_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180506-20180530_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180506-20180530_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180506-20180611_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180506-20180611_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180506-20180623_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180506-20180623_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180506-20180705_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180506-20180705_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180506-20180717_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180506-20180717_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_T005A_dem.tif
│   │   │   ├── r20180106_VV_slc.par
│   │   │   ├── r20180130_VV_slc.par
│   │   │   ├── r20180307_VV_slc.par
│   │   │   ├── r20180319_VV_slc.par
│   │   │   ├── r20180331_VV_slc.par
│   │   │   ├── r20180412_VV_slc.par
│   │   │   ├── r20180506_VV_slc.par
│   │   │   ├── r20180518_VV_slc.par
│   │   │   ├── r20180530_VV_slc.par
│   │   │   ├── r20180611_VV_slc.par
│   │   │   ├── r20180623_VV_slc.par
│   │   │   ├── r20180705_VV_slc.par
│   │   │   └── r20180717_VV_slc.par
│   │   ├── headers/
│   │   │   └── geo_060619-060828.unw.rsc
│   │   ├── incidence/
│   │   │   └── 128x2.tif
│   │   ├── prepifg/
│   │   │   ├── obs/
│   │   │   │   ├── geo_060619-061002.unw
│   │   │   │   ├── geo_060619-061002.unw.rsc
│   │   │   │   ├── geo_070326-070917.unw
│   │   │   │   └── geo_070326-070917.unw.rsc
│   │   │   └── tif/
│   │   │       ├── 0_1lksx_1lksy_4cr.tif
│   │   │       ├── 1_1lksx_1lksy_4cr.tif
│   │   │       ├── geo_060619-061002.tif
│   │   │       ├── geo_060619-061002_unw.tif
│   │   │       ├── geo_070326-070917.tif
│   │   │       └── geo_070326-070917_unw.tif
│   │   ├── small_test/
│   │   │   ├── coherence/
│   │   │   │   ├── 20060619-20061002_utm.unw.cc
│   │   │   │   ├── 20060828-20061211_utm.unw.cc
│   │   │   │   ├── 20061002-20070219_utm.unw.cc
│   │   │   │   ├── 20061002-20070430_utm.unw.cc
│   │   │   │   ├── 20061106-20061211_utm.unw.cc
│   │   │   │   ├── 20061106-20070115_utm.unw.cc
│   │   │   │   ├── 20061106-20070326_utm.unw.cc
│   │   │   │   ├── 20061211-20070709_utm.unw.cc
│   │   │   │   ├── 20061211-20070813_utm.unw.cc
│   │   │   │   ├── 20070115-20070326_utm.unw.cc
│   │   │   │   ├── 20070115-20070917_utm.unw.cc
│   │   │   │   ├── 20070219-20070430_utm.unw.cc
│   │   │   │   ├── 20070219-20070604_utm.unw.cc
│   │   │   │   ├── 20070326-20070917_utm.unw.cc
│   │   │   │   ├── 20070430-20070604_utm.unw.cc
│   │   │   │   ├── 20070604-20070709_utm.unw.cc
│   │   │   │   ├── 20070709-20070813_utm.unw.cc
│   │   │   │   └── coherence_17
│   │   │   ├── conf/
│   │   │   │   ├── pyrate1.conf
│   │   │   │   ├── pyrate2.conf
│   │   │   │   ├── pyrate_gamma_test.conf
│   │   │   │   └── pyrate_roipac_test.conf
│   │   │   ├── dem/
│   │   │   │   └── roipac_test_trimmed.tif
│   │   │   ├── gamma_obs/
│   │   │   │   ├── 20060619-20061002_base.par
│   │   │   │   ├── 20060619-20061002_utm.unw
│   │   │   │   ├── 20060619-20061002_utm_unw.tif.aux.xml
│   │   │   │   ├── 20060619_slc.par
│   │   │   │   ├── 20060619_utm.dem
│   │   │   │   ├── 20060619_utm.inc
│   │   │   │   ├── 20060619_utm.lv_theta
│   │   │   │   ├── 20060619_utm_dem.par
│   │   │   │   ├── 20060828-20061211_base.par
│   │   │   │   ├── 20060828-20061211_utm.unw
│   │   │   │   ├── 20060828_slc.par
│   │   │   │   ├── 20061002-20070219_base.par
│   │   │   │   ├── 20061002-20070219_utm.unw
│   │   │   │   ├── 20061002-20070430_base.par
│   │   │   │   ├── 20061002-20070430_utm.unw
│   │   │   │   ├── 20061002_slc.par
│   │   │   │   ├── 20061106-20061211_base.par
│   │   │   │   ├── 20061106-20061211_utm.unw
│   │   │   │   ├── 20061106-20070115_base.par
│   │   │   │   ├── 20061106-20070115_utm.unw
│   │   │   │   ├── 20061106-20070326_base.par
│   │   │   │   ├── 20061106-20070326_utm.unw
│   │   │   │   ├── 20061106_slc.par
│   │   │   │   ├── 20061211-20070709_base.par
│   │   │   │   ├── 20061211-20070709_utm.unw
│   │   │   │   ├── 20061211-20070813_base.par
│   │   │   │   ├── 20061211-20070813_utm.unw
│   │   │   │   ├── 20061211_slc.par
│   │   │   │   ├── 20070115-20070326_base.par
│   │   │   │   ├── 20070115-20070326_utm.unw
│   │   │   │   ├── 20070115-20070917_base.par
│   │   │   │   ├── 20070115-20070917_utm.unw
│   │   │   │   ├── 20070115_slc.par
│   │   │   │   ├── 20070219-20070430_base.par
│   │   │   │   ├── 20070219-20070430_utm.unw
│   │   │   │   ├── 20070219-20070604_base.par
│   │   │   │   ├── 20070219-20070604_utm.unw
│   │   │   │   ├── 20070219_slc.par
│   │   │   │   ├── 20070326-20070917_base.par
│   │   │   │   ├── 20070326-20070917_utm.unw
│   │   │   │   ├── 20070326_slc.par
│   │   │   │   ├── 20070430-20070604_base.par
│   │   │   │   ├── 20070430-20070604_utm.unw
│   │   │   │   ├── 20070430_slc.par
│   │   │   │   ├── 20070604-20070709_base.par
│   │   │   │   ├── 20070604-20070709_utm.unw
│   │   │   │   ├── 20070604_slc.par
│   │   │   │   ├── 20070709-20070813_base.par
│   │   │   │   ├── 20070709-20070813_utm.unw
│   │   │   │   ├── 20070709_slc.par
│   │   │   │   ├── 20070813_slc.par
│   │   │   │   ├── 20070917_slc.par
│   │   │   │   ├── bad_epochs_headers
│   │   │   │   ├── bad_epochs_ifms_17
│   │   │   │   ├── baseline_17
│   │   │   │   ├── cropped_lookup_table.lt
│   │   │   │   ├── headers
│   │   │   │   ├── ifms_17
│   │   │   │   └── tif_17
│   │   │   ├── linrate/
│   │   │   │   ├── linear_error.npy
│   │   │   │   ├── linear_intercept.npy
│   │   │   │   ├── linear_rate.npy
│   │   │   │   ├── linear_rsquared.npy
│   │   │   │   ├── linear_samples.npy
│   │   │   │   └── tscuml_0.npy
│   │   │   ├── mst/
│   │   │   │   ├── mst_geo_060619-061002.csv
│   │   │   │   ├── mst_geo_060828-061211.csv
│   │   │   │   ├── mst_geo_061002-070219.csv
│   │   │   │   ├── mst_geo_061002-070430.csv
│   │   │   │   ├── mst_geo_061106-061211.csv
│   │   │   │   ├── mst_geo_061106-070115.csv
│   │   │   │   ├── mst_geo_061106-070326.csv
│   │   │   │   ├── mst_geo_061211-070709.csv
│   │   │   │   ├── mst_geo_061211-070813.csv
│   │   │   │   ├── mst_geo_070115-070326.csv
│   │   │   │   ├── mst_geo_070115-070917.csv
│   │   │   │   ├── mst_geo_070219-070430.csv
│   │   │   │   ├── mst_geo_070219-070604.csv
│   │   │   │   ├── mst_geo_070326-070917.csv
│   │   │   │   ├── mst_geo_070430-070604.csv
│   │   │   │   ├── mst_geo_070604-070709.csv
│   │   │   │   └── mst_geo_070709-070813.csv
│   │   │   ├── orbital_error_correction/
│   │   │   │   ├── ifg_orb_planar_1lks_method1_geo_060619-061002.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method1_geo_060828-061211.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method1_geo_061002-070219.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method1_geo_061002-070430.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method1_geo_061106-061211.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method1_geo_061106-070115.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method1_geo_061106-070326.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method1_geo_061211-070709.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method1_geo_061211-070813.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method1_geo_070115-070326.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method1_geo_070115-070917.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method1_geo_070219-070430.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method1_geo_070219-070604.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method1_geo_070326-070917.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method1_geo_070430-070604.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method1_geo_070604-070709.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method1_geo_070709-070813.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method2_geo_060619-061002.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method2_geo_060828-061211.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method2_geo_061002-070219.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method2_geo_061002-070430.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method2_geo_061106-061211.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method2_geo_061106-070115.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method2_geo_061106-070326.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method2_geo_061211-070709.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method2_geo_061211-070813.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method2_geo_070115-070326.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method2_geo_070115-070917.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method2_geo_070219-070430.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method2_geo_070219-070604.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method2_geo_070326-070917.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method2_geo_070430-070604.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method2_geo_070604-070709.unw.csv
│   │   │   │   └── ifg_orb_planar_1lks_method2_geo_070709-070813.unw.csv
│   │   │   ├── ref_phase_est/
│   │   │   │   ├── ifg_orb_and_ref_phase_corrected_method2geo_060619-061002.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_corrected_method2geo_060828-061211.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_corrected_method2geo_061002-070219.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_corrected_method2geo_061002-070430.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_corrected_method2geo_061106-061211.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_corrected_method2geo_061106-070115.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_corrected_method2geo_061106-070326.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_corrected_method2geo_061211-070709.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_corrected_method2geo_061211-070813.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_corrected_method2geo_070115-070326.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_corrected_method2geo_070115-070917.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_corrected_method2geo_070219-070430.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_corrected_method2geo_070219-070604.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_corrected_method2geo_070326-070917.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_corrected_method2geo_070430-070604.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_corrected_method2geo_070604-070709.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_corrected_method2geo_070709-070813.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_correctedgeo_060619-061002.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_correctedgeo_060828-061211.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_correctedgeo_061002-070219.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_correctedgeo_061002-070430.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_correctedgeo_061106-061211.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_correctedgeo_061106-070115.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_correctedgeo_061106-070326.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_correctedgeo_061211-070709.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_correctedgeo_061211-070813.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_correctedgeo_070115-070326.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_correctedgeo_070115-070917.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_correctedgeo_070219-070430.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_correctedgeo_070219-070604.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_correctedgeo_070326-070917.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_correctedgeo_070430-070604.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_correctedgeo_070604-070709.unw.csv
│   │   │   │   └── ifg_orb_and_ref_phase_correctedgeo_070709-070813.unw.csv
│   │   │   ├── roipac_obs/
│   │   │   │   ├── bad_epochs_ifms_17
│   │   │   │   ├── geo_060619-061002.unw
│   │   │   │   ├── geo_060619-061002.unw.rsc
│   │   │   │   ├── geo_060828-061211.unw
│   │   │   │   ├── geo_060828-061211.unw.rsc
│   │   │   │   ├── geo_061002-070219.unw
│   │   │   │   ├── geo_061002-070219.unw.rsc
│   │   │   │   ├── geo_061002-070430.unw
│   │   │   │   ├── geo_061002-070430.unw.rsc
│   │   │   │   ├── geo_061106-061211.unw
│   │   │   │   ├── geo_061106-061211.unw.rsc
│   │   │   │   ├── geo_061106-070115.unw
│   │   │   │   ├── geo_061106-070115.unw.rsc
│   │   │   │   ├── geo_061106-070326.unw
│   │   │   │   ├── geo_061106-070326.unw.rsc
│   │   │   │   ├── geo_061211-070709.unw
│   │   │   │   ├── geo_061211-070709.unw.rsc
│   │   │   │   ├── geo_061211-070813.unw
│   │   │   │   ├── geo_061211-070813.unw.rsc
│   │   │   │   ├── geo_070115-070326.unw
│   │   │   │   ├── geo_070115-070326.unw.rsc
│   │   │   │   ├── geo_070115-070917.unw
│   │   │   │   ├── geo_070115-070917.unw.rsc
│   │   │   │   ├── geo_070219-070430.unw
│   │   │   │   ├── geo_070219-070430.unw.rsc
│   │   │   │   ├── geo_070219-070604.unw
│   │   │   │   ├── geo_070219-070604.unw.rsc
│   │   │   │   ├── geo_070326-070917.unw
│   │   │   │   ├── geo_070326-070917.unw.rsc
│   │   │   │   ├── geo_070430-070604.unw
│   │   │   │   ├── geo_070430-070604.unw.rsc
│   │   │   │   ├── geo_070604-070709.unw
│   │   │   │   ├── geo_070604-070709.unw.rsc
│   │   │   │   ├── geo_070709-070813.unw
│   │   │   │   ├── geo_070709-070813.unw.rsc
│   │   │   │   ├── headers
│   │   │   │   ├── ifms_17
│   │   │   │   ├── roipac_test_trimmed.dem
│   │   │   │   └── roipac_test_trimmed.dem.rsc
│   │   │   ├── stackrate/
│   │   │   │   ├── coh_sta.csv
│   │   │   │   ├── errormap.csv
│   │   │   │   └── stackmap.csv
│   │   │   ├── tif/
│   │   │   │   ├── geo_060619-061002_unw.tif
│   │   │   │   ├── geo_060828-061211_unw.tif
│   │   │   │   ├── geo_061002-070219_unw.tif
│   │   │   │   ├── geo_061002-070430_unw.tif
│   │   │   │   ├── geo_061106-061211_unw.tif
│   │   │   │   ├── geo_061106-070115_unw.tif
│   │   │   │   ├── geo_061106-070326_unw.tif
│   │   │   │   ├── geo_061211-070709_unw.tif
│   │   │   │   ├── geo_061211-070813_unw.tif
│   │   │   │   ├── geo_070115-070326_unw.tif
│   │   │   │   ├── geo_070115-070917_unw.tif
│   │   │   │   ├── geo_070219-070430_unw.tif
│   │   │   │   ├── geo_070219-070604_unw.tif
│   │   │   │   ├── geo_070326-070917_unw.tif
│   │   │   │   ├── geo_070430-070604_unw.tif
│   │   │   │   ├── geo_070604-070709_unw.tif
│   │   │   │   ├── geo_070709-070813_unw.tif
│   │   │   │   └── ifms_17
│   │   │   ├── time_series/
│   │   │   │   ├── ts_cum_interp0_method1.csv
│   │   │   │   ├── ts_cum_interp0_method2.csv
│   │   │   │   ├── ts_error_interp0_method1.csv
│   │   │   │   ├── ts_incr_interp0_method1.csv
│   │   │   │   └── ts_incr_interp0_method2.csv
│   │   │   └── vcm/
│   │   │       ├── alpha.csv
│   │   │       └── vcmt.csv
│   │   └── system/
│   │       ├── gamma/
│   │       │   ├── 20060619-20061002_base.par
│   │       │   ├── 20060619-20061002_utm.unw
│   │       │   ├── 20060619-20061002_utm_unw.tif
│   │       │   ├── 20060619_slc.par
│   │       │   ├── 20060619_utm.dem
│   │       │   ├── 20060619_utm_dem.par
│   │       │   ├── 20060619_utm_dem.tif
│   │       │   ├── 20060828-20061211_base.par
│   │       │   ├── 20060828-20061211_utm.unw
│   │       │   ├── 20060828-20061211_utm_unw.tif
│   │       │   ├── 20060828_slc.par
│   │       │   ├── 20061002-20070219_base.par
│   │       │   ├── 20061002-20070219_utm.unw
│   │       │   ├── 20061002-20070219_utm_unw.tif
│   │       │   ├── 20061002-20070430_base.par
│   │       │   ├── 20061002-20070430_utm.unw
│   │       │   ├── 20061002-20070430_utm_unw.tif
│   │       │   ├── 20061002_slc.par
│   │       │   ├── 20061106-20061211_base.par
│   │       │   ├── 20061106-20061211_utm.unw
│   │       │   ├── 20061106-20061211_utm_unw.tif
│   │       │   ├── 20061106-20070115_base.par
│   │       │   ├── 20061106-20070115_utm.unw
│   │       │   ├── 20061106-20070115_utm_unw.tif
│   │       │   ├── 20061106-20070326_base.par
│   │       │   ├── 20061106-20070326_utm.unw
│   │       │   ├── 20061106-20070326_utm_unw.tif
│   │       │   ├── 20061106_slc.par
│   │       │   ├── 20061211-20070709_base.par
│   │       │   ├── 20061211-20070709_utm.unw
│   │       │   ├── 20061211-20070709_utm_unw.tif
│   │       │   ├── 20061211-20070813_base.par
│   │       │   ├── 20061211-20070813_utm.unw
│   │       │   ├── 20061211-20070813_utm_unw.tif
│   │       │   ├── 20061211_slc.par
│   │       │   ├── 20070115-20070326_base.par
│   │       │   ├── 20070115-20070326_utm.unw
│   │       │   ├── 20070115-20070326_utm_unw.tif
│   │       │   ├── 20070115-20070917_base.par
│   │       │   ├── 20070115-20070917_utm.unw
│   │       │   ├── 20070115-20070917_utm_unw.tif
│   │       │   ├── 20070115_slc.par
│   │       │   ├── 20070219-20070430_base.par
│   │       │   ├── 20070219-20070430_utm.unw
│   │       │   ├── 20070219-20070430_utm_unw.tif
│   │       │   ├── 20070219-20070604_base.par
│   │       │   ├── 20070219-20070604_utm.unw
│   │       │   ├── 20070219-20070604_utm_unw.tif
│   │       │   ├── 20070219_slc.par
│   │       │   ├── 20070326-20070917_base.par
│   │       │   ├── 20070326-20070917_utm.unw
│   │       │   ├── 20070326-20070917_utm_unw.tif
│   │       │   ├── 20070326_slc.par
│   │       │   ├── 20070430-20070604_base.par
│   │       │   ├── 20070430-20070604_utm.unw
│   │       │   ├── 20070430-20070604_utm_unw.tif
│   │       │   ├── 20070430_slc.par
│   │       │   ├── 20070604-20070709_base.par
│   │       │   ├── 20070604-20070709_utm.unw
│   │       │   ├── 20070604-20070709_utm_unw.tif
│   │       │   ├── 20070604_slc.par
│   │       │   ├── 20070709-20070813_base.par
│   │       │   ├── 20070709-20070813_utm.unw
│   │       │   ├── 20070709-20070813_utm_unw.tif
│   │       │   ├── 20070709_slc.par
│   │       │   ├── 20070813_slc.par
│   │       │   ├── 20070917_slc.par
│   │       │   ├── baseline_list.txt
│   │       │   ├── cropped_lookup_table.lt
│   │       │   ├── header_list.txt
│   │       │   ├── input_parameters.conf
│   │       │   └── interferogram_list.txt
│   │       ├── geotiff/
│   │       │   ├── 20060619-20061002_base.par
│   │       │   ├── 20060619-20061002_utm_unw.tif
│   │       │   ├── 20060619_slc.par
│   │       │   ├── 20060619_utm_dem.par
│   │       │   ├── 20060619_utm_dem.tif
│   │       │   ├── 20060828-20061211_base.par
│   │       │   ├── 20060828-20061211_utm_unw.tif
│   │       │   ├── 20060828_slc.par
│   │       │   ├── 20061002-20070219_base.par
│   │       │   ├── 20061002-20070219_utm_unw.tif
│   │       │   ├── 20061002-20070430_base.par
│   │       │   ├── 20061002-20070430_utm_unw.tif
│   │       │   ├── 20061002_slc.par
│   │       │   ├── 20061106-20061211_base.par
│   │       │   ├── 20061106-20061211_utm_unw.tif
│   │       │   ├── 20061106-20070115_base.par
│   │       │   ├── 20061106-20070115_utm_unw.tif
│   │       │   ├── 20061106-20070326_base.par
│   │       │   ├── 20061106-20070326_utm_unw.tif
│   │       │   ├── 20061106_slc.par
│   │       │   ├── 20061211-20070709_base.par
│   │       │   ├── 20061211-20070709_utm_unw.tif
│   │       │   ├── 20061211-20070813_base.par
│   │       │   ├── 20061211-20070813_utm_unw.tif
│   │       │   ├── 20061211_slc.par
│   │       │   ├── 20070115-20070326_base.par
│   │       │   ├── 20070115-20070326_utm_unw.tif
│   │       │   ├── 20070115-20070917_base.par
│   │       │   ├── 20070115-20070917_utm_unw.tif
│   │       │   ├── 20070115_slc.par
│   │       │   ├── 20070219-20070430_base.par
│   │       │   ├── 20070219-20070430_utm_unw.tif
│   │       │   ├── 20070219-20070604_base.par
│   │       │   ├── 20070219-20070604_utm_unw.tif
│   │       │   ├── 20070219_slc.par
│   │       │   ├── 20070326-20070917_base.par
│   │       │   ├── 20070326-20070917_utm_unw.tif
│   │       │   ├── 20070326_slc.par
│   │       │   ├── 20070430-20070604_base.par
│   │       │   ├── 20070430-20070604_utm_unw.tif
│   │       │   ├── 20070430_slc.par
│   │       │   ├── 20070604-20070709_base.par
│   │       │   ├── 20070604-20070709_utm_unw.tif
│   │       │   ├── 20070604_slc.par
│   │       │   ├── 20070709-20070813_base.par
│   │       │   ├── 20070709-20070813_utm_unw.tif
│   │       │   ├── 20070709_slc.par
│   │       │   ├── 20070813_slc.par
│   │       │   ├── 20070917_slc.par
│   │       │   ├── baseline_list.txt
│   │       │   ├── header_list.txt
│   │       │   ├── input_parameters.conf
│   │       │   └── interferogram_list.txt
│   │       └── roipac/
│   │           ├── dem/
│   │           │   ├── roipac_test_trimmed.dem
│   │           │   └── roipac_test_trimmed.dem.rsc
│   │           ├── header_list.txt
│   │           ├── headers/
│   │           │   ├── geo_060619-061002.unw.rsc
│   │           │   ├── geo_060828-061211.unw.rsc
│   │           │   ├── geo_061002-070219.unw.rsc
│   │           │   ├── geo_061002-070430.unw.rsc
│   │           │   ├── geo_061106-061211.unw.rsc
│   │           │   ├── geo_061106-070115.unw.rsc
│   │           │   ├── geo_061106-070326.unw.rsc
│   │           │   ├── geo_061211-070709.unw.rsc
│   │           │   ├── geo_061211-070813.unw.rsc
│   │           │   ├── geo_070115-070326.unw.rsc
│   │           │   ├── geo_070115-070917.unw.rsc
│   │           │   ├── geo_070219-070430.unw.rsc
│   │           │   ├── geo_070219-070604.unw.rsc
│   │           │   ├── geo_070326-070917.unw.rsc
│   │           │   ├── geo_070430-070604.unw.rsc
│   │           │   ├── geo_070604-070709.unw.rsc
│   │           │   └── geo_070709-070813.unw.rsc
│   │           ├── input_parameters.conf
│   │           ├── interferogram_list.txt
│   │           └── interferograms/
│   │               ├── geo_060619-061002.unw
│   │               ├── geo_060619-061002.unw.rsc
│   │               ├── geo_060619-061002_unw.tif
│   │               ├── geo_060828-061211.unw
│   │               ├── geo_060828-061211.unw.rsc
│   │               ├── geo_060828-061211_unw.tif
│   │               ├── geo_061002-070219.unw
│   │               ├── geo_061002-070219.unw.rsc
│   │               ├── geo_061002-070219_unw.tif
│   │               ├── geo_061002-070430.unw
│   │               ├── geo_061002-070430.unw.rsc
│   │               ├── geo_061002-070430_unw.tif
│   │               ├── geo_061106-061211.unw
│   │               ├── geo_061106-061211.unw.rsc
│   │               ├── geo_061106-061211_unw.tif
│   │               ├── geo_061106-070115.unw
│   │               ├── geo_061106-070115.unw.rsc
│   │               ├── geo_061106-070115_unw.tif
│   │               ├── geo_061106-070326.unw
│   │               ├── geo_061106-070326.unw.rsc
│   │               ├── geo_061106-070326_unw.tif
│   │               ├── geo_061211-070709.unw
│   │               ├── geo_061211-070709.unw.rsc
│   │               ├── geo_061211-070709_unw.tif
│   │               ├── geo_061211-070813.unw
│   │               ├── geo_061211-070813.unw.rsc
│   │               ├── geo_061211-070813_unw.tif
│   │               ├── geo_070115-070326.unw
│   │               ├── geo_070115-070326.unw.rsc
│   │               ├── geo_070115-070326_unw.tif
│   │               ├── geo_070115-070917.unw
│   │               ├── geo_070115-070917.unw.rsc
│   │               ├── geo_070115-070917_unw.tif
│   │               ├── geo_070219-070430.unw
│   │               ├── geo_070219-070430.unw.rsc
│   │               ├── geo_070219-070430_unw.tif
│   │               ├── geo_070219-070604.unw
│   │               ├── geo_070219-070604.unw.rsc
│   │               ├── geo_070219-070604_unw.tif
│   │               ├── geo_070326-070917.unw
│   │               ├── geo_070326-070917.unw.rsc
│   │               ├── geo_070326-070917_unw.tif
│   │               ├── geo_070430-070604.unw
│   │               ├── geo_070430-070604.unw.rsc
│   │               ├── geo_070430-070604_unw.tif
│   │               ├── geo_070604-070709.unw
│   │               ├── geo_070604-070709.unw.rsc
│   │               ├── geo_070604-070709_unw.tif
│   │               ├── geo_070709-070813.unw
│   │               ├── geo_070709-070813.unw.rsc
│   │               ├── geo_070709-070813_unw.tif
│   │               └── roipac_test_trimmed_dem.tif
│   ├── test_dem_error.py
│   ├── test_gamma.py
│   ├── test_gamma_vs_roipac.py
│   ├── test_gdal_python.py
│   ├── test_geometry.py
│   ├── test_merge.py
│   ├── test_mpi.py
│   ├── test_mpi_vs_multiprocess_vs_single_process.py
│   ├── test_mst.py
│   ├── test_orbital.py
│   ├── test_prepifg.py
│   ├── test_prepifg_system_vs_python.py
│   ├── test_pyrate.py
│   ├── test_ref_phs_est.py
│   ├── test_refpixel.py
│   ├── test_roipac.py
│   ├── test_shared.py
│   ├── test_stackrate.py
│   ├── test_system.py
│   └── test_timeseries.py
└── utils/
    ├── .coveragerc
    ├── __init__.py
    ├── create_lv_theta.py
    ├── crop_ifgs.py
    ├── developer_hints.txt
    ├── docker_install.txt
    ├── gdaldem.py
    ├── list_creator.sh
    ├── make_tscuml_animation.py
    ├── plot_correction_files.py
    ├── plot_linear_rate_profile.py
    ├── plot_sbas_network.py
    ├── plot_time_series.py
    └── pyrate_pycallgraph.py

================================================
FILE CONTENTS
================================================

================================================
FILE: .coveragerc
================================================
# .coveragerc to control coverage.py
[run]
branch = True
source = pyrate
#omit =
    # omit everything in
    # pyrate/tasks/*
    # omit these files
#    pyrate/pyratelog.py
#    pyrate/scripts/main.py
#    pyrate/pyaps.py
#    pyrate/compat.py

[report]
# Regexes for lines to exclude from consideration
exclude_lines =
    # Have to re-enable the standard pragma
    pragma: no cover

    # Don't complain about missing debug-only code:
    def __repr__
    def __str__
    if self\.debug

    # Don't complain if tests don't hit defensive assertion code:
    raise AssertionError
    raise NotImplementedError
    raise ValueError
    raise RuntimeError
    raise IOError
    except OSError
    except ValueError
    except IndexError
    raise ImportError
    except ImportError
    raise ConfigException
    raise ReferencePhaseError
    raise RefPixelError
    raise RoipacException
    raise GeotiffException
    raise RasterException
    raise IfgException
    raise GammaException
    raise PreprocessError
    raise TimeSeriesError
    raise OrbitalError

    # Don't complain if non-runnable code isn't run:
    if 0:
    if __name__ == .__main__.:

ignore_errors = True

[html]
directory = coverage_html_report


================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''

---

**Describe the bug**
A clear and concise description of what the bug is.

**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error

**Expected behavior**
A clear and concise description of what you expected to happen.

**Screenshots**
If applicable, add screenshots to help explain your problem.

**Desktop (please complete the following information):**
 - OS: [e.g. iOS]
 - Browser [e.g. chrome, safari]
 - Version [e.g. 22]

**Smartphone (please complete the following information):**
 - Device: [e.g. iPhone6]
 - OS: [e.g. iOS8.1]
 - Browser [e.g. stock browser, safari]
 - Version [e.g. 22]

**Additional context**
Add any other context about the problem here.


================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''

---

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

**Describe the solution you'd like**
A clear and concise description of what you want to happen.

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.

**Additional context**
Add any other context or screenshots about the feature request here.


================================================
FILE: .github/workflows/build.yml
================================================
name: PyRate CI


on:
  pull_request:
    branches:
      - 'master'
  push:
    branches:
      - '**'

jobs:
  build:
    if: ${{ ! (contains(github.event.head_commit.message, 'ci skip') || contains(github.event.head_commit.message, 'skip ci'))}}
    runs-on: ubuntu-18.04
    name: Python ${{ matrix.python }}
    strategy:
      matrix:
        include:
          - build: 1
            python-version: "3.7"
            GDALVERSION: "3.0.2"
            PROJVERSION: "6.2.1"
          - build: 2
            python-version: "3.7"
            GDALVERSION: "3.0.4"
            PROJVERSION: "6.1.1"
          - build: 3
            python-version: "3.8"
            GDALVERSION: "3.0.4"
            PROJVERSION: "6.1.1"
          - build: 4
            python-version: "3.9"
            GDALVERSION: "3.0.4"
            PROJVERSION: "6.3.2"

    env:
      PIP_WHEEL_DIR: "/home/runner/.cache/pip/wheels"
      PIP_FIND_LINKS: "file:///home/runner/.cache/pip/wheels"
      GDALINST: "/home/runner/gdalinstall"
      GDALBUILD: "/home/runner/gdalbuild"
      GDALVERSION: ${{ matrix.GDALVERSION }}
      PROJINST: "/home/runner/gdalinstall"
      PROJBUILD: "/home/runner/projbuild"
      PROJVERSION: ${{ matrix.PROJVERSION }}
      PYTHONVERSION: ${{ matrix.python-version }}

    steps:
      - uses: actions/checkout@v2
      - name: Cache multiple paths
        uses: actions/cache@v2
        with:
          path: |
            /home/runner/gdalinstall
          key: ${{ runner.os }}-cache-GDAL-${{ matrix.GDALVERSION }}-proj-${{ matrix.PROJVERSION }}
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v2
        with:
          python-version: ${{ matrix.python-version }}
      - name: Common set up ${{ matrix.python-version }}
        run: |
          sudo apt update
          sudo apt upgrade
          python -m pip install -U pip wheel setuptools==58.0
      - name: Install packages including openmpi
        if: env.PYTHONVERSION != '3.9'
        run: sudo apt install libhdf5-serial-dev libnetcdf13 libatlas-base-dev gfortran openmpi-bin libopenmpi-dev
      - name: Install packages except openmpi libraries
        if: env.PYTHONVERSION == '3.9'
        run: sudo apt install libhdf5-serial-dev libnetcdf13 libatlas-base-dev gfortran
      - name: Install proj ${{matrix.PROJVERSION}}
        run: |
          echo "PATH=$GDALINST/gdal-$GDALVERSION/bin:$PATH" >> $GITHUB_ENV
          echo "LD_LIBRARY_PATH=$GDALINST/gdal-$GDALVERSION/lib:$LD_LIBRARY_PATH" >> $GITHUB_ENV
          source ./scripts/ci_proj_install.sh
      - name: Install GDAL ${{matrix.GDALVERSION}}
        run: |
          echo "GDAL_DATA=$GDALINST/gdal-$GDALVERSION/share/gdal" >> $GITHUB_ENV
          echo "PROJ_LIB=$GDALINST/gdal-$GDALVERSION/share/proj" >> $GITHUB_ENV
          echo "LDFLAGS=-L$GDALINST/gdal-$GDALVERSION/lib -Wl,-rpath,$GDALINST/gdal-$GDALVERSION/lib" >> $GITHUB_ENV
          source ./scripts/ci_gdal_install.sh
      - name: Python ${{ matrix.python-version }} with MPI
        if: env.PYTHONVERSION != '3.9'
        run: |
          python setup.py install
          rm -rf Py_Rate.egg-info  # remove the local egg
          echo "PYTHONPATH=$(pwd):$PYTHONPATH" >> $GITHUB_ENV
          chmod 444 tests/test_data/small_test/tif/geo_070709-070813_unw.tif  # makes the file readonly, used in a test
          pip install -r requirements-dev.txt -r requirements-test.txt
      - name: Python ${{ matrix.python-version }} without MPI
        if: env.PYTHONVERSION == '3.9'
        run: |
          python setup.py install
          rm -rf Py_Rate.egg-info  # remove the local egg
          echo "PYTHONPATH=$(pwd):$PYTHONPATH" >> $GITHUB_ENV
          chmod 444 tests/test_data/small_test/tif/geo_070709-070813_unw.tif  # makes the file readonly, used in a test
          pip install -r requirements-test.txt
      - name: Test Pyrate in Python ${{ matrix.python-version }} with MPI
        if: env.PYTHONVERSION != '3.9'
        run: |
          pytest tests/ -m "slow"
          mpirun -n 3 pytest tests/test_shared.py -k test_tiles_split -s
          pytest --cov-config=.coveragerc --cov-report term-missing:skip-covered --cov=pyrate tests/ -m "not slow"
        env:
             OMP_NUM_THREADS: 1
      - name: Test Pyrate in Python ${{ matrix.python-version }} without MPI
        if: env.PYTHONVERSION == '3.9'
        run: |
          pytest tests/ -m "not mpi and slow"
          pytest --cov-config=.coveragerc --cov-report term-missing:skip-covered --cov=pyrate tests/ -m "not slow and not mpi"
        env:
             OMP_NUM_THREADS: 1
        


================================================
FILE: .gitignore
================================================
!*docs/_build/html/404.html
!*tests/test_data/merge/linrate.tif
!*tests/test_data/small_test/gamma_obs/20060619-20061002_utm_unw.tif
*data/*
*out*
*.pyo
*.pyc
.project
.pydevproject
/tmp
/.idea
.spyderworkspace
doc
.eggs/
.tox/
.coverage.*
.vscode/
*.egg-info/
.installed.cfg
*.egg
*__pycache__/

# files generated by doc build
docs/_build/

# files generated by setup
.cache/
build/
dist/
# out
Py_Rate.egg-info

# files generated during tests
*tests/test_data/prepifg/tif/0_1rlks_4cr.tif
*tests/test_data/prepifg/tif/0_2rlks_4cr.tif
*tests/test_data/prepifg/tif/1_1rlks_4cr.tif
*tests/test_data/prepifg/tif/1_2rlks_4cr.tif

*tests/test_data/merge/colormap.txt
*tests/test_data/merge/linrate.kml
*tests/test_data/merge/linrate.png
*tests/test_data/merge/linrate.png.aux.xml
*tests/test_data/merge/linrate.tif.aux.xml

*tests/test_data/small_test/gamma_obs/*.tif


================================================
FILE: .pylintrc
================================================
[MASTER]

# Specify a configuration file.
#rcfile=

# Python code to execute, usually for sys.path manipulation such as
# pygtk.require().
#init-hook=

# Add files or directories to the blacklist. They should be base names, not
# paths.
ignore=CVS

# Add files or directories matching the regex patterns to the blacklist. The
# regex matches against base names, not paths.
ignore-patterns=

# Pickle collected data for later comparisons.
persistent=yes

# List of plugins (as comma separated values of python modules names) to load,
# usually to register additional checkers.
load-plugins=

# Use multiple processes to speed up Pylint.
jobs=1

# Allow loading of arbitrary C extensions. Extensions are imported into the
# active Python interpreter and may run arbitrary code.
unsafe-load-any-extension=no

# A comma-separated list of package or module names from where C extensions may
# be loaded. Extensions are loading into the active Python interpreter and may
# run arbitrary code
extension-pkg-whitelist=

# Allow optimization of some AST trees. This will activate a peephole AST
# optimizer, which will apply various small optimizations. For instance, it can
# be used to obtain the result of joining multiple strings with the addition
# operator. Joining a lot of strings can lead to a maximum recursion error in
# Pylint and this flag can prevent that. It has one side effect, the resulting
# AST will be different than the one from reality. This option is deprecated
# and it will be removed in Pylint 2.0.
optimize-ast=no


[MESSAGES CONTROL]

# Only show warnings with the listed confidence levels. Leave empty to show
# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED
confidence=

# Enable the message, report, category or checker with the given id(s). You can
# either give multiple identifier separated by comma (,) or put this option
# multiple time (only on the command line, not in the configuration file where
# it should appear only once). See also the "--disable" option for examples.
#enable=

# Disable the message, report, category or checker with the given id(s). You
# can either give multiple identifiers separated by comma (,) or put this
# option multiple times (only on the command line, not in the configuration
# file where it should appear only once).You can also use "--disable=all" to
# disable everything first and then reenable specific checks. For example, if
# you want to run only the similarities checker, you can use "--disable=all
# --enable=similarities". If you want to run only the classes checker, but have
# no Warning level messages displayed, use"--disable=all --enable=classes
# --disable=W"
disable=logging-format-interpolation,too-few-public-methods,import-star-module-level,old-octal-literal,oct-method,print-statement,unpacking-in-except,parameter-unpacking,backtick,old-raise-syntax,old-ne-operator,long-suffix,dict-view-method,dict-iter-method,metaclass-assignment,next-method-called,raising-string,indexing-exception,raw_input-builtin,long-builtin,file-builtin,execfile-builtin,coerce-builtin,cmp-builtin,buffer-builtin,basestring-builtin,apply-builtin,filter-builtin-not-iterating,using-cmp-argument,useless-suppression,range-builtin-not-iterating,suppressed-message,no-absolute-import,old-division,cmp-method,reload-builtin,zip-builtin-not-iterating,intern-builtin,unichr-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,input-builtin,round-builtin,hex-method,nonzero-method,map-builtin-not-iterating,fixme


[REPORTS]

# Set the output format. Available formats are text, parseable, colorized, msvs
# (visual studio) and html. You can also give a reporter class, eg
# mypackage.mymodule.MyReporterClass.
output-format=text

# Put messages in a separate file for each module / package specified on the
# command line instead of printing them on stdout. Reports (if any) will be
# written in a file name "pylint_global.[txt|html]". This option is deprecated
# and it will be removed in Pylint 2.0.
files-output=no

# Tells whether to display a full report or only the messages
reports=yes

# Python expression which should return a note less than 10 (10 is the highest
# note). You have access to the variables errors warning, statement which
# respectively contain the number of errors / warnings messages and the total
# number of statements analyzed. This is used by the global evaluation report
# (RP0004).
evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)

# Template used to display messages. This is a python new-style format string
# used to format the message information. See doc for all details
#msg-template=


[MISCELLANEOUS]

# List of note tags to take in consideration, separated by a comma.
notes=FIXME,XXX,TODO


[LOGGING]

# Logging modules to check that the string format arguments are in logging
# function parameter format
logging-modules=logging


[SPELLING]

# Spelling dictionary name. Available dictionaries: none. To make it working
# install python-enchant package.
spelling-dict=

# List of comma separated words that should not be checked.
spelling-ignore-words=

# A path to a file that contains private dictionary; one word per line.
spelling-private-dict-file=

# Tells whether to store unknown words to indicated private dictionary in
# --spelling-private-dict-file option instead of raising a message.
spelling-store-unknown-words=no


[TYPECHECK]

# Tells whether missing members accessed in mixin class should be ignored. A
# mixin class is detected if its name ends with "mixin" (case insensitive).
ignore-mixin-members=yes

# List of module names for which member attributes should not be checked
# (useful for modules/projects where namespaces are manipulated during runtime
# and thus existing member attributes cannot be deduced by static analysis. It
# supports qualified module names, as well as Unix pattern matching.
ignored-modules=numpy

# List of class names for which member attributes should not be checked (useful
# for classes with dynamically set attributes). This supports the use of
# qualified names.
ignored-classes=optparse.Values,thread._local,_thread._local

# List of members which are set dynamically and missed by pylint inference
# system, and so shouldn't trigger E1101 when accessed. Python regular
# expressions are accepted.
generated-members=

# List of decorators that produce context managers, such as
# contextlib.contextmanager. Add to this list to register other decorators that
# produce valid context managers.
contextmanager-decorators=contextlib.contextmanager


[VARIABLES]

# Tells whether we should check for unused import in __init__ files.
init-import=no

# A regular expression matching the name of dummy variables (i.e. expectedly
# not used).
dummy-variables-rgx=(_+[a-zA-Z0-9]*?$)|dummy

# List of additional names supposed to be defined in builtins. Remember that
# you should avoid to define new builtins when possible.
additional-builtins=

# List of strings which can identify a callback function by name. A callback
# name must start or end with one of those strings.
callbacks=cb_,_cb

# List of qualified module names which can have objects that can redefine
# builtins.
redefining-builtins-modules=six.moves,future.builtins


[SIMILARITIES]

# Minimum lines number of a similarity.
min-similarity-lines=4

# Ignore comments when computing similarities.
ignore-comments=yes

# Ignore docstrings when computing similarities.
ignore-docstrings=yes

# Ignore imports when computing similarities.
ignore-imports=no


[FORMAT]

# Maximum number of characters on a single line.
max-line-length=100

# Regexp for a line that is allowed to be longer than the limit.
ignore-long-lines=^\s*(# )?<?https?://\S+>?$

# Allow the body of an if to be on the same line as the test if there is no
# else.
single-line-if-stmt=no

# List of optional constructs for which whitespace checking is disabled. `dict-
# separator` is used to allow tabulation in dicts, etc.: {1  : 1,\n222: 2}.
# `trailing-comma` allows a space between comma and closing bracket: (a, ).
# `empty-line` allows space-only lines.
no-space-check=trailing-comma,dict-separator

# Maximum number of lines in a module
max-module-lines=1000

# String used as indentation unit. This is usually "    " (4 spaces) or "\t" (1
# tab).
indent-string='    '

# Number of spaces of indent required inside a hanging  or continued line.
indent-after-paren=4

# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
expected-line-ending-format=


[BASIC]

# Good variable names which should always be accepted, separated by a comma
good-names=ts,i,j,k,ex,Run,_,x,w,f,n,v,t,r,d,c,cd,g,r,q,V,m,A,b,log,y,id,ds,gt,md

# Bad variable names which should always be refused, separated by a comma
bad-names=foo,bar,baz,toto,tutu,tata

# Colon-delimited sets of names that determine each other's naming style when
# the name regexes allow several styles.
name-group=

# Include a hint for the correct naming format with invalid-name
include-naming-hint=no

# List of decorators that produce properties, such as abc.abstractproperty. Add
# to this list to register other decorators that produce valid properties.
property-classes=abc.abstractproperty

# Regular expression matching correct function names
function-rgx=[a-z_][a-z0-9_]{2,30}$

# Naming hint for function names
function-name-hint=[a-z_][a-z0-9_]{2,30}$

# Regular expression matching correct variable names
variable-rgx=[a-z_][a-z0-9_]{2,30}$

# Naming hint for variable names
variable-name-hint=[a-z_][a-z0-9_]{2,30}$

# Regular expression matching correct constant names
const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$

# Naming hint for constant names
const-name-hint=(([A-Z_][A-Z0-9_]*)|(__.*__))$

# Regular expression matching correct attribute names
attr-rgx=[a-z_][a-z0-9_]{2,30}$

# Naming hint for attribute names
attr-name-hint=[a-z_][a-z0-9_]{2,30}$

# Regular expression matching correct argument names
argument-rgx=[a-z_][a-z0-9_]{2,30}$

# Naming hint for argument names
argument-name-hint=[a-z_][a-z0-9_]{2,30}$

# Regular expression matching correct class attribute names
class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$

# Naming hint for class attribute names
class-attribute-name-hint=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$

# Regular expression matching correct inline iteration names
inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$

# Naming hint for inline iteration names
inlinevar-name-hint=[A-Za-z_][A-Za-z0-9_]*$

# Regular expression matching correct class names
class-rgx=[A-Z_][a-zA-Z0-9]+$

# Naming hint for class names
class-name-hint=[A-Z_][a-zA-Z0-9]+$

# Regular expression matching correct module names
module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$

# Naming hint for module names
module-name-hint=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$

# Regular expression matching correct method names
method-rgx=[a-z_][a-z0-9_]{2,30}$

# Naming hint for method names
method-name-hint=[a-z_][a-z0-9_]{2,30}$

# Regular expression which should only match function or class names that do
# not require a docstring.
no-docstring-rgx=^_

# Minimum line length for functions/classes that require docstrings, shorter
# ones are exempt.
docstring-min-length=-1


[ELIF]

# Maximum number of nested blocks for function / method body
max-nested-blocks=5


[DESIGN]

# Maximum number of arguments for function / method
max-args=5

# Argument names that match this expression will be ignored. Default to name
# with leading underscore
ignored-argument-names=_.*

# Maximum number of locals for function / method body
max-locals=15

# Maximum number of return / yield for function / method body
max-returns=6

# Maximum number of branch for function / method body
max-branches=12

# Maximum number of statements in function / method body
max-statements=50

# Maximum number of parents for a class (see R0901).
max-parents=7

# Maximum number of attributes for a class (see R0902).
max-attributes=7

# Minimum number of public methods for a class (see R0903).
min-public-methods=2

# Maximum number of public methods for a class (see R0904).
max-public-methods=20

# Maximum number of boolean expressions in a if statement
max-bool-expr=5


[IMPORTS]

# Deprecated modules which should not be used, separated by a comma
deprecated-modules=regsub,TERMIOS,Bastion,rexec

# Create a graph of every (i.e. internal and external) dependencies in the
# given file (report RP0402 must not be disabled)
import-graph=

# Create a graph of external dependencies in the given file (report RP0402 must
# not be disabled)
ext-import-graph=

# Create a graph of internal dependencies in the given file (report RP0402 must
# not be disabled)
int-import-graph=

# Force import order to recognize a module as part of the standard
# compatibility libraries.
known-standard-library=

# Force import order to recognize a module as part of a third party library.
known-third-party=enchant

# Analyse import fallback blocks. This can be used to support both Python 2 and
# 3 compatible code, which means that the block might have code that exists
# only in one or another interpreter, leading to false positives when analysed.
analyse-fallback-blocks=no


[CLASSES]

# List of method names used to declare (i.e. assign) instance attributes.
defining-attr-methods=__init__,__new__,setUp

# List of valid names for the first argument in a class method.
valid-classmethod-first-arg=cls

# List of valid names for the first argument in a metaclass class method.
valid-metaclass-classmethod-first-arg=mcs

# List of member names, which should be excluded from the protected access
# warning.
exclude-protected=_asdict,_fields,_replace,_source,_make


[EXCEPTIONS]

# Exceptions that will emit a warning when being caught. Defaults to
# "Exception"
overgeneral-exceptions=Exception


================================================
FILE: Dockerfile
================================================
FROM ubuntu:16.04

ENV LANG C.UTF-8
ENV LANG=en_AU.UTF-8
ENV WORKON_HOME=$HOME/venvs
ENV GDALINST=$HOME/gdalinstall
ENV GDALBUILD=$HOME/gdalbuild
ENV PROJINST=$HOME/gdalinstall
ENV GDALVERSION="3.0.2"
ENV PROJVERSION="6.1.1"
ENV PROJOPT="--with-proj=$GDALINST/gdal-$GDALVERSION"
ENV PATH=$GDALINST/gdal-$GDALVERSION/bin:$PATH
ENV LD_LIBRARY_PATH=$GDALINST/gdal-$GDALVERSION/lib:$LD_LIBRARY_PATH
ENV PROJ_LIB=$GDALINST/gdal-$GDALVERSION/share/proj
ENV GDAL_DATA=$GDALINST/gdal-$GDALVERSION/share/gdal


RUN apt-get update \
    && apt-get install -y build-essential checkinstall libreadline-gplv2-dev \
    libncursesw5-dev libssl-dev libsqlite3-dev tk-dev libgdbm-dev libc6-dev \
    libbz2-dev openssl curl libffi-dev

RUN mkdir -p $HOME/opt

RUN cd $HOME/opt \
    && curl -O https://www.python.org/ftp/python/3.7.7/Python-3.7.7.tgz \
    && tar -xzf Python-3.7.7.tgz \
    && cd Python-3.7.7 \
    && ./configure --enable-shared --enable-optimizations --prefix=/usr/local LDFLAGS="-Wl,--rpath=/usr/local/lib" \
    && make altinstall

RUN apt-get install -y build-essential python3-pip \
    apt-utils git libgdal-dev libatlas-base-dev openmpi-bin \
    libopenmpi-dev gfortran wget libhdf5-serial-dev sqlite3 vim

# update pip
RUN python3.7 -m pip install pip --upgrade
RUN python3.7 -m pip install wheel
RUN pip3 install --upgrade setuptools


RUN mkdir -p $GDALBUILD $GDALINST $PROJBUILD $PROJINST

ENV GDALOPTS="  --with-geos \
            --with-expat \
            --without-libtool \
            --with-libz=internal \
            --with-libtiff=internal \
            --with-geotiff=internal \
            --without-gif \
            --without-pg \
            --without-grass \
            --without-libgrass \
            --without-cfitsio \
            --without-pcraster \
            --with-netcdf \
            --with-png=internal \
            --with-jpeg=internal \
            --without-gif \
            --without-ogdi \
            --without-fme \
            --without-hdf4 \
            --with-hdf5 \
            --without-jasper \
            --without-ecw \
            --without-kakadu \
            --without-mrsid \
            --without-jp2mrsid \
            --without-mysql \
            --without-ingres \
            --without-xerces \
            --without-odbc \
            --with-curl \
            --without-sqlite3 \
            --without-idb \
            --without-sde \
            --without-perl \
            --without-python"

RUN cd $PROJBUILD && wget -q https://download.osgeo.org/proj/proj-$PROJVERSION.tar.gz \
    && tar -xzf proj-$PROJVERSION.tar.gz \
    && cd proj-$PROJVERSION \
    && ./configure --prefix=$PROJINST/gdal-$GDALVERSION \
    && make -s -j 2 \
    && make install

RUN  cd $GDALBUILD \
    && wget -q http://download.osgeo.org/gdal/$GDALVERSION/gdal-$GDALVERSION.tar.gz \
    && tar -xzf gdal-$GDALVERSION.tar.gz

RUN cd $GDALBUILD/gdal-$GDALVERSION \
    && ./configure --prefix=$GDALINST/gdal-$GDALVERSION $GDALOPTS $PROJOPT

RUN cd $GDALBUILD/gdal-$GDALVERSION && make

RUN cd $GDALBUILD/gdal-$GDALVERSION  && make install

RUN pip install virtualenv virtualenvwrapper
ENV VIRTUALENVWRAPPER_PYTHON=/usr/local/bin/python3.7

ADD . / PyRate/
SHELL ["/bin/bash", "-c"]
RUN source /usr/local/bin/virtualenvwrapper.sh \
    && mkvirtualenv -p python3.7 pyrate \
    && cd PyRate \
    && sed -i '/^GDAL/d' requirements.txt \
    && workon pyrate \
    && pip install -r requirements.txt -r requirements-dev.txt -r requirements-test.txt \
    && pip install GDAL==$(gdal-config --version) \
    && python setup.py install


================================================
FILE: LICENSE
================================================

                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright [yyyy] [name of copyright owner]

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.


================================================
FILE: README.rst
================================================
.. image:: docs/PyRate_logo_50.png
   :alt: PyRate logo

Python tool for InSAR Rate and Time-series Estimation
=====================================================

.. image:: https://github.com/GeoscienceAustralia/PyRate/workflows/PyRate%20CI/badge.svg?branch=master
   :target: https://github.com/GeoscienceAustralia/PyRate/actions
.. image:: https://codecov.io/gh/GeoscienceAustralia/PyRate/branch/master/graph/badge.svg
   :target: https://codecov.io/gh/GeoscienceAustralia/PyRate
.. image:: https://img.shields.io/badge/License-Apache%202.0-blue.svg
   :target: https://opensource.org/licenses/Apache-2.0
.. image:: https://img.shields.io/pypi/pyversions/Py-Rate 
   :target: https://pypi.org/project/Py-Rate/ 

PyRate is a Python tool for estimating the average displacement rate (velocity) and cumulative displacement time-series of surface movements for every pixel in a stack of geocoded unwrapped interferograms generated by Interferometric Synthetic Aperture Radar (InSAR) processing. PyRate uses a "Small Baseline Subset" (SBAS) processing strategy and currently supports input data in the GAMMA or ROI_PAC software formats.
Additionally, the European Space Agency `SNAP software <https://step.esa.int/main/download/snap-download/>`_ version 8 has a "PyRate export" capability that prepares SNAP output data in the GAMMA format for use with PyRate.

The PyRate project started in 2012 as a partial Python translation of "Pirate", a Matlab tool developed by the University of Leeds and the Guangdong University of Technology.

The full PyRate documentation is available at http://geoscienceaustralia.github.io/PyRate

Dependencies
------------

The following system dependencies are required by PyRate:

- `Python <https://www.python.org/downloads/>`_, versions 3.7, 3.8 or 3.9.
- `GDAL <https://gdal.org/download.html>`_, versions 3.0.2 or 3.0.4

The following optional dependency is required for MPI processing capability:

- `Open MPI <https://www.open-mpi.org/software/ompi/v4.0/>`_, versions 2.1.6, 3.0.4, 3.1.4 or 4.0.2

The versions of each package stated above have been tested to work using `GitHub Actions <https://github.com/GeoscienceAustralia/PyRate/actions>`_ continuous integration testing.

Python dependencies for PyRate are::

    joblib==1.0.0
    mpi4py==3.0.3
    networkx==2.5
    numpy==1.19.4
    pyproj==3.0.0
    scipy==1.5.4
    numexpr==2.7.2
    nptyping==1.4.0

Install
-------

Details of all install options are given in the `PyRate documentation <http://geoscienceaustralia.github.io/PyRate>`_.

PyRate and its Python dependencies can be installed directly from the `Python Package Index (PyPI) <https://pypi.org/project/Py-Rate/>`_::

    pip install Py-Rate

Alternatively, to install from source and create an executable program in Linux, enter these commands in a terminal::

    cd ~
    git clone https://github.com/GeoscienceAustralia/PyRate.git
    python3 -m venv ~/PyRateVenv
    source ~/PyRateVenv/bin/activate
    cd ~/PyRate
    python3 setup.py install

This will install the above-listed Python dependencies and compile the executable program ``pyrate``.
To learn more about using PyRate, type ``pyrate`` command in the terminal::

    >> pyrate --help
    usage: pyrate [-h] [-v {DEBUG,INFO,WARNING,ERROR}]
              {conv2tif,prepifg,correct,timeseries,stack,merge,workflow} ...

    PyRate workflow:

        Step 1: conv2tif
        Step 2: prepifg
        Step 3: correct
        Step 4: timeseries
        Step 5: stack
        Step 6: merge

    Refer to https://geoscienceaustralia.github.io/PyRate/usage.html for
    more details.

    positional arguments:
      {conv2tif,prepifg,correct,timeseries,stack,merge,workflow}
        conv2tif            Convert interferograms to geotiff.
        prepifg             Perform multilooking, cropping and coherence masking to interferogram geotiffs.
        correct             Calculate and apply corrections to interferogram phase data.
        timeseries          Timeseries inversion of interferogram phase data.
        stack               Stacking of interferogram phase data.
        merge               Reassemble computed tiles and save as geotiffs.
        workflow            Sequentially run all the PyRate processing steps.

    optional arguments:
      -h, --help            show this help message and exit
      -v {DEBUG,INFO,WARNING,ERROR}, --verbosity {DEBUG,INFO,WARNING,ERROR}
                            Increase output verbosity

Test
----

To run the test suite, enter these commands in the terminal::

   pip install -r requirements-test.txt
   python3 -m pytest -m "not slow" tests/

To run the tests for a single module (e.g. test_timeseries.py), use this command::

   python3 -m pytest tests/test_timeseries.py



================================================
FILE: __init__.py
================================================


================================================
FILE: docs/Makefile
================================================
# Minimal makefile for Sphinx documentation
#

# You can set these variables from the command line.
SPHINXOPTS    =
SPHINXBUILD   = sphinx-build
SPHINXPROJ    = PyRate
SOURCEDIR     = .
BUILDDIR      = _build

# Put it first so that "make" without argument is like "make help".
help:
	@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

.PHONY: help Makefile

# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
	@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)



================================================
FILE: docs/algorithm.rst
================================================
Algorithm Module
================

.. automodule:: pyrate.core.algorithm
   :members:

================================================
FILE: docs/aps.rst
================================================
Atmospheric Phase Screen Module
===============================

.. automodule:: pyrate.core.aps
   :members:


================================================
FILE: docs/authors.rst
================================================
=======
Credits
=======

Development Lead
----------------

`PyRate` has been developed by `Geoscience Australia <http://www.ga.gov.au>`__
with some initial assistance from the `National Computational Infrastructure <http://nci.org.au/>`__.

Contact: `Geoscience Australia InSAR team <mailto:insar@ga.gov.au>`__

Contributors
------------

Thanks to `all the contributors`_ who helped to build the ship and raise the sail, Arrrr!

.. _`all the contributors`: https://github.com/GeoscienceAustralia/PyRate/graphs/contributors

* Sudipta Basak (GA)
* Ben Davies (NCI)
* Alistair Deane (GA)
* Thomas Fuhrmann (GA)
* Syed Sheece Raza Gardezi (GA)
* Matt Garthwaite (GA)
* Simon Knapp (GA)
* Sarah Lawrie (GA)
* Jonathan Mettes (GA)
* Negin Moghaddam (GA)
* Brenainn Moushall (GA)
* Vanessa Newey (GA)
* Chandrakanta Ojha (GA)
* Garrick Paskos (GA)
* Nahidul Samrat (GA)
* Richard Taylor (GA)


================================================
FILE: docs/conf.py
================================================
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import datetime
import sphinx_rtd_theme


__version__ = "0.6.0"
# -- General configuration ------------------------------------------------

# If your documentation needs a minimal Sphinx version, state it here.
#
# needs_sphinx = '1.0'

# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = ['sphinx.ext.autodoc',
              'sphinx.ext.imgmath',
              'sphinx.ext.viewcode',
              'sphinx.ext.githubpages',
              'sphinx.ext.mathjax',
              'sphinx.ext.autosummary',
              'sphinx.ext.napoleon',
              'matplotlib.sphinxext.plot_directive',
              'IPython.sphinxext.ipython_console_highlighting',
              'IPython.sphinxext.ipython_directive',
              'sphinxcontrib.programoutput',
              'm2r2'
              ]

# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']

# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
from recommonmark.parser import CommonMarkParser
source_parsers = {'.md': CommonMarkParser}
source_suffix = ['.rst', '.md']
# source_suffix = '.rst'

# The main toctree document.
main_doc = 'index'

# General information about the project.
project = 'PyRate'
copyright = str(datetime.datetime.now().year)+', Geoscience Australia'
author = 'Geoscience Australia InSAR Team'

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = __version__
# The full version, including alpha/beta/rc tags.
release = __version__

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = 'en'

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This patterns also effect to html_static_path and html_extra_path
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']

# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'

# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = False


# -- Options for HTML output ----------------------------------------------

# The theme to use for HTML and HTML Help pages.  See the documentation for
# a list of builtin themes.

html_theme = "sphinx_rtd_theme"
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
html_logo = "PyRate_logo.png"
html_show_sourcelink = False
# Theme options are theme-specific and customize the look and feel of a theme
# further.  For a list of options available for each theme, see the
# documentation.
#
# html_theme_options = {}
html_theme_options = {
    'collapse_navigation': False,
    'sticky_navigation': True,
    'display_version': False,
    # 'titles_only': True,
    'navigation_depth': 2,
    'logo_only': True,
    'prev_next_buttons_location': 'top',
    'style_nav_header_background': 'white'
}

# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = [os.path.join('_build', 'html', '_static')]



# -- Options for HTMLHelp output ------------------------------------------

# Output file base name for HTML help builder.
htmlhelp_basename = 'PyRatedoc'


# -- Options for LaTeX output ---------------------------------------------

latex_elements = {
    # The paper size ('letterpaper' or 'a4paper').
    #
    # 'papersize': 'letterpaper',

    # The font size ('10pt', '11pt' or '12pt').
    #
    # 'pointsize': '10pt',

    # Additional stuff for the LaTeX preamble.
    #
    # 'preamble': '',

    # Latex figure (float) alignment
    #
    # 'figure_align': 'htbp',
}

# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
#  author, documentclass [howto, manual, or own class]).
latex_documents = [
    (main_doc, 'PyRate.tex', 'PyRate Documentation',
     'Geoscience Australia InSAR team', 'manual'),
]


# -- Options for manual page output ---------------------------------------

# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
    (main_doc, 'pyrate', 'PyRate Documentation',
     [author], 1)
]


# -- Options for Texinfo output -------------------------------------------

# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
#  dir menu entry, description, category)
texinfo_documents = [
    (main_doc, 'PyRate', 'PyRate Documentation',
     author, 'PyRate', 'One line description of project.',
     'Miscellaneous'),
]



# -- Options for Epub output ----------------------------------------------

# Bibliographic Dublin Core info.
epub_title = project
epub_author = author
epub_publisher = author
epub_copyright = copyright

# The unique identifier of the text. This can be a ISBN number
# or the project homepage.
#
# epub_identifier = ''

# A unique identification for the text.
#
# epub_uid = ''

# A list of files that should not be packed into the epub file.
epub_exclude_files = ['search.html']


# link check ignore
linkcheck_ignore = [r'http://localhost:\d+/',
                    'https://github.com/Nekroze/PyRate/fork']


def setup(app):
    app.add_stylesheet('css/custom.css')


================================================
FILE: docs/configuration.rst
================================================
Configuration Module
====================

.. automodule:: pyrate.configuration
   :members:


================================================
FILE: docs/contributing.rst
================================================
============
Contributing
============

Contributions to `PyRate` are welcome, and they are greatly appreciated! Every
little bit helps, and credit will always be given.

Types of Contributions
----------------------

You can contribute to `PyRate` in many ways:

Report Bugs
^^^^^^^^^^^

Report bugs on the `Github issues`_ page. If you are reporting a bug, please include:

.. _`Github issues`: https://github.com/GeoscienceAustralia/PyRate/issues

* Your operating system name and version.
* Any details about your local setup that might be helpful in troubleshooting.
* Detailed steps to reproduce the bug.

For an example of how to report a bug please see: https://github.com/GeoscienceAustralia/PyRate/issues/146

Fix Bugs
^^^^^^^^

Look for any `GitHub issues`_ with the "bug" label.

Implement Features
^^^^^^^^^^^^^^^^^^

Look for any `GitHub issues`_ with the "enhancement" label.

Write Documentation
^^^^^^^^^^^^^^^^^^^

`PyRate` could always use more documentation, whether as part of the
official documentation, in docstrings, or even on the web in blog posts,
articles etc.

Submit Feedback
^^^^^^^^^^^^^^^

General feedback or questions about `PyRate` can be emailed to the
`Geoscience Australia InSAR Team`_.

.. _`Geoscience Australia InSAR Team`: mailto:insar@ga.gov.au

The best way to send feedback about a bug in the software is to lodge an Issue_.

.. _Issue: https://github.com/GeoscienceAustralia/PyRate/issues

If you are proposing a feature:

* Explain in detail how it would work.
* Keep the scope as narrow as possible, to make it easier to implement.
* Remember that this is a volunteer-driven project, and that contributions
  are welcome :)

Get Started!
------------

Ready to contribute? Here's how to set up `PyRate` for local development.

1. Fork_ the `PyRate` repository on GitHub.
2. Clone your fork locally:

::

    cd ~
    git clone git@github.com:<account_where_you_forked>/PyRate.git

3. Create a branch for local development

::

    git checkout -b name-of-your-bugfix-or-feature

Now you can make your changes locally.

4. When you have finished making changes, check that your changes pass against unit
   tests. A suite of tests have been developed for use in testing `PyRate` functionality
   and for further code development. The tests use `pytest <http://doc.pytest.org/en/latest/>`__
   and can be found in the ``PyRate/tests/`` directory. A small test dataset used by
   the test suite is included in the repository in the ``PyRate/tests/test_data/small_test`` directory.

::

    cd ~/PyRate
    # 'not slow' avoids running those tests marked as 'slow'
    pytest tests/ -m "not slow"

5. If the tests pass, commit your changes and push your branch to GitHub:

::

    git add .
    git commit -m "Short description of your changes."
    git push origin name-of-your-bugfix-or-feature

6. Submit a pull request through the GitHub website.

.. _Fork: https://help.github.com/articles/fork-a-repo/

Pull Request Guidelines
-----------------------

Before you submit a pull request, check that it meets these guidelines:

1. The pull request should include tests that cover new functionality.
2. If the pull request adds functionality, the documentation should be updated.
   Put your new functionality into a function with a docstring.
3. The pull request should work for Python 3.7+.

   Check https://github.com/GeoscienceAustralia/PyRate/actions
   for active pull requests or run the ``tox`` command and
   make sure that the tests pass for all supported Python versions.


================================================
FILE: docs/covariance.rst
================================================
Covariance Module
=====================

.. automodule:: pyrate.core.covariance
   :members:


================================================
FILE: docs/demerror.rst
================================================
DEM Error Correction Module
===========================

.. automodule:: pyrate.core.dem_error
   :members:


================================================
FILE: docs/dependencies.rst
================================================
Dependencies
------------

The following dependencies need to be on your system (or in your working
environment) prior to `PyRate` installation:

- Python_, versions 3.7, 3.8 or 3.9.
- GDAL_, versions 3.0.2 or 3.0.4

The following optional dependency should be on your system if you want to make
use of MPI processing:

- `Open MPI`_, versions 2.1.6, 3.0.4, 3.1.4 or 4.0.2

The versions of each package stated above have been tested to work using
`GitHub Actions`_ continuous integration testing.

.. _Python: https://www.python.org/downloads/
.. _GDAL: https://gdal.org/download.html
.. _`Open MPI`: https://www.open-mpi.org/software/ompi/v4.0/
.. _`GitHub Actions`: https://github.com/GeoscienceAustralia/PyRate/actions

Other Python dependencies that will be installed are listed in
``PyRate/requirements.txt``.


================================================
FILE: docs/docker.rst
================================================
Docker
^^^^^^

Docker can be used to run `PyRate` on Linux, Windows and MacOS systems.

.. note::

    - Docker is the recommended method to use `PyRate` under Windows.

The only system pre-requisites for using docker are Git and Docker Desktop
(e.g. for Windows https://docs.docker.com/docker-for-windows/ ).
The other system dependencies required by PyRate are installed in to the
docker container itself during the build operation.
Once Git and Docker Desktop are installed, and Docker Desktop is running,
execute the following at a command line prompt (e.g. PowerShell in Windows 10)::

    git clone git@github.com:GeoscienceAustralia/PyRate.git
    cd PyRate
    docker build -t pyrate-image .
    docker run -it pyrate-image

.. note::

    - The image name “pyrate-image” is not mandatory.
      You are free to name the docker image whatever you choose.

The ``docker build`` command builds the docker container described in the
``Dockerfile`` in the `PyRate` repo. It first starts by setting up an Ubuntu linux
system image, and then installs the required system and python dependencies.

Once the docker container is running (you will see a different-looking command
prompt in the PowerShell), execute the following commands::

    source /usr/local/bin/virtualenvwrapper.sh
    workon pyrate
    cd PyRate
    python3 setup.py install
    pyrate --help
    pyrate workflow -f input_parameters.conf

The ``pyrate`` executable program is built as part of the ``docker build`` step.
If the ``pyrate`` executable is reported as "not found", re-run the compilation::

    cd PyRate
    python3 setup.py install



================================================
FILE: docs/gamma.rst
================================================
GAMMA Module
============

.. automodule:: pyrate.core.gamma
   :members:

================================================
FILE: docs/gdal_python.rst
================================================
GDAL-Python Bindings Module
===========================

.. automodule:: pyrate.core.gdal_python
   :members:

================================================
FILE: docs/geometry.rst
================================================
Geometry Module
===============

.. automodule:: pyrate.core.geometry
   :members:


================================================
FILE: docs/history.rst
================================================
.. :changelog:

Release History
===============

0.6.1 (2022-02-18)
------------------
Added
+++++
- List generator in ``utils/listcreator.sh`` for easier input generation from GAMMA output to PyRate.

Fixed
+++++
- Fix wrong sign in Y-intercept output file.
- Fix and simplify how user supplied reference pixel is validated and cropping issue.
- Add metadata for reference pixel latitude and longitude to output files.

0.6.0 (2021-10-18)
------------------
Added
+++++
- Geometry and baseline calculations, making use of GAMMA software MLI metadata and baseline files.
- DEM error estimation and correction functionality (untested prototype).
- Unwrapping error detection and masking functionality, making use of phase closure loops.
- Tests to check that the independent and network orbital methods are both able to recover the input parameters in synthetic examples.
- Tests for temporal and spatial gaussian filter options. Compare PyRate code against ``scipy.ndimage`` equivalents.
- More output visualisation scripts in the ``utils/`` directory, including an interferogram plotting script.
- New "Crop A" unit test dataset derived from Sentinel-1 data over Mexico City.
- Scaling factor parameter ``velerror_nsig`` for uncertainty/error output products.
- Calculate and output coherence statistics files during ``prepifg``.
- Add line-of-sight projection functionality for output products.
- Add signal polarity switching functionality for output products.
- Error handling for more than two MLI.par files in the header list matching an interferograms date-pair.

Fixed
+++++
- Fix bugs in the application of NaN masking and radian-to-millimetre conversion of interferogram data in ``correct`` step.
- Fix bugs in the implementation of the orbital error network and independent methods.
- Fix bugs in the implementation of spatial and temporal filters in the APS module.
- Fix bug in the application of reference phase subtraction that resulted in NaNs in the reference window.
- Fix file handling behaviour in ``prepifg`` so that a large number of files are not left open.

Changed
+++++++
- Enabled multi-looking and parallel processing for the independent orbital method.
- Simplify output filenames produced by PyRate.
- Move output files to dedicated named sub-directories. 
- Use of the ``offset`` parameter in orbital module; now renamed to ``intercept``.
- Input rasters to ``conv2tif`` can now have un-equal X and Y pixel resolutions.
- Change units of temporal filter from years to days.
- Moved Continuous Integration from Travis service to GitHub Actions.
- Made MPI an optional system dependency for PyRate (previously required).

Removed
+++++++
- Remove unused cython, glob2 and pillow dependencies.
- Remove support for Python 3.6.
- Remove support for filter types other than Gaussian in the APS module, and associated config options ``slpfmethod``, ``slpforder``, ``tlpfmethod``.
- ``config`` module deprecated; functionality moved to ``configuration``, ``shared`` and ``constants`` modules.
- Deprecated ``obs_dir``, ``slc_dir`` and ``coh_file_dir`` configuration parameters.

0.5.0 (2020-09-08)
------------------
Added
+++++
- New functionality "``linear_rate``" to calculate linear regression of
  cumulative displacement time series for every pixel as part of the ``timeseries`` step.
- Script for plotting ``timeseries`` and ``linear_rate`` output geotiff products using Matplotlib.
  To use, additional dependencies listed in ``requirements-plot.txt`` are required.
- Correction data (except ``maxvar`` and ``vcmt``) applied to the ifg data is saved to disk
  and re-used on subsequent repeat runs. Corrections are only re-calculated if config
  parameters change between runs.
- MPI parallelisation of APS spatio-temporal filter correction.
- Unit test coverage for refpixel lat/lon to x/y conversion and ``aps`` module.

Fixed
+++++
- Re-enable ``ifglksx`` and ``ifglksy`` to be different values, resulting in different
  resolutions in x and y dimensions in multi-looked interferograms.
- Re-enable ``orbfitlksx`` and ``orbfitlksy`` to be different values, resulting in different
  resolutions in x and y dimensions during network orbit correction.
- Screen messages from main process only during MPI runs.

Changed
+++++++
- ``process`` step has been renamed ``correct``. Stacking and timeseries have been removed from
  this step and are now invoked by separate ``timeseries`` and ``stack`` command line options.
- Processing of coherence files by ``conv2tif`` and ``prepifg`` is now triggered by the presence
  of ``cohfilelist`` in the config file. If the list is present, multilooked/cropped coherence
  files are saved to disk, regardless of whether ``cohmask`` is 0 or 1.
- Parallelisation capability is refactored - MPI and multiprocessing both now use a common
  tiling framework for ``stack``, ``timeseries`` and ``mst`` algorithms.
- Introduced a simplified and standardised file naming format for files produced by the
  ``prepifg`` step. Information previously saved in the filename (e.g. ``ifglksx``, ``ifglksy``,
  and ``ifgcropopt`` values) is now saved to the geotiff header instead.

Removed
+++++++
- Redundant ``tscal`` config parameter was deprecated - not needed now there is a ``timeseries``
  step invokable on the command line.
- Unused ``Pillow``, ``cython`` and ``glob2`` dependencies.
- Deprecated function ``pyrate.prepifg_helper.prepare_ifgs``, which is no longer needed.

0.4.3 (2020-08-04)
------------------
Added
+++++
- Ability to define the order of steps in the ``process`` workflow
  (default order unchanged).
  
Fixed
+++++
- Nil

Changed
+++++++
- ``prepifg`` output interferograms are saved as read-only files.
- ``process`` makes a writable copy of the ``prepifg`` output data
  at the beginning of each run.
- The selected reference pixel is saved to disk and re-used on subsequent
  ``process`` runs.  
- Saving of incremental time series (``tsincr``) products is optional,
  controlled by the ``savetsincr`` configuration parameter (default is on).

Removed
+++++++
- Removed obsolete InSAR terminology from code, docs and test data
  (changed to `first` and `second` images).
- Stopped using ``unittest`` unit test framework in favour of exclusively
  using ``pytest``.

0.4.2 (2020-06-26)
------------------
Added
+++++
- Save full-res coherence files to disk in ``conv2tif`` step if ``cohmask = 1``.
- Save multi-looked coherence files to disk in ``prepifg`` step if ``cohmask = 1``.
- Additional ``DATA_TYPE`` geotiff header metadata for above coherence files.
- ``conv2tif`` and ``prepifg`` output files have a tag applied to filename dependent
  on data type, i.e. ``_ifg.tif``, ``_coh.tif``, ``_dem.tif``.
- Metadata about used reference pixel is added to interferogram geotiff headers:
  lat/lon and x/y values; mean and standard deviation of reference window samples.
- Quicklook PNG and KML files are generated for the ``Stack Rate`` error map by default.

Fixed
+++++
- Ensure ``prepifg`` treats input data files as `read only`.
- Fix the way that the reference phase is subtracted from interferograms
  during ``process`` step.
- Manual entry of ``refx/y`` converted to type ``int``.

Changed
+++++++
- User supplies latitude and longitude values when specifying a reference pixel in
  the config file. Pixel x/y values are calculated and used internally.
- Move ``Stack Rate`` masking to a standalone function ``pyrate.core.stack.mask_rate``,
  applied during the ``merge`` step and add unit tests.
- Skip ``Stack Rate`` masking if threshold parameter ``maxsig = 0``.
- Provide log message indicating the percentage of pixels masked by 
  ``pyrate.core.stack.mask_rate``.
- Refactor ``pyrate.core.stack`` module; expose two functions in documentation:
  i) single pixel stacking algorithm, and
  ii) loop function for processing full ifg array.
- Refactor ``pyrate.merge`` script; remove duplicated code and create reusable
  generic functions.
- Colourmap used to render quicklook PNG images is calculated from min/max values of
  the geotiff band.
- Updated ``test`` and ``dev`` requirements.

Removed
+++++++
- Deprecate unused functions in ``pyrate.core.config`` and corresponding tests.
- Static colourmap ``utils/colourmap.txt`` that was previously used to render
  quicklook PNG images is removed. 

0.4.1 (2020-05-19)
------------------
Added
+++++
- Python 3.8 support.
- Algorithm to automatically calculate rows and columns for tiling.
  User no longer specifies these as part of the CLI, but can optionally
  specify ``rows`` and ``cols`` in the configuration file.
- Improvements to the test suite, including systems-wide tests.
- Improved logging.

Fixed
+++++
- Fixed bug in resampling/multi-looking when coherence masking is used.
  This bugfix will result in significantly fewer ``nan`` pixels in the outputs.
- Fixed a bug in how NaNs are handled during coherence masking and multi-looking.
  Output rasters will contain ``nan`` as the nodata value.

Changed
+++++++
- ``Linear Rate`` algorithm has been renamed ``Stack Rate``.
- User supplies full paths to input files in respective file lists.
- All files generated by `PyRate` saved to user-defined ``outdir`` directory.
- Renamed ``slcfilelist`` parameter to ``hdrfilelist``.
- Log files are generated in the ``outdir`` and every `PyRate` step produces independent log files.

Removed
+++++++
- Deprecate the use of ``obsdir``, ``slcfiledir`` and ``cohdir`` configuration variables.
- Deprecate ``parallel = 2`` option; splitting image via rows for parallelisation.

0.4.0 (2019-10-31)
------------------
Added
+++++
- Python 3.7 support.
- Optional ``conv2tif`` step.
- Building of docs integrated with Travis CI.
- Coherence masking, view coherence masking section in ``input_parameters.conf``
  for options.
- Input parameter validation.
- SLC and coherence file lists for file discovery.
- Create quick view png for rate map product.
- Add support for reading interferogram in Geotiff format.
- Add detailed validation and hints for configuration parameters
- Add system tests for all 3 types of input formats

Changed
+++++++
- ``linrate`` step has been renamed to ``process``.
- ``postprocess`` step has been renamed to ``merge``.
- ``converttogeotiff`` step has been renamed to ``conv2tif``.
- CLI structure: config files now need to be provided with ``-f`` flag.
- Reduced console output, default verbosity setting is now ``INFO``.
- Restructure of code layout, src modules now in ``PyRate/pyrate/core`` directory
  and scripts at ``PyRate/scripts``.
- Reference pixel values are expected to be in latitude and longitude values.

Removed
+++++++
- Unused luigi code.
- References to Matlab.
- Unused tests for legacy api.

0.3.0 (2019-07-26)
------------------
Added
+++++
- ``utils/apt_install.sh`` script that lists Ubuntu/apt package requirements.
- ``utils/load_modules.sh`` script that sets up NCI Raijin HPC environment.

Fixed
+++++
- Errors being caused by newer version of ``networkx``; v2.3 now supported.

Removed
+++++++
- Unused Python and OS packages.
- environment.yml - conda env will now be installed using ``requirements.txt``.
- HPC directory - hpc README.rst moved to docs.
- setup.cfg - no longer needed.
- Luigi functionality - hasn't been operational and is reported as vulnerable.
  Single machine parallelism is achieved with joblib. 

Changed
+++++++
- Requirements now managed by ``requirements.txt`` file, parsed by ``setup.py``.
- Requirements now split across base ``requirements.txt`` and separate files
  for dev (``requirements-dev.txt``) and testing (``requirements-test.txt``).
- Moved default config files to top level source directory.
- Pinned Python dependencies to specific versions.
- Travis build now installs GDAL from apt.
- Travis only builds on master, develop and \*-travis branches.
- Consolidated documentation into ``PyRate/docs``.
- Updated install instructions for Ubuntu and NCI.

0.2.0 (2017-05-22)
------------------
- Stable beta release.

0.1.0 (2017-01-31)
------------------
- First release on PyPI.


================================================
FILE: docs/hpc.rst
================================================
HPC
^^^

These instructions have been written for the Gadi supercomputer of the 
`National Computational Infrastructure (NCI)`_. The process for other
HPC platforms may differ. 

.. _`National Computational Infrastructure (NCI)`: https://nci.org.au/ 

Login to Gadi and clone the `PyRate` repository::

    ssh <user_name>@gadi.nci.org.au
    cd ~
    git clone https://github.com/GeoscienceAustralia/PyRate.git

Load the required Gadi modules (this will also remove the default NCI GDAL
Python bindings so we can build and use our own)::

    source ~/PyRate/scripts/nci_load_modules.sh

Create a Python virtual environment::

    python3 -m venv ~/PyRateVenv
    source ~/PyRateVenv/bin/activate

Install `PyRate`::

    cd ~/PyRate
    python3 setup.py install

Following this, `PyRate` will be available for PBS jobs. To verify the 
installation, first run an interactive session::

    qsub -I -q express -l walltime=01:00:00,mem=16Gb,ncpus=4,wd

Once the session has started, you will need to reactivate your virtual 
environment and reload the required modules. 
There is a call to activate the virtual environment built into the
script below so this can be completed with a single command::

    source ~/PyRate/scripts/nci_load_modules.sh


================================================
FILE: docs/ifgconstants.rst
================================================
Ifgconstants Module
===================

.. automodule:: pyrate.core.ifgconstants
    :members:


================================================
FILE: docs/index.rst
================================================
PyRate documentation
====================

This is the documentation for the `PyRate` software.

`PyRate` is a Python tool for estimating the velocity and cumulative
displacement time-series of surface movements for every pixel in a stack of
geocoded unwrapped interferograms generated by Interferometric Synthetic
Aperture Radar (InSAR) processing. `PyRate` exploits distributed scatterers
using a "Small Baseline Subset" (SBAS) processing strategy and currently
supports input data in the `GAMMA` or `ROI\_PAC` software formats.
Additionally, the European Space Agency SNAP_ software version 8 has a
"PyRate export" capability that prepares `SNAP` output data in the `GAMMA`
format for use with `PyRate`.

.. _`SNAP`: https://step.esa.int/main/download/snap-download/

.. note::

    - Support and development of `ROI\_PAC` has been discontinued.
    - `ROI\_PAC` support in `PyRate` will be deprecated in a future release.

The `PyRate` project started in 2012 as a partial Python translation of
"Pirate", a Matlab tool developed by the University of Leeds and the Guangdong
University of Technology.

* Link to `Github Repository`_
* Link to `Issue tracking page`_

.. _`Github Repository`: https://github.com/GeoscienceAustralia/PyRate
.. _`Issue tracking page`: https://github.com/GeoscienceAustralia/PyRate/issues

Feedback
--------

If you have any suggestions or questions about `PyRate` please
email the `Geoscience Australia InSAR team`_.

.. _`Geoscience Australia InSAR team`: mailto:insar@ga.gov.au

If you encounter any errors or problems with `PyRate`, please let us
know! Open an Issue_ in the GitHub repository.

.. _Issue: https://github.com/GeoscienceAustralia/PyRate/issues

Contents:
---------

.. toctree::
   :maxdepth: 3

   installation
   usage
   scripts
   modules
   troubleshooting
   contributing
   authors
   history

.. _Home: https://geoscienceaustralia.github.io/PyRate/


Indices and tables
==================

* :ref:`modindex`
* :ref:`genindex`


================================================
FILE: docs/installation.rst
================================================
Installation
============

This is an installation guide to get `PyRate` running on various platforms.
Follow the instructions to install `PyRate` and run a small toy example using
the test dataset included in the repository.

.. include:: dependencies.rst

Platforms
---------

PyPI
^^^^

`PyRate` and its Python dependencies can be installed directly from the
Python Package Index (PyPI_)::

    pip install Py-Rate

.. _PyPI: https://pypi.org/project/Py-Rate/

.. include:: ubuntu.rst
.. include:: docker.rst
.. include:: hpc.rst


Verify Installation
-------------------

To verify `PyRate` has been successfully installed, run the full processing
workflow with the example config file and the small dataset included
in the repository. If you compiled the ``pyrate`` executable program::

    pyrate workflow -f input_parameters.conf

If you installed from the Python Package Index (PyPI_), you won't have a
``pyrate`` executable program. Instead use::

    python3 pyrate/main.py workflow -f input_parameters.conf

If the installation has been successful, this workflow will complete without 
errors and output geotiff files will be generated in::

    ~/PyRate/out


================================================
FILE: docs/logger.rst
================================================
Logging Module
==============

.. automodule:: pyrate.core.logger
   :members:


================================================
FILE: docs/make.bat
================================================
@ECHO OFF

pushd %~dp0

REM Command file for Sphinx documentation

if "%SPHINXBUILD%" == "" (
	set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=.
set BUILDDIR=_build
set SPHINXPROJ=PyRate

if "%1" == "" goto help

%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
	echo.
	echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
	echo.installed, then set the SPHINXBUILD environment variable to point
	echo.to the full path of the 'sphinx-build' executable. Alternatively you
	echo.may add the Sphinx directory to PATH.
	echo.
	echo.If you don't have Sphinx installed, grab it from
	echo.http://sphinx-doc.org/
	exit /b 1
)

%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
goto end

:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%

:end
popd


================================================
FILE: docs/modules.rst
================================================
PyRate Modules
==============

.. toctree::
   :maxdepth: 4

   algorithm
   aps
   configuration
   covariance
   demerror
   gamma
   geometry
   gdal_python
   ifgconstants
   logger
   mpiops
   mst
   orbital
   phase_closure
   prepifg_helper
   ref_phs_est
   refpixel
   roipac
   shared
   stack
   timeseries


================================================
FILE: docs/mpiops.rst
================================================
MPI operations Module
=====================

.. automodule:: pyrate.core.mpiops
    :members:


================================================
FILE: docs/mst.rst
================================================
Minimum Spanning Tree Module
============================

.. automodule:: pyrate.core.mst
   :members:


================================================
FILE: docs/orbital.rst
================================================
Orbital Error Correction Module
===============================

.. automodule:: pyrate.core.orbital
   :members:

================================================
FILE: docs/phase_closure.rst
================================================
Phase Closure Module
====================

The phase closure functionality in PyRate is designed to identify and mitigate the 
effects of spatial unwrapping errors in the input interferograms (ifgs).
Identification is by forming "closure loops" between sets of ifgs and then
summing the phase in this closed loop for each pixel. Theoretically, the closure
phase should be equal to zero, though in reality, close to zero is good enough.
An unwrapping error in one of the loop edges will manifest as a closure phase of
n\ *2*\ pi radians.
By forming many loops amongst a network of ifgs, we attempt to identify
the individual ifgs that are contributing the unwrapping error.
Once identified, the unwrapping errors are mitigated by masking those pixels in
the necessary (but not all) ifgs.

By default, PyRate will do the phase closure step after orbital error, reference
phase and DEM error correction steps.
If a user wants to change the order of the corrections during PyRate's ``correct``
step, copy and paste the following code-block in to the PyRate configuration file
and re-order the steps. This will over-ride the default behaviour.

.. code-block::

   [correct]
   steps =
       orbfit
       refphase
       demerror
       phase_closure
       mst
       apscorrect
       maxvar

Five parameters control the phase closure functionality in PyRate.
These are described in the example PyRate configuration file
_input\ *parameters.conf* as follows:

.. code-block::

   #------------------------------------
   # Phase closure correction parameters

   # closure_thr:         Closure threshold for each pixel in multiples of pi, e.g. 0.5 = pi/2, 1 = pi.
   # ifg_drop_thr:        Ifgs with more than this fraction of pixels above the closure threshold in all
   #                      loops it participates in, will be dropped entirely.
   # min_loops_per_ifg:   Ifgs are dropped entirely if they do not participate in at least this many closure loops.
   # max_loop_length:     Closure loops with up to this many edges will be used.
   # max_loop_redundancy: A closure loop will be discarded if all constituent ifgs in that loop have
   #                      already contributed to a number of loops equal to this parameter.
   closure_thr:         0.5
   ifg_drop_thr:        0.05
   min_loops_per_ifg:   2
   max_loop_length:     4
   max_loop_redundancy: 2

The PyRate *phase closure* algorithm proceeds as follows:


#. 
   Find the closed loops within the given ifg network having edges less than or
   equal to the parameter ``max_loop_length``. This is done in the function
   ``mst_closure.sort_loops_based_on_weights_and_date``.
   We perform several steps in this stage:


   * Find closed loops with edges numbering between 3 and ``max_loop_length``.
     (function ``mst_closure.__find_closed_loops``\ )
   * Sort ifgs within each loop based on first date (earlier date first).
     In case of a tie, we sort based on the second date. We then compute
     weight of each ifg as the temporal baseline in days.
     Then we sum the ifg weights in a loop to give the weight of each closure loop
     (function ``mst_closure.__add_signs_and_weights_to_loops``\ ). 
   * Sort the loops based on their weights, and in case of ties, further
     sort by primary date, and secondary date.
     (function ``mst_closure.sort_loops_based_on_weights_and_date``\ )

#. 
   Discard closure loops when all of the constituent ifgs have already contributed
   to a number of loops equalling the ``max_loop_redundancy`` parameter.
   (function ``closure_check.discard_loops_containing_max_ifg_count``\ )

#. 
   Drop ifgs from further PyRate processing when they are found to not form part
   of any closed loop.
   (function ``closure_check.__drop_ifgs_if_not_part_of_any_loop``\ )

#. 
   Compute phase closure sums for each pixel (in radians) in all the chosen loops
   and flag when the resultant absolute sum exceeds the quantity <\ ``closure_thr`` * pi>.
   The median closure sum across all pixels is subtracted from the closure phase 
   (optional parameter ``subtract_median``\ , which is on by default).
   (function ``sum_closure.__compute_ifgs_breach_count``\ )

#. 
   Next, ifgs are dropped (removed from the processing list) if the fraction of
   constituent pixels breaching the ``closure_thr`` parameter in all loops
   the ifg participates in exceeds the parameter ``ifg_drop_thr``\ , or the ifg
   does not contribute to a number of loops at least equal to the parameter
   ``min_loops_per_ifg``.
   (function ``closure_check.__drop_ifgs_exceeding_threshold``\ )

#. 
   Steps 1-5 are repeated iteratively until a stable list of ifgs is returned.
   The iteration is orchestrated by the function ``closure_check.iterative_closure_check``.

#. 
   Once a stable list of ifgs is found, a new ifglist is written in the working
   directory, and used for further PyRate processing.

#. 
   The final step involves finding pixels in the ifg phase data that breach the
   closure threshold defined by the ``closure_thr`` parameter. Those pixels in breach
   are masked (changed to NaN value) for those pixels in those ifgs.
   (function ``closure_check.mask_pixels_with_unwrapping_errors``\ )

Example usage
-------------

To illustrate the PyRate phase closure functionality, we use a small example dataset
of 8 Sentinel-1 ifgs which connect 5 common acquisition dates:

.. code-block::

   20160314-20160326
   20160314-20160407
   20160314-20160501
   20160326-20160407
   20160326-20160513
   20160407-20160501
   20160407-20160513
   20160501-20160513

The below plots show the ifgs following ``prepifg``\ :


.. image:: ./phase_closure_images/ifg-phase-plot-1-before.png
   :target: ./phase_closure_images/ifg-phase-plot-1-before.png
   :alt: Ifgs before phase closure correction


Circled in black are some visually obvious unwrapping errors.

In this example, we run the ``correct`` step with orbital correction and phase
closure correction enabled, and the following parameters:

.. code-block::

   orbfitmethod:  2
   orbfitdegrees: 1
   orbfitlksx:    10
   orbfitlksy:    10

   closure_thr:         0.5
   ifg_drop_thr:        0.1
   min_loops_per_ifg:   2
   max_loop_length:     4
   max_loop_redundancy: 2

We get the following log information from iteration #1:

.. code-block::

   16:40:45 closure_check:126 421776 INFO 0/7 Closure check iteration #1: working on 8 ifgs
   16:40:45 closure_check:187 421776 INFO 0/7 Total number of selected closed loops with up to MAX_LOOP_LENGTH = 4 edges is 9
   16:40:45 closure_check:202 421776 INFO 0/7 After applying MAX_LOOP_REDUNDANCY = 2 criteria, 8 loops are retained
   16:40:52 plot_closure:76 421776 INFO 0/7 8 closure loops plotted in out/phase_closure_dir/closure_loops_iteration_1_fig_0.png


.. image:: ./phase_closure_images/closure_loops_iteration_1_fig_0.png
   :target: ./phase_closure_images/closure_loops_iteration_1_fig_0.png
   :alt: Iteration #1 closure loops


The 8 plotted closure loops from iteration #1 show areas where the ``closure_thr``
threshold has been breached as either dark red or dark blue. The previously
circled unwrapping errors show up as breached areas in several closure loops.

The ``ifg_drop_thr`` parameter is set to 10% in this example. This is enough
to detect the largest mis-closed area, which amounts to around 25% of the phase
data area spatially. The ifg introducing this mis-closure (20160407-20160513)
is dropped and iteration #2 continues:

.. code-block::

   16:40:52 closure_check:126 421776 INFO 0/7 Closure check iteration #2: working on 7 ifgs
   16:40:52 closure_check:187 421776 INFO 0/7 Total number of selected closed loops with up to MAX_LOOP_LENGTH = 4 edges is 5
   16:40:52 closure_check:202 421776 INFO 0/7 After applying MAX_LOOP_REDUNDANCY = 2 criteria, 5 loops are retained
   16:40:58 plot_closure:76 421776 INFO 0/7 5 closure loops plotted in out/phase_closure_dir/closure_loops_iteration_2_fig_0.png


.. image:: ./phase_closure_images/closure_loops_iteration_2_fig_0.png
   :target: ./phase_closure_images/closure_loops_iteration_2_fig_0.png
   :alt: Iteration #2 closure loops


Now the ifg network is smaller (7 ifgs) and less closure loops (5) are retained.
Three smaller breached areas are evident: in the top left, centre bottom and
bottom right of the image. The average breached area is now not greater than 10%
so no further ifgs are fully dropped and no further iteration is required.

Finally, pixels found to be breaching the ``closure_thr`` are masked in ifgs:


.. image:: ./phase_closure_images/ifg-phase-plot-1-after.png
   :target: ./phase_closure_images/ifg-phase-plot-1-after.png
   :alt: Ifgs after phase closure correction


The previously circled unwrapping error in ifg 20160314-20160501 has now been
masked, but this spatial area has not been masked in other ifgs. In this case,
the algorithm has been successfully able to attribute the source of the unwrapping
error to this single ifg. The ability to do this depends on the parameter
settings chosen.

.. automodule:: pyrate.core.phase_closure.closure_check
   :members:
.. automodule:: pyrate.core.phase_closure.collect_loops
   :members:
.. automodule:: pyrate.core.phase_closure.correct_phase
   :members:
.. automodule:: pyrate.core.phase_closure.mst_closure
   :members:
.. automodule:: pyrate.core.phase_closure.plot_closure
   :members:
.. automodule:: pyrate.core.phase_closure.sum_closure
   :members:



================================================
FILE: docs/prepifg_helper.rst
================================================
Prepifg Helper Module
=====================

.. automodule:: pyrate.core.prepifg_helper
    :members:


================================================
FILE: docs/pyrate.conv2tif.rst
================================================
PyRate Conv2tif Script
======================

.. automodule:: pyrate.conv2tif
    :members:
    :undoc-members:
    :show-inheritance:


================================================
FILE: docs/pyrate.correct.rst
================================================
PyRate Correct Script
========================

.. automodule:: pyrate.correct
    :members:
    :undoc-members:
    :show-inheritance:


================================================
FILE: docs/pyrate.main.rst
================================================
PyRate Main Script
==================

.. automodule:: pyrate.main

   .. rubric:: Functions
   .. autosummary::

      conv2tif
      prepifg
      correct
      timeseries
      stack
      merge


================================================
FILE: docs/pyrate.merge.rst
================================================
PyRate Merge Script
===================

.. automodule:: pyrate.merge
    :members:
    :undoc-members:
    :show-inheritance:


================================================
FILE: docs/pyrate.prepifg.rst
================================================
PyRate Prepifg Script
=========================

.. automodule:: pyrate.prepifg
    :members:
    :undoc-members:
    :show-inheritance:


================================================
FILE: docs/ref_phs_est.rst
================================================
Reference Phase Calculation Module
==================================

.. automodule:: pyrate.core.ref_phs_est
   :members:

================================================
FILE: docs/refpixel.rst
================================================
Reference Pixel Calculation Module
==================================

.. automodule:: pyrate.core.refpixel
   :members:

================================================
FILE: docs/roipac.rst
================================================
ROI_PAC Module
==============

.. automodule:: pyrate.core.roipac
   :members:


================================================
FILE: docs/scripts.rst
================================================
PyRate Scripts
==============

.. toctree::
   :maxdepth: 4

   pyrate.conv2tif
   pyrate.prepifg
   pyrate.correct
   pyrate.merge
   pyrate.main


================================================
FILE: docs/shared.rst
================================================
Shared Module
=============

.. automodule:: pyrate.core.shared
   :members:

================================================
FILE: docs/stack.rst
================================================
Stacking Module
===============

.. automodule:: pyrate.core.stack
   :members:


================================================
FILE: docs/timeseries.rst
================================================
Time Series Module
==================

.. automodule:: pyrate.core.timeseries
   :members:

================================================
FILE: docs/troubleshooting.rst
================================================
Troubleshooting
===============

Some common/known issues with `PyRate` that users may encounter are described below.

If your issue is not covered below, please contact the `Geoscience Australia InSAR Team`_ for help.

.. _`Geoscience Australia InSAR Team`: mailto:insar@ga.gov.au

ValueError: too many values to unpack (expected 2)
--------------------------------------------------
**Problem**: During ``prepifg`` step, the following error is encountered:

::

    Traceback (most recent call last):
      File "pyrate/main.py", line 131, in <module>
        main()
      File "pyrate/main.py", line 103, in main
        prepifg.main(params)
      File "~/PyRateVenv/lib/python3.7/site-packages/Py_Rate-0.4.0-py3.7.egg/pyrate/prepifg.py", line 57, in main
        do_prepifg(gtiff_paths, params)
      File "~/PyRateVenv/lib/python3.7/site-packages/Py_Rate-0.4.0-py3.7.egg/pyrate/prepifg.py", line 88, in do_prepifg
        _prepifg_multiprocessing(gtiff_path, xlooks, ylooks, exts, thresh, crop, params)
      File "~/PyRateVenv/lib/python3.7/site-packages/Py_Rate-0.4.0-py3.7.egg/pyrate/prepifg.py", line 112, in _prepifg_multiprocessing
        coherence_path=coherence_path, coherence_thresh=coherence_thresh)
      File "~/PyRateVenv/lib/python3.7/site-packages/Py_Rate-0.4.0-py3.7.egg/pyrate/core/prepifg_helper.py", line 187, in prepare_ifg
        op = output_tiff_filename(raster.data_path, out_path)
      File "~/PyRateVenv/lib/python3.7/site-packages/Py_Rate-0.4.0-py3.7.egg/pyrate/core/shared.py", line 1222, in output_tiff_filename
        fname, ext = os.path.basename(inpath).split('.')
    ValueError: too many values to unpack (expected 2)

**Reason**: This is caused by multiple double dots being used in the file names.

**Solution**: Ensure only a single dot is given in the file names, delimiting the file extension.
For example, rename ``20151219-20160112.unw.tif`` to ``20151219-20160112_unw.tif``.


Stack Rate map appears to be blank/empty
----------------------------------------
**Problem**: Output of Stack Rate algorithm contains NaN values causing “merge“ to fail:

::

    Traceback (most recent call last):
    File "~/PyRateVenv/bin/pyrate", line 11, in <module> load_entry_point('Py-Rate==0.4.0', 'console_scripts', 'pyrate')()
    File "~/PyRateVenv/lib/python3.7/site-packages/Py_Rate-0.4.0-py3.7.egg/main.py", line 154, in main merge_handler(args.config_file)
    File "~/PyRateVenv/lib/python3.7/site-packages/Py_Rate-0.4.0-py3.7.egg/main.py", line 87, in merge_handler merge.main(config.__dict__)
    File "~/PyRateVenv/lib/python3.7/site-packages/Py_Rate-0.4.0-py3.7.egg/merge.py", line 64, in main create_png_from_tif(output_folder_path)
    File "~/PyRateVenv/lib/python3.7/site-packages/Py_Rate-0.4.0-py3.7.egg/merge.py", line 130, in create_png_from_tif minimum, maximum, mean, stddev = srcband.GetStatistics(True, True)
    File "/apps/gdal/3.0.2/lib/python3.7/site-packages/osgeo/gdal.py", line 2610, in GetStatistics return _gdal.Band_GetStatistics(self, *args)
    RuntimeError: ~/out/stack_rate.tif, band 1: Failed to compute statistics, no valid pixels found in sampling.
    Traceback (most recent call last):
    File "~/PyRateVenv/bin/pyrate", line 11, in <module> load_entry_point('Py-Rate==0.4.0', 'console_scripts', 'pyrate')()
    File "~/PyRateVenv/lib/python3.7/site-packages/Py_Rate-0.4.0-py3.7.egg/main.py", line 154, in main merge_handler(args.config_file)
    File "~/PyRateVenv/lib/python3.7/site-packages/Py_Rate-0.4.0-py3.7.egg/main.py", line 87, in merge_handler merge.main(config.__dict__)
    File "~/PyRateVenv/lib/python3.7/site-packages/Py_Rate-0.4.0-py3.7.egg/merge.py", line 64, in main create_png_from_tif(output_folder_path)
    File "~/PyRateVenv/lib/python3.7/site-packages/Py_Rate-0.4.0-py3.7.egg/merge.py", line 130, in create_png_from_tif minimum, maximum, mean, stddev = srcband.GetStatistics(True, True)
    File "/apps/gdal/3.0.2/lib/python3.7/site-packages/osgeo/gdal.py", line 2610, in GetStatistics return _gdal.Band_GetStatistics(self, *args)
    RuntimeError: ~/out/stack_rate.tif, band 1: Failed to compute statistics, no valid pixels found in sampling.
    Traceback (most recent call last):
    File "~/PyRateVenv/bin/pyrate", line 11, in <module> load_entry_point('Py-Rate==0.4.0', 'console_scripts', 'pyrate')()
    File "~/PyRateVenv/lib/python3.7/site-packages/Py_Rate-0.4.0-py3.7.egg/main.py", line 154, in main merge_handler(args.config_file)
    File "~/PyRateVenv/lib/python3.7/site-packages/Py_Rate-0.4.0-py3.7.egg/main.py", line 87, in merge_handler merge.main(config.__dict__)
    File "~/PyRateVenv/lib/python3.7/site-packages/Py_Rate-0.4.0-py3.7.egg/merge.py", line 64, in main create_png_from_tif(output_folder_path)
    File "~/PyRateVenv/lib/python3.7/site-packages/Py_Rate-0.4.0-py3.7.egg/merge.py", line 130, in create_png_from_tif minimum, maximum, mean, stddev = srcband.GetStatistics(True, True)
    File "/apps/gdal/3.0.2/lib/python3.7/site-packages/osgeo/gdal.py", line 2610, in GetStatistics return _gdal.Band_GetStatistics(self, *args)
    RuntimeError: ~/out/stack_rate.tif, band 1: Failed to compute statistics, no valid pixels found in sampling.

**Reason**: The ``maxsig`` parameter is too low, resulting in stack rate values being replaced by NaNs. ``maxsig`` is a threshold for masking stack rate pixels according to the corresponding stack error estimate saved in ``out/tmpdir/stack_error_*.npy``.

**Solution**: Increase ``maxsig``, then re-run the ``merge`` step. Maximum permittable value for ``maxsig`` is 1000 mm.


Failure of APS spatial low pass filter
---------------------------------------
**Problem**: Atmospheric corrections during ``correct`` step fails due to the interpolated grid used for correction being empty:

::

    +8s pyrate.aps:INFO Applying spatial low pass filter
    Traceback (most recent call last):
    File "~/PyRateVenv/bin/pyrate", line 11, in <module>
    load_entry_point('Py-Rate==0.3.0.post3', 'console_scripts', 'pyrate')()
    File "~/PyRateVenv/lib/python3.6/site-packages/Click-7.0-py3.6.egg/click/core.py", line 764, in __call__
    return self.main(*args, **kwargs)
    File "~/PyRateVenv/lib/python3.6/site-packages/Click-7.0-py3.6.egg/click/core.py", line 717, in main
    rv = self.invoke(ctx)
    File "~/PyRateVenv/lib/python3.6/site-packages/Click-7.0-py3.6.egg/click/core.py", line 1137, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
    File "~/PyRateVenv/lib/python3.6/site-packages/Click-7.0-py3.6.egg/click/core.py", line 956, in invoke
    return ctx.invoke(self.callback, **ctx.params)
    File "~/PyRateVenv/lib/python3.6/site-packages/Click-7.0-py3.6.egg/click/core.py", line 555, in invoke
    return callback(*args, **kwargs)
    File "~/PyRateVenv/lib/python3.6/site-packages/Py_Rate-0.3.0.post3-py3.6.egg/pyrate/scripts/main.py", line 69, in linrate
    run_pyrate.process_ifgs(sorted(dest_paths), params, rows, cols)
    File "~/PyRateVenv/lib/python3.6/site-packages/Py_Rate-0.3.0.post3-py3.6.egg/pyrate/scripts/run_pyrate.py", line 391, in process_ifgs
    _wrap_spatio_temporal_filter(ifg_paths, params, tiles, preread_ifgs)
    File "~/PyRateVenv/lib/python3.6/site-packages/Py_Rate-0.3.0.post3-py3.6.egg/pyrate/aps.py", line 63, in _wrap_spatio_temporal_filter
    spatio_temporal_filter(tsincr, ifg, params, preread_ifgs)
    File "~/PyRateVenv/lib/python3.6/site-packages/Py_Rate-0.3.0.post3-py3.6.egg/pyrate/aps.py", line 86, in spatio_temporal_filter
    ts_aps = mpiops.run_once(spatial_low_pass_filter, ts_hp, ifg, params)
    File "~/PyRateVenv/lib/python3.6/site-packages/Py_Rate-0.3.0.post3-py3.6.egg/pyrate/mpiops.py", line 54, in run_once
    f_result = f(*args, **kwargs)
    File "~/PyRateVenv/lib/python3.6/site-packages/Py_Rate-0.3.0.post3-py3.6.egg/pyrate/aps.py", line 192, in spatial_low_pass_filter
    _interpolate_nans(ts_lp, params[cf.SLPF_NANFILL_METHOD])
    File "~/PyRateVenv/lib/python3.6/site-packages/Py_Rate-0.3.0.post3-py3.6.egg/pyrate/aps.py", line 208, in _interpolate_nans
    _interpolate_nans_2d(a, rows, cols, method)
    File "~/PyRateVenv/lib/python3.6/site-packages/Py_Rate-0.3.0.post3-py3.6.egg/pyrate/aps.py", line 224, in _interpolate_nans_2d
    method=method
    File "~/PyRateVenv/lib/python3.6/site-packages/scipy-1.3.0-py3.6-linux-x86_64.egg/scipy/interpolate/ndgriddata.py", line 226, in griddata
    rescale=rescale)
    File "interpnd.pyx", line 846, in scipy.interpolate.interpnd.CloughTocher2DInterpolator.__init__
    File "qhull.pyx", line 1836, in scipy.spatial.qhull.Delaunay.__init__
    File "qhull.pyx", line 276, in scipy.spatial.qhull._Qhull.__init__
    ValueError: No points given

**Solution**: Use more interferograms as input and/or reduce the threshold parameters ``ts_pthr``, ``pthr``, ``tlpfpthr`` in the configuration file.

In general, users are advised to input a network of small-baseline interferograms
that has at least 2 interferometric connections per SAR image epoch. Furthermore,
make sure that ``ts_pthr``, ``pthr`` and ``tlpfpthr`` are smaller than the number
of image epochs. To check that the spatio-temporal filters worked correctly, users can check that
the numpy arrays saved at ``/<outdir>/aps_error/*aps_error.npy`` contain numeric values and not NaNs.


Out of memory errors
--------------------
**Problem**: `PyRate` is memory intensive. You may receive various out of memory errors if there is not enough memory to accommodate the images being processed.

::

    joblib.externals.loky.process_executor.TerminatedWorkerError: A worker process managed by the executor was unexpectedly terminated. This could be caused by a segmentation fault while calling the function or by an excessive memory usage causing the Operating System to kill the worker. The exit codes of the workers are {EXIT(1), EXIT(1), EXIT(1)}

**Solution**: Increase the amount of memory available. On HPC systems this can be done by increasing the value provided to the ``mem`` argument when submitting a PBS job, e.g.::

    mem=32Gb

If no more memory can be called upon, users can try running the job in serial, or reducing the size of the interferograms by increasing the multi-looking factors applied during ``prepifg`` (parameters ``ifglksx`` and ``ifglksy``).

Incorrect modules loaded on Gadi
----------------------------------
**Problem**: `PyRate` requires certain versions of Python, GDAL and Open MPI to be loaded on Gadi and other HPC systems. While sourcing the `PyRate/scripts/nci_load_modules.sh` script will load the correct modules, you may need to unload previously unloaded modules.

Example of errors caused by module conflicts::

    ERROR:150: Module 'python3/3.7.2' conflicts with the currently loaded module(s) 'python3/3.4.3-matplotlib'
    ERROR:150: Module 'gdal/2.2.2' conflicts with the currently loaded module(s) 'gdal/2.0.0'

**Solution**: Purge the loaded modules and source the ``nci_load_modules.sh`` script:

::

    module purge
    source ~/PyRate/scripts/nci_load_modules.sh


================================================
FILE: docs/ubuntu.rst
================================================
Linux
^^^^^

These instructions have been tested using Ubuntu 18.04. If using another
Linux distribution, you will have to install packages equivalent to those
listed in ``PyRate/scripts/apt_install.sh``.

Clone the repository, install required packages and install `PyRate`:

::

    git clone git@github.com:GeoscienceAustralia/PyRate.git
    ./PyRate/scripts/apt_install.sh

    # Add GDAL includes to C/CPLUS paths before building Python GDAL bindings.
    export C_INCLUDE_PATH=$C_INCLUDE_PATH:/usr/include/gdal
    export CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH:/usr/include/gdal

    python3 setup.py install

These commands will compile the executable program ``pyrate``.


================================================
FILE: docs/usage.rst
================================================
Usage
=====

Configuration
-------------

Various parameters are controlled by values given in a text-based configuration file.
The user can choose any filename for this configuration file.
Example parameters for running `PyRate` with `GAMMA`-format interferograms are
contained in the example configuration file ``PyRate/input_parameters.conf``.


Workflow
--------

File Discovery
^^^^^^^^^^^^^^

To allow flexibility in the file types that can be processed, `PyRate` requires
file lists to be provided. This allows `PyRate` to identify files of each
type without relying on file extensions. The file path to these lists are 
provided under ``ifgfilelist``, ``hdrfilelist``, ``cohfilelist`` and 
``basefilelist`` keywords in the configuration file. These lists can be created manually 
or generated using the script ``list_creator.sh`` located in the ``utils`` folder.
This script may need to be slightly modified depending on the output paths of your input data.

.. note::

    - Filenames should be provided in these lists with their absolute system path,
      with each name on a separate line.
    - Filenames should only have a single period (".") delimiting the file extension.
      Multiple periods in a filename will raise an error during runtime.

The ``ifgfilelist`` gives the list of interferograms to be processed.
Example of an interferogram file list for `GAMMA` flat-binary files::

    /absolute/path/to/20150702-20150920.unw
    /absolute/path/to/20151219-20160109.unw
    /absolute/path/to/20160202-20160415.unw

.. note::

    - Interferogram filenames must contain a pair of date epochs.
      Any naming convention is appropriate as long as an epoch pair of format
      ``YYYYMMDD-YYYYMMDD`` or ``YYMMDD-YYMMDD`` exists in the filename.

The ``hdrfilelist`` gives the list of `GAMMA` Multi-Look Intensity (MLI) header
text files. Example of a `GAMMA` MLI header file list::

    /absolute/path/to/20150702_mli.par
    /absolute/path/to/20150920_mli.par
    /absolute/path/to/20151219_mli.par
    /absolute/path/to/20160109_mli.par
    /absolute/path/to/20160202_mli.par
    /absolute/path/to/20160415_mli.par

.. note::

    - MLI header filenames must contain a single date epoch in the format
      ``YYYYMMDD`` or ``YYMMDD``.
    - `GAMMA` Single-Look Complex (SLC) header files could be used instead, but
      the geometry calculations in ``prepifg`` will not work, and subsequently
      the DEM Error correction step in ``correct`` will not work. Both require
      parameters valid for the multi-looked radar-coded interferograms.

The ``cohfilelist`` is an optional list which contains the pool of all available
coherence files to be used for optional coherence masking.
Example of a coherence file list for `GAMMA` flat-binary files::

    /absolute/path/to/20150702-20150920.coh
    /absolute/path/to/20151219-20160109.coh
    /absolute/path/to/20160202-20160415.coh

.. note::

    - Like interferograms, coherence filenames must contain a pair of epochs.
      The epoch pair must be in the format ``YYYYMMDD-YYYYMMDD`` or
      ``YYMMDD-YYMMDD``. Otherwise, any naming convention is appropriate.

The ``basefilelist`` is an optional list which contains the pool of all
available GAMMA baseline vector files. These are only needed if the user
wants to use the DEM error correction functionality.
Example of a baseline file list for `GAMMA` baseline vector files::

    /absolute/path/to/20150702-20150920_base.par
    /absolute/path/to/20151219-20160109_base.par
    /absolute/path/to/20160202-20160415_base.par

The date epochs in filenames are used to match the corresponding MLI header
or coherence files to each interferogram. It is recommended to provide a
complete list of available headers/coherence/baseline files for a stack in
their respective lists, since only the necessary files will be used. This
allows you to process a subset of interferograms by removing entries in
``ifgfilelist`` without needing to modify all four lists.

`PyRate` Workflow
^^^^^^^^^^^^^^^^^

After `Installation <installation.html>`__, an
executable program ``pyrate`` is created in the system path::

    >> pyrate --help
    usage: pyrate [-h] [-v {DEBUG,INFO,WARNING,ERROR}]
                  {conv2tif,prepifg,correct,timeseries,stack,merge,workflow} ...

    PyRate workflow:

        Step 1: conv2tif
        Step 2: prepifg
        Step 3: correct
        Step 4: timeseries
        Step 5: stack
        Step 6: merge

    Refer to https://geoscienceaustralia.github.io/PyRate/usage.html for
    more details.

    positional arguments:
      {conv2tif,prepifg,correct,timeseries,stack,merge,workflow}
        conv2tif            <Optional> Convert interferograms to geotiff.
        prepifg             Perform multilooking, cropping and coherence masking to interferogram geotiffs.
        correct             Calculate and apply corrections to interferogram phase data.
        timeseries          <Optional> Timeseries inversion of interferogram phase data.
        stack               <Optional> Stacking of interferogram phase data.
        merge               Reassemble computed tiles and save as geotiffs.
        workflow            <Optional> Sequentially run all the PyRate processing steps.

    optional arguments:
      -h, --help            show this help message and exit
      -v {DEBUG,INFO,WARNING,ERROR}, --verbosity {DEBUG,INFO,WARNING,ERROR}
                            Increase output verbosity

 .. note::

    - If running on NCI, be sure to first load the correct modules and virtual environment:
      ``source ~/PyRate/scripts/nci_load_modules.sh`` 

The ``pyrate`` program has six command line options corresponding to
different steps in the `PyRate` workflow:

1. ``conv2tif`` (optional)
2. ``prepifg``
3. ``correct``
4. ``timeseries`` (optional)
5. ``stack`` (optional)
6. ``merge``

Not all steps are required as indicated above. A seventh option, ``workflow``, is
available that will run all six of the above steps in the order shown.

Command line arguments for each step can be found using (e.g. for ``conv2tif``)::

    >> pyrate conv2tif --help
    usage: pyrate conv2tif [-h] -f CONFIG_FILE

    optional arguments:
      -h, --help            show this help message and exit
      -f CONFIG_FILE, --config_file CONFIG_FILE
                            Pass configuration file

Each step can be run on the command line in one of the following two ways
(e.g. for ``conv2tif``)::

    >> pyrate conv2tif -f /path/to/config_file

or::

    >> python3 pyrate/main.py conv2tif -f /path/to/config_file

In the following sub-sections we describe each of the available steps.


``conv2tif``: Converting flat-binary files to Geotiff format
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Before `PyRate` can process interferograms that are in flat-binary file format, they
need to be converted into geotiff format using the optional ``conv2tif`` step.

.. note::

    - Users of the `GAMMA` software can skip the ``conv2tif`` step if they have generated
      geotiffs using the `GAMMA` program ``data2geotiff``, which is included in all
      `GAMMA` software distributions.
    - In this case, ``ifgfilelist`` and ``cohfilelist`` would contain the absolute
      paths to these geotiff files. Even when using geotiff files, the MLI header files
      are still required by ``prepifg``.
    - If a DEM is to be processed by ``prepifg``, it's file format should match the
      input interferograms (e.g. geotiff or flat-binary files).

Upon completion of ``conv2tif`` geotiff formatted copies of the input files will be placed
in the ``<outdir>`` directory defined in the configuration file.

.. note::

     - ``conv2tif`` will not perform the conversion if geotiffs for the provided
       input files already exist.


``prepifg``: Preparing input interferograms
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

``prepifg`` is the second step of `PyRate`, which applys optional multi-looking
(sub-sampling), cropping and coherence masking operations to the geotiff-format
input interferograms. This is a required step, which formats the input data in
a way expected by the rest of the `PyRate` workflow.

**Coherence masking**

``prepifg`` will perform optional coherence masking on the interferograms
before multi-looking and cropping is performed. This requires corresponding
coherence images for each interferogram.
The purpose of coherence masking is to remove poor quality phase observations
and leave a set of high-quality pixels for analysis.

Coherence masking is enabled by setting ``cohmask: 1`` in
the configuration file. A threshold, ``cohthresh`` needs to be provided. 
Pixels with coherence values below ``cohthresh`` will be set to Not-a-Number (NaN).

.. note::

    - The number of pixels with numeric phase values (i.e. pixels not equal to NaN)
      will be different in each interferogram after coherence masking.

The available coherence files need to be specified in a list file as described above
and defined in the ``cohfilelist`` parameter.

.. note::

    - Multi-looked and cropped versions of those coherence images found that match
      the epochs of the input interferograms will be saved to disk in geotiff format,
      even if coherence masking is not applied (i.e. ``cohmask: 0``).
    - Additionally, the mean, median and standard deviation of the coherence for
      each pixel is calculated and saved as part of ``prepifg``.
    - All coherence files are saved to the ``<outdir>\coherence_dir`` directory.

**Multi-looking**

The ``prepifg`` step will perform optional multi-looking (image sub-sampling) 
of the input interferograms in geotiff format. The purpose of multi-looking is twofold:

- Reduce the spatial resolution of the interferograms in order to improve the
  computational efficiency of `PyRate` analysis.
- Reduce the general phase noise in the interferograms in order to enhance the
  signal-to-noise ratio in the output products.

To multi-look, set ``ifglksx`` and ``ifglksy`` to an integer subsampling factor greater
than one in the x (easting) and y (northing) dimensions respectively. Separate parameters
for x and y gives flexibility for users in case they want to achieve different spatial
resolution in each dimension.

.. note::

    - For example, a value of ``2`` will reduce the resolution by half.
      A value of ``1`` will keep the resolution the same as the input interferograms
      (i.e. no multi-looking).
    - It is recommended to try a large multi-look factor to start with (e.g. ``10``
      or greater), and subsequently reduce the multi-looking factor once the user
      has experience with processing a particular dataset.

**Cropping**

The ``prepifg`` step will perform optional spatial cropping of the input interferograms.
This is useful if you are focussing on a specific area of interest within the full
extent of the input interferograms. The advantage of cropping is that `PyRate`
analysis will be computationally more efficient.

To crop, set ``ifgcropopt`` to ``3`` and provide the geographic latitude and longitude
bounds in the ``ifgxfirst`` (west), ``ifgxlast`` (east), ``ifgyfirst`` (north), and
``ifgylast`` (south) parameters.

**Geometry calculations**

During the ``prepifg`` step, the radar viewing geometry for every pixel is
calculated using metadata from the `GAMMA` MLI parameter files.

.. note::

    - Geometry calculations are only implemented for `GAMMA` format input data.

The output arrays are saved to ``<outdir>/geometry_dir`` and contain as follows:

- ``rdc_azimuth.tif``: azimuth coordinate in range-doppler system;
- ``rdc_range.tif``: range coordinate in range-doppler system;
- ``look_angle.tif``: look angle (vector between line-of-sight and satellite nadir);
- ``incidence_angle.tif``: incidence angle (vector between line-of-sight and vector perpendicular to local ground surface);
- ``azimuth_angle.tif``: azimuth angle (projection of line-of-sight on the surface);
- ``range_dist.tif``: satellite to ground range distance;
- ``dem.tif``: digital elevation model.

Upon completion, ``prepifg`` will save a new set of interferogram files in the
``<outdir>\interferogram_dir`` (``*_ifg.tif``).
If provided as input, coherence files will be saved to ``<outdir>\coherence_dir``
(``*_coh.tif``).


``correct``: Compute and apply interferometric phase corrections
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

``correct`` is the third step in the `PyRate` processing workflow. This step
will perform a series of optional corrections to the interferogram phase data
and apply a number of prepatory steps required prior to data inversion.

The sub-steps are performed in the following default order:

- Search for a suitable reference pixel;
- Residual Orbit error correction (optional, controlled by ``orbfit`` parameter);
- Correction of reference phase in interferograms;
- Residual DEM error correction (optional, controlled by ``demerror`` parameter);
- Unwrapping error detection and masking (optional, controlled by ``phase_closure`` parameter); 
- Minimum Spanning Tree matrix formation;
- Spatio-temporal filtering of the interferograms ((optional, controlled by ``apsest`` parameter);  
- Calculation of interferogram spatial covariance functions;
- Assembly of the variance-covariance matrix.

This default order of steps can be modified by the user by copying the
following code block in to the configuration file and switching the order of
steps as required::

    [correct]
    steps =
        orbfit
        refphase
        demerror
        phase_closure
        mst
        apscorrect
        maxvar


The corrected interferogram phase is saved to copies of the ``prepifg``
interferograms in the directory ``<outdir>/temp_mlooked_dir/`` (the original
output from ``prepifg`` is retained as a read-only interferogram dataset in the
``<outdir>/interferogram_dir``).
Additionally, copies of the phase corrections subtracted from interferograms
are saved to disk as numpy array files (``*.npy``) for use in post-processing.
These can be found in labelled sub-directories in the ``<outdir>``.


``timeseries``: Compute the displacement time series
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

``timeseries`` is the optional fourth step in the `PyRate` processing workflow.
This step will perform a time series inversion to derive the cumulative displacement
time series from the stack of corrected interferograms.
The cumulative displacement time series (``tscuml*``) is saved by default.
Users can optionally save the incremental displacement time series (``tsincr*``)
by setting parameter ``savetsincr: 1``.

A linear regression of the cumulative displacement time series is also computed
as part of the ``timeseries`` step. The resulting linear rate (velocity),
standard error, R-squared and y-intercept terms are all saved to disk.


``stack``: Compute the average velocity via stacking
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

``stack`` is the optional fifth step in the `PyRate` processing workflow.
This step will perform an iterative stacking of the phase data to derive a
robust velocity estimate for each pixel in the interferograms.
The velocity from stacking (``stack_rate*``) is saved by default.

.. note::

    - Both ``timeseries`` and ``stack`` are optional and independent steps
      that can be computed in either order.


``merge``: Reassemble the tiles
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

``merge`` is the sixth and final step of the `PyRate` workflow, which produces
geotiff files containing the final time series, linear rate and stacking products.
``merge`` will also re-assemble tiles that were generated during the previous
steps. Tiling is discussed in the :ref:`parallel_label` section below.

The final outputs contain signals in the line-of-sight (LOS) of the satellite.
Using the ``los_projection`` option, the user can project those signals to
either the pseudo-vertical (set to 1) or pseudo-horizontal (set to 2). This
projection makes use of the per-pixel incidence angle image generated during
``prepifg``.

.. note::

    - Users should be aware that the pseudo-vertical and pseudo-horizontal
      signal projections do not necessarily represent the **true** vertical
      or horizontal ground movement signal. The true signals cannot be
      recovered with InSAR data from a single LOS viewing geometry.
    - If the user has InSAR data from multiple viewing geometries (e.g. from
      both ascending and descending orbits), signal decomposition can be
      carried out after PyRate analysis as a post-processing step.

If necessary, the user can switch the polarity of the final output products
by setting ``signal_polarity: -1``.

The error products produced by `PyRate` can be scaled by n-sigma using the
parameter ``velerror_nsig``.

After running the ``merge`` step, several geotiff products will appear in the
``<outdir>/velocity_dir`` and ``<outdir>/timeseries_dir`` directories.


``workflow``: Run the full PyRate workflow
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

``workflow`` is an additional option that will run all the above six steps
in order as a single job. This could be useful for batch processing runs.


Input Files
-----------

`PyRate` currently supports input files generated by the `GAMMA`, `ROI\_PAC`
and `SNAP` interferometry softwares. `PyRate` will determine the input
format from the ``processor:`` parameter in the configuration file
(``0``: `ROI\_PAC`; ``1``: `GAMMA` (and `SNAP`)).

`GAMMA`
^^^^^^^

Each `GAMMA` geocoded unwrapped interferogram requires three header files
to extract metadata required for data formatting: a geocoded DEM header
file (``demHeaderFile`` keyword in the configuration file) and the relevant
MLI image header files (``*mli.par``) found in the ``hdrfilelist``.
The header files for the first and second MLI images used in the formation
of a particular interferogram are found automatically by date-string pattern
matching based on date epochs given in the filenames.
A DEM with matching size and geometry to the interferograms can also be processed.
The DEM absolute path and filename are set with the ``demfile`` parameter.

`SNAP`
^^^^^^

The European Space Agency SNAP_ software has supported PyRate since version
8.0.0. Users can convert their output data in to `GAMMA` format by
using the "PyRate export" function in `SNAP`. Then users should follow the
`PyRate` instructions for `GAMMA`-formatted data.

.. note::

    - The capability to generate SBAS interferogram networks that are needed
      for time series analysis of large InSAR stacks in `PyRate` is planned
      for a future version of `SNAP`.

.. _SNAP: https://step.esa.int/main/download/snap-download/


`ROI\_PAC`
^^^^^^^^^^

Each `ROI\_PAC` geocoded unwrapped interferogram requires its own
header/resource file (``*.rsc``). These header files need to be
listed in the defined ``hdrfilelist``. In addition, the geocoded DEM
header file is required and its path and name are specified in the config file under
``demHeaderFile``. The geographic projection in the parameter ``DATUM:`` is extracted
from the DEM header file.
A DEM with matching size and geometry to the interferograms can also be processed.
The DEM absolute path and filename are set with the ``demfile`` parameter.

.. note::

    - Support and development of `ROI\_PAC` has been discontinued.
    - `ROI\_PAC` support in `PyRate` will be deprecated in a future release.

.. _parallel_label:

Parallel Processing
-------------------

By their very nature, interferograms are large files. This is particularly the case
for `Sentinel-1`_, which has an image swath of 250 km and a pixel resolution on the order
of tens of metres in IW-mode.
Consequently, InSAR processing can be computationally expensive and time consuming.
It therefore makes sense to parallelise processing operations wherever possible.

.. _`Sentinel-1`: https://sentinel.esa.int/web/sentinel/user-guides/sentinel-1-sar

`PyRate` can be run in parallel using standard multi-threading simply by turning
``parallel: 1`` in the configuration file to take advantage of multiple cores
on a single machine. The parameter ``processes`` sets the number of threads.

Alternatively, `PyRate` can be parallelised on a system with an installed MPI library
by using ``mpirun``::

    # Modify '-n' based on the number of processors available.
    mpirun -n 4 pyrate conv2tif -f path/to/config_file
    mpirun -n 4 pyrate prepifg -f path/to/config_file
    mpirun -n 4 pyrate correct -f path/to/config_file
    mpirun -n 4 pyrate timeseries -f input_parameters.conf
    mpirun -n 4 pyrate stack -f input_parameters.conf
    mpirun -n 4 pyrate merge -f path/to/config_file

.. note::

    - In the case that `PyRate` is run using ``mpirun``, standard multi-threading is
      automatically disabled (i.e. equivalent to setting ``parallel: 0``).

During ``conv2tif`` and ``prepifg``, parallelism is achieved by sending sub-lists of input
files to each process.
Parallelism in the ``correct``, ``timeseries`` and ``stack`` steps is achieved by splitting
the images in to a grid of tiles, where the number of tiles equals the number of processes
passed with the ``-n`` argument to ``mpirun``, or the ``processes`` parameter for multi-threading.
The number of tiles in x and y dimension are automatically calculated by `PyRate`, ensuring
a roughly equivalent number in both dimensions. One of the functions of the ``merge`` step
is to reassemble these tiles in to the full image for each output product.


Results Visualisation
---------------------

Several plotting scripts are included in the ``utils/`` directory to help the
user visually inspect the output products of `PyRate`:

- ``make_tscuml_animation.py``: Make an animated gif from cumulative time series data;
- ``plot_linear_rate_profile.py``: Plot a profile through a linear rate map;
- ``plot_time_series.py``: Map and graph view of cumulative time series data;
- ``plot_correction_files.py``: Before and after viewing of interferogram corrections;
- ``plot_sbas_network.py``: Baseline-time plot for the interferogram network.


Example usage of ``plot_time_series.py`` with the included test data::

    cd PyRate
    source ~/PyRateVenv/bin/activate
    pyrate workflow -f input_parameters.conf
    pip install -r requirements-plot.txt
    python3 utils/plot_time_series.py out/

.. image:: PyRate_plot_screenshot.png 
   :alt: Screenshot of PyRate plotting tool
   :scale: 30 %



================================================
FILE: input_parameters.conf
================================================
# PyRate configuration file for GAMMA-format interferograms
#
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# Optional Correction ON/OFF switches - ON = 1; OFF = 0

# Coherence masking (PREPIFG)
cohmask:       0

# Orbital error correction (CORRECT)
orbfit:        0

# DEM error (residual topography) correction (CORRECT)
demerror:      0

# Phase Closure correction (CORRECT)
phase_closure: 1

# APS correction using spatio-temporal filter (CORRECT)
apsest:        0

#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# Integer parameters

# LOS Projection of output products (MERGE)
# Converts slanted (native) LOS signals to either "pseudo-vertical" or "pseudo-horizontal", 
# by dividing by the cosine or sine of the incidence angle for each pixel, respectively.
# los_projection: 0 = LOS (no conversion); 1 = pseudo-vertical; 2 = pseudo-horizontal.
los_projection:  0

# Sign convention for phase data (MERGE)
# signal_polarity:  1 = retain sign convention of input interferograms
# signal_polarity: -1 = reverse sign convention of input interferograms (default)
signal_polarity: -1

# Number of sigma to report velocity error. Positive integer. Default: 2 (TIMESERIES/STACK)
velerror_nsig:   2

# Optional save of numpy array files for output products (MERGE)
savenpy:         0

# Optional save of incremental time series products (TIMESERIES/MERGE)
savetsincr:      0

#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# Multi-threading parameters (CORRECT/TIMESERIES/STACK)
# parallel: 1 = parallel, 0 = serial
parallel:      0
# number of processes
processes:     8

#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# Input/Output file locations
#
# File containing the list of interferograms to use.
ifgfilelist:   tests/test_data/cropA/ifg_30

# The DEM file used in the InSAR processing
demfile:       tests/test_data/cropA/geotiffs/cropA_T005A_dem.tif

# The DEM header file from GAMMA (*.par) or ROI_PAC (*.rsc).
demHeaderFile: tests/test_data/cropA/headers/cropA_20180106_VV_8rlks_eqa_dem.par

# File listing the pool of available header files (GAMMA: *mli.par, ROI_PAC: *.rsc)
hdrfilelist:   tests/test_data/cropA/headers_13

# File listing the pool of available coherence files.
cohfilelist:   tests/test_data/cropA/coherence_30

# File listing the pool of available baseline files (GAMMA).
basefilelist:  tests/test_data/cropA/baseline_30

# Look-up table containing radar-coded row and column for lat/lon pixels (GAMMA)
ltfile:        tests/test_data/cropA/geometry/20180106_VV_8rlks_eqa_to_rdc.lt

# Directory to write the outputs to
outdir:        out/

#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# PREPIFG parameters
#------------------------------------
# Input data format: ROI_PAC = 0, GAMMA = 1
processor:     1

# Coherence threshold value for masking, between 0 and 1
cohthresh:     0.3

# Multi-look/subsampling factor in east (x) and north (y) dimension
ifglksx:       1
ifglksy:       1

# Cropping options
# ifgcropopt: 1 = minimum extent 2 = maximum extent 3 = crop 4 = no cropping
# ifgxfirst,ifgyfirst: longitude (x) and latitude (y) of north-west corner
# ifgxlast,ifgylast: longitude (x) and latitude (y) of south-east corner
ifgcropopt:    4
ifgxfirst:     150.92
ifgyfirst:     -34.18
ifgxlast:      150.94
ifgylast:      -34.22

# No-data averaging threshold (0 = 0%; 1 = 100%)
noDataAveragingThreshold: 0.5

# The No-data value used in the interferogram files
noDataValue:   0.0

# Nan conversion flag. Set to 1 if missing No-data values are to be converted to NaN
nan_conversion: 1

#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# CORRECT parameters
#------------------------------------
# Reference pixel search parameters

# refx/y: Lon/Lat coordinate of reference pixel. If left blank then search for best pixel will be performed
# refnx/y: number of search grid points in x/y image dimensions
# refchipsize: size of the data window at each search grid point
# refminfrac: minimum fraction of valid (non-NaN) pixels in the data window
refx:          -99.18
refy:          19.44
refnx:         5
refny:         5
refchipsize:   7
refminfrac:    0.01

#------------------------------------
# Reference phase correction method

# refest: 1 = median of the whole interferogram
# refest: 2 = median within the window surrounding the chosen reference pixel
refest:        2

#------------------------------------
# Orbital error correction parameters

# orbfitmethod = 1: interferograms corrected independently; 2: network method
# orbfitdegrees: Degree of polynomial surface to fit (1 = planar; 2 = quadratic; 3 = part-cubic)
# orbfitlksx/y: additional multi-look factor for network orbital correction
orbfitmethod:  1
orbfitdegrees: 1
orbfitlksx:    5
orbfitlksy:    5

#------------------------------------
# Phase closure correction parameters

# closure_thr:         Closure threshold for each pixel in multiples of pi, e.g. 0.5 = pi/2, 1 = pi.
# ifg_drop_thr:        Ifgs with more than this fraction of pixels above the closure threshold in all
#                      loops it participates in, will be dropped entirely.
# min_loops_per_ifg:   Ifgs are dropped entirely if they do not participate in at least this many closure loops.
# max_loop_length:     Closure loops with up to this many edges will be used.
# max_loop_redundancy: A closure loop will be discarded if all constituent ifgs in that loop have
#                      already contributed to a number of loops equal to this parameter.
closure_thr:         0.5
ifg_drop_thr:        0.5
min_loops_per_ifg:   2
max_loop_length:     4
max_loop_redundancy: 2

#------------------------------------
# APS filter parameters

# tlpfcutoff: cutoff t0 for temporal high-pass Gaussian filter in days (int);
# tlpfpthr: valid pixel threshold;
# slpfcutoff: spatial low-pass Gaussian filter cutoff in km (greater than zero).
# slpfcutoff=0 triggers cutoff estimation from exponential covariance function
tlpfcutoff:    30
tlpfpthr:      1
slpfcutoff:    1

#------------------------------------
# DEM error (residual topography) correction parameters

# de_pthr: valid observations threshold;
de_pthr:       20

#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# TIMESERIES parameters
#------------------------------------

# tsmethod: Method for time series inversion (1 = Laplacian Smoothing; 2 = SVD)
# smorder: order of Laplacian smoothing operator (1 = first-order difference; 2 = second-order difference)
# smfactor: smoothing factor for Laplacian smoothing (value provided is converted as 10**smfactor)
# ts_pthr: valid observations threshold for time series inversion
tsmethod:      2
smorder:       2
smfactor:      -0.25
ts_pthr:       10

#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# STACK parameters
#------------------------------------

# pthr: threshold for minimum number of ifg observations for each pixel
# nsig: threshold for iterative removal of observations
# maxsig: maximum sigma (std dev; millimetres) used as an output masking threshold applied in Merge step. 0 = OFF.
pthr:          5
nsig:          3
maxsig:        1000



================================================
FILE: pyrate/__init__.py
================================================


================================================
FILE: pyrate/configuration.py
================================================
#   This Python module is part of the PyRate software package.
#
#   Copyright 2022 Geoscience Australia
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.
"""
This Python module contains utilities to validate user input parameters
parsed in a PyRate configuration file.
"""
import re
from configparser import ConfigParser
from pathlib import Path, PurePath
from typing import Union

import pyrate.constants as C
from pyrate.constants import NO_OF_PARALLEL_PROCESSES, sixteen_digits_pattern, twelve_digits_pattern, ORB_ERROR_DIR, \
    DEM_ERROR_DIR, TEMP_MLOOKED_DIR
from pyrate.core import ifgconstants as ifg
from pyrate.default_parameters import PYRATE_DEFAULT_CONFIGURATION
from pyrate.core.algorithm import factorise_integer
from pyrate.core.shared import extract_epochs_from_filename, InputTypes, get_tiles


def set_parameter_value(data_type, input_value, default_value, required, input_name):
    if len(input_value) < 1:
        input_value = None
        if required:  # pragma: no cover
            raise ValueError("A required parameter is missing value in input configuration file: " + str(input_name))

    if input_value is not None:
        if str(data_type) in "path":
            return Path(input_value)
        return data_type(input_value)
    return default_value


def validate_parameter_value(input_name, input_value, min_value=None, max_value=None, possible_values=None):
    if isinstance(input_value, PurePath):
        if not Path.exists(input_value):  # pragma: no cover
            raise ValueError("Given path: " + str(input_value) + " does not exist.")
    if input_value is not None:
        if min_value is not None:
            if input_value < min_value:  # pragma: no cover
                raise ValueError(
                    "Invalid value for " + str(input_name) + " supplied: " + str(
                        input_value) + ". Provide a value greater than or equal to " + str(min_value) + ".")
    if input_value is not None:
        if max_value is not None:
            if input_value > max_value:  # pragma: no cover
                raise ValueError(
                    "Invalid value for " + str(input_name) + " supplied: " + str(
                        input_value) + ". Provide a value less than or equal to " + str(max_value) + ".")

    if possible_values is not None:
        if input_value not in possible_values:  # pragma: no cover
            raise ValueError(
                "Invalid value for " + str(input_name) + " supplied: " + str(
                    input_value) + ". Provide one of these values: " + str(possible_values) + ".")
    return True


def validate_file_list_values(file_list, no_of_epochs):
    if file_list is None:  # pragma: no cover
        raise ValueError("No value supplied for input file list: " + str(file_list))

    files = parse_namelist(file_list)

    for f in files:
        if not Path(f).exists():  # pragma: no cover
            raise ConfigException(f"{f} does not exist")
        else:
            matches = extract_epochs_from_filename(filename_with_epochs=f)
            if len(matches) < no_of_epochs:  # pragma: no cover
                raise ConfigException(f"the number of epochs in {f} names are less the required number: {no_of_epochs}")


class MultiplePaths:
    def __init__(self, file_name: str, params: dict, input_type: InputTypes = InputTypes.IFG):

        self.input_type = input_type
        out_dir = params[C.OUT_DIR]
        tempdir = params[C.TEMP_MLOOKED_DIR]
        if isinstance(tempdir, str):
            tempdir = Path(tempdir)
        b = Path(file_name)
        if input_type in [InputTypes.IFG, InputTypes.COH]:
            d = re.search(sixteen_digits_pattern, b.stem)
            if d is None:  # could be 6 digit epoch dates
                d = re.search(twelve_digits_pattern, b.stem)
            if d is None:
                raise ValueError(f"{input_type.value} filename does not contain two 8- or 6-digit date strings")
            filestr = d.group() + '_'
        else:
            filestr = ''

        dir_exists = input_type.value in InputTypes.dir_map.value.keys()
        anchoring_dir = Path(out_dir).joinpath(InputTypes.dir_map.value[input_type.value]) \
            if dir_exists else Path(out_dir)

        if b.suffix == ".tif":
            self.unwrapped_path = None
            converted_path = b  # original file
            self.sampled_path = anchoring_dir.joinpath(filestr + input_type.value + '.tif')
        else:
            self.unwrapped_path = b.as_posix()
            converted_path = anchoring_dir.joinpath(b.stem.split('.')[0] + '_' + b.suffix[1:]).with_suffix('.tif')
            self.sampled_path = converted_path.with_name(filestr + input_type.value + '.tif')

        # tmp_sampled_paths are used after prepifg, during correct steps
        self.tmp_sampled_path = tempdir.joinpath(self.sampled_path.name).as_posix()
        self.converted_path = converted_path.as_posix()
        self.sampled_path = self.sampled_path.as_posix()

    @staticmethod
    def orb_error_path(ifg_path: Union[str, Path], params) -> Path:
        if isinstance(ifg_path, str):
            ifg_path = Path(ifg_path)
        return Path(params[C.OUT_DIR], C.ORB_ERROR_DIR,
                    ifg_path.stem + '_' +
                    '_'.join([str(params[C.ORBITAL_FIT_METHOD]),
                              str(params[C.ORBITAL_FIT_DEGREE]),
                              str(params[C.ORBITAL_FIT_LOOKS_X]),
                              str(params[C.ORBITAL_FIT_LOOKS_Y])]) +
                    '_orbfit.npy')

    @staticmethod
    def dem_error_path(ifg_path: Union[str, Path], params) -> Path:
        if isinstance(ifg_path, str):
            ifg_path = Path(ifg_path)
        return Path(params[C.OUT_DIR], C.DEM_ERROR_DIR,
                    ifg_path.stem + '_' + str(params[C.DE_PTHR]) + '_dem_error.npy')

    @staticmethod
    def aps_error_path(ifg_path: Union[str, Path], params) -> Path:
        if isinstance(ifg_path, str):
            ifg_path = Path(ifg_path)
        return Path(params[C.OUT_DIR], C.APS_ERROR_DIR,
                    ifg_path.stem + '_' +
                    '_'.join([str(x) for x in [
                        params[C.SLPF_CUTOFF],
                        params[C.SLPF_NANFILL],
                        params[C.SLPF_NANFILL_METHOD],
                        params[C.TLPF_CUTOFF],
                        params[C.TLPF_PTHR]
                    ]
                              ]) + '_aps_error.npy')

    def __str__(self):  # pragma: no cover
        st = ""
        if self.unwrapped_path is not None:
            st += """\nunwrapped_path = """ + self.unwrapped_path
        else:
            st += """\nunwrapped_path = None"""
        st += """
            converted_path = """ + self.converted_path + """ 
            sampled_path = """ + self.sampled_path + """    
            tmp_sampled_path = """ + self.tmp_sampled_path + """
            """
        return st


class Configuration:

    def __init__(self, config_file_path):

        parser = ConfigParser()
        parser.optionxform = str
        # mimic header to fulfil the requirement for configparser
        with open(config_file_path) as stream:
            parser.read_string("[root]\n" + stream.read())

        for key, value in parser["root"].items():
            self.__dict__[key] = value

        # make output path, if not provided will error
        Path(self.outdir).mkdir(exist_ok=True, parents=True)

        # custom correct sequence if 'correct' section is provided in config
        if 'correct' in parser and 'steps' in parser['correct']:
            self.__dict__['correct'] = list(filter(None, parser['correct'].get('steps').splitlines()))
        else:
            self.__dict__['correct'] = [
                'orbfit',
                'refphase',
                'demerror',
                'phase_closure',
                'mst',
                'apscorrect',
                'maxvar',
            ]

        # Validate required parameters exist.

        required = {k for k, v in PYRATE_DEFAULT_CONFIGURATION.items() if v['Required']}

        if not required.issubset(self.__dict__):  # pragma: no cover
            raise ValueError("Required configuration parameters: " + str(
                required.difference(self.__dict__)) + " are missing from input config file.")

        # handle control parameters
        for parameter_name in PYRATE_DEFAULT_CONFIGURATION:
            param_value = self.__dict__[parameter_name] if parameter_name in required or \
                                                           parameter_name in self.__dict__ else ''

            self.__dict__[parameter_name] = set_parameter_value(
                PYRATE_DEFAULT_CONFIGURATION[parameter_name]["DataType"],
                param_value,
                PYRATE_DEFAULT_CONFIGURATION[parameter_name]["DefaultValue"],
                PYRATE_DEFAULT_CONFIGURATION[parameter_name]["Required"],
                parameter_name)
            validate_parameter_value(parameter_name, self.__dict__[parameter_name],
                                     PYRATE_DEFAULT_CONFIGURATION[parameter_name]["MinValue"],
                                     PYRATE_DEFAULT_CONFIGURATION[parameter_name]["MaxValue"],
                                     PYRATE_DEFAULT_CONFIGURATION[parameter_name]["PossibleValues"])

        # bespoke parameter validation
        if self.refchipsize % 2 != 1:  # pragma: no cover
            if self.refchipsize - 1 > 1:
                # Configuration parameters refchipsize must be odd
                # values too large (>101) will slow down the process without significant gains in results.
                self.refchipsize = self.refchipsize - 1

        # calculate rows and cols if not supplied
        if hasattr(self, 'rows') and hasattr(self, 'cols'):
            self.rows, self.cols = int(self.rows), int(self.cols)
        else:
            if NO_OF_PARALLEL_PROCESSES > 1:  # i.e. mpirun
                self.rows, self.cols = [int(num) for num in factorise_integer(NO_OF_PARALLEL_PROCESSES)]
            else:
                if self.parallel:  # i.e. joblib parallelism
                    self.rows, self.cols = [int(num) for num in factorise_integer(self.processes)]
                else:  # i.e. serial
                    self.rows, self.cols = 1, 1

        # create a temporary directory if not supplied
        if not hasattr(self, 'tmpdir'):
            self.tmpdir = Path(self.outdir).joinpath("tmpdir")
        else:
            self.tmpdir = Path(self.tmpdir)

        self.tmpdir.mkdir(parents=True, exist_ok=True)

        # create orbfit error dir
        self.orb_error_dir = Path(self.outdir).joinpath(ORB_ERROR_DIR)
        self.orb_error_dir.mkdir(parents=True, exist_ok=True)

        self.interferogram_dir = Path(self.outdir).joinpath(C.INTERFEROGRAM_DIR)
        self.interferogram_dir.mkdir(parents=True, exist_ok=True)

        # create DEM error dir
        self.dem_error_dir = Path(self.outdir).joinpath(DEM_ERROR_DIR)
        self.dem_error_dir.mkdir(parents=True, exist_ok=True)

        # create aps error dir
        self.aps_error_dir = Path(self.outdir).joinpath(C.APS_ERROR_DIR)
        self.aps_error_dir.mkdir(parents=True, exist_ok=True)

        # create mst dir
        self.mst_dir = Path(self.outdir).joinpath(C.MST_DIR)
        self.mst_dir.mkdir(parents=True, exist_ok=True)

        self.phase_closure_dir = Path(self.outdir).joinpath(C.PHASE_CLOSURE_DIR)
        self.phase_closure_dir.mkdir(parents=True, exist_ok=True)

        self.coherence_dir = Path(self.outdir).joinpath(C.COHERENCE_DIR)
        self.coherence_dir.mkdir(parents=True, exist_ok=True)

        self.geometry_dir = Path(self.outdir).joinpath(C.GEOMETRY_DIR)
        self.geometry_dir.mkdir(parents=True, exist_ok=True)

        self.timeseries_dir = Path(self.outdir).joinpath(C.TIMESERIES_DIR)
        self.timeseries_dir.mkdir(parents=True, exist_ok=True)

        self.velocity_dir = Path(self.outdir).joinpath(C.VELOCITY_DIR)
        self.velocity_dir.mkdir(parents=True, exist_ok=True)

        # create temp multilooked files dir
        self.temp_mlooked_dir = Path(self.outdir).joinpath(TEMP_MLOOKED_DIR)
        self.temp_mlooked_dir.mkdir(parents=True, exist_ok=True)

        self.ref_pixel_file = self.ref_pixel_path(self.__dict__)

        # var no longer used
        self.APS_ELEVATION_EXT = None
        self.APS_INCIDENCE_EXT = None
        self.apscorrect = 0
        self.apsmethod = 0
        self.elevationmap = None
        self.incidencemap = None

        # define parallel processes that will run
        self.NUMEXPR_MAX_THREADS = str(NO_OF_PARALLEL_PROCESSES)

        # Validate file names supplied in list exist and contain correct epochs in file names
        if self.cohfilelist is not None:
            # if self.processor != 0:  # not roipac
            validate_file_list_values(self.cohfilelist, 1)
            self.coherence_file_paths = self.__get_files_from_attr('cohfilelist', input_type=InputTypes.COH)

        if self.basefilelist is not None:
            # if self.processor != 0:  # not roipac
            validate_file_list_values(self.basefilelist, 1)
            self.baseline_file_paths = self.__get_files_from_attr('basefilelist', input_type=InputTypes.BASE)

        self.header_file_paths = self.__get_files_from_attr('hdrfilelist', input_type=InputTypes.HEADER)

        self.interferogram_files = self.__get_files_from_attr('ifgfilelist')

        self.dem_file = MultiplePaths(self.demfile, self.__dict__, input_type=InputTypes.DEM)

        # backward compatibility for string paths
        for key in self.__dict__:
            if isinstance(self.__dict__[key], PurePath):
                self.__dict__[key] = str(self.__dict__[key])

    @staticmethod
    def ref_pixel_path(params):
        return Path(params[C.OUT_DIR]).joinpath(
            '_'.join(
                [str(x) for x in [
                    'ref_pixel', params[C.REFX], params[C.REFY], params[
                        C.REFNX], params[C.REFNY],
                    params[C.REF_CHIP_SIZE], params[C.REF_MIN_FRAC], '.npy'
                ]
                 ]
            )
        )

    @staticmethod
    def mst_path(params, index) -> Path:
        return Path(params[C.OUT_DIR], C.MST_DIR).joinpath(f'mst_mat_{index}.npy')

    @staticmethod
    def preread_ifgs(params: dict) -> Path:
        return Path(params[C.TMPDIR], 'preread_ifgs.pk')

    @staticmethod
    def vcmt_path(params):
        return Path(params[C.OUT_DIR], C.VCMT).with_suffix('.npy')

    @staticmethod
    def phase_closure_filtered_ifgs_list(params):
        return Path(params[C.TEMP_MLOOKED_DIR]).joinpath('phase_closure_filtered_ifgs_list')

    def refresh_ifg_list(self, params):  # update params dict
        filtered_ifgs_list = self.phase_closure_filtered_ifgs_list(params)
        files = parse_namelist(filtered_ifgs_list.as_posix())
        params[C.INTERFEROGRAM_FILES] = [MultiplePaths(p, self.__dict__, input_type=InputTypes.IFG) for p in files]
        return params

    @staticmethod
    def ref_phs_file(params):
        ref_pixel_path = Configuration.ref_pixel_path(params)
        # add ref pixel path as when ref pixel changes - ref phs path should also change
        return Path(params[C.OUT_DIR]).joinpath(
            ref_pixel_path.stem + '_' +
            '_'.join(['ref_phs', str(params[C.REF_EST_METHOD]), '.npy'])
        )

    @staticmethod
    def get_tiles(params):
        ifg_path = params[C.INTERFEROGRAM_FILES][0].sampled_path
        rows, cols = params['rows'], params['cols']
        return get_tiles(ifg_path, rows, cols)

    def __get_files_from_attr(self, attr, input_type=InputTypes.IFG):
        val = self.__getattribute__(attr)
        files = parse_namelist(val)
        return [MultiplePaths(p, self.__dict__, input_type=input_type) for p in files]

    def closure(self):
        closure_d = Path(self.phase_closure_dir)

        class Closure:
            def __init__(self):
                self.closure = closure_d.joinpath('closure.npy')
                self.ifgs_breach_count = closure_d.joinpath('ifgs_breach_count.npy')
                self.num_occurences_each_ifg = closure_d.joinpath('num_occurrences_each_ifg.npy')
                self.loops = closure_d.joinpath('loops.npy')

        return Closure()

    @staticmethod
    def coherence_stats(params):
        coh_d = Path(params[C.COHERENCE_DIR])
        return {k: coh_d.joinpath(k.lower() + '.tif').as_posix() for k in [ifg.COH_MEDIAN, ifg.COH_MEAN, ifg.COH_STD]}

    @staticmethod
    def geometry_files(params):
        geom_dir = Path(params[C.GEOMETRY_DIR])
        return {k: geom_dir.joinpath(k.lower() + '.tif').as_posix() for k in C.GEOMETRY_OUTPUT_TYPES}


def write_config_parser_file(conf: ConfigParser, output_conf_file: Union[str, Path]):
    """replacement function for write_config_file which uses dict instead of a ConfigParser instance"""
    with open(output_conf_file, 'w') as configfile:
        conf.write(configfile)


def write_config_file(params, output_conf_file):
    """
    Takes a param object and writes the config file. Reverse of get_conf_params.

    :param dict params: parameter dictionary
    :param str output_conf_file: output file name

    :return: config file
    :rtype: list
    """
    with open(output_conf_file, 'w') as f:
        for k, v in params.items():
            if v is not None:
                if k == 'correct':
                    f.write(''.join(['[', k, ']' ':\t', '', '\n']))
                    f.write(''.join(['steps = ', '\n']))
                    for vv in v:
                        f.write(''.join(['\t' + str(vv), '\n']))
                elif isinstance(v, list):
                    continue
                else:
                    if isinstance(v, MultiplePaths):
                        if v.unwrapped_path is None:
                            vv = v.converted_path
                        else:
                            vv = v.unwrapped_path
                    else:
                        vv = v
                    f.write(''.join([k, ':\t', str(vv), '\n']))
            else:
                f.write(''.join([k, ':\t', '', '\n']))


def parse_namelist(nml):
    """
    Parses name list file into array of paths

    :param str nml: interferogram file list

    :return: list of interferogram file names
    :rtype: list
    """
    with open(nml) as f_in:
        lines = [line.rstrip() for line in f_in]
    return filter(None, lines)


class ConfigException(Exception):
    """
    Default exception class for configuration errors.
    """



================================================
FILE: pyrate/constants.py
================================================
import os
import re
from pathlib import Path
import numpy as np

PYRATEPATH = Path(__file__).parent.parent


__version__ = "0.6.0"
CLI_DESCRIPTION = """
PyRate workflow: 

    Step 1: conv2tif
    Step 2: prepifg
    Step 3: correct
    Step 4: timeseries
    Step 5: stack
    Step 6: merge

Refer to https://geoscienceaustralia.github.io/PyRate/usage.html for 
more details.
"""

from pyrate.core.mpiops import comm

NO_OF_PARALLEL_PROCESSES = comm.Get_size()

CONV2TIF = 'conv2tif'
PREPIFG = 'prepifg'
CORRECT = 'correct'
TIMESERIES = 'timeseries'
STACK = 'stack'
MERGE = 'merge'

# distance division factor of 1000 converts to km and is needed to match legacy output
DISTFACT = 1000
# mappings for metadata in header for interferogram
GAMMA_DATE = 'date'
GAMMA_TIME = 'center_time'
GAMMA_WIDTH = 'width'
GAMMA_NROWS = 'nlines'
GAMMA_CORNER_LAT = 'corner_lat'
GAMMA_CORNER_LONG = 'corner_lon'
GAMMA_Y_STEP = 'post_lat'
GAMMA_X_STEP = 'post_lon'
GAMMA_DATUM = 'ellipsoid_name'
GAMMA_FREQUENCY = 'radar_frequency'
GAMMA_INCIDENCE = 'incidence_angle'
GAMMA_HEADING = 'heading'
GAMMA_AZIMUTH = 'azimuth_angle'
GAMMA_RANGE_PIX = 'range_pixel_spacing'
GAMMA_RANGE_N = 'range_samples'
GAMMA_AZIMUTH_PIX = 'azimuth_pixel_spacing'
GAMMA_AZIMUTH_N = 'azimuth_lines'
GAMMA_AZIMUTH_LOOKS = 'azimuth_looks'
GAMMA_PRF = 'prf'
GAMMA_NEAR_RANGE = 'near_range_slc'
GAMMA_SAR_EARTH = 'sar_to_earth_center'
GAMMA_SEMI_MAJOR_AXIS = 'earth_semi_major_axis'
GAMMA_SEMI_MINOR_AXIS = 'earth_semi_minor_axis'
GAMMA_PRECISION_BASELINE = 'precision_baseline(TCN)'
GAMMA_PRECISION_BASELINE_RATE = 'precision_baseline_rate'
# RADIANS = 'RADIANS'
# GAMMA = 'GAMMA'
# value assigned to no-data-value
LOW_FLOAT32 = np.finfo(np.float32).min*1e-10

SIXTEEN_DIGIT_EPOCH_PAIR = r'\d{8}-\d{8}'
sixteen_digits_pattern = re.compile(SIXTEEN_DIGIT_EPOCH_PAIR)
TWELVE_DIGIT_EPOCH_PAIR = r'\d{6}-\d{6}'
twelve_digits_pattern = re.compile(TWELVE_DIGIT_EPOCH_PAIR)

# general constants

NO_MULTILOOKING = 1
ROIPAC = 0
GAMMA = 1
LOG_LEVEL = 'INFO'

# constants for lookups
#: STR; Name of input interferogram list file
IFG_FILE_LIST = 'ifgfilelist'
#: (0/1/2); The interferogram processor used (0==ROIPAC, 1==GAMMA, 2: GEOTIF)
PROCESSOR = 'processor'

#: STR; Name of directory for saving output products
OUT_DIR = 'outdir'
#: STR; Name of Digital Elevation Model file
DEM_FILE = 'demfile'
#: STR; Name of the DEM header file
DEM_HEADER_FILE = 'demHeaderFile'

#: STR; Name of the file list containing the pool of available header files
HDR_FILE_LIST = 'hdrfilelist'

INTERFEROGRAM_FILES = 'interferogram_files'
HEADER_FILE_PATHS = 'header_file_paths'
COHERENCE_FILE_PATHS = 'coherence_file_paths'
BASELINE_FILE_PATHS = 'baseline_file_paths'
DEM_FILE_PATH = 'dem_file'


# STR; The projection of the input interferograms.
# TODO: only used in tests; deprecate?
INPUT_IFG_PROJECTION = 'projection'
#: FLOAT; The no data value in the interferogram files.
NO_DATA_VALUE = 'noDataValue'
#: FLOAT; No data averaging threshold for prepifg
NO_DATA_AVERAGING_THRESHOLD = 'noDataAveragingThreshold'
# BOOL (1/2/3); Re-project data from Line of sight, 1 = vertical, 2 = horizontal, 3 = no conversion
# REPROJECTION = 'prjflag' # NOT CURRENTLY USED
#: BOOL (0/1): Convert no data values to Nan
NAN_CONVERSION = 'nan_conversion'

# Prepifg parameters
#: BOOL (1/2/3/4); Method for cropping interferograms, 1 = minimum overlapping area (intersection), 2 = maximum area (union), 3 = customised area, 4 = all ifgs already same size
IFG_CROP_OPT = 'ifgcropopt'
#: INT; Multi look factor for interferogram preparation in x dimension
IFG_LKSX = 'ifglksx'
#: INT; Multi look factor for interferogram preparation in y dimension
IFG_LKSY = 'ifglksy'
#: FLOAT; Minimum longitude for cropping with method 3
IFG_XFIRST = 'ifgxfirst'
#: FLOAT; Maximum longitude for cropping with method 3
IFG_XLAST = 'ifgxlast'
#: FLOAT; Minimum latitude for cropping with method 3
IFG_YFIRST = 'ifgyfirst'
#: FLOAT; Maximum latitude for cropping with method 3
IFG_YLAST = 'ifgylast'

# reference pixel parameters
#: INT; Longitude (decimal degrees) of reference pixel, or if left blank a search will be performed
REFX = 'refx'
REFX_FOUND = 'refxfound'
#: INT; Latitude (decimal degrees) of reference pixel, or if left blank a search will be performed
REFY = 'refy'
REFY_FOUND = 'refyfound'
#: INT; Number of reference pixel grid search nodes in x dimension
REFNX = "refnx"
#: INT; Number of reference pixel grid search nodes in y dimension
REFNY = "refny"
#: INT; Dimension of reference pixel search window (in number of pixels)
REF_CHIP_SIZE = 'refchipsize'
#: FLOAT; Minimum fraction of observations required in search window for pixel to be a viable reference pixel
REF_MIN_FRAC = 'refminfrac'
#: BOOL (1/2); Reference phase estimation method (1: median of the whole interferogram, 2: median within the window surrounding the reference pixel)
REF_EST_METHOD = 'refest'

MAXVAR = 'maxvar'
VCMT = 'vcmt'
PREREAD_IFGS = 'preread_ifgs'
TILES = 'tiles'

# coherence masking parameters
#: BOOL (0/1); Perform coherence masking (1: yes, 0: no)
COH_MASK = 'cohmask'
#: FLOAT; Coherence threshold for masking
COH_THRESH = 'cohthresh'

#: STR; Name of the file list containing the pool of available coherence files
COH_FILE_LIST = 'cohfilelist'

# baseline parameters
#: STR; Directory containing baseline files
BASE_FILE_DIR = 'basefiledir'
#: STR; Name of the file list containing the pool of available baseline files
BASE_FILE_LIST = 'basefilelist'

#: STR; Name of the file containing the GAMMA lookup table between lat/lon and radar coordinates (row/col)
LT_FILE = 'ltfile'

# atmospheric error correction parameters NOT CURRENTLY USED
APS_CORRECTION = 'apscorrect'
APS_METHOD = 'apsmethod'
APS_INCIDENCE_MAP = 'incidencemap'
APS_INCIDENCE_EXT = 'APS_INCIDENCE_EXT'
APS_ELEVATION_MAP = 'elevationmap'
APS_ELEVATION_EXT = 'APS_ELEVATION_EXT'


# phase closure
PHASE_CLOSURE = 'phase_closure'
CLOSURE_THR = 'closure_thr'
IFG_DROP_THR = 'ifg_drop_thr'
MIN_LOOPS_PER_IFG = 'min_loops_per_ifg'
MAX_LOOP_LENGTH = 'max_loop_length'
MAX_LOOP_REDUNDANCY = 'max_loop_redundancy'
SUBTRACT_MEDIAN = 'subtract_median'

# orbital error correction/parameters
#: BOOL (1/0); Perform orbital error correction (1: yes, 0: no)
ORBITAL_FIT = 'orbfit'
#: BOOL (1/2); Method for orbital error correction (1: independent, 2: network)
ORBITAL_FIT_METHOD = 'orbfitmethod'
#: BOOL (1/2/3) Polynomial order of orbital error model (1: planar in x and y - 2 parameter model, 2: quadratic in x and y - 5 parameter model, 3: quadratic in x and cubic in y - part-cubic 6 parameter model)
ORBITAL_FIT_DEGREE = 'orbfitdegrees'
#: INT; Multi look factor for orbital error calculation in x dimension
ORBITAL_FIT_LOOKS_X = 'orbfitlksx'
#: INT; Multi look factor for orbital error calculation in y dimension
ORBITAL_FIT_LOOKS_Y = 'orbfitlksy'
#: BOOL (1/0); Estimate interferogram offsets during orbit correction design matrix (1: yes, 0: no)
ORBFIT_OFFSET = 'orbfitoffset'
#: FLOAT; Scaling parameter for orbital correction design matrix
ORBFIT_SCALE = 'orbfitscale'
ORBFIT_INTERCEPT = 'orbfitintercept'

# Stacking parameters
#: FLOAT; Threshold ratio between 'model minus observation' residuals and a-priori observation standard deviations for stacking estimate acceptance (otherwise remove furthest outlier and re-iterate)
LR_NSIG = 'nsig'
#: INT; Number of required observations per pixel for stacking to occur
LR_PTHRESH = 'pthr'
#: FLOAT; Maximum allowable standard error for pixels in stacking
LR_MAXSIG = 'maxsig'

# atmospheric delay errors fitting parameters NOT CURRENTLY USED
# atmfitmethod = 1: interferogram by interferogram; atmfitmethod = 2, epoch by epoch
# ATM_FIT = 'atmfit'
# ATM_FIT_METHOD = 'atmfitmethod'

# APS correction parameters
#: BOOL (0/1) Perform APS correction (1: yes, 0: no)
APSEST = 'apsest'
# temporal low-pass filter parameters
#: FLOAT; Cutoff time for gaussian filter in days;
TLPF_CUTOFF = 'tlpfcutoff'
#: INT; Number of required input observations per pixel for temporal filtering
TLPF_PTHR = 'tlpfpthr'
# spatially correlated noise low-pass filter parameters
#: FLOAT; Cutoff  value for both butterworth and gaussian filters in km
SLPF_CUTOFF = 'slpfcutoff'
#: INT (1/0); Do spatial interpolation at NaN locations (1 for interpolation, 0 for zero fill)
SLPF_NANFILL = 'slpnanfill'
#: #: STR; Method for spatial interpolation (one of: linear, nearest, cubic), only used when slpnanfill=1
SLPF_NANFILL_METHOD = 'slpnanfill_method'

# DEM error correction parameters
#: BOOL (0/1) Perform DEM error correction (1: yes, 0: no)
DEMERROR = 'demerror'
#: INT; Number of required input observations per pixel for DEM error estimation
DE_PTHR = 'de_pthr'

# Time series parameters
#: INT (1/2); Method for time series inversion (1: Laplacian Smoothing; 2: SVD)
TIME_SERIES_METHOD = 'tsmethod'
#: INT; Number of required input observations per pixel for time series inversion
TIME_SERIES_PTHRESH = 'ts_pthr'
#: INT (1/2); Order of Laplacian smoothing operator, first or second order
TIME_SERIES_SM_ORDER = 'smorder'
#: FLOAT; Laplacian smoothing factor (values used is 10**smfactor)
TIME_SERIES_SM_FACTOR = 'smfactor'
# tsinterp is automatically assigned in the code; not needed in conf file
# TIME_SERIES_INTERP = 'tsinterp'

#: BOOL (0/1/2); Use parallelisation/Multi-threading (0: in serial, 1: in parallel by rows, 2: in parallel by pixel)
PARALLEL = 'parallel'
#: INT; Number of processes for multi-threading
PROCESSES = 'processes'
LARGE_TIFS = 'largetifs'
# Orbital error correction constants for conversion to readable strings
INDEPENDENT_METHOD = 1
NETWORK_METHOD = 2
PLANAR = 1
QUADRATIC = 2
PART_CUBIC = 3

# Orbital error name look up for logging
ORB_METHOD_NAMES = {INDEPENDENT_METHOD: 'INDEPENDENT',
                    NETWORK_METHOD: 'NETWORK'}
ORB_DEGREE_NAMES = {PLANAR: 'PLANAR',
                    QUADRATIC: 'QUADRATIC',
                    PART_CUBIC: 'PART CUBIC'}

# geometry outputs
GEOMETRY_OUTPUT_TYPES = ['rdc_azimuth', 'rdc_range', 'look_angle', 'incidence_angle', 'azimuth_angle', 'range_dist']

# sign convention for phase data
SIGNAL_POLARITY = 'signal_polarity'

# LOS projection
LOS_PROJECTION = 'los_projection'

# Number of sigma to report velocity error
VELERROR_NSIG = 'velerror_nsig'

# dir for temp files
TMPDIR = 'tmpdir'

# Lookup to help convert args to correct type/defaults
# format is	key : (conversion, default value)
# None = no conversion

# filenames reused in  many parts of the program
REF_PIXEL_FILE = 'ref_pixel_file'
ORB_ERROR_DIR = 'orb_error_dir'
DEM_ERROR_DIR = 'dem_error_dir'
APS_ERROR_DIR = 'aps_error_dir'
PHASE_CLOSURE_DIR = 'phase_closure_dir'
MST_DIR = 'mst_dir'
TEMP_MLOOKED_DIR = 'temp_mlooked_dir'
COHERENCE_DIR = 'coherence_dir'
INTERFEROGRAM_DIR = 'interferogram_dir'
GEOMETRY_DIR = 'geometry_dir'
TIMESERIES_DIR = 'timeseries_dir'
VELOCITY_DIR = 'velocity_dir'



================================================
FILE: pyrate/conv2tif.py
================================================
#   This Python module is part of the PyRate software package.
#
#   Copyright 2022 Geoscience Australia
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.
"""
This Python script converts ROI_PAC or GAMMA format input interferograms 
into geotiff format files
"""
# -*- coding: utf-8 -*-
import os
from typing import Tuple, List
from joblib import Parallel, delayed
import numpy as np
from pathlib import Path

import pyrate.constants as C
from pyrate.core.prepifg_helper import PreprocessError
from pyrate.core import shared, mpiops, gamma, roipac
from pyrate.core import ifgconstants as ifc
from pyrate.core.logger import pyratelogger as log
from pyrate.configuration import MultiplePaths
from pyrate.core.shared import mpi_vs_multiprocess_logging

GAMMA = 1
ROIPAC = 0
GEOTIF = 2


def main(params):
    """
    Parse parameters and prepare files for conversion.

    :param dict params: Parameters dictionary read in from the config file
    """
    # TODO: looks like base_ifg_paths are ordered according to ifg list
    # This probably won't be a problem because input list won't be reordered
    # and the original gamma generated list is ordered) this may not affect
    # the important pyrate stuff anyway, but might affect gen_thumbs.py.
    # Going to assume base_ifg_paths is ordered correcly
    # pylint: disable=too-many-branches

    if params[C.PROCESSOR] == 2:  # if geotif
        log.warning("'conv2tif' step not required for geotiff!")
        return

    mpi_vs_multiprocess_logging("conv2tif", params)

    base_ifg_paths = params[C.INTERFEROGRAM_FILES]

    if params[C.COH_FILE_LIST] is not None:
        base_ifg_paths.extend(params[C.COHERENCE_FILE_PATHS])

    if params[C.DEM_FILE] is not None:  # optional DEM conversion
        base_ifg_paths.append(params[C.DEM_FILE_PATH])

    process_base_ifgs_paths = np.array_split(base_ifg_paths, mpiops.size)[mpiops.rank]
    gtiff_paths = do_geotiff(process_base_ifgs_paths, params)
    mpiops.comm.barrier()
    log.info("Finished 'conv2tif' step")
    return gtiff_paths


def do_geotiff(unw_paths: List[MultiplePaths], params: dict) -> List[str]:
    """
    Convert input interferograms to geotiff format.
    """
    # pylint: disable=expression-not-assigned
    log.info("Converting input interferograms to geotiff")
    parallel = params[C.PARALLEL]

    if parallel:
        log.info("Running geotiff conversion in parallel with {} processes".format(params[C.PROCESSES]))
        dest_base_ifgs = Parallel(n_jobs=params[C.PROCESSES], verbose=shared.joblib_log_level(
            C.LOG_LEVEL))(
            delayed(_geotiff_multiprocessing)(p, params) for p in unw_paths)
    else:
        log.info("Running geotiff conversion in serial")
        dest_base_ifgs = [_geotiff_multiprocessing(b, params) for b in unw_paths]
    return dest_base_ifgs


def _geotiff_multiprocessing(unw_path: MultiplePaths, params: dict) -> Tuple[str, bool]:
    """
    Multiprocessing wrapper for full-res geotiff conversion
    """
    # TODO: Need a more robust method for identifying coherence files.
    dest = unw_path.converted_path
    processor = params[C.PROCESSOR]  # roipac or gamma

    # Create full-res geotiff if not already on disk
    if not os.path.exists(dest):
        if processor == GAMMA:
            header = gamma.gamma_header(unw_path.unwrapped_path, params)
        elif processor == ROIPAC:
            log.info("Warning: ROI_PAC support will be deprecated in a future PyRate release")
            header = roipac.roipac_header(unw_path.unwrapped_path, params)
        else:
            raise PreprocessError('Processor must be ROI_PAC (0) or GAMMA (1)')
        header[ifc.INPUT_TYPE] = unw_path.input_type
        shared.write_fullres_geotiff(header, unw_path.unwrapped_path, dest, nodata=params[
            C.NO_DATA_VALUE])
        Path(dest).chmod(0o444)  # readonly output
        return dest, True
    else:
        log.warning(f"Full-res geotiff already exists in {dest}! Returning existing geotiff!")
        return dest, False


================================================
FILE: pyrate/core/.coveragerc
================================================
[run]
plugins = Cython.Coverage
source = pyrate
omit = aps.py
branch = True

[report]
exclude_lines =
    pragma: no cover
    def __repr__
    raise AssertionError
    raise NotImplementedError
    if __name__ == .__main__.:

================================================
FILE: pyrate/core/__init__.py
================================================


================================================
FILE: pyrate/core/algorithm.py
================================================
#   This Python module is part of the PyRate software package.
#
#   Copyright 2022 Geoscience Australia
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.
"""
This Python module contains a collection of generic algorithms used in PyRate
"""
from typing import Union, Iterable, Dict, Tuple
from numpy import sin, cos, unique, histogram, diag, dot
from scipy.linalg import qr, solve, lstsq
from pyrate.core.shared import EpochList, IfgException, PrereadIfg
from pyrate.core.ifgconstants import DAYS_PER_YEAR


def is_square(arr):
    """
    Determines whether an array is square or not.

    :param ndarray arr: numpy array

    :return: condition
    :rtype: bool
    """

    shape = arr.shape
    if len(shape) == 2 and (shape[0] == shape[1]):
        return True
    return False


def least_squares_covariance(A, b, v):
    """
    Least squares solution in the presence of known covariance.

    :param ndarray A: Design matrix
    :param ndarray b: Observations (vector of phase values)
    :param ndarray v: Covariances (vector of weights)

    :return: solution
    :rtype: ndarray
    """

    # pylint: disable=too-many-locals
    # X = LSCOV(A,b,V) returns the vector X that minimizes
    # (A*X-b)'*inv(V)*(A*X-b) for the case in which length(b) > length(X).
    # This is the over-determined least squares problem with covariance V.
    # The solution is found without needing to invert V which is a square
    # symmetric matrix with dimensions equal to length(b).
    #
    # The classical linear algebra solution to this problem is:
    #
    #     x = inv(A'*inv(V)*A)*A'*inv(V)*b
    #
    # Reference:
    # G. Strang, "Introduction to Applied Mathematics",
    # Wellesley-Cambridge, p. 398, 1986.
    # L. S hure 3-31-89

    # convert vectors to 2D singleton array
    if len(A.shape) != 2:
        raise ValueError('')

    m, n = A.shape
    if m <= n:
        raise ValueError('Problem must be over-determined')

    V = diag(1.0 / v.squeeze())
    q, r = qr(A)  # Orthogonal-triangular Decomposition
    efg = dot(q.T, dot(V, q))  # TODO: round it??
    g = efg[n:, n:]  # modified to 0 indexing
    cd = dot(q.T, b)  # q.T * b
    f = efg[:n, n:]  # TODO: check +1/indexing
    c = cd[:n]  # modified to 0 indexing
    d = cd[n:]  # modified to 0 indexing
    r = r[:n, :n]  # modified to 0 indexing

    func = solve if is_square(g) else lstsq
    tmp = func(g, d)
    func = solve if is_square(r) else lstsq
    return func(r, (c-f * tmp))


def los_conversion(phase_data, unit_vec):
    """
    Converts phase from line-of-sight (LOS) to horizontal/vertical components.

    :param ndarray phase_data: Phase band data array (eg. ifg.phase_data)
    :param tuple unit_vec: 3 component unit vector e.g. (EW, NS, vertical)

    :return: converted_phase
    :rtype: ndarray
    """

    # NB: currently not tested as implementation is too simple
    return phase_data * unit_vec


def unit_vector(incidence, azimuth):
    """
    Returns unit vector tuple (east_west, north_south, vertical).

    :param float incidence: incidence angle w.r.t. nadir
    :param float azimuth: azimuth of looking vector

    :return: Unit vector (EW, NS, vertical).
    :rtype: tuple
    """

    vertical = cos(incidence)
    north_south = sin(incidence) * cos(azimuth)
    east_west = sin(incidence) * sin(azimuth)
    return east_west, north_south, vertical


def ifg_date_lookup(ifgs, date_pair):
    """
    Returns the Interferogram which has the first and second dates given
    in 'date_pair'.

    :param list ifgs: List of interferogram objects to search
    :param tuple date_pair: A (datetime.date, datetime.date)

    :return: interferogram list
    :rtype: list
    """

    if len(date_pair) != 2:
        msg = "Need (datetime.date, datetime.date) first/second image pair"
        raise IfgException(msg)

    # check first/second dates are in order
    try:
        # TODO: Clarify: Is the comparison here for a different date?
        # Then it should be written in a more pythonic way
        # The if below is always true as long as the dates are different
        # and not in order
        if date_pair[0] > date_pair[1]:
            date_pair = date_pair[1], date_pair[0]
    except:
        raise ValueError("Bad date_pair arg to ifg_date_lookup()")

    for i in ifgs:
        if date_pair == (i.first, i.second):
            return i

    raise ValueError("Cannot find Ifg with first/second"
                     "image dates of %s" % str(date_pair))


def ifg_date_index_lookup(ifgs, date_pair):
    """
    Returns the Interferogram index which has the first and second image
    dates given in 'date_pair'.

    :param list ifgs: List of interferogram objects to search
    :param tuple date_pair: A (datetime.date, datetime.date)

    :return: interferogram index
    :rtype: int
    """

    if len(date_pair) != 2:
        msg = "Need (datetime.date, datetime.date) first/second image date pair"
        raise IfgException(msg)

    # check first/second image dates are in order
    try:
        if date_pair[0] > date_pair[1]:
            date_pair = date_pair[1], date_pair[0]
    except:
        raise ValueError("Bad date_pair arg to ifg_date_lookup()")

    for i, _ in enumerate(ifgs):
        if date_pair == (ifgs[i].first, ifgs[i].second):
            return i

    raise ValueError("Cannot find Ifg with first/second image dates of %s" % str(date_pair))


def get_epochs(ifgs: Union[Iterable, Dict]) -> Tuple[EpochList, int]:
    """
    Returns an EpochList derived from the given interferograms.

    :param ifgs: List of interferogram objects

    :return: EpochList
    :rtype: list
    """

    if isinstance(ifgs, dict):
        ifgs = [v for v in ifgs.values() if isinstance(v, PrereadIfg)]
    combined = get_all_epochs(ifgs)
    dates, n = unique(combined, False, True)
    repeat, _ = histogram(n, bins=len(set(n)))

    # absolute span for each date from the zero/start point
    span = [(dates[i] - dates[0]).days / DAYS_PER_YEAR for i in range(len(dates))]
    return EpochList(dates, repeat, span), n


def get_all_epochs(ifgs):
    """
    Returns a sequence of all image dates used to form given interferograms.

    :param list ifgs: List of interferogram objects

    :return: list of all image dates
    :rtype: list
    """

    return [ifg.first for ifg in ifgs] + [ifg.second for ifg in ifgs]


def first_second_ids(dates):
    """
    Returns a dictionary of 'date:unique ID' for each date in 'dates'.
    IDs are ordered from oldest to newest, starting at 0.

    :param list dates: List of dates

    :return: unique dates IDs
    :rtype: dict
    """

    dset = sorted(set(dates))
    return dict([(date_, i) for i, date_ in enumerate(dset)])


def factorise_integer(n, memo={}, left=2):
    """
    Returns two factors a and b of a supplied number n such that a * b = n.
    The two factors are evaluated to be as close to each other in size as possible

    :param int n: Number to factorise
    :param dict memo: dictionary of candidate factors
    :param int left: operation flag (default = 2)

    :return: a, factor one
    :rtype: int
    :return: b, factor two
    :rtype: int
    """
    n = int(n)
    if (n, left) in memo:
        return memo[(n, left)]
    if left == 1:
        return n, [n]
    i = 2
    best = n
    bestTuple = [n]
    while i * i <= n:
        if n % i == 0:
            rem = factorise_integer(n / i, memo, left - 1)
            if rem[0] + i < best:
                best = rem[0] + i
                bestTuple = [i] + rem[1]
        i += 1

    # handle edge case when only one processor is available
    if bestTuple == [4]:
        return 2, 2

    if len(bestTuple) == 1:
        bestTuple.append(1)

    return int(bestTuple[0]), int(bestTuple[1])


================================================
FILE: pyrate/core/aps.py
================================================
#   This Python module is part of the PyRate software package.
#
#   Copyright 2022 Geoscience Australia
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.
"""
This Python module implements a spatio-temporal filter method
for correcting interferograms for atmospheric phase screen (APS)
signals.
"""
# pylint: disable=invalid-name, too-many-locals, too-many-arguments
import os
from copy import deepcopy
from collections import OrderedDict
from typing import List
import numpy as np
from numpy import isnan
from scipy.fftpack import fft2, ifft2, fftshift, ifftshift
from scipy.interpolate import griddata

import pyrate.constants as C
from pyrate.core.logger import pyratelogger as log

from pyrate.core import shared, ifgconstants as ifc, mpiops
from pyrate.core.covariance import cvd_from_phase, RDist
from pyrate.core.algorithm import get_epochs
from pyrate.core.shared import Ifg, Tile, EpochList, nan_and_mm_convert
from pyrate.core.timeseries import time_series
from pyrate.merge import assemble_tiles
from pyrate.configuration import MultiplePaths, Configuration


def spatio_temporal_filter(params: dict) -> None:
    """
    Applies a spatio-temporal filter to remove the atmospheric phase screen
    (APS) and saves the corrected interferograms. Firstly the incremental
    time series is computed using the SVD method, before a cascade of temporal
    then spatial Gaussian filters is applied. The resulting APS corrections are
    saved to disc before being subtracted from each interferogram.

    :param params: Dictionary of PyRate configuration parameters.
    """
    if params[C.APSEST]:
        log.info('Doing APS spatio-temporal filtering')
    else:
        log.info('APS spatio-temporal filtering not required')
        return
    tiles = params[C.TILES]
    preread_ifgs = params[C.PREREAD_IFGS]
    ifg_paths = [ifg_path.tmp_sampled_path for ifg_path in params[C.INTERFEROGRAM_FILES]]

    # perform some checks on existing ifgs
    log.debug('Checking APS correction status')
    if mpiops.run_once(shared.check_correction_status, ifg_paths, ifc.PYRATE_APS_ERROR):
        log.debug('Finished APS correction')
        return  # return if True condition returned

    aps_paths = [MultiplePaths.aps_error_path(i, params) for i in ifg_paths]
    if all(a.exists() for a in aps_paths):
        log.warning('Reusing APS errors from previous run')
        _apply_aps_correction(ifg_paths, aps_paths, params)
        return

    # obtain the incremental time series using SVD
    tsincr = _calc_svd_time_series(ifg_paths, params, preread_ifgs, tiles)
    mpiops.comm.barrier()

    # get lists of epochs and ifgs
    ifgs = list(OrderedDict(sorted(preread_ifgs.items())).values())
    epochlist = mpiops.run_once(get_epochs, ifgs)[0]

    # first perform temporal high pass filter
    ts_hp = temporal_high_pass_filter(tsincr, epochlist, params)

    # second perform spatial low pass filter to obtain APS correction in ts domain
    ifg = Ifg(ifg_paths[0])  # just grab any for parameters in slpfilter
    ifg.open()
    ts_aps = spatial_low_pass_filter(ts_hp, ifg, params)
    ifg.close()

    # construct APS corrections for each ifg
    _make_aps_corrections(ts_aps, ifgs, params)

    # apply correction to ifgs and save ifgs to disc.
    _apply_aps_correction(ifg_paths, aps_paths, params)

    # update/save the phase_data in the tiled numpy files
    shared.save_numpy_phase(ifg_paths, params)


def _calc_svd_time_series(ifg_paths: List[str], params: dict, preread_ifgs: dict,
                          tiles: List[Tile]) -> np.ndarray:
    """
    Helper function to obtain time series for spatio-temporal filter
    using SVD method
    """
    # Is there other existing functions that can perform this same job?
    log.info('Calculating incremental time series via SVD method for APS '
             'correction')
    # copy params temporarily
    new_params = deepcopy(params)
    new_params[C.TIME_SERIES_METHOD] = 2  # use SVD method

    process_tiles = mpiops.array_split(tiles)

    nvels = None
    for t in process_tiles:
        log.debug(f'Calculating time series for tile {t.index} during APS '
                  f'correction')
        ifgp = [shared.IfgPart(p, t, preread_ifgs, params) for p in ifg_paths]
        mst_tile = np.load(Configuration.mst_path(params, t.index))
        tsincr = time_series(ifgp, new_params, vcmt=None, mst=mst_tile)[0]
        np.save(file=os.path.join(params[C.TMPDIR],
                                  f'tsincr_aps_{t.index}.npy'), arr=tsincr)
        nvels = tsincr.shape[2]

    nvels = mpiops.comm.bcast(nvels, root=0)
    mpiops.comm.barrier()
    # need to assemble tsincr from all processes
    tsincr_g = _assemble_tsincr(ifg_paths, params, preread_ifgs, tiles, nvels)
    log.debug('Finished calculating time series for spatio-temporal filter')
    return tsincr_g


def _assemble_tsincr(ifg_paths: List[str], params: dict, preread_ifgs: dict,
                     tiles: List[Tile], nvels: np.float32) -> np.ndarray:
    """
    Helper function to reconstruct time series images from tiles
    """
    # pre-allocate dest 3D array
    shape = preread_ifgs[ifg_paths[0]].shape
    tsincr_p = {}
    process_nvels = mpiops.array_split(range(nvels))
    for i in process_nvels:
        tsincr_p[i] = assemble_tiles(shape, params[C.TMPDIR], tiles,
                                     out_type='tsincr_aps', index=i)
    tsincr_g = shared.join_dicts(mpiops.comm.allgather(tsincr_p))
    return np.dstack([v[1] for v in sorted(tsincr_g.items())])


def _make_aps_corrections(ts_aps: np.ndarray, ifgs: List[Ifg], params: dict) -> None:
    """
    Function to convert the time series APS filter output into interferometric
    phase corrections and save them to disc.

    :param ts_aps: Incremental APS time series array.
    :param ifgs:   List of Ifg class objects.
    :param params: Dictionary of PyRate configuration parameters.
    """
    log.debug('Reconstructing interferometric observations from time series')
    # get first and second image indices 
    _ , n = mpiops.run_once(get_epochs, ifgs)
    index_first, index_second = n[:len(ifgs)], n[len(ifgs):]

    num_ifgs_tuples = mpiops.array_split(list(enumerate(ifgs)))
    for i, ifg in [(int(num), ifg) for num, ifg in num_ifgs_tuples]:
        # sum time slice data from first to second epoch
        ifg_aps = np.sum(ts_aps[:, :, index_first[i]: index_second[i]], axis=2)
        aps_error_on_disc = MultiplePaths.aps_error_path(ifg.tmp_path, params)
        np.save(file=aps_error_on_disc, arr=ifg_aps) # save APS as numpy array

    mpiops.comm.barrier()


def _apply_aps_correction(ifg_paths: List[str], aps_paths: List[str], params: dict) -> None:
    """
    Function to read and apply (subtract) APS corrections from interferogram data.
    """
    for ifg_path, aps_path in mpiops.array_split(list(zip(ifg_paths, aps_paths))):
        # read the APS correction from numpy array
        aps_corr = np.load(aps_path)
        # open the Ifg object
        ifg = Ifg(ifg_path)
        ifg.open(readonly=False)
        # convert NaNs and convert to mm
        nan_and_mm_convert(ifg, params)
        # subtract the correction from the ifg phase data
        ifg.phase_data[~np.isnan(ifg.phase_data)] -= aps_corr[~np.isnan(ifg.phase_data)]
        # set meta-data tags after aps error correction
        ifg.dataset.SetMetadataItem(ifc.PYRATE_APS_ERROR, ifc.APS_REMOVED)
        # write phase data to disc and close ifg.
        ifg.write_modified_phase()
        ifg.close()


def spatial_low_pass_filter(ts_hp: np.ndarray, ifg: Ifg, params: dict) -> np.ndarray:
    """
    Filter time series data spatially using a Gaussian low-pass
    filter defined by a cut-off distance. If the cut-off distance is
    defined as zero in the parameters dictionary then it is calculated for
    each time step using the pyrate.covariance.cvd_from_phase method.
    :param ts_hp: Array of temporal high-pass time series data, shape (ifg.shape, n_epochs)
    :param ifg: pyrate.core.shared.Ifg Class object.
    :param params: Dictionary of PyRate configuration parameters.
    :return: ts_lp: Low-pass filtered time series data of shape (ifg.shape, n_epochs).
    """
    log.info('Applying spatial low-pass filter')

    nvels = ts_hp.shape[2]
    cutoff = params[C.SLPF_CUTOFF]
    # nanfill = params[cf.SLPF_NANFILL]
    # fillmethod = params[cf.SLPF_NANFILL_METHOD]
    if cutoff == 0:
        r_dist = RDist(ifg)()  # only needed for cvd_for_phase
    else:
        r_dist = None
        log.info(f'Gaussian spatial filter cutoff is {cutoff:.3f} km for all '
                 f'{nvels} time-series images')

    process_nvel = mpiops.array_split(range(nvels))
    process_ts_lp = {}

    for i in process_nvel:
        process_ts_lp[i] = _slpfilter(ts_hp[:, :, i], ifg, r_dist, params)

    ts_lp_d = shared.join_dicts(mpiops.comm.allgather(process_ts_lp))
    ts_lp = np.dstack([v[1] for v in sorted(ts_lp_d.items())])
    log.debug('Finished applying spatial low pass filter')
    return ts_lp


def _interpolate_nans_2d(arr: np.ndarray, method: str) -> None:
    """
    In-place array interpolation and NaN-fill using scipy.interpolation.griddata.
    :param arr: 2D ndarray to be interpolated.
    :param method: Method; one of 'nearest', 'linear', and 'cubic'.
    """
    log.debug(f'Interpolating array with "{method}" method')
    r, c = np.indices(arr.shape)
    arr[np.isnan(arr)] = griddata(
        (r[~np.isnan(arr)], c[~np.isnan(arr)]),  # points we know
        arr[~np.isnan(arr)],  # values we know
        (r[np.isnan(arr)], c[np.isnan(arr)]),  # points to interpolate
        method=method, fill_value=0)


def _slpfilter(phase: np.ndarray, ifg: Ifg, r_dist: float, params: dict) -> np.ndarray:
    """
    Wrapper function for spatial low pass filter
    """
    cutoff = params[C.SLPF_CUTOFF]
    nanfill = params[C.SLPF_NANFILL]
    fillmethod = params[C.SLPF_NANFILL_METHOD]

    if np.all(np.isnan(phase)):  # return for nan matrix
        return phase

    if cutoff == 0:
        _, alpha = cvd_from_phase(phase, ifg, r_dist, calc_alpha=True)
        cutoff = 1.0 / alpha
        log.info(f'Gaussian spatial filter cutoff is {cutoff:.3f} km')

    return gaussian_spatial_filter(phase, cutoff, ifg.x_size, ifg.y_size, nanfill, fillmethod)


def gaussian_spatial_filter(image: np.ndarray, cutoff: float, x_size: float,
                            y_size: float, nanfill: bool = True,
                            fillmethod: str = 'nearest') -> np.ndarray:
    """
    Function to apply a Gaussian spatial low-pass filter to a 2D image with
    unequal pixel resolution in x and y dimensions. Performs filtering in the
    Fourier domain. Any NaNs in the image are interpolated prior to Fourier
    transformation, with NaNs being replaced in to the filtered output image.
    :param image: 2D image to be filtered
    :param cutoff: filter cutoff in kilometres
    :param x_size: pixel size in x dimension, in metres
    :param y_size: pixel size in y dimension, in metres
    :param nanfill: interpolate image to fill NaNs
    :param fillmethod: interpolation method ('nearest', 'cubic', or 'linear')
    :return: filt: Gaussian low-pass filtered 2D image
    """
    # create NaN mask of image
    mask = np.isnan(image)
    # in-place nearest-neighbour interpolation to fill NaNs
    # nearest neighbour will fill values outside the convex hull
    if nanfill:
        _interpolate_nans_2d(image, fillmethod)

    rows, cols = image.shape
    pad = 4096
    # pad the image to a large square array.
    # TODO: implement variable padding dependent on image size
    im = np.pad(image, ((0, pad - rows), (0, pad - cols)), 'constant')
    # fast fourier transform of the input image
    imf = fftshift(fft2(im))

    # calculate centre coords of image
    cx = np.floor(pad / 2)
    cy = np.floor(pad / 2)
    # calculate distance array
    [xx, yy] = np.meshgrid(range(pad), range(pad))
    xx = (xx - cx) * x_size  # these are in meters as x_size in metres
    yy = (yy - cy) * y_size
    dist = np.sqrt(xx ** 2 + yy ** 2) / ifc.METRE_PER_KM  # change m to km

    # Estimate sigma value for Gaussian kernel function in spectral domain
    # by converting cutoff distance to wavenumber and applying a scaling
    # factor based on fixed kernel window size. 
    sigma = np.std(dist) * (1 / cutoff)
    # Calculate kernel weights
    wgt = _kernel(dist, sigma)
    # Apply Gaussian smoothing kernel
    outf = imf * wgt
    # Inverse Fourier transform
    out = np.real(ifft2(ifftshift(outf)))
    filt = out[:rows, :cols]  # grab non-padded part
    filt[mask] = np.nan  # re-insert nans in output image
    return filt


# TODO: use tiles here and distribute amongst processes
def temporal_high_pass_filter(tsincr: np.ndarray, epochlist: EpochList,
                              params: dict) -> np.ndarray:
    """
    Isolate high-frequency components of time series data by subtracting
    low-pass components obtained using a Gaussian filter defined by a
    cut-off time period (in days).
    :param tsincr: Array of incremental time series data of shape (ifg.shape, n_epochs).
    :param epochlist: A pyrate.core.shared.EpochList Class instance.
    :param params: Dictionary of PyRate configuration parameters.
    :return: ts_hp: Filtered high frequency time series data; shape (ifg.shape, nepochs).
    """
    log.info('Applying temporal high-pass filter')
    threshold = params[C.TLPF_PTHR]
    cutoff_day = params[C.TLPF_CUTOFF]
    if cutoff_day < 1 or type(cutoff_day) != int:
        raise ValueError(f'tlpf_cutoff must be an integer greater than or '
                         f'equal to 1 day. Value provided = {cutoff_day}')

    # convert cutoff in days to years
    cutoff_yr = cutoff_day / ifc.DAYS_PER_YEAR
    log.info(f'Gaussian temporal filter cutoff is {cutoff_day} days '
             f'({cutoff_yr:.4f} years)')

    intv = np.diff(epochlist.spans)  # time interval for the neighboring epochs
    span = epochlist.spans[: tsincr.shape[2]] + intv / 2  # accumulated time
    rows, cols = tsincr.shape[:2]

    tsfilt_row = {}
    process_rows = mpiops.array_split(list(range(rows)))

    for r in process_rows:
        tsfilt_row[r] = np.empty(tsincr.shape[1:], dtype=np.float32) * np.nan
        for j in range(cols):
            # Result of gaussian filter is low frequency time series
            tsfilt_row[r][j, :] = gaussian_temporal_filter(tsincr[r, j, :],
                                                           cutoff_yr, span, threshold)

    tsfilt_combined = shared.join_dicts(mpiops.comm.allgather(tsfilt_row))
    tsfilt = np.array([v[1] for v in tsfilt_combined.items()])
    log.debug("Finished applying temporal high-pass filter")
    # Return the high-pass time series by subtracting low-pass result from input
    return tsincr - tsfilt


def gaussian_temporal_filter(tsincr: np.ndarray, cutoff: float, span: np.ndarray,
                             thr: int) -> np.ndarray:
    """
    Function to apply a Gaussian temporal low-pass filter to a 1D time-series
    vector for one pixel with irregular temporal sampling.
    :param tsincr: 1D time-series vector to be filtered.
    :param cutoff: filter cutoff in years.
    :param span: 1D vector of cumulative time spans, in years.
    :param thr: threshold for non-NaN values in tsincr.
    :return: ts_lp: Low-pass filtered time series vector.
    """
    nanmat = ~isnan(tsincr)
    sel = np.nonzero(nanmat)[0]  # don't select if nan
    ts_lp = np.empty(tsincr.shape, dtype=np.float32) * np.nan
    m = len(sel)
    if m >= thr:
        for k in range(m):
            yr = span[sel] - span[sel[k]]
            # apply Gaussian smoothing kernel
            wgt = _kernel(yr, cutoff)
            wgt /= np.sum(wgt)
            ts_lp[sel[k]] = np.sum(tsincr[sel] * wgt)

    return ts_lp


def _kernel(x: np.ndarray, sigma: float) -> np.ndarray:
    """
    Gaussian low-pass filter kernel
    """
    return np.exp(-0.5 * (x / sigma) ** 2)


================================================
FILE: pyrate/core/covariance.py
================================================
#   This Python module is part of the PyRate software package.
#
#   Copyright 2022 Geoscience Australia
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.
"""
This Python module implements covariance calculation and
Variance/Covariance matrix functionality.
"""
# coding: utf-8
from os.path import basename, join
from collections import OrderedDict
from numpy import array, where, isnan, real, imag, sqrt, meshgrid
from numpy import zeros, vstack, ceil, mean, exp, reshape
from numpy.linalg import norm
import numpy as np
from scipy.fftpack import fft2, ifft2, fftshift
from scipy.optimize import fmin

import pyrate.constants as C
from pyrate.core import shared, ifgconstants as ifc, mpiops
from pyrate.core.shared import PrereadIfg, Ifg
from pyrate.core.algorithm import first_second_ids
from pyrate.core.logger import pyratelogger as log
from pyrate.configuration import Configuration

# pylint: disable=too-many-arguments
MAIN_PROCESS = 0


def _pendiffexp(alphamod, cvdav):
    """
    Fits an exponential model to data.

    :param float alphamod: Exponential decay exponent.
    :param ndarray cvdav: Function magnitude at 0 radius (2 col array of
    radius, variance)
    """
    # pylint: disable=invalid-name
    # maxvar usually at zero lag
    mx = cvdav[1, 0]
    return norm(cvdav[1, :] - (mx * exp(-alphamod * cvdav[0, :])))


# this is not used any more
def _unique_points(points):  # pragma: no cover
    """
    Returns unique points from a list of coordinates.

    :param points: Sequence of (y,x) or (x,y) tuples.
    """
    return vstack([array(u) for u in set(points)])


def cvd(ifg_path, params, r_dist, calc_alpha=False, write_vals=False, save_acg=False):
    """
    Calculate the 1D covariance function of an entire interferogram as the
    radial average of its 2D autocorrelation.

    :param str ifg_path: An interferogram file path. OR
    :param dict params: Dictionary of configuration parameters
    :param ndarray r_dist: Array of distance values from the image centre
                (See Rdist class for more details)
    :param bool calc_alpha: If True calculate alpha
    :param bool write_vals: If True write maxvar and alpha values to
                interferogram metadata
    :param bool save_acg: If True write autocorrelation and radial distance
                data to numpy array file on disk

    :return: maxvar: The maximum variance (at zero lag)
    :rtype: float
    :return: alpha: the exponential length-scale of decay factor
    :rtype: float
    """
    ifg = shared.Ifg(ifg_path)
    ifg.open()
    shared.nan_and_mm_convert(ifg, params)
    # calculate 2D auto-correlation of image using the
    # spectral method (Wiener-Khinchin theorem)
    if ifg.nan_converted:  # if nancoverted earlier, convert nans back to 0's
        phase = where(isnan(ifg.phase_data), 0, ifg.phase_data)
    else:
        phase = ifg.phase_data

    maxvar, alpha = cvd_from_phase(phase, ifg, r_dist, calc_alpha, save_acg=save_acg, params=params)
    if write_vals:
        ifg.add_metadata(**{
            ifc.PYRATE_MAXVAR: str(maxvar),
            ifc.PYRATE_ALPHA: str(alpha)
        })

    ifg.close()

    return maxvar, alpha


def _save_cvd_data(acg, r_dist, ifg_path, outdir):
    """
    Function to save numpy array of autocorrelation data to disk
    """
    data = np.column_stack((acg, r_dist))
    data_file = join(outdir, 'cvd_data_{b}.npy'.format(b=basename(ifg_path).split('.')[0]))
    np.save(file=data_file, arr=data)


def cvd_from_phase(phase, ifg, r_dist, calc_alpha, save_acg=False, params=None):
    """
    A convenience function used to compute radial autocovariance from phase
    data

    :param ndarray phase: An array of interferogram phase data
    :param Ifg class ifg: A pyrate.shared.Ifg class instance
    :param ndarray r_dist: Array of distance values from the image centre
                (See Rdist class for more details)
    :param bool calc_alpha: If True calculate alpha
    :param bool save_acg: If True write autocorrelation and radial distance
                data to numpy array file on disk
    :param dict params: [optional] Dictionary of configuration parameters;
                Must be provided if save_acg=True

    :return: maxvar: The maximum variance (at zero lag)
    :rtype: float
    :return: alpha: the exponential length-scale of decay factor
    :rtype: float
    """
    # pylint: disable=invalid-name
    # pylint: disable=too-many-locals

    autocorr_grid = _get_autogrid(phase)
    acg = reshape(autocorr_grid, phase.size, order='F')
    # Symmetry in image; keep only unique points
    # tmp = _unique_points(zip(acg, r_dist))
    # Sudipta: Unlikely, as unique_point is a search/comparison,
    # whereas keeping 1st half is just numpy indexing.
    # If it is not faster, why was this done differently here?
    # r_dist = r_dist[:int(ceil(phase.size / 2.0)) + nrows]
    acg = acg[:len(r_dist)]
    # Alternative method to remove duplicate cells
    # r_dist = r_dist[:ceil(len(r_dist)/2)+nlines]
    #  Reason for '+nlines' term unknown
    # eg. array([x for x in set([(1,1), (2,2), (1,1)])])
    # the above shortens r_dist by some number of cells

    # pick the smallest axis to determine circle search radius
    if (ifg.x_centre * ifg.x_size) < (ifg.y_centre * ifg.y_size):
        maxdist = (ifg.x_centre+1) * ifg.x_size / ifc.METRE_PER_KM
    else:
        maxdist = (ifg.y_centre+1) * ifg.y_size / ifc.METRE_PER_KM

    # filter out data where the of lag distance is greater than maxdist
    # r_dist = array([e for e in rorig if e <= maxdist]) #
    # MG: prefers to use all the data
    # acg = array([e for e in rorig if e <= maxdist])
    indices_to_keep = r_dist < maxdist
    acg = acg[indices_to_keep]

    # optionally save acg vs dist observations to disk
    if save_acg:
        _save_cvd_data(acg, r_dist[indices_to_keep],
                       ifg.data_path, params[C.TMPDIR])

    if calc_alpha:
        # bin width for collecting data
        bin_width = max(ifg.x_size, ifg.y_size
Download .txt
gitextract_ml4uzp09/

├── .coveragerc
├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   └── feature_request.md
│   └── workflows/
│       └── build.yml
├── .gitignore
├── .pylintrc
├── Dockerfile
├── LICENSE
├── README.rst
├── __init__.py
├── docs/
│   ├── Makefile
│   ├── algorithm.rst
│   ├── aps.rst
│   ├── authors.rst
│   ├── conf.py
│   ├── configuration.rst
│   ├── contributing.rst
│   ├── covariance.rst
│   ├── demerror.rst
│   ├── dependencies.rst
│   ├── docker.rst
│   ├── gamma.rst
│   ├── gdal_python.rst
│   ├── geometry.rst
│   ├── history.rst
│   ├── hpc.rst
│   ├── ifgconstants.rst
│   ├── index.rst
│   ├── installation.rst
│   ├── logger.rst
│   ├── make.bat
│   ├── modules.rst
│   ├── mpiops.rst
│   ├── mst.rst
│   ├── orbital.rst
│   ├── phase_closure.rst
│   ├── prepifg_helper.rst
│   ├── pyrate.conv2tif.rst
│   ├── pyrate.correct.rst
│   ├── pyrate.main.rst
│   ├── pyrate.merge.rst
│   ├── pyrate.prepifg.rst
│   ├── ref_phs_est.rst
│   ├── refpixel.rst
│   ├── roipac.rst
│   ├── scripts.rst
│   ├── shared.rst
│   ├── stack.rst
│   ├── timeseries.rst
│   ├── troubleshooting.rst
│   ├── ubuntu.rst
│   └── usage.rst
├── input_parameters.conf
├── pyrate/
│   ├── __init__.py
│   ├── configuration.py
│   ├── constants.py
│   ├── conv2tif.py
│   ├── core/
│   │   ├── .coveragerc
│   │   ├── __init__.py
│   │   ├── algorithm.py
│   │   ├── aps.py
│   │   ├── covariance.py
│   │   ├── dem_error.py
│   │   ├── gamma.py
│   │   ├── gdal_python.py
│   │   ├── geometry.py
│   │   ├── ifgconstants.py
│   │   ├── logger.py
│   │   ├── mpiops.py
│   │   ├── mst.py
│   │   ├── orbital.py
│   │   ├── phase_closure/
│   │   │   ├── __init__.py
│   │   │   ├── closure_check.py
│   │   │   ├── collect_loops.py
│   │   │   ├── correct_phase.py
│   │   │   ├── mst_closure.py
│   │   │   ├── plot_closure.py
│   │   │   └── sum_closure.py
│   │   ├── prepifg_helper.py
│   │   ├── ref_phs_est.py
│   │   ├── refpixel.py
│   │   ├── roipac.py
│   │   ├── shared.py
│   │   ├── stack.py
│   │   └── timeseries.py
│   ├── correct.py
│   ├── default_parameters.py
│   ├── main.py
│   ├── merge.py
│   └── prepifg.py
├── pytest.ini
├── requirements-dev.txt
├── requirements-plot.txt
├── requirements-test.txt
├── requirements.txt
├── scripts/
│   ├── apt_install.sh
│   ├── ci_gdal_install.sh
│   ├── ci_proj_install.sh
│   ├── create_html_documentation.sh
│   ├── gdal_calc_local.py
│   ├── nci_install.sh
│   ├── nci_load_modules.sh
│   ├── nci_run_tests.sh
│   ├── plot_ifgs.py
│   └── prepifg.sh
├── setup.cfg
├── setup.py
├── tests/
│   ├── __init__.py
│   ├── common.py
│   ├── conftest.py
│   ├── phase_closure/
│   │   ├── __init__.py
│   │   ├── common.py
│   │   ├── conftest.py
│   │   ├── test_closure_check.py
│   │   ├── test_collect_loops.py
│   │   ├── test_mst_closure.py
│   │   ├── test_plot_closure.py
│   │   └── test_sum_closure.py
│   ├── test_algorithm.py
│   ├── test_aps.py
│   ├── test_constants.py
│   ├── test_conv2tif.py
│   ├── test_correct.py
│   ├── test_covariance.py
│   ├── test_data/
│   │   ├── cropA/
│   │   │   ├── baseline_30
│   │   │   ├── coherence_30
│   │   │   ├── coherence_stats/
│   │   │   │   ├── coh_mean.tif
│   │   │   │   ├── coh_median.tif
│   │   │   │   └── coh_std.tif
│   │   │   ├── dem_error_result/
│   │   │   │   ├── 20180106-20180319_ifg_20_dem_error.npy
│   │   │   │   ├── 20180130-20180412_ifg_20_dem_error.npy
│   │   │   │   ├── 20180412-20180518_ifg_20_dem_error.npy
│   │   │   │   └── dem_error.tif
│   │   │   ├── geometry/
│   │   │   │   ├── 20180106-20180130_VV_8rlks_base.par
│   │   │   │   ├── 20180106-20180130_VV_8rlks_bperp.par
│   │   │   │   ├── 20180106-20180319_VV_8rlks_base.par
│   │   │   │   ├── 20180106-20180319_VV_8rlks_bperp.par
│   │   │   │   ├── 20180106-20180412_VV_8rlks_base.par
│   │   │   │   ├── 20180106-20180412_VV_8rlks_bperp.par
│   │   │   │   ├── 20180106-20180518_VV_8rlks_base.par
│   │   │   │   ├── 20180106-20180518_VV_8rlks_bperp.par
│   │   │   │   ├── 20180106_VV_8rlks_eqa_to_rdc.lt
│   │   │   │   ├── 20180130-20180307_VV_8rlks_base.par
│   │   │   │   ├── 20180130-20180307_VV_8rlks_bperp.par
│   │   │   │   ├── 20180130-20180412_VV_8rlks_base.par
│   │   │   │   ├── 20180130-20180412_VV_8rlks_bperp.par
│   │   │   │   ├── 20180307-20180319_VV_8rlks_base.par
│   │   │   │   ├── 20180307-20180319_VV_8rlks_bperp.par
│   │   │   │   ├── 20180307-20180331_VV_8rlks_base.par
│   │   │   │   ├── 20180307-20180331_VV_8rlks_bperp.par
│   │   │   │   ├── 20180307-20180506_VV_8rlks_base.par
│   │   │   │   ├── 20180307-20180506_VV_8rlks_bperp.par
│   │   │   │   ├── 20180307-20180530_VV_8rlks_base.par
│   │   │   │   ├── 20180307-20180530_VV_8rlks_bperp.par
│   │   │   │   ├── 20180307-20180611_VV_8rlks_base.par
│   │   │   │   ├── 20180307-20180611_VV_8rlks_bperp.par
│   │   │   │   ├── 20180319-20180331_VV_8rlks_base.par
│   │   │   │   ├── 20180319-20180331_VV_8rlks_bperp.par
│   │   │   │   ├── 20180319-20180506_VV_8rlks_base.par
│   │   │   │   ├── 20180319-20180506_VV_8rlks_bperp.par
│   │   │   │   ├── 20180319-20180518_VV_8rlks_base.par
│   │   │   │   ├── 20180319-20180518_VV_8rlks_bperp.par
│   │   │   │   ├── 20180319-20180530_VV_8rlks_base.par
│   │   │   │   ├── 20180319-20180530_VV_8rlks_bperp.par
│   │   │   │   ├── 20180319-20180623_VV_8rlks_base.par
│   │   │   │   ├── 20180319-20180623_VV_8rlks_bperp.par
│   │   │   │   ├── 20180331-20180412_VV_8rlks_base.par
│   │   │   │   ├── 20180331-20180412_VV_8rlks_bperp.par
│   │   │   │   ├── 20180331-20180506_VV_8rlks_base.par
│   │   │   │   ├── 20180331-20180506_VV_8rlks_bperp.par
│   │   │   │   ├── 20180331-20180518_VV_8rlks_base.par
│   │   │   │   ├── 20180331-20180518_VV_8rlks_bperp.par
│   │   │   │   ├── 20180331-20180530_VV_8rlks_base.par
│   │   │   │   ├── 20180331-20180530_VV_8rlks_bperp.par
│   │   │   │   ├── 20180331-20180623_VV_8rlks_base.par
│   │   │   │   ├── 20180331-20180623_VV_8rlks_bperp.par
│   │   │   │   ├── 20180331-20180717_VV_8rlks_base.par
│   │   │   │   ├── 20180331-20180717_VV_8rlks_bperp.par
│   │   │   │   ├── 20180412-20180506_VV_8rlks_base.par
│   │   │   │   ├── 20180412-20180506_VV_8rlks_bperp.par
│   │   │   │   ├── 20180412-20180518_VV_8rlks_base.par
│   │   │   │   ├── 20180412-20180518_VV_8rlks_bperp.par
│   │   │   │   ├── 20180506-20180518_VV_8rlks_base.par
│   │   │   │   ├── 20180506-20180518_VV_8rlks_bperp.par
│   │   │   │   ├── 20180506-20180530_VV_8rlks_base.par
│   │   │   │   ├── 20180506-20180530_VV_8rlks_bperp.par
│   │   │   │   ├── 20180506-20180611_VV_8rlks_base.par
│   │   │   │   ├── 20180506-20180611_VV_8rlks_bperp.par
│   │   │   │   ├── 20180506-20180623_VV_8rlks_base.par
│   │   │   │   ├── 20180506-20180623_VV_8rlks_bperp.par
│   │   │   │   ├── 20180506-20180705_VV_8rlks_base.par
│   │   │   │   ├── 20180506-20180705_VV_8rlks_bperp.par
│   │   │   │   ├── 20180506-20180717_VV_8rlks_base.par
│   │   │   │   └── 20180506-20180717_VV_8rlks_bperp.par
│   │   │   ├── geotiffs/
│   │   │   │   ├── cropA_20180106-20180130_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180106-20180130_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180106-20180319_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180106-20180319_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180106-20180412_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180106-20180412_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180106-20180518_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180106-20180518_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180130-20180307_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180130-20180307_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180130-20180412_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180130-20180412_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180307-20180319_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180307-20180319_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180307-20180331_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180307-20180331_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180307-20180506_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180307-20180506_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180307-20180530_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180307-20180530_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180307-20180611_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180307-20180611_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180319-20180331_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180319-20180331_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180319-20180506_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180319-20180506_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180319-20180518_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180319-20180518_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180319-20180530_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180319-20180530_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180319-20180623_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180319-20180623_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180331-20180412_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180331-20180412_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180331-20180506_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180331-20180506_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180331-20180518_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180331-20180518_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180331-20180530_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180331-20180530_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180331-20180623_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180331-20180623_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180331-20180717_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180331-20180717_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180412-20180506_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180412-20180506_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180412-20180518_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180412-20180518_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180506-20180518_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180506-20180518_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180506-20180530_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180506-20180530_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180506-20180611_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180506-20180611_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180506-20180623_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180506-20180623_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180506-20180705_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180506-20180705_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   ├── cropA_20180506-20180717_VV_8rlks_eqa_unw.tif
│   │   │   │   ├── cropA_20180506-20180717_VV_8rlks_flat_eqa_cc.tif
│   │   │   │   └── cropA_T005A_dem.tif
│   │   │   ├── headers/
│   │   │   │   ├── cropA_20180106_VV_8rlks_eqa_dem.par
│   │   │   │   ├── r20180106_VV_8rlks_mli.par
│   │   │   │   ├── r20180106_VV_slc.par
│   │   │   │   ├── r20180130_VV_8rlks_mli.par
│   │   │   │   ├── r20180130_VV_slc.par
│   │   │   │   ├── r20180307_VV_8rlks_mli.par
│   │   │   │   ├── r20180307_VV_slc.par
│   │   │   │   ├── r20180319_VV_8rlks_mli.par
│   │   │   │   ├── r20180319_VV_slc.par
│   │   │   │   ├── r20180331_VV_8rlks_mli.par
│   │   │   │   ├── r20180331_VV_slc.par
│   │   │   │   ├── r20180412_VV_8rlks_mli.par
│   │   │   │   ├── r20180412_VV_slc.par
│   │   │   │   ├── r20180506_VV_8rlks_mli.par
│   │   │   │   ├── r20180506_VV_slc.par
│   │   │   │   ├── r20180518_VV_8rlks_mli.par
│   │   │   │   ├── r20180518_VV_slc.par
│   │   │   │   ├── r20180530_VV_8rlks_mli.par
│   │   │   │   ├── r20180530_VV_slc.par
│   │   │   │   ├── r20180611_VV_8rlks_mli.par
│   │   │   │   ├── r20180611_VV_slc.par
│   │   │   │   ├── r20180623_VV_8rlks_mli.par
│   │   │   │   ├── r20180623_VV_slc.par
│   │   │   │   ├── r20180705_VV_8rlks_mli.par
│   │   │   │   ├── r20180705_VV_slc.par
│   │   │   │   ├── r20180717_VV_8rlks_mli.par
│   │   │   │   └── r20180717_VV_slc.par
│   │   │   ├── headers_13
│   │   │   ├── ifg_30
│   │   │   └── pyrate_mexico_cropa.conf
│   │   ├── cropB/
│   │   │   └── 20180106-20180130_ifg.tif
│   │   ├── gamma/
│   │   │   ├── 16x20_20090713-20090817_VV_4rlks_utm.tif
│   │   │   ├── 16x20_20090713-20090817_VV_4rlks_utm.unw
│   │   │   ├── 20160114-20160126_base.par
│   │   │   ├── 20160114-20160126_base_init.par
│   │   │   ├── cropped_lookup_table.lt
│   │   │   ├── dem16x20_subset_from_gamma.tif
│   │   │   ├── dem16x20raw.dem
│   │   │   ├── dem16x20raw.dem.par
│   │   │   ├── r20090713_VV.slc.par
│   │   │   └── r20090817_VV.slc.par
│   │   ├── geotiffs/
│   │   │   ├── cropA_20180106-20180130_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180106-20180130_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180106-20180319_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180106-20180319_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180106-20180412_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180106-20180412_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180106-20180518_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180106-20180518_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180106_VV_8rlks_eqa_dem.par
│   │   │   ├── cropA_20180130-20180307_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180130-20180307_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180130-20180412_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180130-20180412_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180307-20180319_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180307-20180319_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180307-20180331_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180307-20180331_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180307-20180506_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180307-20180506_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180307-20180530_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180307-20180530_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180307-20180611_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180307-20180611_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180319-20180331_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180319-20180331_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180319-20180506_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180319-20180506_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180319-20180518_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180319-20180518_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180319-20180530_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180319-20180530_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180319-20180623_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180319-20180623_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180331-20180412_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180331-20180412_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180331-20180506_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180331-20180506_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180331-20180518_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180331-20180518_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180331-20180530_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180331-20180530_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180331-20180623_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180331-20180623_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180331-20180717_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180331-20180717_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180412-20180506_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180412-20180506_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180412-20180518_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180412-20180518_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180506-20180518_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180506-20180518_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180506-20180530_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180506-20180530_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180506-20180611_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180506-20180611_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180506-20180623_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180506-20180623_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180506-20180705_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180506-20180705_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_20180506-20180717_VV_8rlks_eqa_unw.tif
│   │   │   ├── cropA_20180506-20180717_VV_8rlks_flat_eqa_cc.tif
│   │   │   ├── cropA_T005A_dem.tif
│   │   │   ├── r20180106_VV_slc.par
│   │   │   ├── r20180130_VV_slc.par
│   │   │   ├── r20180307_VV_slc.par
│   │   │   ├── r20180319_VV_slc.par
│   │   │   ├── r20180331_VV_slc.par
│   │   │   ├── r20180412_VV_slc.par
│   │   │   ├── r20180506_VV_slc.par
│   │   │   ├── r20180518_VV_slc.par
│   │   │   ├── r20180530_VV_slc.par
│   │   │   ├── r20180611_VV_slc.par
│   │   │   ├── r20180623_VV_slc.par
│   │   │   ├── r20180705_VV_slc.par
│   │   │   └── r20180717_VV_slc.par
│   │   ├── headers/
│   │   │   └── geo_060619-060828.unw.rsc
│   │   ├── incidence/
│   │   │   └── 128x2.tif
│   │   ├── prepifg/
│   │   │   ├── obs/
│   │   │   │   ├── geo_060619-061002.unw
│   │   │   │   ├── geo_060619-061002.unw.rsc
│   │   │   │   ├── geo_070326-070917.unw
│   │   │   │   └── geo_070326-070917.unw.rsc
│   │   │   └── tif/
│   │   │       ├── 0_1lksx_1lksy_4cr.tif
│   │   │       ├── 1_1lksx_1lksy_4cr.tif
│   │   │       ├── geo_060619-061002.tif
│   │   │       ├── geo_060619-061002_unw.tif
│   │   │       ├── geo_070326-070917.tif
│   │   │       └── geo_070326-070917_unw.tif
│   │   ├── small_test/
│   │   │   ├── coherence/
│   │   │   │   ├── 20060619-20061002_utm.unw.cc
│   │   │   │   ├── 20060828-20061211_utm.unw.cc
│   │   │   │   ├── 20061002-20070219_utm.unw.cc
│   │   │   │   ├── 20061002-20070430_utm.unw.cc
│   │   │   │   ├── 20061106-20061211_utm.unw.cc
│   │   │   │   ├── 20061106-20070115_utm.unw.cc
│   │   │   │   ├── 20061106-20070326_utm.unw.cc
│   │   │   │   ├── 20061211-20070709_utm.unw.cc
│   │   │   │   ├── 20061211-20070813_utm.unw.cc
│   │   │   │   ├── 20070115-20070326_utm.unw.cc
│   │   │   │   ├── 20070115-20070917_utm.unw.cc
│   │   │   │   ├── 20070219-20070430_utm.unw.cc
│   │   │   │   ├── 20070219-20070604_utm.unw.cc
│   │   │   │   ├── 20070326-20070917_utm.unw.cc
│   │   │   │   ├── 20070430-20070604_utm.unw.cc
│   │   │   │   ├── 20070604-20070709_utm.unw.cc
│   │   │   │   ├── 20070709-20070813_utm.unw.cc
│   │   │   │   └── coherence_17
│   │   │   ├── conf/
│   │   │   │   ├── pyrate1.conf
│   │   │   │   ├── pyrate2.conf
│   │   │   │   ├── pyrate_gamma_test.conf
│   │   │   │   └── pyrate_roipac_test.conf
│   │   │   ├── dem/
│   │   │   │   └── roipac_test_trimmed.tif
│   │   │   ├── gamma_obs/
│   │   │   │   ├── 20060619-20061002_base.par
│   │   │   │   ├── 20060619-20061002_utm.unw
│   │   │   │   ├── 20060619-20061002_utm_unw.tif.aux.xml
│   │   │   │   ├── 20060619_slc.par
│   │   │   │   ├── 20060619_utm.dem
│   │   │   │   ├── 20060619_utm.inc
│   │   │   │   ├── 20060619_utm.lv_theta
│   │   │   │   ├── 20060619_utm_dem.par
│   │   │   │   ├── 20060828-20061211_base.par
│   │   │   │   ├── 20060828-20061211_utm.unw
│   │   │   │   ├── 20060828_slc.par
│   │   │   │   ├── 20061002-20070219_base.par
│   │   │   │   ├── 20061002-20070219_utm.unw
│   │   │   │   ├── 20061002-20070430_base.par
│   │   │   │   ├── 20061002-20070430_utm.unw
│   │   │   │   ├── 20061002_slc.par
│   │   │   │   ├── 20061106-20061211_base.par
│   │   │   │   ├── 20061106-20061211_utm.unw
│   │   │   │   ├── 20061106-20070115_base.par
│   │   │   │   ├── 20061106-20070115_utm.unw
│   │   │   │   ├── 20061106-20070326_base.par
│   │   │   │   ├── 20061106-20070326_utm.unw
│   │   │   │   ├── 20061106_slc.par
│   │   │   │   ├── 20061211-20070709_base.par
│   │   │   │   ├── 20061211-20070709_utm.unw
│   │   │   │   ├── 20061211-20070813_base.par
│   │   │   │   ├── 20061211-20070813_utm.unw
│   │   │   │   ├── 20061211_slc.par
│   │   │   │   ├── 20070115-20070326_base.par
│   │   │   │   ├── 20070115-20070326_utm.unw
│   │   │   │   ├── 20070115-20070917_base.par
│   │   │   │   ├── 20070115-20070917_utm.unw
│   │   │   │   ├── 20070115_slc.par
│   │   │   │   ├── 20070219-20070430_base.par
│   │   │   │   ├── 20070219-20070430_utm.unw
│   │   │   │   ├── 20070219-20070604_base.par
│   │   │   │   ├── 20070219-20070604_utm.unw
│   │   │   │   ├── 20070219_slc.par
│   │   │   │   ├── 20070326-20070917_base.par
│   │   │   │   ├── 20070326-20070917_utm.unw
│   │   │   │   ├── 20070326_slc.par
│   │   │   │   ├── 20070430-20070604_base.par
│   │   │   │   ├── 20070430-20070604_utm.unw
│   │   │   │   ├── 20070430_slc.par
│   │   │   │   ├── 20070604-20070709_base.par
│   │   │   │   ├── 20070604-20070709_utm.unw
│   │   │   │   ├── 20070604_slc.par
│   │   │   │   ├── 20070709-20070813_base.par
│   │   │   │   ├── 20070709-20070813_utm.unw
│   │   │   │   ├── 20070709_slc.par
│   │   │   │   ├── 20070813_slc.par
│   │   │   │   ├── 20070917_slc.par
│   │   │   │   ├── bad_epochs_headers
│   │   │   │   ├── bad_epochs_ifms_17
│   │   │   │   ├── baseline_17
│   │   │   │   ├── cropped_lookup_table.lt
│   │   │   │   ├── headers
│   │   │   │   ├── ifms_17
│   │   │   │   └── tif_17
│   │   │   ├── linrate/
│   │   │   │   ├── linear_error.npy
│   │   │   │   ├── linear_intercept.npy
│   │   │   │   ├── linear_rate.npy
│   │   │   │   ├── linear_rsquared.npy
│   │   │   │   ├── linear_samples.npy
│   │   │   │   └── tscuml_0.npy
│   │   │   ├── mst/
│   │   │   │   ├── mst_geo_060619-061002.csv
│   │   │   │   ├── mst_geo_060828-061211.csv
│   │   │   │   ├── mst_geo_061002-070219.csv
│   │   │   │   ├── mst_geo_061002-070430.csv
│   │   │   │   ├── mst_geo_061106-061211.csv
│   │   │   │   ├── mst_geo_061106-070115.csv
│   │   │   │   ├── mst_geo_061106-070326.csv
│   │   │   │   ├── mst_geo_061211-070709.csv
│   │   │   │   ├── mst_geo_061211-070813.csv
│   │   │   │   ├── mst_geo_070115-070326.csv
│   │   │   │   ├── mst_geo_070115-070917.csv
│   │   │   │   ├── mst_geo_070219-070430.csv
│   │   │   │   ├── mst_geo_070219-070604.csv
│   │   │   │   ├── mst_geo_070326-070917.csv
│   │   │   │   ├── mst_geo_070430-070604.csv
│   │   │   │   ├── mst_geo_070604-070709.csv
│   │   │   │   └── mst_geo_070709-070813.csv
│   │   │   ├── orbital_error_correction/
│   │   │   │   ├── ifg_orb_planar_1lks_method1_geo_060619-061002.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method1_geo_060828-061211.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method1_geo_061002-070219.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method1_geo_061002-070430.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method1_geo_061106-061211.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method1_geo_061106-070115.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method1_geo_061106-070326.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method1_geo_061211-070709.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method1_geo_061211-070813.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method1_geo_070115-070326.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method1_geo_070115-070917.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method1_geo_070219-070430.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method1_geo_070219-070604.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method1_geo_070326-070917.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method1_geo_070430-070604.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method1_geo_070604-070709.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method1_geo_070709-070813.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method2_geo_060619-061002.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method2_geo_060828-061211.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method2_geo_061002-070219.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method2_geo_061002-070430.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method2_geo_061106-061211.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method2_geo_061106-070115.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method2_geo_061106-070326.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method2_geo_061211-070709.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method2_geo_061211-070813.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method2_geo_070115-070326.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method2_geo_070115-070917.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method2_geo_070219-070430.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method2_geo_070219-070604.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method2_geo_070326-070917.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method2_geo_070430-070604.unw.csv
│   │   │   │   ├── ifg_orb_planar_1lks_method2_geo_070604-070709.unw.csv
│   │   │   │   └── ifg_orb_planar_1lks_method2_geo_070709-070813.unw.csv
│   │   │   ├── ref_phase_est/
│   │   │   │   ├── ifg_orb_and_ref_phase_corrected_method2geo_060619-061002.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_corrected_method2geo_060828-061211.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_corrected_method2geo_061002-070219.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_corrected_method2geo_061002-070430.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_corrected_method2geo_061106-061211.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_corrected_method2geo_061106-070115.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_corrected_method2geo_061106-070326.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_corrected_method2geo_061211-070709.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_corrected_method2geo_061211-070813.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_corrected_method2geo_070115-070326.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_corrected_method2geo_070115-070917.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_corrected_method2geo_070219-070430.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_corrected_method2geo_070219-070604.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_corrected_method2geo_070326-070917.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_corrected_method2geo_070430-070604.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_corrected_method2geo_070604-070709.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_corrected_method2geo_070709-070813.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_correctedgeo_060619-061002.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_correctedgeo_060828-061211.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_correctedgeo_061002-070219.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_correctedgeo_061002-070430.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_correctedgeo_061106-061211.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_correctedgeo_061106-070115.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_correctedgeo_061106-070326.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_correctedgeo_061211-070709.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_correctedgeo_061211-070813.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_correctedgeo_070115-070326.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_correctedgeo_070115-070917.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_correctedgeo_070219-070430.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_correctedgeo_070219-070604.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_correctedgeo_070326-070917.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_correctedgeo_070430-070604.unw.csv
│   │   │   │   ├── ifg_orb_and_ref_phase_correctedgeo_070604-070709.unw.csv
│   │   │   │   └── ifg_orb_and_ref_phase_correctedgeo_070709-070813.unw.csv
│   │   │   ├── roipac_obs/
│   │   │   │   ├── bad_epochs_ifms_17
│   │   │   │   ├── geo_060619-061002.unw
│   │   │   │   ├── geo_060619-061002.unw.rsc
│   │   │   │   ├── geo_060828-061211.unw
│   │   │   │   ├── geo_060828-061211.unw.rsc
│   │   │   │   ├── geo_061002-070219.unw
│   │   │   │   ├── geo_061002-070219.unw.rsc
│   │   │   │   ├── geo_061002-070430.unw
│   │   │   │   ├── geo_061002-070430.unw.rsc
│   │   │   │   ├── geo_061106-061211.unw
│   │   │   │   ├── geo_061106-061211.unw.rsc
│   │   │   │   ├── geo_061106-070115.unw
│   │   │   │   ├── geo_061106-070115.unw.rsc
│   │   │   │   ├── geo_061106-070326.unw
│   │   │   │   ├── geo_061106-070326.unw.rsc
│   │   │   │   ├── geo_061211-070709.unw
│   │   │   │   ├── geo_061211-070709.unw.rsc
│   │   │   │   ├── geo_061211-070813.unw
│   │   │   │   ├── geo_061211-070813.unw.rsc
│   │   │   │   ├── geo_070115-070326.unw
│   │   │   │   ├── geo_070115-070326.unw.rsc
│   │   │   │   ├── geo_070115-070917.unw
│   │   │   │   ├── geo_070115-070917.unw.rsc
│   │   │   │   ├── geo_070219-070430.unw
│   │   │   │   ├── geo_070219-070430.unw.rsc
│   │   │   │   ├── geo_070219-070604.unw
│   │   │   │   ├── geo_070219-070604.unw.rsc
│   │   │   │   ├── geo_070326-070917.unw
│   │   │   │   ├── geo_070326-070917.unw.rsc
│   │   │   │   ├── geo_070430-070604.unw
│   │   │   │   ├── geo_070430-070604.unw.rsc
│   │   │   │   ├── geo_070604-070709.unw
│   │   │   │   ├── geo_070604-070709.unw.rsc
│   │   │   │   ├── geo_070709-070813.unw
│   │   │   │   ├── geo_070709-070813.unw.rsc
│   │   │   │   ├── headers
│   │   │   │   ├── ifms_17
│   │   │   │   ├── roipac_test_trimmed.dem
│   │   │   │   └── roipac_test_trimmed.dem.rsc
│   │   │   ├── stackrate/
│   │   │   │   ├── coh_sta.csv
│   │   │   │   ├── errormap.csv
│   │   │   │   └── stackmap.csv
│   │   │   ├── tif/
│   │   │   │   ├── geo_060619-061002_unw.tif
│   │   │   │   ├── geo_060828-061211_unw.tif
│   │   │   │   ├── geo_061002-070219_unw.tif
│   │   │   │   ├── geo_061002-070430_unw.tif
│   │   │   │   ├── geo_061106-061211_unw.tif
│   │   │   │   ├── geo_061106-070115_unw.tif
│   │   │   │   ├── geo_061106-070326_unw.tif
│   │   │   │   ├── geo_061211-070709_unw.tif
│   │   │   │   ├── geo_061211-070813_unw.tif
│   │   │   │   ├── geo_070115-070326_unw.tif
│   │   │   │   ├── geo_070115-070917_unw.tif
│   │   │   │   ├── geo_070219-070430_unw.tif
│   │   │   │   ├── geo_070219-070604_unw.tif
│   │   │   │   ├── geo_070326-070917_unw.tif
│   │   │   │   ├── geo_070430-070604_unw.tif
│   │   │   │   ├── geo_070604-070709_unw.tif
│   │   │   │   ├── geo_070709-070813_unw.tif
│   │   │   │   └── ifms_17
│   │   │   ├── time_series/
│   │   │   │   ├── ts_cum_interp0_method1.csv
│   │   │   │   ├── ts_cum_interp0_method2.csv
│   │   │   │   ├── ts_error_interp0_method1.csv
│   │   │   │   ├── ts_incr_interp0_method1.csv
│   │   │   │   └── ts_incr_interp0_method2.csv
│   │   │   └── vcm/
│   │   │       ├── alpha.csv
│   │   │       └── vcmt.csv
│   │   └── system/
│   │       ├── gamma/
│   │       │   ├── 20060619-20061002_base.par
│   │       │   ├── 20060619-20061002_utm.unw
│   │       │   ├── 20060619-20061002_utm_unw.tif
│   │       │   ├── 20060619_slc.par
│   │       │   ├── 20060619_utm.dem
│   │       │   ├── 20060619_utm_dem.par
│   │       │   ├── 20060619_utm_dem.tif
│   │       │   ├── 20060828-20061211_base.par
│   │       │   ├── 20060828-20061211_utm.unw
│   │       │   ├── 20060828-20061211_utm_unw.tif
│   │       │   ├── 20060828_slc.par
│   │       │   ├── 20061002-20070219_base.par
│   │       │   ├── 20061002-20070219_utm.unw
│   │       │   ├── 20061002-20070219_utm_unw.tif
│   │       │   ├── 20061002-20070430_base.par
│   │       │   ├── 20061002-20070430_utm.unw
│   │       │   ├── 20061002-20070430_utm_unw.tif
│   │       │   ├── 20061002_slc.par
│   │       │   ├── 20061106-20061211_base.par
│   │       │   ├── 20061106-20061211_utm.unw
│   │       │   ├── 20061106-20061211_utm_unw.tif
│   │       │   ├── 20061106-20070115_base.par
│   │       │   ├── 20061106-20070115_utm.unw
│   │       │   ├── 20061106-20070115_utm_unw.tif
│   │       │   ├── 20061106-20070326_base.par
│   │       │   ├── 20061106-20070326_utm.unw
│   │       │   ├── 20061106-20070326_utm_unw.tif
│   │       │   ├── 20061106_slc.par
│   │       │   ├── 20061211-20070709_base.par
│   │       │   ├── 20061211-20070709_utm.unw
│   │       │   ├── 20061211-20070709_utm_unw.tif
│   │       │   ├── 20061211-20070813_base.par
│   │       │   ├── 20061211-20070813_utm.unw
│   │       │   ├── 20061211-20070813_utm_unw.tif
│   │       │   ├── 20061211_slc.par
│   │       │   ├── 20070115-20070326_base.par
│   │       │   ├── 20070115-20070326_utm.unw
│   │       │   ├── 20070115-20070326_utm_unw.tif
│   │       │   ├── 20070115-20070917_base.par
│   │       │   ├── 20070115-20070917_utm.unw
│   │       │   ├── 20070115-20070917_utm_unw.tif
│   │       │   ├── 20070115_slc.par
│   │       │   ├── 20070219-20070430_base.par
│   │       │   ├── 20070219-20070430_utm.unw
│   │       │   ├── 20070219-20070430_utm_unw.tif
│   │       │   ├── 20070219-20070604_base.par
│   │       │   ├── 20070219-20070604_utm.unw
│   │       │   ├── 20070219-20070604_utm_unw.tif
│   │       │   ├── 20070219_slc.par
│   │       │   ├── 20070326-20070917_base.par
│   │       │   ├── 20070326-20070917_utm.unw
│   │       │   ├── 20070326-20070917_utm_unw.tif
│   │       │   ├── 20070326_slc.par
│   │       │   ├── 20070430-20070604_base.par
│   │       │   ├── 20070430-20070604_utm.unw
│   │       │   ├── 20070430-20070604_utm_unw.tif
│   │       │   ├── 20070430_slc.par
│   │       │   ├── 20070604-20070709_base.par
│   │       │   ├── 20070604-20070709_utm.unw
│   │       │   ├── 20070604-20070709_utm_unw.tif
│   │       │   ├── 20070604_slc.par
│   │       │   ├── 20070709-20070813_base.par
│   │       │   ├── 20070709-20070813_utm.unw
│   │       │   ├── 20070709-20070813_utm_unw.tif
│   │       │   ├── 20070709_slc.par
│   │       │   ├── 20070813_slc.par
│   │       │   ├── 20070917_slc.par
│   │       │   ├── baseline_list.txt
│   │       │   ├── cropped_lookup_table.lt
│   │       │   ├── header_list.txt
│   │       │   ├── input_parameters.conf
│   │       │   └── interferogram_list.txt
│   │       ├── geotiff/
│   │       │   ├── 20060619-20061002_base.par
│   │       │   ├── 20060619-20061002_utm_unw.tif
│   │       │   ├── 20060619_slc.par
│   │       │   ├── 20060619_utm_dem.par
│   │       │   ├── 20060619_utm_dem.tif
│   │       │   ├── 20060828-20061211_base.par
│   │       │   ├── 20060828-20061211_utm_unw.tif
│   │       │   ├── 20060828_slc.par
│   │       │   ├── 20061002-20070219_base.par
│   │       │   ├── 20061002-20070219_utm_unw.tif
│   │       │   ├── 20061002-20070430_base.par
│   │       │   ├── 20061002-20070430_utm_unw.tif
│   │       │   ├── 20061002_slc.par
│   │       │   ├── 20061106-20061211_base.par
│   │       │   ├── 20061106-20061211_utm_unw.tif
│   │       │   ├── 20061106-20070115_base.par
│   │       │   ├── 20061106-20070115_utm_unw.tif
│   │       │   ├── 20061106-20070326_base.par
│   │       │   ├── 20061106-20070326_utm_unw.tif
│   │       │   ├── 20061106_slc.par
│   │       │   ├── 20061211-20070709_base.par
│   │       │   ├── 20061211-20070709_utm_unw.tif
│   │       │   ├── 20061211-20070813_base.par
│   │       │   ├── 20061211-20070813_utm_unw.tif
│   │       │   ├── 20061211_slc.par
│   │       │   ├── 20070115-20070326_base.par
│   │       │   ├── 20070115-20070326_utm_unw.tif
│   │       │   ├── 20070115-20070917_base.par
│   │       │   ├── 20070115-20070917_utm_unw.tif
│   │       │   ├── 20070115_slc.par
│   │       │   ├── 20070219-20070430_base.par
│   │       │   ├── 20070219-20070430_utm_unw.tif
│   │       │   ├── 20070219-20070604_base.par
│   │       │   ├── 20070219-20070604_utm_unw.tif
│   │       │   ├── 20070219_slc.par
│   │       │   ├── 20070326-20070917_base.par
│   │       │   ├── 20070326-20070917_utm_unw.tif
│   │       │   ├── 20070326_slc.par
│   │       │   ├── 20070430-20070604_base.par
│   │       │   ├── 20070430-20070604_utm_unw.tif
│   │       │   ├── 20070430_slc.par
│   │       │   ├── 20070604-20070709_base.par
│   │       │   ├── 20070604-20070709_utm_unw.tif
│   │       │   ├── 20070604_slc.par
│   │       │   ├── 20070709-20070813_base.par
│   │       │   ├── 20070709-20070813_utm_unw.tif
│   │       │   ├── 20070709_slc.par
│   │       │   ├── 20070813_slc.par
│   │       │   ├── 20070917_slc.par
│   │       │   ├── baseline_list.txt
│   │       │   ├── header_list.txt
│   │       │   ├── input_parameters.conf
│   │       │   └── interferogram_list.txt
│   │       └── roipac/
│   │           ├── dem/
│   │           │   ├── roipac_test_trimmed.dem
│   │           │   └── roipac_test_trimmed.dem.rsc
│   │           ├── header_list.txt
│   │           ├── headers/
│   │           │   ├── geo_060619-061002.unw.rsc
│   │           │   ├── geo_060828-061211.unw.rsc
│   │           │   ├── geo_061002-070219.unw.rsc
│   │           │   ├── geo_061002-070430.unw.rsc
│   │           │   ├── geo_061106-061211.unw.rsc
│   │           │   ├── geo_061106-070115.unw.rsc
│   │           │   ├── geo_061106-070326.unw.rsc
│   │           │   ├── geo_061211-070709.unw.rsc
│   │           │   ├── geo_061211-070813.unw.rsc
│   │           │   ├── geo_070115-070326.unw.rsc
│   │           │   ├── geo_070115-070917.unw.rsc
│   │           │   ├── geo_070219-070430.unw.rsc
│   │           │   ├── geo_070219-070604.unw.rsc
│   │           │   ├── geo_070326-070917.unw.rsc
│   │           │   ├── geo_070430-070604.unw.rsc
│   │           │   ├── geo_070604-070709.unw.rsc
│   │           │   └── geo_070709-070813.unw.rsc
│   │           ├── input_parameters.conf
│   │           ├── interferogram_list.txt
│   │           └── interferograms/
│   │               ├── geo_060619-061002.unw
│   │               ├── geo_060619-061002.unw.rsc
│   │               ├── geo_060619-061002_unw.tif
│   │               ├── geo_060828-061211.unw
│   │               ├── geo_060828-061211.unw.rsc
│   │               ├── geo_060828-061211_unw.tif
│   │               ├── geo_061002-070219.unw
│   │               ├── geo_061002-070219.unw.rsc
│   │               ├── geo_061002-070219_unw.tif
│   │               ├── geo_061002-070430.unw
│   │               ├── geo_061002-070430.unw.rsc
│   │               ├── geo_061002-070430_unw.tif
│   │               ├── geo_061106-061211.unw
│   │               ├── geo_061106-061211.unw.rsc
│   │               ├── geo_061106-061211_unw.tif
│   │               ├── geo_061106-070115.unw
│   │               ├── geo_061106-070115.unw.rsc
│   │               ├── geo_061106-070115_unw.tif
│   │               ├── geo_061106-070326.unw
│   │               ├── geo_061106-070326.unw.rsc
│   │               ├── geo_061106-070326_unw.tif
│   │               ├── geo_061211-070709.unw
│   │               ├── geo_061211-070709.unw.rsc
│   │               ├── geo_061211-070709_unw.tif
│   │               ├── geo_061211-070813.unw
│   │               ├── geo_061211-070813.unw.rsc
│   │               ├── geo_061211-070813_unw.tif
│   │               ├── geo_070115-070326.unw
│   │               ├── geo_070115-070326.unw.rsc
│   │               ├── geo_070115-070326_unw.tif
│   │               ├── geo_070115-070917.unw
│   │               ├── geo_070115-070917.unw.rsc
│   │               ├── geo_070115-070917_unw.tif
│   │               ├── geo_070219-070430.unw
│   │               ├── geo_070219-070430.unw.rsc
│   │               ├── geo_070219-070430_unw.tif
│   │               ├── geo_070219-070604.unw
│   │               ├── geo_070219-070604.unw.rsc
│   │               ├── geo_070219-070604_unw.tif
│   │               ├── geo_070326-070917.unw
│   │               ├── geo_070326-070917.unw.rsc
│   │               ├── geo_070326-070917_unw.tif
│   │               ├── geo_070430-070604.unw
│   │               ├── geo_070430-070604.unw.rsc
│   │               ├── geo_070430-070604_unw.tif
│   │               ├── geo_070604-070709.unw
│   │               ├── geo_070604-070709.unw.rsc
│   │               ├── geo_070604-070709_unw.tif
│   │               ├── geo_070709-070813.unw
│   │               ├── geo_070709-070813.unw.rsc
│   │               ├── geo_070709-070813_unw.tif
│   │               └── roipac_test_trimmed_dem.tif
│   ├── test_dem_error.py
│   ├── test_gamma.py
│   ├── test_gamma_vs_roipac.py
│   ├── test_gdal_python.py
│   ├── test_geometry.py
│   ├── test_merge.py
│   ├── test_mpi.py
│   ├── test_mpi_vs_multiprocess_vs_single_process.py
│   ├── test_mst.py
│   ├── test_orbital.py
│   ├── test_prepifg.py
│   ├── test_prepifg_system_vs_python.py
│   ├── test_pyrate.py
│   ├── test_ref_phs_est.py
│   ├── test_refpixel.py
│   ├── test_roipac.py
│   ├── test_shared.py
│   ├── test_stackrate.py
│   ├── test_system.py
│   └── test_timeseries.py
└── utils/
    ├── .coveragerc
    ├── __init__.py
    ├── create_lv_theta.py
    ├── crop_ifgs.py
    ├── developer_hints.txt
    ├── docker_install.txt
    ├── gdaldem.py
    ├── list_creator.sh
    ├── make_tscuml_animation.py
    ├── plot_correction_files.py
    ├── plot_linear_rate_profile.py
    ├── plot_sbas_network.py
    ├── plot_time_series.py
    └── pyrate_pycallgraph.py
Download .txt
SYMBOL INDEX (1108 symbols across 73 files)

FILE: docs/conf.py
  function setup (line 195) | def setup(app):

FILE: pyrate/configuration.py
  function set_parameter_value (line 34) | def set_parameter_value(data_type, input_value, default_value, required,...
  function validate_parameter_value (line 47) | def validate_parameter_value(input_name, input_value, min_value=None, ma...
  function validate_file_list_values (line 72) | def validate_file_list_values(file_list, no_of_epochs):
  class MultiplePaths (line 87) | class MultiplePaths:
    method __init__ (line 88) | def __init__(self, file_name: str, params: dict, input_type: InputType...
    method orb_error_path (line 125) | def orb_error_path(ifg_path: Union[str, Path], params) -> Path:
    method dem_error_path (line 137) | def dem_error_path(ifg_path: Union[str, Path], params) -> Path:
    method aps_error_path (line 144) | def aps_error_path(ifg_path: Union[str, Path], params) -> Path:
    method __str__ (line 158) | def __str__(self):  # pragma: no cover
  class Configuration (line 172) | class Configuration:
    method __init__ (line 174) | def __init__(self, config_file_path):
    method ref_pixel_path (line 327) | def ref_pixel_path(params):
    method mst_path (line 340) | def mst_path(params, index) -> Path:
    method preread_ifgs (line 344) | def preread_ifgs(params: dict) -> Path:
    method vcmt_path (line 348) | def vcmt_path(params):
    method phase_closure_filtered_ifgs_list (line 352) | def phase_closure_filtered_ifgs_list(params):
    method refresh_ifg_list (line 355) | def refresh_ifg_list(self, params):  # update params dict
    method ref_phs_file (line 362) | def ref_phs_file(params):
    method get_tiles (line 371) | def get_tiles(params):
    method __get_files_from_attr (line 376) | def __get_files_from_attr(self, attr, input_type=InputTypes.IFG):
    method closure (line 381) | def closure(self):
    method coherence_stats (line 394) | def coherence_stats(params):
    method geometry_files (line 399) | def geometry_files(params):
  function write_config_parser_file (line 404) | def write_config_parser_file(conf: ConfigParser, output_conf_file: Union...
  function write_config_file (line 410) | def write_config_file(params, output_conf_file):
  function parse_namelist (line 443) | def parse_namelist(nml):
  class ConfigException (line 457) | class ConfigException(Exception):

FILE: pyrate/conv2tif.py
  function main (line 40) | def main(params):
  function do_geotiff (line 74) | def do_geotiff(unw_paths: List[MultiplePaths], params: dict) -> List[str]:
  function _geotiff_multiprocessing (line 93) | def _geotiff_multiprocessing(unw_path: MultiplePaths, params: dict) -> T...

FILE: pyrate/core/algorithm.py
  function is_square (line 26) | def is_square(arr):
  function least_squares_covariance (line 42) | def least_squares_covariance(A, b, v):
  function los_conversion (line 94) | def los_conversion(phase_data, unit_vec):
  function unit_vector (line 109) | def unit_vector(incidence, azimuth):
  function ifg_date_lookup (line 126) | def ifg_date_lookup(ifgs, date_pair):
  function ifg_date_index_lookup (line 161) | def ifg_date_index_lookup(ifgs, date_pair):
  function get_epochs (line 191) | def get_epochs(ifgs: Union[Iterable, Dict]) -> Tuple[EpochList, int]:
  function get_all_epochs (line 212) | def get_all_epochs(ifgs):
  function first_second_ids (line 225) | def first_second_ids(dates):
  function factorise_integer (line 240) | def factorise_integer(n, memo={}, left=2):

FILE: pyrate/core/aps.py
  function spatio_temporal_filter (line 43) | def spatio_temporal_filter(params: dict) -> None:
  function _calc_svd_time_series (line 101) | def _calc_svd_time_series(ifg_paths: List[str], params: dict, preread_if...
  function _assemble_tsincr (line 135) | def _assemble_tsincr(ifg_paths: List[str], params: dict, preread_ifgs: d...
  function _make_aps_corrections (line 151) | def _make_aps_corrections(ts_aps: np.ndarray, ifgs: List[Ifg], params: d...
  function _apply_aps_correction (line 175) | def _apply_aps_correction(ifg_paths: List[str], aps_paths: List[str], pa...
  function spatial_low_pass_filter (line 196) | def spatial_low_pass_filter(ts_hp: np.ndarray, ifg: Ifg, params: dict) -...
  function _interpolate_nans_2d (line 232) | def _interpolate_nans_2d(arr: np.ndarray, method: str) -> None:
  function _slpfilter (line 247) | def _slpfilter(phase: np.ndarray, ifg: Ifg, r_dist: float, params: dict)...
  function gaussian_spatial_filter (line 266) | def gaussian_spatial_filter(image: np.ndarray, cutoff: float, x_size: fl...
  function temporal_high_pass_filter (line 322) | def temporal_high_pass_filter(tsincr: np.ndarray, epochlist: EpochList,
  function gaussian_temporal_filter (line 366) | def gaussian_temporal_filter(tsincr: np.ndarray, cutoff: float, span: np...
  function _kernel (line 392) | def _kernel(x: np.ndarray, sigma: float) -> np.ndarray:

FILE: pyrate/core/covariance.py
  function _pendiffexp (line 41) | def _pendiffexp(alphamod, cvdav):
  function _unique_points (line 56) | def _unique_points(points):  # pragma: no cover
  function cvd (line 65) | def cvd(ifg_path, params, r_dist, calc_alpha=False, write_vals=False, sa...
  function _save_cvd_data (line 107) | def _save_cvd_data(acg, r_dist, ifg_path, outdir):
  function cvd_from_phase (line 116) | def cvd_from_phase(phase, ifg, r_dist, calc_alpha, save_acg=False, param...
  class RDist (line 199) | class RDist():
    method __init__ (line 204) | def __init__(self, ifg):
    method __call__ (line 209) | def __call__(self):
  function _get_autogrid (line 229) | def _get_autogrid(phase):
  function _calc_autoc_grid (line 239) | def _calc_autoc_grid(phase):
  function _calc_power_spectrum (line 248) | def _calc_power_spectrum(phase):
  function get_vcmt (line 257) | def get_vcmt(ifgs, maxvar):
  function maxvar_vcm_calc_wrapper (line 312) | def maxvar_vcm_calc_wrapper(params):

FILE: pyrate/core/dem_error.py
  function dem_error_calc_wrapper (line 35) | def dem_error_calc_wrapper(params: dict) -> None:
  function _process_dem_error_per_tile (line 86) | def _process_dem_error_per_tile(tile: Tile, params: dict) -> None:
  function _calculate_bperp_wrapper (line 141) | def _calculate_bperp_wrapper(ifg_paths: list, az_parts: np.ndarray, rg_p...
  function calc_dem_errors (line 169) | def calc_dem_errors(ifgs: list, bperp: np.ndarray, look_angle: np.ndarra...
  function _per_tile_setup (line 231) | def _per_tile_setup(ifgs: list) -> Tuple[np.ndarray, np.ndarray, int, in...
  function _write_dem_errors (line 259) | def _write_dem_errors(ifg_paths: list, params: dict, preread_ifgs: dict)...
  function __check_and_apply_demerrors_found_on_disc (line 306) | def __check_and_apply_demerrors_found_on_disc(ifg_paths: list, params: d...
  function _save_dem_error_corrected_phase (line 331) | def _save_dem_error_corrected_phase(ifg: Ifg, bperp: Optional[np.float64...
  class DEMError (line 345) | class DEMError(Exception):

FILE: pyrate/core/gamma.py
  function _parse_header (line 69) | def _parse_header(path):
  function parse_epoch_header (line 79) | def parse_epoch_header(path):
  function _parse_date_time (line 173) | def _parse_date_time(lookup):
  function parse_dem_header (line 199) | def parse_dem_header(path):
  function parse_baseline_header (line 229) | def parse_baseline_header(path: str) -> dict:
  function _frequency_to_wavelength (line 270) | def _frequency_to_wavelength(freq):
  function combine_headers (line 277) | def combine_headers(hdr0, hdr1, dem_hdr, base_hdr=None):
  function manage_headers (line 443) | def manage_headers(dem_header_file, header_paths, baseline_paths=None):
  function get_header_paths (line 474) | def get_header_paths(input_file, slc_file_list):
  function gamma_header (line 490) | def gamma_header(ifg_file_path, params):
  function read_lookup_table (line 519) | def read_lookup_table(head, data_path, xlooks, ylooks, xmin, xmax, ymin,...
  function _check_raw_data (line 597) | def _check_raw_data(bytes_per_col, data_path, ncols, nrows):
  class GammaException (line 613) | class GammaException(Exception):
  function baseline_paths_for (line 617) | def baseline_paths_for(path: str, params: dict) -> str:

FILE: pyrate/core/gdal_python.py
  function coherence_masking (line 36) | def coherence_masking(input_gdal_dataset: Dataset, coh_file_path: str,
  function world_to_pixel (line 64) | def world_to_pixel(geo_transform, x, y):
  function resample_nearest_neighbour (line 89) | def resample_nearest_neighbour(input_tif, extents, new_res, output_file):
  function _crop_resample_setup (line 109) | def _crop_resample_setup(extents, input_tif, new_res, output_file,
  function _gdalwarp_width_and_height (line 151) | def _gdalwarp_width_and_height(max_x, max_y, min_x, min_y, geo_trans):
  function crop_resample_average (line 164) | def crop_resample_average(
  function _add_looks_and_crop_from_header (line 254) | def _add_looks_and_crop_from_header(hdr, md, coh_thr):
  function _alignment (line 272) | def _alignment(input_tif, new_res, resampled_average, src_ds_mem,
  function gdal_average (line 296) | def gdal_average(dst_ds, src_ds, src_ds_mem, thresh):
  function _setup_source (line 327) | def _setup_source(input_tif):
  function _get_resampled_data_size (line 343) | def _get_resampled_data_size(xscale, yscale, data):

FILE: pyrate/core/geometry.py
  function get_lonlat_coords (line 31) | def get_lonlat_coords(ifg: Ifg) -> Tuple[MemGeometry, MemGeometry]:
  function calc_radar_coords (line 55) | def calc_radar_coords(ifg: Ifg, params: dict, xmin: int, xmax: int,
  function get_sat_positions (line 89) | def get_sat_positions(lat: np.ndarray, lon: np.ndarray, look_angle: np.n...
  function calc_pixel_geometry (line 123) | def calc_pixel_geometry(ifg: Union[Ifg, IfgPart], rg: np.ndarray, lon: n...
  function calc_local_baseline (line 184) | def calc_local_baseline(ifg: Ifg, az: np.ndarray, look_angle: np.ndarray...
  function vincinv (line 218) | def vincinv(lat1: np.ndarray, lon1: np.ndarray, lat2: np.ndarray, lon2: ...

FILE: pyrate/core/logger.py
  function configure_stage_log (line 32) | def configure_stage_log(verbosity, step_name, log_file_name='pyrate.log.'):
  function warn_with_traceback (line 48) | def warn_with_traceback(message, category, filename, lineno, line=None):
  class MPIStreamHandler (line 58) | class MPIStreamHandler(logging.StreamHandler):
    method emit (line 62) | def emit(self, record):

FILE: pyrate/core/mpiops.py
  class MPI (line 48) | class MPI:
  class comm (line 51) | class comm:
    method barrier (line 57) | def barrier():
    method reduce (line 61) | def reduce(arr, op, root=0):
    method Get_size (line 65) | def Get_size():
    method allgather (line 69) | def allgather(* args):
    method gather (line 73) | def gather(* args, **kwargs):
    method allreduce (line 77) | def allreduce(arr, op):
    method Bcast (line 81) | def Bcast(arr, root=0):
    method bcast (line 85) | def bcast(arr, root=0):
  class MPIException (line 89) | class MPIException(Exception):
  function validate_mpi (line 93) | def validate_mpi():
  function run_once (line 98) | def run_once(f: Callable, *args, **kwargs) -> Any:
  function array_split (line 129) | def array_split(arr: Iterable, process: int = None) -> Iterable:
  function sum_vars (line 147) | def sum_vars(x, y, dtype):
  function sum_axis_0 (line 152) | def sum_axis_0(x, y, dtype):

FILE: pyrate/core/mst.py
  function mst_from_ifgs (line 45) | def mst_from_ifgs(ifgs):
  function mst_parallel (line 73) | def mst_parallel(ifgs, params):
  function mst_multiprocessing (line 114) | def mst_multiprocessing(tile, ifgs_or_paths, preread_ifgs=None, params=N...
  function _build_graph_networkx (line 137) | def _build_graph_networkx(edges_with_weights):
  function mst_boolean_array (line 146) | def mst_boolean_array(ifgs):
  function _mst_matrix_ifgs_only (line 173) | def _mst_matrix_ifgs_only(ifgs):
  function _mst_matrix_as_array (line 190) | def _mst_matrix_as_array(ifgs):
  function mst_matrix_networkx (line 205) | def mst_matrix_networkx(ifgs):
  function _minimum_spanning_edges_from_mst (line 260) | def _minimum_spanning_edges_from_mst(edges):
  function mst_calc_wrapper (line 270) | def mst_calc_wrapper(params):

FILE: pyrate/core/orbital.py
  function remove_orbital_error (line 74) | def remove_orbital_error(ifgs: List, params: dict) -> None:
  function __create_multilooked_datasets (line 130) | def __create_multilooked_datasets(params):
  function __extents_from_params (line 141) | def __extents_from_params(params):
  function _create_mlooked_dataset (line 152) | def _create_mlooked_dataset(multi_path, ifg_path, exts, params):
  function _validate_mlooked (line 169) | def _validate_mlooked(mlooked, ifgs):
  function _get_num_params (line 183) | def _get_num_params(degree, intercept: Optional[bool] = False):
  function independent_orbital_correction (line 205) | def independent_orbital_correction(ifg_path, params):
  function __orb_correction (line 273) | def __orb_correction(fullres_dm, mlooked_dm, fullres_phase, mlooked_phas...
  function __orb_inversion (line 294) | def __orb_inversion(design_matrix, data):
  function network_orbital_correction (line 303) | def network_orbital_correction(ifg_paths, params, m_ifgs: Optional[List]...
  function calc_network_orb_correction (line 366) | def calc_network_orb_correction(src_ifgs, degree, scale, nepochs, interc...
  function __check_and_apply_orberrors_found_on_disc (line 392) | def __check_and_apply_orberrors_found_on_disc(ifg_paths, params):
  function _remove_network_orb_error (line 410) | def _remove_network_orb_error(coefs, dm, ifg, ids, offset, params):
  function _save_orbital_error_corrected_phase (line 431) | def _save_orbital_error_corrected_phase(ifg, params):
  function __methods_as_string (line 446) | def __methods_as_string(method):
  function __degrees_as_string (line 452) | def __degrees_as_string(degree):
  function get_design_matrix (line 459) | def get_design_matrix(ifg, degree, intercept: Optional[bool] = True, sca...
  function get_network_design_matrix (line 519) | def get_network_design_matrix(ifgs, degree, scale, intercept=True):
  class OrbitalError (line 573) | class OrbitalError(Exception):
  function orb_fit_calc_wrapper (line 579) | def orb_fit_calc_wrapper(params: dict) -> None:

FILE: pyrate/core/phase_closure/closure_check.py
  function mask_pixels_with_unwrapping_errors (line 32) | def mask_pixels_with_unwrapping_errors(ifgs_breach_count: NDArray[(Any, ...
  function __drop_ifgs_if_not_part_of_any_loop (line 56) | def __drop_ifgs_if_not_part_of_any_loop(ifg_files: List[str], loops: Lis...
  function __drop_ifgs_exceeding_threshold (line 80) | def __drop_ifgs_exceeding_threshold(orig_ifg_files: List[str], ifgs_brea...
  function iterative_closure_check (line 113) | def iterative_closure_check(config, interactive_plot=True) -> \
  function discard_loops_containing_max_ifg_count (line 147) | def discard_loops_containing_max_ifg_count(loops: List[WeightedLoop], pa...
  function __wrap_closure_check (line 169) | def __wrap_closure_check(config: Configuration) -> \
  function update_ifg_list (line 223) | def update_ifg_list(ifg_files: List[str], multi_paths: List[MultiplePath...

FILE: pyrate/core/phase_closure/collect_loops.py
  function dfs (line 21) | def dfs(graph, marked, n, vert, start, count, loop, all_loops):
  function find_loops (line 59) | def find_loops(graph, loop_length):
  function dedupe_loops (line 76) | def dedupe_loops(loops: List[List]) -> List:

FILE: pyrate/core/phase_closure/mst_closure.py
  class SignedEdge (line 31) | class SignedEdge:
    method __init__ (line 33) | def __init__(self, edge: Edge, sign: int):
    method __repr__ (line 39) | def __repr__(self):
  class SignedWeightedEdge (line 43) | class SignedWeightedEdge(SignedEdge):
    method __init__ (line 45) | def __init__(self, signed_edge: SignedEdge, weight: int):
  class WeightedLoop (line 51) | class WeightedLoop:
    method __init__ (line 56) | def __init__(self, loop: List[SignedWeightedEdge]):
    method weight (line 60) | def weight(self):
    method earliest_date (line 64) | def earliest_date(self):
    method primary_dates (line 68) | def primary_dates(self):
    method secondary_dates (line 75) | def secondary_dates(self):
    method __len__ (line 81) | def __len__(self):
    method edges (line 85) | def edges(self):
  function __find_closed_loops (line 89) | def __find_closed_loops(edges: List[Edge], max_loop_length: int) -> List...
  function __add_signs_and_weights_to_loops (line 119) | def __add_signs_and_weights_to_loops(loops: List[List[date]], available_...
  function __setup_edges (line 152) | def __setup_edges(ifg_files: List[str]) -> List[Edge]:
  function __find_signed_closed_loops (line 161) | def __find_signed_closed_loops(params: dict) -> List[WeightedLoop]:
  function sort_loops_based_on_weights_and_date (line 171) | def sort_loops_based_on_weights_and_date(params: dict) -> List[WeightedL...

FILE: pyrate/core/phase_closure/plot_closure.py
  function plot_closure (line 27) | def plot_closure(closure: np.ndarray, loops: List[WeightedLoop],

FILE: pyrate/core/phase_closure/sum_closure.py
  class IfgPhase (line 32) | class IfgPhase:
    method __init__ (line 37) | def __init__(self, phase_data):
  function __create_ifg_edge_dict (line 41) | def __create_ifg_edge_dict(ifg_files: List[str], params: dict) -> Dict[E...
  function sum_phase_closures (line 64) | def sum_phase_closures(ifg_files: List[str], loops: List[WeightedLoop], ...
  function _find_num_occurrences_each_ifg (line 145) | def _find_num_occurrences_each_ifg(loops: List[WeightedLoop],
  function __compute_ifgs_breach_count (line 158) | def __compute_ifgs_breach_count(weighted_loop: WeightedLoop,

FILE: pyrate/core/prepifg_helper.py
  function get_analysis_extent (line 51) | def get_analysis_extent(crop_opt: int, rasters: List[Union[Ifg, DEM]], x...
  function _is_number (line 84) | def _is_number(s):
  function _check_looks (line 97) | def _check_looks(xlooks, ylooks):
  function _check_resolution (line 116) | def _check_resolution(ifgs: List[Union[Ifg, DEM]]):
  function _get_extents (line 133) | def _get_extents(ifgs, crop_opt, user_exts=None):
  function prepare_ifg (line 155) | def prepare_ifg(raster_path, xlooks, ylooks, exts, thresh, crop_opt, hea...
  function _resample (line 206) | def _resample(data, xscale, yscale, thresh):
  function __bounds (line 240) | def __bounds(ifgs: List[Ifg], func: Callable) -> Tuple[float, float, flo...
  function _get_same_bounds (line 265) | def _get_same_bounds(ifgs: List[Ifg]) -> Tuple[float, float, float, float]:
  function _custom_bounds (line 300) | def _custom_bounds(ifgs, xw, ytop, xe, ybot):
  function _check_crop_coords (line 359) | def _check_crop_coords(ifgs, xmin, ymin, xmax, ymax):
  class PreprocessError (line 384) | class PreprocessError(Exception):
  function transform_params (line 390) | def transform_params(params):
  function coherence_paths_for (line 405) | def coherence_paths_for(path: str, params: dict, tif=False) -> str:

FILE: pyrate/core/ref_phs_est.py
  function est_ref_phase_patch_median (line 35) | def est_ref_phase_patch_median(ifg_paths, params, refpx, refpy):
  function _est_ref_phs_patch_median (line 81) | def _est_ref_phs_patch_median(phase_data, half_chip_size, refpx, refpy, ...
  function est_ref_phase_ifg_median (line 98) | def est_ref_phase_ifg_median(ifg_paths, params):
  function _est_ref_phs_ifg_median (line 160) | def _est_ref_phs_ifg_median(phase_data, comp):
  function _update_phase_and_metadata (line 169) | def _update_phase_and_metadata(ifgs, ref_phs, params):
  class ReferencePhaseError (line 191) | class ReferencePhaseError(Exception):
  function ref_phase_est_wrapper (line 198) | def ref_phase_est_wrapper(params):

FILE: pyrate/core/refpixel.py
  function update_refpix_metadata (line 42) | def update_refpix_metadata(ifg_paths, refx, refy, transform, params):
  function convert_pixel_value_to_geographic_coordinate (line 78) | def convert_pixel_value_to_geographic_coordinate(refx, refy, transform):
  function lat_from_pixel_coordinate (line 97) | def lat_from_pixel_coordinate(refy, transform):
  function lon_from_pixel_coordinate (line 104) | def lon_from_pixel_coordinate(refx, transform):
  function convert_geographic_coordinate_to_pixel_value (line 111) | def convert_geographic_coordinate_to_pixel_value(lon, lat, transform):
  function ref_pixel (line 136) | def ref_pixel(ifgs, params):
  function find_min_mean (line 180) | def find_min_mean(mean_sds, grid):
  function ref_pixel_setup (line 200) | def ref_pixel_setup(ifgs_or_paths, params):
  function save_ref_pixel_blocks (line 247) | def save_ref_pixel_blocks(grid, half_patch_size, ifg_paths, params):
  function _ref_pixel_mpi (line 277) | def _ref_pixel_mpi(process_grid, half_patch_size, ifgs, thresh, params):
  function _ref_pixel_multi (line 288) | def _ref_pixel_multi(g, half_patch_size, phase_data_or_ifg_paths,
  function _step (line 319) | def _step(dim, ref, radius):
  function _validate_chipsize (line 344) | def _validate_chipsize(chipsize, head):
  function _validate_minimum_fraction (line 357) | def _validate_minimum_fraction(min_frac):
  function _validate_search_win (line 368) | def _validate_search_win(refnx, refny, chipsize, head):
  function __validate_supplied_lat_lon (line 389) | def __validate_supplied_lat_lon(params: dict) -> None:
  class RefPixelError (line 413) | class RefPixelError(Exception):
  function ref_pixel_calc_wrapper (line 419) | def ref_pixel_calc_wrapper(params: dict) -> Tuple[int, int]:

FILE: pyrate/core/roipac.py
  function parse_date (line 77) | def parse_date(dstr):
  function parse_header (line 98) | def parse_header(hdr_file):
  function _parse_dates_from (line 169) | def _parse_dates_from(filename):
  function manage_header (line 186) | def manage_header(header_file, projection):
  function roipac_header (line 204) | def roipac_header(file_path, params):
  class RoipacException (line 234) | class RoipacException(Exception):

FILE: pyrate/core/shared.py
  class InputTypes (line 68) | class InputTypes(Enum):
  function joblib_log_level (line 82) | def joblib_log_level(level: str) -> int:
  function mkdir_p (line 91) | def mkdir_p(path):
  class RasterBase (line 108) | class RasterBase(object):
    method __init__ (line 114) | def __init__(self, path: Union[gdal.Dataset, str, Path]):
    method __str__ (line 128) | def __str__(self):
    method __repr__ (line 132) | def __repr__(self):
    method open (line 136) | def open(self, readonly=None):
    method add_geographic_data (line 161) | def add_geographic_data(self):
    method ncols (line 174) | def ncols(self):
    method nrows (line 181) | def nrows(self):
    method x_step (line 188) | def x_step(self):
    method y_step (line 195) | def y_step(self):
    method x_first (line 202) | def x_first(self):
    method x_last (line 209) | def x_last(self):
    method y_first (line 216) | def y_first(self):
    method y_last (line 223) | def y_last(self):
    method shape (line 230) | def shape(self):
    method num_cells (line 237) | def num_cells(self):
    method is_open (line 247) | def is_open(self):
    method close (line 253) | def close(self):
    method is_read_only (line 263) | def is_read_only(self):
    method _get_band (line 269) | def _get_band(self, band):
  class Ifg (line 281) | class Ifg(RasterBase):
    method __init__ (line 287) | def __init__(self, path: Union[str, Path, gdal.Dataset]):
    method open (line 305) | def open(self, readonly=None):
    method initialize (line 314) | def initialize(self):
    method _init_dates (line 324) | def _init_dates(self):
    method convert_to_nans (line 342) | def convert_to_nans(self):
    method phase_band (line 371) | def phase_band(self):
    method nodata_value (line 380) | def nodata_value(self):
    method nodata_value (line 387) | def nodata_value(self, val):
    method phase_data (line 394) | def phase_data(self):
    method convert_to_mm (line 403) | def convert_to_mm(self):
    method convert_to_radians (line 430) | def convert_to_radians(self):
    method phase_data (line 454) | def phase_data(self, data):
    method phase_rows (line 461) | def phase_rows(self):
    method nan_count (line 471) | def nan_count(self):
    method nan_fraction (line 478) | def nan_fraction(self):
    method write_modified_phase (line 494) | def write_modified_phase(self, data=None):
    method add_metadata (line 518) | def add_metadata(self, **kwargs):
  class Tile (line 527) | class Tile:
    method __init__ (line 531) | def __init__(self, index, top_left, bottom_right):
    method __str__ (line 549) | def __str__(self):
  class IfgPart (line 553) | class IfgPart(object):
    method __init__ (line 557) | def __init__(self, ifg_or_path, tile: Tile, ifg_dict=None, params=None):
    method read_tile (line 591) | def read_tile(self, ifg: Ifg):
    method nrows (line 608) | def nrows(self):
    method ncols (line 615) | def ncols(self):
  class Incidence (line 622) | class Incidence(RasterBase):   # pragma: no cover
    method __init__ (line 628) | def __init__(self, path):
    method incidence_band (line 639) | def incidence_band(self):
    method incidence_data (line 649) | def incidence_data(self):
    method azimuth_band (line 658) | def azimuth_band(self):
    method azimuth_data (line 667) | def azimuth_data(self):
  class TileMixin (line 676) | class TileMixin:
    method __call__ (line 677) | def __call__(self, tile: Tile):
  class DEM (line 682) | class DEM(RasterBase, TileMixin):
    method __init__ (line 687) | def __init__(self, path):
    method band (line 696) | def band(self):
    method data (line 707) | def data(self):
  class MemGeometry (line 716) | class MemGeometry(TileMixin):
    method __init__ (line 718) | def __init__(self, data):
    method data (line 725) | def data(self):
  class IfgException (line 732) | class IfgException(Exception):
  class RasterException (line 738) | class RasterException(Exception):
  class EpochList (line 744) | class EpochList(object):
    method __init__ (line 749) | def __init__(self, dates=None, repeat=None, spans=None):
    method __str__ (line 757) | def __str__(self):
    method __repr__ (line 760) | def __repr__(self):
  function convert_radians_to_mm (line 764) | def convert_radians_to_mm(data, wavelength):
  function convert_mm_to_radians (line 777) | def convert_mm_to_radians(data, wavelength):
  function nanmedian (line 790) | def nanmedian(x):
  function _is_interferogram (line 808) | def _is_interferogram(hdr):
  function _is_coherence (line 816) | def _is_coherence(hdr):
  function _is_baseline (line 824) | def _is_baseline(hdr):
  function _is_lookuptable (line 832) | def _is_lookuptable(hdr):
  function _is_incidence (line 840) | def _is_incidence(hdr):
  function write_fullres_geotiff (line 847) | def write_fullres_geotiff(header, data_path, dest, nodata):
  function gdal_dataset (line 912) | def gdal_dataset(out_fname, columns, rows, driver="GTiff", bands=1,
  function collate_metadata (line 942) | def collate_metadata(header):
  function data_format (line 994) | def data_format(ifg_proc, is_ifg, ncols):
  function _check_raw_data (line 1014) | def _check_raw_data(bytes_per_col, data_path, ncols, nrows):
  function write_unw_from_data_or_geotiff (line 1025) | def write_unw_from_data_or_geotiff(geotif_or_data, dest_unw, ifg_proc):
  function write_output_geotiff (line 1057) | def write_output_geotiff(md, gt, wkt, data, dest, nodata):
  function write_geotiff (line 1098) | def write_geotiff(data, outds, nodata):
  class GeotiffException (line 1129) | class GeotiffException(Exception):
  function create_tiles (line 1135) | def create_tiles(shape, nrows=2, ncols=2):
  function get_tiles (line 1164) | def get_tiles(ifg_path, rows, cols) -> List[Tile]:
  function nan_and_mm_convert (line 1183) | def nan_and_mm_convert(ifg, params):
  function cell_size (line 1201) | def cell_size(lat, lon, x_step, y_step):
  function _utm_zone (line 1230) | def _utm_zone(longitude):
  class PrereadIfg (line 1241) | class PrereadIfg:
    method __init__ (line 1247) | def __init__(self, path, tmp_path, nan_fraction, first, second, time_s...
  function save_numpy_phase (line 1261) | def save_numpy_phase(ifg_paths, params):
  function get_geotiff_header_info (line 1291) | def get_geotiff_header_info(ifg_path):
  function warp_required (line 1312) | def warp_required(xlooks, ylooks, crop):
  function check_correction_status (line 1330) | def check_correction_status(ifgs, meta):  # pragma: no cover
  class CorrectionStatusError (line 1372) | class CorrectionStatusError(Exception):
  function extract_epochs_from_filename (line 1378) | def extract_epochs_from_filename(filename_with_epochs: str) -> List[str]:
  function mpi_vs_multiprocess_logging (line 1385) | def mpi_vs_multiprocess_logging(step, params):
  function dem_or_ifg (line 1397) | def dem_or_ifg(data_path: str) -> Union[Ifg, DEM]:
  function join_dicts (line 1415) | def join_dicts(dicts: List[dict]) -> dict:
  function iterable_split (line 1425) | def iterable_split(func: Callable, iterable: Iterable, params: dict, *ar...
  function tiles_split (line 1452) | def tiles_split(func: Callable, params: dict, *args, **kwargs) -> np.nda...
  function output_tiff_filename (line 1462) | def output_tiff_filename(inpath: str, outpath: str) -> str:
  function remove_file_if_exists (line 1479) | def remove_file_if_exists(filename: str) -> None:

FILE: pyrate/core/stack.py
  function stack_rate_array (line 34) | def stack_rate_array(ifgs, params, vcmt, mst=None):
  function mask_rate (line 62) | def mask_rate(rate, error, maxsig):
  function stack_rate_pixel (line 92) | def stack_rate_pixel(obs, mst, vcmt, span, nsig, pthresh):
  function _stack_setup (line 168) | def _stack_setup(ifgs, mst, params):
  function stack_calc_wrapper (line 194) | def stack_calc_wrapper(params):
  function _stacking_for_tile (line 208) | def _stacking_for_tile(tile, params):

FILE: pyrate/core/timeseries.py
  function _time_series_setup (line 40) | def _time_series_setup(ifgs, params, mst=None):
  function _validate_params (line 87) | def _validate_params(params, tsmethod):
  function time_series (line 111) | def time_series(ifgs, params, vcmt=None, mst=None):
  function _remove_rank_def_rows (line 160) | def _remove_rank_def_rows(b_mat, nvelpar, ifgv, sel):
  function _time_series_pixel (line 173) | def _time_series_pixel(row, col, b0_mat, sm_factor, sm_order, ifg_data, ...
  function _solve_ts_svd (line 214) | def _solve_ts_svd(nvelpar, velflag, ifgv, b_mat):
  function _solve_ts_lap (line 225) | def _solve_ts_lap(nvelpar, velflag, ifgv, mat_b, smorder, smfactor, sel,...
  function linear_rate_pixel (line 292) | def linear_rate_pixel(y, t):
  function linear_rate_array (line 332) | def linear_rate_array(tscuml, ifgs, params):
  function _missing_option_error (line 382) | def _missing_option_error(option):
  class TimeSeriesError (line 390) | class TimeSeriesError(Exception):
  function timeseries_calc_wrapper (line 396) | def timeseries_calc_wrapper(params):
  function __calc_time_series_for_tile (line 413) | def __calc_time_series_for_tile(tile, params):

FILE: pyrate/correct.py
  function _create_ifg_dict (line 46) | def _create_ifg_dict(params):
  function __save_ifgs_dict_with_headers_and_epochs (line 87) | def __save_ifgs_dict_with_headers_and_epochs(dest_tifs, ifgs_dict, param...
  function _copy_mlooked (line 111) | def _copy_mlooked(params):
  function main (line 124) | def main(config):
  function _update_params_with_tiles (line 145) | def _update_params_with_tiles(params: dict) -> None:
  function phase_closure_wrapper (line 153) | def phase_closure_wrapper(params: dict, config: Configuration) -> dict:
  function correct_ifgs (line 208) | def correct_ifgs(config: Configuration) -> None:
  function __validate_correct_steps (line 237) | def __validate_correct_steps(params):

FILE: pyrate/main.py
  function _params_from_conf (line 37) | def _params_from_conf(config_file):
  function update_params_due_to_ifg_selection (line 44) | def update_params_due_to_ifg_selection(config):
  function main (line 53) | def main():
  function timeseries (line 160) | def timeseries(config: Configuration) -> None:
  function stack (line 167) | def stack(config: Configuration) -> None:

FILE: pyrate/merge.py
  function main (line 37) | def main(params: dict) -> None:
  function _merge_stack (line 79) | def _merge_stack(params: dict) -> None:
  function _merge_linrate (line 104) | def _merge_linrate(params: dict) -> None:
  function _merge_timeseries (line 121) | def _merge_timeseries(params: dict, tstype: str) -> None:
  function create_png_and_kml_from_tif (line 149) | def create_png_and_kml_from_tif(output_folder_path: str, output_type: st...
  function assemble_tiles (line 240) | def assemble_tiles(s: Tuple, dir: str, tiles: Tile, out_type: str, index...
  function __save_merged_files (line 290) | def __save_merged_files(ifgs_dict, params, array, out_type, index=None, ...
  function __merge_setup (line 350) | def __merge_setup(params):

FILE: pyrate/prepifg.py
  function main (line 63) | def main(params):
  function __calc_coherence_stats (line 119) | def __calc_coherence_stats(params, ifg_path):
  function do_prepifg (line 137) | def do_prepifg(multi_paths: List[MultiplePaths], exts: Tuple[float, floa...
  function __prepifg_system (line 181) | def __prepifg_system(exts, gtiff, params, res):
  function __update_meta_data (line 250) | def __update_meta_data(p_unset, c, l, params):
  function _prepifg_multiprocessing (line 279) | def _prepifg_multiprocessing(m_path: MultiplePaths, exts: Tuple[float, f...
  function find_header (line 308) | def find_header(path: MultiplePaths, params: dict) -> Dict[str, str]:
  function __write_geometry_files (line 324) | def __write_geometry_files(params: dict, exts: Tuple[float, float, float...
  function __parallelly_write (line 370) | def __parallelly_write(tup, params, ifg_path):
  function __save_geom_files (line 391) | def __save_geom_files(ifg_path, dest, array, out_type):

FILE: scripts/gdal_calc_local.py
  function doit (line 58) | def doit(opts, args):
  function Calc (line 304) | def Calc(calc, outfile, NoDataValue=None, type=None, format='GTiff', cre...
  function store_input_file (line 338) | def store_input_file(option, opt_str, value, parser):
  function main (line 343) | def main():

FILE: scripts/plot_ifgs.py
  function main (line 44) | def main():
  function __plot_ifg (line 118) | def __plot_ifg(file, cmap, ax, num_ifgs, params):

FILE: setup.py
  function update_reqs_based_on_envs (line 50) | def update_reqs_based_on_envs(reqs):
  class CustomInstall (line 61) | class CustomInstall(install):
    method run (line 62) | def run(self):
    method install_setup_requirements (line 72) | def install_setup_requirements():
    method install_requirements (line 78) | def install_requirements():
  class PyTest (line 89) | class PyTest(TestCommand, object):
    method initialize_options (line 91) | def initialize_options(self):
    method finalize_options (line 95) | def finalize_options(self):
    method run_tests (line 100) | def run_tests(self):

FILE: tests/common.py
  function remove_tifs (line 159) | def remove_tifs(path):
  function small_data_setup (line 165) | def small_data_setup(datafiles=None, is_dir=False):
  function assert_tifs_equal (line 186) | def assert_tifs_equal(tif1, tif2):
  function copy_small_ifg_file_list (line 209) | def copy_small_ifg_file_list():
  function copy_and_setup_small_data (line 218) | def copy_and_setup_small_data():
  function small_ifg_file_list (line 229) | def small_ifg_file_list(datafiles=None):
  function small_data_roipac_unws (line 241) | def small_data_roipac_unws():
  function small_data_setup_gamma_unws (line 247) | def small_data_setup_gamma_unws():
  function small5_ifgs (line 253) | def small5_ifgs():
  function small5_ifg_paths (line 260) | def small5_ifg_paths():
  function small5_mock_ifgs (line 270) | def small5_mock_ifgs(xs=3, ys=4):
  class MockIfg (line 280) | class MockIfg(object):
    method __init__ (line 283) | def __init__(self, ifg, xsize=None, ysize=None):
    method __repr__ (line 304) | def __repr__(self, *args, **kwargs):
    method open (line 307) | def open(self):
    method nan_count (line 312) | def nan_count(self):
    method shape (line 316) | def shape(self):
    method write_modified_phase (line 319) | def write_modified_phase(self):  #dummy
    method close (line 322) | def close(self):  # dummy
  function reconstruct_stack_rate (line 326) | def reconstruct_stack_rate(shape, tiles, output_dir, out_type):
  function reconstruct_mst (line 337) | def reconstruct_mst(shape, tiles, output_dir):
  function move_files (line 349) | def move_files(source_dir, dest_dir, file_type='*.tif', copy=False):
  function assert_ifg_phase_equal (line 357) | def assert_ifg_phase_equal(ifg_path1, ifg_path2):
  function prepare_ifgs_without_phase (line 365) | def prepare_ifgs_without_phase(ifg_paths, params):
  function mst_calculation (line 377) | def mst_calculation(ifg_paths_or_instance, params):
  function get_nml (line 391) | def get_nml(ifg_list_instance, nodata_value, nan_conversion=False):
  function compute_time_series (line 412) | def compute_time_series(ifgs, mst_grid, params, vcmt):
  function calculate_time_series (line 431) | def calculate_time_series(ifgs, params, vcmt, mst):
  function write_timeseries_geotiff (line 441) | def write_timeseries_geotiff(ifgs, params, tsincr, pr_type):
  function calculate_stack_rate (line 457) | def calculate_stack_rate(ifgs, params, vcmt, mst_mat=None):
  function write_stackrate_tifs (line 471) | def write_stackrate_tifs(ifgs, params, res):
  function write_stackrate_numpy_files (line 488) | def write_stackrate_numpy_files(error, rate, samples, params):
  function copytree (line 497) | def copytree(src: Union[str, bytes, os.PathLike], dst: Union[str, bytes,...
  function repair_params_for_correct_tests (line 535) | def repair_params_for_correct_tests(out_dir, params):
  function pre_prepare_ifgs (line 546) | def pre_prepare_ifgs(ifg_paths, params):
  function assert_two_dirs_equal (line 557) | def assert_two_dirs_equal(dir1, dir2, ext, num_files=None):
  function assert_same_files_produced (line 586) | def assert_same_files_produced(dir1, dir2, dir3, ext, num_files=None):
  function manipulate_test_conf (line 600) | def manipulate_test_conf(conf_file, work_dir: Path):
  class UnitTestAdaptation (line 642) | class UnitTestAdaptation:
    method assertEqual (line 644) | def assertEqual(arg1, arg2):
    method assertTrue (line 648) | def assertTrue(arg, msg=''):
    method assertFalse (line 652) | def assertFalse(arg, msg=''):
    method assertIsNotNone (line 656) | def assertIsNotNone(arg, msg=''):
    method assertIsNone (line 660) | def assertIsNone(arg, msg=''):
    method assertDictEqual (line 664) | def assertDictEqual(d1: dict, d2: dict):
    method assertRaises (line 668) | def assertRaises(excpt: Exception, func, *args, **kwargs):
    method assertIn (line 673) | def assertIn(item, s: Iterable):
    method assertAlmostEqual (line 677) | def assertAlmostEqual(arg1, arg2, places=7):
  function min_params (line 683) | def min_params(out_dir):
  function sub_process_run (line 698) | def sub_process_run(cmd, *args, **kwargs):
  function original_ifg_paths (line 702) | def original_ifg_paths(ifglist_path, working_dir):

FILE: tests/conftest.py
  function tempdir (line 34) | def tempdir():
  function system_conf (line 44) | def system_conf(request):
  function random_filename (line 51) | def random_filename(tmp_path_factory):
  function mpisync (line 60) | def mpisync(request):
  function coh_mask (line 71) | def coh_mask(request):
  function ref_est_method (line 76) | def ref_est_method(request):
  function ref_pixel (line 81) | def ref_pixel(request):
  function orbfit_lks (line 86) | def orbfit_lks(request):
  function orbfit_method (line 91) | def orbfit_method(request):
  function orbfit_degrees (line 96) | def orbfit_degrees(request):
  function get_lks (line 101) | def get_lks(request):
  function get_crop (line 106) | def get_crop(request):
  function get_config (line 111) | def get_config():
  function gamma_params (line 119) | def gamma_params():
  function roipac_params (line 127) | def roipac_params():
  function mexico_cropa_params (line 134) | def mexico_cropa_params():
  function roipac_or_gamma_conf (line 141) | def roipac_or_gamma_conf(request):
  function gamma_conf (line 146) | def gamma_conf(request):
  function coh_list_file (line 153) | def coh_list_file():
  function dem (line 158) | def dem():
  function gamma_or_mexicoa_conf (line 165) | def gamma_or_mexicoa_conf(request):
  function run_number (line 172) | def run_number(request):
  function geotiffs (line 180) | def geotiffs():
  function ten_geotiffs (line 187) | def ten_geotiffs():
  function cropa_geotifs (line 194) | def cropa_geotifs(mexico_cropa_params):

FILE: tests/phase_closure/common.py
  class IfgDummy (line 1) | class IfgDummy:
    method __init__ (line 2) | def __init__(self, ifg_path):

FILE: tests/phase_closure/conftest.py
  function closure_params (line 9) | def closure_params(geotiffs):
  function cropa_geotifs (line 20) | def cropa_geotifs():

FILE: tests/phase_closure/test_closure_check.py
  function test_discard_loops_containing_max_ifg_count (line 30) | def test_discard_loops_containing_max_ifg_count(closure_params):
  function retain_loops (line 39) | def retain_loops(params):
  function test_drop_ifgs_if_not_part_of_any_loop (line 55) | def test_drop_ifgs_if_not_part_of_any_loop(closure_params):

FILE: tests/phase_closure/test_collect_loops.py
  function test_collect_loops (line 10) | def test_collect_loops():
  function test_count_loops (line 28) | def test_count_loops():
  function __find_closed_loops_nx (line 47) | def __find_closed_loops_nx(edges: List[Edge], max_loop_length: int) -> L...
  function available_edges (line 69) | def available_edges(cropa_geotifs):
  function max_loop_length (line 74) | def max_loop_length(available_edges):
  function test_find_closed_loops_vs_networkx (line 80) | def test_find_closed_loops_vs_networkx(available_edges):

FILE: tests/phase_closure/test_mst_closure.py
  function geotiffs (line 34) | def geotiffs():
  function all_loops (line 41) | def all_loops(geotiffs):
  function edges (line 49) | def edges(geotiffs):
  function signed_loops (line 55) | def signed_loops(all_loops, edges):
  function weight (line 61) | def weight(request):
  function test_setup_edges (line 65) | def test_setup_edges(geotiffs):
  function test_associate_ifgs_with_loops (line 71) | def test_associate_ifgs_with_loops(signed_loops, geotiffs):
  function test_sort_loops_based_on_weights_and_date (line 83) | def test_sort_loops_based_on_weights_and_date(geotiffs):
  function test_add_signs_and_weights_to_loops (line 105) | def test_add_signs_and_weights_to_loops(closure_params):
  function compare_loops (line 120) | def compare_loops(loops1, loops2):
  function test_find_signed_closed_loops (line 132) | def test_find_signed_closed_loops(closure_params):
  function test_sort_loops_based_on_weights_and_date_2 (line 138) | def test_sort_loops_based_on_weights_and_date_2(closure_params):

FILE: tests/phase_closure/test_plot_closure.py
  function test_plot_closure (line 46) | def test_plot_closure(mexico_cropa_params):

FILE: tests/phase_closure/test_sum_closure.py
  function modified_config (line 27) | def modified_config(tempdir, get_lks=1, get_crop=1, orbfit_lks=2, orbfit...
  function test_mpi_vs_single_process (line 65) | def test_mpi_vs_single_process(modified_config):

FILE: tests/test_algorithm.py
  class TestLeastSquaresTests (line 42) | class TestLeastSquaresTests(UnitTestAdaptation):
    method test_least_squares_covariance (line 48) | def test_least_squares_covariance():
    method test_least_squares_covariance_overdetermined (line 56) | def test_least_squares_covariance_overdetermined(self):
  class TestAlgorithmTests (line 70) | class TestAlgorithmTests(UnitTestAdaptation):
    method test_factorise (line 75) | def test_factorise(self):
    method test_is_square (line 86) | def test_is_square(self):
    method test_is_not_square (line 89) | def test_is_not_square(self):
    method test_phase_conversion (line 94) | def test_phase_conversion():
    method test_unit_vector (line 104) | def test_unit_vector(self):
  class TestDateLookup (line 137) | class TestDateLookup(UnitTestAdaptation):
    method setup_class (line 143) | def setup_class(cls):
    method test_ifg_date_lookup (line 146) | def test_ifg_date_lookup(self):
    method test_ifg_date_lookup_failure (line 157) | def test_ifg_date_lookup_failure(self):
    method test_date_lookup_bad_inputs (line 162) | def test_date_lookup_bad_inputs(self):
  class TestEpochs (line 181) | class TestEpochs(UnitTestAdaptation):
    method test_get_epochs (line 186) | def test_get_epochs(self):
    method test_get_all_epochs (line 211) | def test_get_all_epochs(self):
    method test_get_epoch_count (line 221) | def test_get_epoch_count(self):
    method test_first_second_ids (line 224) | def test_first_second_ids(self):

FILE: tests/test_aps.py
  function slpnanfill_method (line 40) | def slpnanfill_method(request):
  function slpfcutoff_method (line 45) | def slpfcutoff_method(request):
  function slpfcutoff (line 50) | def slpfcutoff(request):
  function test_interpolate_nans_2d (line 54) | def test_interpolate_nans_2d(slpnanfill_method):
  class TestSpatialFilter (line 62) | class TestSpatialFilter:
    method setup_method (line 67) | def setup_method(self):
    method test_gaussian_filter (line 78) | def test_gaussian_filter(self, slpfcutoff_method):
  function test_gaussian_kernel (line 92) | def test_gaussian_kernel():
  class TestTemporalFilter (line 110) | class TestTemporalFilter:
    method setup_method (line 115) | def setup_method(self):
    method test_tlpfilter_repeatability (line 130) | def test_tlpfilter_repeatability(self):
    method test_tlpfilter_scipy_sig1 (line 141) | def test_tlpfilter_scipy_sig1(self):
    method test_tlpfilter_scipy_sig2 (line 150) | def test_tlpfilter_scipy_sig2(self):
    method test_tlpfilter_scipy_sig05 (line 159) | def test_tlpfilter_scipy_sig05(self):
  class TestAPSErrorCorrectionsOnDiscReused (line 171) | class TestAPSErrorCorrectionsOnDiscReused:
    method setup_method (line 174) | def setup_method(cls):
    method teardown_method (line 193) | def teardown_method(cls):
    method test_aps_error_files_on_disc (line 196) | def test_aps_error_files_on_disc(self, slpnanfill_method, slpfcutoff):

FILE: tests/test_constants.py
  function six_digits_filenames (line 10) | def six_digits_filenames():
  function eight_digits_filenames (line 15) | def eight_digits_filenames():
  function test_file_patterns (line 27) | def test_file_patterns(regex_pattern, extracted_string_length, six_digit...

FILE: tests/test_conv2tif.py
  function test_dem_and_incidence_not_converted (line 35) | def test_dem_and_incidence_not_converted(gamma_params):
  function test_conv2tif_file_types (line 46) | def test_conv2tif_file_types(tempdir, gamma_conf):
  function test_tifs_placed_in_out_dir (line 78) | def test_tifs_placed_in_out_dir(gamma_params):
  function test_num_gamma_tifs_equals_num_unws (line 91) | def test_num_gamma_tifs_equals_num_unws(gamma_params):
  function test_num_roipac_tifs_equals_num_unws (line 99) | def test_num_roipac_tifs_equals_num_unws(roipac_params):
  function test_conversion_not_recomputed (line 105) | def test_conversion_not_recomputed(gamma_params):
  function test_no_tifs_exits (line 116) | def test_no_tifs_exits(gamma_params):
  function test_tifs_succeeds (line 121) | def test_tifs_succeeds(gamma_params):

FILE: tests/test_correct.py
  function test_unsupported_process_steps_raises (line 29) | def test_unsupported_process_steps_raises(gamma_conf):
  function test_supported_process_steps_dont_raise (line 37) | def test_supported_process_steps_dont_raise(gamma_params):
  function test_process_treats_prepif_outputs_readonly (line 45) | def test_process_treats_prepif_outputs_readonly(gamma_conf, tempdir, coh...

FILE: tests/test_covariance.py
  class TestCovariance (line 44) | class TestCovariance:
    method setup_class (line 47) | def setup_class(cls):
    method test_covariance_basic (line 57) | def test_covariance_basic(self):
    method test_covariance_17ifgs (line 65) | def test_covariance_17ifgs(self):
  class TestVCMT (line 95) | class TestVCMT:
    method setup_class (line 97) | def setup_class(cls):
    method test_vcm_basic (line 100) | def test_vcm_basic(self):
    method test_vcm_17ifgs (line 113) | def test_vcm_17ifgs(self):
  class TestLegacyEquality (line 179) | class TestLegacyEquality:
    method setup_class (line 181) | def setup_class(cls):
    method teardown_class (line 224) | def teardown_class(cls):
    method test_legacy_maxvar_equality_small_test_files (line 227) | def test_legacy_maxvar_equality_small_test_files(self):
    method test_legacy_vcmt_equality_small_test_files (line 230) | def test_legacy_vcmt_equality_small_test_files(self):
    method test_metadata (line 236) | def test_metadata(self):
    method test_save_cvd_data (line 243) | def test_save_cvd_data(self):

FILE: tests/test_dem_error.py
  function point (line 25) | def point():
  class TestPyRateGammaBperp (line 30) | class TestPyRateGammaBperp:
    method setup_class (line 33) | def setup_class(cls):
    method gamma_bperp (line 53) | def gamma_bperp(self, x, y):
    method pyrate_bperp (line 102) | def pyrate_bperp(cls):
    method teardown_class (line 121) | def teardown_class(cls):
    method test_pyrate_bperp_matches_gamma_bperp (line 124) | def test_pyrate_bperp_matches_gamma_bperp(self, point):
    method test_avg_bperp_calculation (line 136) | def test_avg_bperp_calculation(self):
  class TestDEMErrorFilesReusedFromDisc (line 145) | class TestDEMErrorFilesReusedFromDisc:
    method setup_class (line 148) | def setup_class(cls):
    method teardown_class (line 157) | def teardown_class(cls):
    method test_dem_error_used_from_disc_on_rerun (line 160) | def test_dem_error_used_from_disc_on_rerun(self):
    method __run_once (line 168) | def __run_once(self):
  class TestDEMErrorResults (line 179) | class TestDEMErrorResults:
    method setup_class (line 182) | def setup_class(cls):
    method teardown_class (line 193) | def teardown_class(cls):
    method test_calc_dem_errors (line 196) | def test_calc_dem_errors(self):

FILE: tests/test_gamma.py
  class TestGammaCommandLineTests (line 51) | class TestGammaCommandLineTests:
    method setup_method (line 53) | def setup_method(self):
    method teardown_method (line 63) | def teardown_method(self):
    method makeInputFiles (line 70) | def makeInputFiles(self, data):
  class TestGammaToGeoTiff (line 83) | class TestGammaToGeoTiff:
    method setup_method (line 87) | def setup_method(cls):
    method teardown_method (line 99) | def teardown_method(self):
    method test_to_geotiff_dem (line 103) | def test_to_geotiff_dem(self):
    method test_to_geotiff_ifg (line 122) | def test_to_geotiff_ifg(self):
    method test_to_geotiff_wrong_input_data (line 149) | def test_to_geotiff_wrong_input_data(self):
    method compare_rasters (line 156) | def compare_rasters(self, ds, exp_ds):
    method test_bad_projection (line 170) | def test_bad_projection(self):
  class TestGammaHeaderListRaiseException (line 178) | class TestGammaHeaderListRaiseException:
    method setup_method (line 181) | def setup_method(self):
    method test_exception (line 185) | def test_exception(self):
  class TestGammaHeaderParsingTests (line 190) | class TestGammaHeaderParsingTests:
    method test_parse_gamma_epoch_header (line 193) | def test_parse_gamma_epoch_header(self):
    method test_parse_gamma_dem_header (line 209) | def test_parse_gamma_dem_header(self):
    method assert_equal (line 221) | def assert_equal(arg1, arg2):
  class TestHeaderCombination (line 251) | class TestHeaderCombination:
    method setup_method (line 254) | def setup_method(self):
    method assert_equal (line 262) | def assert_equal(arg1, arg2):
    method test_combine_headers (line 265) | def test_combine_headers(self):
    method test_fail_non_dict_header (line 283) | def test_fail_non_dict_header(self):
    method test_fail_mismatching_wavelength (line 289) | def test_fail_mismatching_wavelength(self):
    method test_fail_mismatching_incidence (line 292) | def test_fail_mismatching_incidence(self):
    method test_fail_same_date (line 295) | def test_fail_same_date(self):
    method test_fail_bad_date_order (line 298) | def test_fail_bad_date_order(self):
    method assertRaises (line 302) | def assertRaises(self, func, * args):
  function parallel_ifgs (line 312) | def parallel_ifgs(gamma_conf):
  function series_ifgs (line 336) | def series_ifgs(gamma_conf):
  function test_equality (line 361) | def test_equality(series_ifgs, parallel_ifgs):
  function test_meta_data_exists (line 366) | def test_meta_data_exists(series_ifgs, parallel_ifgs):
  class TestGammaBaselineRead (line 378) | class TestGammaBaselineRead:
    method setup_method (line 381) | def setup_method(self):
    method test_prec_baseline_read (line 387) | def test_prec_baseline_read(self):
    method test_init_baseline_read (line 408) | def test_init_baseline_read(self):

FILE: tests/test_gamma_vs_roipac.py
  function test_files_are_same (line 38) | def test_files_are_same(tempdir, get_config):
  function __workflow (line 62) | def __workflow(params, tdir):
  function __assert_same_files_produced (line 83) | def __assert_same_files_produced(dir1, dir2, ext, num_files):

FILE: tests/test_gdal_python.py
  class TestResample (line 38) | class TestResample(common.UnitTestAdaptation):
    method test_small_data_resampling (line 40) | def test_small_data_resampling(self):
    method check_same_resampled_output (line 52) | def check_same_resampled_output(self, extents, extents_str, res,
    method test_none_resolution_output (line 84) | def test_none_resolution_output(self):
    method test_output_file_written (line 93) | def test_output_file_written(self):
    method test_resampled_tif_has_metadata (line 107) | def test_resampled_tif_has_metadata(self):
  class TestBasicReampleTests (line 127) | class TestBasicReampleTests(common.UnitTestAdaptation):
    method test_reproject_with_no_data (line 129) | def test_reproject_with_no_data(self):
    method test_reproject_with_no_data_2 (line 148) | def test_reproject_with_no_data_2(self):
    method test_reproject_with_no_data_3 (line 168) | def test_reproject_with_no_data_3(self):
    method test_reproject_with_no_data_4 (line 191) | def test_reproject_with_no_data_4(self):
    method test_reproject_with_no_data_5 (line 215) | def test_reproject_with_no_data_5(self):
    method test_reproject_average_resampling (line 241) | def test_reproject_average_resampling(self):
    method test_reproject_average_resampling_with_2bands (line 268) | def test_reproject_average_resampling_with_2bands(self):
  class TestMEMVsGTiff (line 309) | class TestMEMVsGTiff(common.UnitTestAdaptation):
    method check (line 312) | def check(driver_type):
    method test_mem (line 358) | def test_mem(self):
    method test_gtiff (line 361) | def test_gtiff(self):
  function test_coherence_files_not_converted (line 365) | def test_coherence_files_not_converted():
  function test_small_data_coherence (line 439) | def test_small_data_coherence(gamma_or_mexicoa_conf):

FILE: tests/test_geometry.py
  function get_lonlat_coords_slow (line 18) | def get_lonlat_coords_slow(ifg: Ifg) -> Tuple[np.ndarray, np.ndarray]:
  function test_get_lonlat_coords_vectorised (line 39) | def test_get_lonlat_coords_vectorised(dem):
  function point_azimuth (line 47) | def point_azimuth(request):
  function point_incidence (line 52) | def point_incidence(request):
  class TestPyRateAngleFiles (line 56) | class TestPyRateAngleFiles:
    method setup_class (line 59) | def setup_class(cls):
    method teardown_class (line 67) | def teardown_class(cls):
    method get_pyrate_angle (line 85) | def get_pyrate_angle(self, x0, y0, tif_file):
    method test_pyrate_azimuth_matches_gamma_azimuth (line 96) | def test_pyrate_azimuth_matches_gamma_azimuth(self, point_azimuth):
    method test_pyrate_incidence_matches_gamma_incidence (line 114) | def test_pyrate_incidence_matches_gamma_incidence(self, point_incidence):
    method test_azimuth_angle_calculation (line 133) | def test_azimuth_angle_calculation(self):

FILE: tests/test_merge.py
  function los_projection (line 40) | def los_projection(request):
  function signal_polarity (line 45) | def signal_polarity(request):
  function test_los_conversion_divisors (line 49) | def test_los_conversion_divisors():
  class TestLOSConversion (line 74) | class TestLOSConversion:
    method setup_class (line 76) | def setup_class(cls):
    method teardown_class (line 93) | def teardown_class(cls):
    method test_los_conversion_comparison (line 96) | def test_los_conversion_comparison(self):
    method run_with_new_params (line 157) | def run_with_new_params(self, k_dir, params):
    method test_file_creation (line 168) | def test_file_creation(self, los_projection):
    method __check_md (line 194) | def __check_md(los_projection, output_image_path):

FILE: tests/test_mpi.py
  function test_vcm_legacy_vs_mpi (line 40) | def test_vcm_legacy_vs_mpi(mpisync, tempdir, roipac_or_gamma_conf):

FILE: tests/test_mpi_vs_multiprocess_vs_single_process.py
  function parallel (line 44) | def parallel(request):
  function local_crop (line 49) | def local_crop(request):
  function modified_config (line 54) | def modified_config(tempdir, get_lks, get_crop, orbfit_lks, orbfit_metho...
  function test_pipeline_parallel_vs_mpi (line 92) | def test_pipeline_parallel_vs_mpi(modified_config, gamma_or_mexicoa_conf...
  function __check_equality_of_phase_closure_outputs (line 237) | def __check_equality_of_phase_closure_outputs(mpi_conf, sr_conf):
  function coh_mask (line 265) | def coh_mask(request):
  function modified_config_short (line 270) | def modified_config_short(tempdir, local_crop, get_lks, coh_mask):
  function create_mpi_files (line 311) | def create_mpi_files():
  function test_stack_and_ts_mpi_vs_parallel_vs_serial (line 336) | def test_stack_and_ts_mpi_vs_parallel_vs_serial(modified_config_short, g...

FILE: tests/test_mst.py
  class TestMST (line 34) | class TestMST(UnitTestAdaptation):
    method setup_method (line 37) | def setup_method(self):
    method test_mst_matrix_as_array (line 40) | def test_mst_matrix_as_array(self):
    method test_mst_matrix_as_ifgs (line 68) | def test_mst_matrix_as_ifgs(self):
    method test_partial_nan_pixel_stack (line 84) | def test_partial_nan_pixel_stack(self):
    method test_all_nan_pixel_stack (line 103) | def test_all_nan_pixel_stack(self):
  class TestDefaultMST (line 119) | class TestDefaultMST(UnitTestAdaptation):
    method test_default_mst (line 121) | def test_default_mst(self):
  class TestNetworkxMSTTreeCheck (line 142) | class TestNetworkxMSTTreeCheck(UnitTestAdaptation):
    method setup_class (line 145) | def setup_class(cls):
    method test_assert_is_not_tree (line 148) | def test_assert_is_not_tree(self):
    method test_small_data_tree (line 155) | def test_small_data_tree(self):
    method test_assert_is_tree (line 158) | def test_assert_is_tree(self):
    method test_assert_two_trees_overlapping (line 166) | def test_assert_two_trees_overlapping(self):
    method test_assert_two_trees_non_overlapping (line 174) | def test_assert_two_trees_non_overlapping(self):
  class TestIfgPart (line 182) | class TestIfgPart(UnitTestAdaptation):
    method setup_method (line 184) | def setup_method(self):
    method test_ifg_part_shape_and_slice (line 188) | def test_ifg_part_shape_and_slice(self):
    method test_mst_multiprocessing_serial (line 197) | def test_mst_multiprocessing_serial(self):
    method test_mst_multiprocessing (line 203) | def test_mst_multiprocessing(self):
  class TestMSTFilesReusedFromDisc (line 210) | class TestMSTFilesReusedFromDisc:
    method setup_class (line 213) | def setup_class(cls):
    method teardown_class (line 224) | def teardown_class(cls):
    method test_mst_used_from_disc_on_rerun (line 227) | def test_mst_used_from_disc_on_rerun(self):
    method __run_once (line 235) | def __run_once(self):

FILE: tests/test_orbital.py
  class TestSingleDesignMatrixTests (line 70) | class TestSingleDesignMatrixTests:
    method setup_class (line 78) | def setup_class(cls):
    method test_create_planar_dm (line 92) | def test_create_planar_dm(self):
    method test_create_planar_dm_offsets (line 98) | def test_create_planar_dm_offsets(self):
    method test_create_quadratic_dm (line 106) | def test_create_quadratic_dm(self):
    method test_create_quadratic_dm_offsets (line 112) | def test_create_quadratic_dm_offsets(self):
    method test_create_partcubic_dm (line 120) | def test_create_partcubic_dm(self):
    method test_create_partcubic_dm_offsets (line 126) | def test_create_partcubic_dm_offsets(self):
    method test_create_planar_dm_network (line 134) | def test_create_planar_dm_network(self):
    method test_create_quadratic_dm_network (line 143) | def test_create_quadratic_dm_network(self):
    method test_create_partcubic_dm_network (line 152) | def test_create_partcubic_dm_network(self):
  class TestIndependentCorrection (line 162) | class TestIndependentCorrection:
    method setup_class (line 166) | def setup_class(cls):
    method alt_orbital_correction (line 175) | def alt_orbital_correction(self, ifg, deg, offset, scale):
    method check_correction (line 198) | def check_correction(self, degree, method, offset, decimal=2):
    method check_results (line 226) | def check_results(self, ifgs, corrections):
    method test_independent_correction_planar (line 238) | def test_independent_correction_planar(self):
    method test_independent_correction_planar_offsets (line 241) | def test_independent_correction_planar_offsets(self):
    method test_independent_correction_quadratic (line 244) | def test_independent_correction_quadratic(self):
    method test_independent_correction_quadratic_offsets (line 247) | def test_independent_correction_quadratic_offsets(self):
    method test_independent_correction_partcubic (line 250) | def test_independent_correction_partcubic(self):
    method test_independent_correction_partcubic_offsets (line 253) | def test_independent_correction_partcubic_offsets(self):
  class TestError (line 257) | class TestError:
    method setup_method (line 261) | def setup_method(cls):
    method test_invalid_ifgs_arg (line 266) | def test_invalid_ifgs_arg(self):
    method test_invalid_degree_arg (line 271) | def test_invalid_degree_arg(self):
    method test_invalid_method (line 280) | def test_invalid_method(self):
    method test_different_looks_raise (line 287) | def test_different_looks_raise(self):
    method test_looks_as_int (line 296) | def test_looks_as_int(self):
  class TestNetworkDesignMatrixTests (line 307) | class TestNetworkDesignMatrixTests:
    method setup_class (line 310) | def setup_class(self):
    method test_planar_network_dm (line 323) | def test_planar_network_dm(self):
    method test_planar_network_dm_offset (line 331) | def test_planar_network_dm_offset(self):
    method test_quadratic_network_dm (line 340) | def test_quadratic_network_dm(self):
    method test_quadratic_network_dm_offset (line 348) | def test_quadratic_network_dm_offset(self):
    method test_partcubic_network_dm (line 357) | def test_partcubic_network_dm(self):
    method test_partcubic_network_dm_offset (line 365) | def test_partcubic_network_dm_offset(self):
    method check_equality (line 374) | def check_equality(self, ncoef, dm, ifgs, offset):
  function network_correction (line 402) | def network_correction(ifgs, deg, intercept, ml_ifgs=None, tol=1e-6):
  function _expand_corrections (line 433) | def _expand_corrections(ifgs, dm, params, ncoef, offset):
  class TestNetworkCorrectionTests (line 463) | class TestNetworkCorrectionTests:
    method setup_class (line 466) | def setup_class(cls):
    method test_offset_inversion (line 487) | def test_offset_inversion(self):
    method test_network_correction_planar (line 523) | def test_network_correction_planar(self):
    method test_network_correction_planar_offset (line 536) | def test_network_correction_planar_offset(self):
    method test_network_correction_quadratic (line 541) | def test_network_correction_quadratic(self):
    method test_network_correction_quadratic_offset (line 548) | def test_network_correction_quadratic_offset(self):
    method test_network_correction_partcubic (line 553) | def test_network_correction_partcubic(self):
    method test_network_correction_partcubic_offset (line 559) | def test_network_correction_partcubic_offset(self):
    method verify_corrections (line 565) | def verify_corrections(ifgs, exp, deg, intercept):
  class TestNetworkCorrectionTestsMultilooking (line 584) | class TestNetworkCorrectionTestsMultilooking:
    method setup_class (line 588) | def setup_class(cls):
    method test_mlooked_network_correction_planar (line 607) | def test_mlooked_network_correction_planar(self):
    method test_mlooked_network_correction_planar_offset (line 613) | def test_mlooked_network_correction_planar_offset(self):
    method test_mlooked_network_correction_quadratic (line 618) | def test_mlooked_network_correction_quadratic(self):
    method test_mlooked_network_correction_quadratic_offset (line 624) | def test_mlooked_network_correction_quadratic_offset(self):
    method test_mlooked_network_correction_partcubic (line 629) | def test_mlooked_network_correction_partcubic(self):
    method test_mlooked_network_correction_partcubic_offset (line 635) | def test_mlooked_network_correction_partcubic_offset(self):
    method verify_corrections (line 640) | def verify_corrections(self, ifgs, exp, deg, intercept):
  function unittest_dm (line 659) | def unittest_dm(ifg, method, degree, offset=False, scale=100.0):
  function get_date_ids (line 706) | def get_date_ids(ifgs):
  function _add_nodata (line 717) | def _add_nodata(ifgs):
  class TestLegacyComparisonTestsOrbfitMethod1 (line 726) | class TestLegacyComparisonTestsOrbfitMethod1:
    method setup_class (line 740) | def setup_class(cls, roipac_params):
    method teardown_class (line 757) | def teardown_class(cls):
    method test_orbital_correction_legacy_equality (line 762) | def test_orbital_correction_legacy_equality(self):
    method test_orbfit_treats_process_inputs_as_read_only (line 806) | def test_orbfit_treats_process_inputs_as_read_only(self):
  class TestLegacyComparisonTestsOrbfitMethod2 (line 810) | class TestLegacyComparisonTestsOrbfitMethod2:
    method setup_class (line 823) | def setup_class(cls):
    method teardown_class (line 849) | def teardown_class(cls):
    method test_orbital_correction_legacy_equality_orbfit_method_2 (line 852) | def test_orbital_correction_legacy_equality_orbfit_method_2(self):
    method test_orbital_error_method2_dummy (line 879) | def test_orbital_error_method2_dummy(self):
  class TestOrbErrorCorrectionsOnDiscReused (line 914) | class TestOrbErrorCorrectionsOnDiscReused:
    method setup_class (line 917) | def setup_class(cls):
    method teardown_class (line 928) | def teardown_class(cls):
    method test_orb_error (line 931) | def test_orb_error(self, orbfit_method, orbfit_degrees):
  class TestOrbErrorCorrectionsReappliedDoesNotChangePhaseData (line 967) | class TestOrbErrorCorrectionsReappliedDoesNotChangePhaseData:
    method setup_method (line 970) | def setup_method(cls):
    method teardown_method (line 983) | def teardown_method(cls):
    method test_orb_error_multiple_run_does_not_change_phase_data (line 986) | def test_orb_error_multiple_run_does_not_change_phase_data(self, orbfi...
  function orbfit_looks (line 1011) | def orbfit_looks(request):
  class TestOrbfitIndependentMethodWithMultilooking (line 1017) | class TestOrbfitIndependentMethodWithMultilooking:
    method setup_class (line 1020) | def setup_class(cls):
    method teardown_class (line 1031) | def teardown_class(cls):
    method test_independent_method_works_with_multilooking (line 1034) | def test_independent_method_works_with_multilooking(self, orbfit_looks...
  class SyntheticIfg (line 1056) | class SyntheticIfg:
    method __init__ (line 1063) | def __init__(self, orbfit_degrees):
    method add_geographic_data (line 1080) | def add_geographic_data(self):
    method phase_data (line 1093) | def phase_data(self):
    method open (line 1101) | def open(self):
  function mlk_ifg (line 1132) | def mlk_ifg(ifg, nlooks):
  function orb_lks (line 1155) | def orb_lks(request):
  function test_single_synthetic_ifg_independent_method (line 1159) | def test_single_synthetic_ifg_independent_method(orbfit_degrees, orb_lks...
  function test_set_synthetic_ifgs_independent_method (line 1190) | def test_set_synthetic_ifgs_independent_method(mexico_cropa_params, orbf...
  class FakeIfg (line 1205) | class FakeIfg:
    method __init__ (line 1206) | def __init__(self, orbfit_deg, model_params, date_first, date_second):
    method add_geographic_data (line 1223) | def add_geographic_data(self):
    method phase_data (line 1236) | def phase_data(self):
    method open (line 1244) | def open(self):
  class SyntheticNetwork (line 1264) | class SyntheticNetwork:
    method __init__ (line 1271) | def __init__(self, orbfit_deg, epochs, network, model_params):
  function test_synthetic_network_correction (line 1290) | def test_synthetic_network_correction(orbfit_degrees, orb_lks):
  function test_orbital_inversion (line 1355) | def test_orbital_inversion():

FILE: tests/test_prepifg.py
  function test_prepifg_treats_inputs_and_outputs_read_only (line 61) | def test_prepifg_treats_inputs_and_outputs_read_only(gamma_conf, tempdir...
  function test_prepifg_file_types (line 93) | def test_prepifg_file_types(tempdir, gamma_conf, coh_mask):
  function diff_exts_ifgs (line 175) | def diff_exts_ifgs():
  function same_exts_ifgs (line 188) | def same_exts_ifgs():
  function extents_from_params (line 193) | def extents_from_params(params):
  function test_extents_from_params (line 200) | def test_extents_from_params():
  class TestPrepifgOutput (line 209) | class TestPrepifgOutput(UnitTestAdaptation):
    method assert_geotransform_equal (line 213) | def assert_geotransform_equal(files):
    method setup_class (line 231) | def setup_class(cls):
    method test_mlooked_paths (line 256) | def test_mlooked_paths():
    method test_extents_from_params (line 260) | def test_extents_from_params():
    method teardown_class (line 264) | def teardown_class(cls):
    method _custom_ext_latlons (line 272) | def _custom_ext_latlons(self):
    method _custom_extents_tuple (line 278) | def _custom_extents_tuple(self):
    method assert_projection_equal (line 281) | def assert_projection_equal(self, files):
    method test_multilooked_projection_same_as_geotiff (line 298) | def test_multilooked_projection_same_as_geotiff(self):
    method test_default_max_extents (line 319) | def test_default_max_extents(self):
    method test_min_extents (line 343) | def test_min_extents(self):
    method test_custom_extents (line 363) | def test_custom_extents(self):
    method test_exception_without_all_4_crop_parameters (line 384) | def test_exception_without_all_4_crop_parameters(self):
    method test_custom_extents_misalignment (line 400) | def test_custom_extents_misalignment(self):
    method test_nodata (line 417) | def test_nodata(self):
    method test_nans (line 431) | def test_nans(self):
    method test_multilook (line 450) | def test_multilook(self):
    method test_output_datatype (line 503) | def test_output_datatype(self):
    method test_invalid_looks (line 530) | def test_invalid_looks(self):
  class TestThresholdTests (line 541) | class TestThresholdTests(UnitTestAdaptation):
    method test_nan_threshold_inputs (line 544) | def test_nan_threshold_inputs(self):
    method test_nan_threshold (line 550) | def test_nan_threshold():
    method test_nan_threshold_alt (line 568) | def test_nan_threshold_alt():
  class TestSameSizeTests (line 580) | class TestSameSizeTests(UnitTestAdaptation):
    method setup_class (line 584) | def setup_class(cls):
    method test_already_same_size (line 611) | def test_already_same_size(self):
    method test_already_same_size_mismatch (line 619) | def test_already_same_size_mismatch(self):
    method test_same_size_multilooking (line 629) | def test_same_size_multilooking(self):
  function mlooked_path (line 656) | def mlooked_path(path, params, input_type):
  function test_mlooked_path (line 661) | def test_mlooked_path():
  class TestLocalMultilookTests (line 691) | class TestLocalMultilookTests:
    method test_multilooking_thresh (line 695) | def test_multilooking_thresh():
  function multilooking (line 708) | def multilooking(src, xscale, yscale, thresh=0):
  class TestLegacyEqualityTestRoipacSmallTestData (line 743) | class TestLegacyEqualityTestRoipacSmallTestData(UnitTestAdaptation):
    method setup_class (line 748) | def setup_class(cls):
    method teardown_class (line 763) | def teardown_class(cls):
    method test_legacy_prepifg_equality_array (line 769) | def test_legacy_prepifg_equality_array(self):
    method test_legacy_prepifg_and_convert_phase (line 791) | def test_legacy_prepifg_and_convert_phase(self):
  class TestOneIncidenceOrElevationMap (line 831) | class TestOneIncidenceOrElevationMap(UnitTestAdaptation):
    method setup_class (line 834) | def setup_class(cls):
    method teardown_class (line 841) | def teardown_class(cls):
    method make_input_files (line 846) | def make_input_files(self, inc='', ele=''):
    method common_check (line 870) | def common_check(self, ele, inc):
  function prepare_ifgs (line 895) | def prepare_ifgs(raster_data_paths, crop_opt, xlooks, ylooks, headers, p...
  function test_coh_stats_equality (line 939) | def test_coh_stats_equality(mexico_cropa_params):

FILE: tests/test_prepifg_system_vs_python.py
  function local_crop (line 37) | def local_crop(request):
  function modified_config_short (line 42) | def modified_config_short(tempdir, local_crop, get_lks, coh_mask):
  function create_mpi_files (line 81) | def create_mpi_files(modified_config_short):
  function modified_config_largetifs (line 96) | def modified_config_largetifs(tempdir, local_crop, get_lks, coh_mask):
  function test_prepifg_largetifs_vs_python (line 136) | def test_prepifg_largetifs_vs_python(modified_config_largetifs, gamma_co...

FILE: tests/test_pyrate.py
  function symlink_ms (line 44) | def symlink_ms(source, link_name):
  function test_transform_params (line 60) | def test_transform_params():
  function test_warp_required (line 65) | def test_warp_required():
  function test_original_ifg_paths (line 76) | def test_original_ifg_paths():
  function dest_ifg_paths (line 84) | def dest_ifg_paths(ifg_paths, outdir):
  function test_dest_ifg_paths (line 93) | def test_dest_ifg_paths():
  function get_ifgs (line 102) | def get_ifgs(out_dir, _open=True):
  class TestPyRate (line 113) | class TestPyRate:
    method setup_class (line 118) | def setup_class(cls):
    method teardown_class (line 163) | def teardown_class(cls):
    method key_check (line 167) | def key_check(self, ifg, key, value):
    method test_basic_outputs (line 173) | def test_basic_outputs(self):
    method test_phase_conversion (line 183) | def test_phase_conversion(self):
    method test_orbital_correction (line 191) | def test_orbital_correction(self):
  class TestParallelPyRate (line 201) | class TestParallelPyRate:
    method setup_class (line 207) | def setup_class(cls):
    method teardown_class (line 282) | def teardown_class(cls):
    method test_orbital_correction (line 285) | def test_orbital_correction(self):
    method key_check (line 294) | def key_check(self, ifg, key, value):
    method test_phase_conversion (line 300) | def test_phase_conversion(self):
    method test_mst_equal (line 311) | def test_mst_equal(self):
    method test_refpixel_equal (line 314) | def test_refpixel_equal(self):
    method test_maxvar_equal (line 317) | def test_maxvar_equal(self):
    method test_vcmt_equal (line 320) | def test_vcmt_equal(self):
    method test_stack_rate_equal (line 323) | def test_stack_rate_equal(self):
  class TestPrePrepareIfgs (line 331) | class TestPrePrepareIfgs:
    method setup_class (line 334) | def setup_class(cls):
    method teardown_class (line 371) | def teardown_class(cls):
    method test_small_data_prep_phase_equality (line 375) | def test_small_data_prep_phase_equality(self):
    method test_small_data_prep_metadata_equality (line 383) | def test_small_data_prep_metadata_equality(self):

FILE: tests/test_ref_phs_est.py
  class TestRefPhsTests (line 77) | class TestRefPhsTests:
    method setup_method (line 80) | def setup_method(self):
    method teardown_method (line 107) | def teardown_method(self):
    method test_need_at_least_two_ifgs (line 110) | def test_need_at_least_two_ifgs(self):
    method test_metadata (line 119) | def test_metadata(self):
    method test_mixed_metadata_raises (line 130) | def test_mixed_metadata_raises(self):
  class TestRefPhsEstimationLegacyTestMethod1Serial (line 154) | class TestRefPhsEstimationLegacyTestMethod1Serial:
    method setup_class (line 160) | def setup_class(cls):
    method teardown_class (line 199) | def teardown_class(cls):
    method test_estimate_reference_phase (line 203) | def test_estimate_reference_phase(self):
    method test_ifgs_after_ref_phs_est (line 206) | def test_ifgs_after_ref_phs_est(self):
  class TestRefPhsEstimationLegacyTestMethod1Parallel (line 238) | class TestRefPhsEstimationLegacyTestMethod1Parallel:
    method setup_class (line 243) | def setup_class(cls):
    method teardown_class (line 283) | def teardown_class(cls):
    method test_estimate_reference_phase (line 287) | def test_estimate_reference_phase(self):
    method test_ifgs_after_ref_phs_est (line 290) | def test_ifgs_after_ref_phs_est(self):
  class TestRefPhsEstimationLegacyTestMethod2Serial (line 323) | class TestRefPhsEstimationLegacyTestMethod2Serial:
    method setup_class (line 329) | def setup_class(cls):
    method teardown_class (line 369) | def teardown_class(cls):
    method test_ifgs_after_ref_phs_est (line 372) | def test_ifgs_after_ref_phs_est(self):
    method test_estimate_reference_phase_method2 (line 404) | def test_estimate_reference_phase_method2(self):
  class TestRefPhsEstimationLegacyTestMethod2Parallel (line 408) | class TestRefPhsEstimationLegacyTestMethod2Parallel:
    method setup_class (line 416) | def setup_class(cls):
    method teardown_class (line 455) | def teardown_class(cls):
    method test_ifgs_after_ref_phs_est (line 458) | def test_ifgs_after_ref_phs_est(self):
    method test_estimate_reference_phase_method2 (line 489) | def test_estimate_reference_phase_method2(self):
  class TestRefPhsEstReusedFromDisc (line 493) | class TestRefPhsEstReusedFromDisc:
    method setup_class (line 496) | def setup_class(cls):
    method teardown_class (line 505) | def teardown_class(cls):
    method test_ref_phase_used_from_disc_on_rerun (line 508) | def test_ref_phase_used_from_disc_on_rerun(self, ref_est_method):
    method __run_once (line 530) | def __run_once(self):

FILE: tests/test_refpixel.py
  class TestReferencePixelInputTests (line 54) | class TestReferencePixelInputTests:
    method setup_method (line 60) | def setup_method(cls):
    method test_missing_chipsize (line 69) | def test_missing_chipsize(self):
    method test_chipsize_valid (line 74) | def test_chipsize_valid(self):
    method test_minimum_fraction_missing (line 80) | def test_minimum_fraction_missing(self):
    method test_minimum_fraction_threshold (line 85) | def test_minimum_fraction_threshold(self):
    method test_search_windows (line 91) | def test_search_windows(self):
    method test_missing_search_windows (line 104) | def test_missing_search_windows(self):
  class TestReferencePixelTests (line 116) | class TestReferencePixelTests:
    method setup_method (line 122) | def setup_method(cls):
    method test_all_below_threshold_exception (line 131) | def test_all_below_threshold_exception(self):
    method test_refnxy_step_1 (line 149) | def test_refnxy_step_1(self):
    method test_large_window (line 165) | def test_large_window(self):
    method test_step (line 177) | def test_step(self):
    method test_ref_pixel (line 205) | def test_ref_pixel(self):
  function _expected_ref_pixel (line 224) | def _expected_ref_pixel(ifgs, cs):
  class TestLegacyEqualityTest (line 244) | class TestLegacyEqualityTest:
    method setup_method (line 247) | def setup_method(cls):
    method teardown_method (line 271) | def teardown_method(cls):
    method test_small_test_data_ref_pixel_lat_lon_provided (line 274) | def test_small_test_data_ref_pixel_lat_lon_provided(self):
    method test_small_test_data_ref_pixel (line 281) | def test_small_test_data_ref_pixel(self):
    method test_small_test_data_ref_chipsize_15 (line 287) | def test_small_test_data_ref_chipsize_15(self):
    method test_metadata (line 294) | def test_metadata(self):
    method test_small_test_data_ref_all_1 (line 307) | def test_small_test_data_ref_all_1(self):
  class TestLegacyEqualityTestMultiprocessParallel (line 316) | class TestLegacyEqualityTestMultiprocessParallel:
    method setup_method (line 319) | def setup_method(cls):
    method teardown_method (line 343) | def teardown_method(cls):
    method test_small_test_data_ref_pixel (line 346) | def test_small_test_data_ref_pixel(self):
    method test_more_small_test_data_ref_pixel (line 352) | def test_more_small_test_data_ref_pixel(self):
    method test_small_test_data_ref_pixel_all_2 (line 359) | def test_small_test_data_ref_pixel_all_2(self):
    method test_small_test_data_ref_chipsize_15 (line 366) | def test_small_test_data_ref_chipsize_15(self):
    method test_small_test_data_ref_all_1 (line 373) | def test_small_test_data_ref_all_1(self):
  function test_error_msg_refpixel_out_of_bounds (line 386) | def test_error_msg_refpixel_out_of_bounds(tempdir, gamma_conf):
  function test_gamma_ref_pixel_search_vs_lat_lon (line 397) | def test_gamma_ref_pixel_search_vs_lat_lon(tempdir, gamma_conf):
  function _get_mlooked_files (line 405) | def _get_mlooked_files(gamma_conf, tdir, refx, refy):
  class TestRefPixelReuseLoadsSameFileAndPixels (line 422) | class TestRefPixelReuseLoadsSameFileAndPixels:
    method setup_method (line 425) | def setup_method(cls):
    method teardown_method (line 436) | def teardown_method(cls):
    method test_ref_pixel_multiple_runs_reuse_from_disc (line 439) | def test_ref_pixel_multiple_runs_reuse_from_disc(self, ref_pixel):
  function x_y_pixel (line 467) | def x_y_pixel():
  function test_convert_pixel_value_to_geographic_coordinate (line 477) | def test_convert_pixel_value_to_geographic_coordinate(x_y_pixel):
  function dem_transform (line 488) | def dem_transform():
  function test_convert_geographic_coordinate_to_pixel_value (line 495) | def test_convert_geographic_coordinate_to_pixel_value(x_y_pixel):

FILE: tests/test_roipac.py
  class TestRoipacToGeoTiff (line 47) | class TestRoipacToGeoTiff(UnitTestAdaptation):
    method setup_class (line 51) | def setup_class(cls):
    method teardown_class (line 56) | def teardown_class(cls):
    method test_to_geotiff_dem (line 59) | def test_to_geotiff_dem(self):
    method test_to_geotiff_ifg (line 73) | def test_to_geotiff_ifg(self):
    method test_to_geotiff_wrong_input_data (line 106) | def test_to_geotiff_wrong_input_data(self):
    method test_bad_projection (line 118) | def test_bad_projection(self):
    method compare_rasters (line 126) | def compare_rasters(self, ds, exp_ds):
  class TestDateParsing (line 141) | class TestDateParsing(UnitTestAdaptation):
    method test_parse_short_date_pre2000 (line 143) | def test_parse_short_date_pre2000(self):
    method test_parse_short_date_post2000 (line 147) | def test_parse_short_date_post2000(self):
    method test_parse_date_range (line 151) | def test_parse_date_range(self):
  class TestHeaderParsingTests (line 157) | class TestHeaderParsingTests(UnitTestAdaptation):
    method test_parse_short_roipac_header (line 161) | def test_parse_short_roipac_header(self):
    method test_parse_short_header_has_timespan (line 171) | def test_parse_short_header_has_timespan(self):
    method test_parse_full_roipac_header (line 183) | def test_parse_full_roipac_header(self):
    method test_read_full_roipac_header2 (line 193) | def test_read_full_roipac_header2(self):
    method test_xylast (line 198) | def test_xylast(self):

FILE: tests/test_shared.py
  class TestIfgTests (line 56) | class TestIfgTests:
    method setup_class (line 59) | def setup_class(cls):
    method test_headers_as_attr (line 64) | def test_headers_as_attr(self):
    method test_convert_to_nans (line 69) | def test_convert_to_nans(self):
    method test_xylast (line 73) | def test_xylast(self):
    method test_num_cells (line 78) | def test_num_cells(self):
    method test_shape (line 85) | def test_shape(self):
    method test_nan_count (line 88) | def test_nan_count(self):
    method test_phase_band (line 99) | def test_phase_band(self):
    method test_nan_fraction (line 103) | def test_nan_fraction(self):
    method test_xy_size (line 121) | def test_xy_size(self):
    method test_centre_latlong (line 134) | def test_centre_latlong(self):
    method test_centre_cell (line 142) | def test_centre_cell(self):
    method test_time_span (line 146) | def test_time_span(self):
    method test_wavelength (line 149) | def test_wavelength(self):
  class TestIfgIOTests (line 153) | class TestIfgIOTests:
    method setup_method (line 155) | def setup_method(self):
    method test_open (line 159) | def test_open(self):
    method test_open_ifg_from_dataset (line 171) | def test_open_ifg_from_dataset(self):
    method test_write (line 182) | def test_write(self):
    method test_write_fails_on_readonly (line 206) | def test_write_fails_on_readonly(self):
    method test_phase_band_unopened_ifg (line 215) | def test_phase_band_unopened_ifg(self):
    method test_nan_fraction_unopened (line 222) | def test_nan_fraction_unopened(self):
    method test_phase_data_properties (line 231) | def test_phase_data_properties(self):
  class TestDEMTests (line 292) | class TestDEMTests:
    method setup_method (line 295) | def setup_method(self):
    method test_create_raster (line 298) | def test_create_raster(self):
    method test_headers_as_attr (line 302) | def test_headers_as_attr(self):
    method test_is_dem (line 310) | def test_is_dem(self):
    method test_open (line 314) | def test_open(self):
    method test_band_read_with_open_raster (line 329) | def test_band_read_with_open_raster(self):
  class TestWriteUnw (line 334) | class TestWriteUnw:
    method setup_class (line 338) | def setup_class(cls, gamma_params):
    method teardown_class (line 368) | def teardown_class(cls):
    method test_unw_contains_same_data_as_numpy_array (line 371) | def test_unw_contains_same_data_as_numpy_array(self):
    method test_multilooked_tiffs_converted_to_unw_are_same (line 419) | def test_multilooked_tiffs_converted_to_unw_are_same(self):
    method test_roipac_raises (line 452) | def test_roipac_raises(self):
  class TestGeodesy (line 464) | class TestGeodesy:
    method test_utm_zone (line 466) | def test_utm_zone(self):
    method test_cell_size_polar_region (line 483) | def test_cell_size_polar_region(self):
    method test_cell_size_calc (line 489) | def test_cell_size_calc(self):
  function parallel (line 510) | def parallel(request):
  function get_random_string (line 514) | def get_random_string(length):
  function _data_types (line 520) | def _data_types():
  function data_type (line 532) | def data_type(request):
  function test_tiles_split (line 536) | def test_tiles_split(parallel, data_type):
  function test_convert_to_radians (line 554) | def test_convert_to_radians():
  function test_convert_to_radians_ifg (line 563) | def test_convert_to_radians_ifg(ten_geotiffs):

FILE: tests/test_stackrate.py
  function default_params (line 41) | def default_params():
  class SinglePixelIfg (line 45) | class SinglePixelIfg(object):
    method __init__ (line 47) | def __init__(self, timespan, phase):
  class TestStackRatePixel (line 52) | class TestStackRatePixel:
    method setup_method (line 58) | def setup_method(self):
    method test_stack_rate_pixel (line 66) | def test_stack_rate_pixel(self):
  class TestMaskRate (line 78) | class TestMaskRate:
    method setup_method (line 83) | def setup_method(self):
    method test_mask_rate_maxsig1 (line 87) | def test_mask_rate_maxsig1(self):
    method test_mask_rate_maxsig2 (line 93) | def test_mask_rate_maxsig2(self):
    method test_mask_rate_maxsig3 (line 99) | def test_mask_rate_maxsig3(self):
  class TestLegacyEquality (line 106) | class TestLegacyEquality:
    method setup_class (line 112) | def setup_class(cls):
    method teardown_class (line 177) | def teardown_class(cls):
    method test_stack_rate_full_parallel (line 180) | def test_stack_rate_full_parallel(self):
    method test_stackrate_error_parallel (line 186) | def test_stackrate_error_parallel(self):
    method test_stackrate_samples_parallel (line 192) | def test_stackrate_samples_parallel(self):
    method test_stack_rate (line 198) | def test_stack_rate(self):
    method test_stackrate_error (line 204) | def test_stackrate_error(self):
    method test_stackrate_samples (line 210) | def test_stackrate_samples(self):

FILE: tests/test_system.py
  function test_workflow (line 35) | def test_workflow(system_conf):
  function test_single_workflow (line 53) | def test_single_workflow(gamma_or_mexicoa_conf):

FILE: tests/test_timeseries.py
  function default_params (line 41) | def default_params():
  class SinglePixelIfg (line 52) | class SinglePixelIfg(object):
    method __init__ (line 57) | def __init__(self, first, second, phase, nan_fraction):
    method convert_to_nans (line 65) | def convert_to_nans(self, val=0):
  class TestTimeSeries (line 74) | class TestTimeSeries:
    method setup_class (line 78) | def setup_class(cls):
    method test_time_series_unit (line 87) | def test_time_series_unit(self):
  class TestLegacyTimeSeriesEquality (line 113) | class TestLegacyTimeSeriesEquality:
    method setup_class (line 116) | def setup_class(cls):
    method teardown_class (line 179) | def teardown_class(cls):
    method test_time_series_equality_parallel_by_rows (line 182) | def test_time_series_equality_parallel_by_rows(self):
    method test_time_series_equality_serial_by_the_pixel (line 196) | def test_time_series_equality_serial_by_the_pixel(self):
    method assertEqual (line 210) | def assertEqual(val1, val2):
  class TestLegacyTimeSeriesEqualityMethod2Interp0 (line 214) | class TestLegacyTimeSeriesEqualityMethod2Interp0:
    method setup_class (line 217) | def setup_class(cls):
    method teardown_class (line 284) | def teardown_class(cls):
    method test_time_series_equality_parallel_by_rows (line 287) | def test_time_series_equality_parallel_by_rows(self):
    method test_time_series_equality_serial_by_the_pixel (line 295) | def test_time_series_equality_serial_by_the_pixel(self):
  class TestLinearRatePixel (line 304) | class TestLinearRatePixel:
    method test_linear_rate_pixel_clean (line 310) | def test_linear_rate_pixel_clean(self):
    method test_linear_rate_pixel_neg_rate (line 317) | def test_linear_rate_pixel_neg_rate(self):
    method test_linear_rate_pixel_outlier (line 324) | def test_linear_rate_pixel_outlier(self):
    method test_linear_rate_pixel_noise (line 331) | def test_linear_rate_pixel_noise(self):
    method test_linear_rate_pixel_exception (line 343) | def test_linear_rate_pixel_exception(self):
    method test_linear_rate_pixel_nans (line 350) | def test_linear_rate_pixel_nans(self):
  class TestLinearRateArray (line 359) | class TestLinearRateArray:
    method setup_class (line 366) | def setup_class(cls, roipac_params):
    method test_linear_rate_array (line 391) | def test_linear_rate_array(self):
    method test_linear_rate_array_two_sigma (line 404) | def test_linear_rate_array_two_sigma(self):
    method test_linear_rate_array_exception (line 416) | def test_linear_rate_array_exception(self):

FILE: utils/crop_ifgs.py
  function crop_using_gdalwarp (line 28) | def crop_using_gdalwarp(input_file, output_file, extents):

FILE: utils/gdaldem.py
  function main (line 44) | def main(input_file, color_file, output_file):
  function gen_color_file (line 50) | def gen_color_file(input_file):

FILE: utils/plot_linear_rate_profile.py
  function get_profile (line 67) | def get_profile(pts, img):

FILE: utils/plot_sbas_network.py
  function readtif (line 46) | def readtif(tifname: str):
  function plot_baseline_time_sbas (line 57) | def plot_baseline_time_sbas(epochs, Bperps, epoch1, epoch2, filename):
  function epoch_baselines (line 121) | def epoch_baselines(epochs, bperp, masidx, slvidx, supermaster):

FILE: utils/plot_time_series.py
  function readtif (line 48) | def readtif(tifname: str):
  function get_range (line 112) | def get_range(arr, refarea):
  function line_select_callback (line 185) | def line_select_callback(eclick, erelease):
  function show_vel (line 231) | def show_vel(val_ind):
  function tim_slidupdate (line 281) | def tim_slidupdate(val):
  function fitfunc (line 327) | def fitfunc(label):
  function calc_model (line 349) | def calc_model(dph, imdates_ordinal, xvalues, model, vel1p, intercept1p):
  function printcoords (line 385) | def printcoords(event):
Condensed preview — 856 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (6,257K chars).
[
  {
    "path": ".coveragerc",
    "chars": 1224,
    "preview": "# .coveragerc to control coverage.py\n[run]\nbranch = True\nsource = pyrate\n#omit =\n    # omit everything in\n    # pyrate/t"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "chars": 834,
    "preview": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Describe the b"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "chars": 595,
    "preview": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Is your fea"
  },
  {
    "path": ".github/workflows/build.yml",
    "chars": 4618,
    "preview": "name: PyRate CI\n\n\non:\n  pull_request:\n    branches:\n      - 'master'\n  push:\n    branches:\n      - '**'\n\njobs:\n  build:\n"
  },
  {
    "path": ".gitignore",
    "chars": 863,
    "preview": "!*docs/_build/html/404.html\n!*tests/test_data/merge/linrate.tif\n!*tests/test_data/small_test/gamma_obs/20060619-20061002"
  },
  {
    "path": ".pylintrc",
    "chars": 13881,
    "preview": "[MASTER]\n\n# Specify a configuration file.\n#rcfile=\n\n# Python code to execute, usually for sys.path manipulation such as\n"
  },
  {
    "path": "Dockerfile",
    "chars": 3589,
    "preview": "FROM ubuntu:16.04\n\nENV LANG C.UTF-8\nENV LANG=en_AU.UTF-8\nENV WORKON_HOME=$HOME/venvs\nENV GDALINST=$HOME/gdalinstall\nENV "
  },
  {
    "path": "LICENSE",
    "chars": 11358,
    "preview": "\n                                 Apache License\n                           Version 2.0, January 2004\n                  "
  },
  {
    "path": "README.rst",
    "chars": 4759,
    "preview": ".. image:: docs/PyRate_logo_50.png\n   :alt: PyRate logo\n\nPython tool for InSAR Rate and Time-series Estimation\n========="
  },
  {
    "path": "__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/Makefile",
    "chars": 605,
    "preview": "# Minimal makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line.\nSPHINXOPTS    =\nSPHI"
  },
  {
    "path": "docs/algorithm.rst",
    "chars": 85,
    "preview": "Algorithm Module\n================\n\n.. automodule:: pyrate.core.algorithm\n   :members:"
  },
  {
    "path": "docs/aps.rst",
    "chars": 110,
    "preview": "Atmospheric Phase Screen Module\n===============================\n\n.. automodule:: pyrate.core.aps\n   :members:\n"
  },
  {
    "path": "docs/authors.rst",
    "chars": 888,
    "preview": "=======\nCredits\n=======\n\nDevelopment Lead\n----------------\n\n`PyRate` has been developed by `Geoscience Australia <http:/"
  },
  {
    "path": "docs/conf.py",
    "chars": 5850,
    "preview": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\nimport os\nimport datetime\nimport sphinx_rtd_theme\n\n\n__version__ = \"0.6.0\""
  },
  {
    "path": "docs/configuration.rst",
    "chars": 93,
    "preview": "Configuration Module\n====================\n\n.. automodule:: pyrate.configuration\n   :members:\n"
  },
  {
    "path": "docs/contributing.rst",
    "chars": 3530,
    "preview": "============\nContributing\n============\n\nContributions to `PyRate` are welcome, and they are greatly appreciated! Every\nl"
  },
  {
    "path": "docs/covariance.rst",
    "chars": 93,
    "preview": "Covariance Module\n=====================\n\n.. automodule:: pyrate.core.covariance\n   :members:\n"
  },
  {
    "path": "docs/demerror.rst",
    "chars": 108,
    "preview": "DEM Error Correction Module\n===========================\n\n.. automodule:: pyrate.core.dem_error\n   :members:\n"
  },
  {
    "path": "docs/dependencies.rst",
    "chars": 815,
    "preview": "Dependencies\n------------\n\nThe following dependencies need to be on your system (or in your working\nenvironment) prior t"
  },
  {
    "path": "docs/docker.rst",
    "chars": 1619,
    "preview": "Docker\n^^^^^^\n\nDocker can be used to run `PyRate` on Linux, Windows and MacOS systems.\n\n.. note::\n\n    - Docker is the r"
  },
  {
    "path": "docs/gamma.rst",
    "chars": 73,
    "preview": "GAMMA Module\n============\n\n.. automodule:: pyrate.core.gamma\n   :members:"
  },
  {
    "path": "docs/gdal_python.rst",
    "chars": 109,
    "preview": "GDAL-Python Bindings Module\n===========================\n\n.. automodule:: pyrate.core.gdal_python\n   :members:"
  },
  {
    "path": "docs/geometry.rst",
    "chars": 83,
    "preview": "Geometry Module\n===============\n\n.. automodule:: pyrate.core.geometry\n   :members:\n"
  },
  {
    "path": "docs/history.rst",
    "chars": 12033,
    "preview": ".. :changelog:\n\nRelease History\n===============\n\n0.6.1 (2022-02-18)\n------------------\nAdded\n+++++\n- List generator in `"
  },
  {
    "path": "docs/hpc.rst",
    "chars": 1248,
    "preview": "HPC\n^^^\n\nThese instructions have been written for the Gadi supercomputer of the \n`National Computational Infrastructure "
  },
  {
    "path": "docs/ifgconstants.rst",
    "chars": 96,
    "preview": "Ifgconstants Module\n===================\n\n.. automodule:: pyrate.core.ifgconstants\n    :members:\n"
  },
  {
    "path": "docs/index.rst",
    "chars": 1985,
    "preview": "PyRate documentation\n====================\n\nThis is the documentation for the `PyRate` software.\n\n`PyRate` is a Python to"
  },
  {
    "path": "docs/installation.rst",
    "chars": 1171,
    "preview": "Installation\n============\n\nThis is an installation guide to get `PyRate` running on various platforms.\nFollow the instru"
  },
  {
    "path": "docs/logger.rst",
    "chars": 79,
    "preview": "Logging Module\n==============\n\n.. automodule:: pyrate.core.logger\n   :members:\n"
  },
  {
    "path": "docs/make.bat",
    "chars": 810,
    "preview": "@ECHO OFF\r\n\r\npushd %~dp0\r\n\r\nREM Command file for Sphinx documentation\r\n\r\nif \"%SPHINXBUILD%\" == \"\" (\r\n\tset SPHINXBUILD=sp"
  },
  {
    "path": "docs/modules.rst",
    "chars": 319,
    "preview": "PyRate Modules\n==============\n\n.. toctree::\n   :maxdepth: 4\n\n   algorithm\n   aps\n   configuration\n   covariance\n   demer"
  },
  {
    "path": "docs/mpiops.rst",
    "chars": 94,
    "preview": "MPI operations Module\n=====================\n\n.. automodule:: pyrate.core.mpiops\n    :members:\n"
  },
  {
    "path": "docs/mst.rst",
    "chars": 104,
    "preview": "Minimum Spanning Tree Module\n============================\n\n.. automodule:: pyrate.core.mst\n   :members:\n"
  },
  {
    "path": "docs/orbital.rst",
    "chars": 113,
    "preview": "Orbital Error Correction Module\n===============================\n\n.. automodule:: pyrate.core.orbital\n   :members:"
  },
  {
    "path": "docs/phase_closure.rst",
    "chars": 9441,
    "preview": "Phase Closure Module\n====================\n\nThe phase closure functionality in PyRate is designed to identify and mitigat"
  },
  {
    "path": "docs/prepifg_helper.rst",
    "chars": 102,
    "preview": "Prepifg Helper Module\n=====================\n\n.. automodule:: pyrate.core.prepifg_helper\n    :members:\n"
  },
  {
    "path": "docs/pyrate.conv2tif.rst",
    "chars": 136,
    "preview": "PyRate Conv2tif Script\n======================\n\n.. automodule:: pyrate.conv2tif\n    :members:\n    :undoc-members:\n    :sh"
  },
  {
    "path": "docs/pyrate.correct.rst",
    "chars": 136,
    "preview": "PyRate Correct Script\n========================\n\n.. automodule:: pyrate.correct\n    :members:\n    :undoc-members:\n    :sh"
  },
  {
    "path": "docs/pyrate.main.rst",
    "chars": 198,
    "preview": "PyRate Main Script\n==================\n\n.. automodule:: pyrate.main\n\n   .. rubric:: Functions\n   .. autosummary::\n\n      "
  },
  {
    "path": "docs/pyrate.merge.rst",
    "chars": 127,
    "preview": "PyRate Merge Script\n===================\n\n.. automodule:: pyrate.merge\n    :members:\n    :undoc-members:\n    :show-inheri"
  },
  {
    "path": "docs/pyrate.prepifg.rst",
    "chars": 137,
    "preview": "PyRate Prepifg Script\n=========================\n\n.. automodule:: pyrate.prepifg\n    :members:\n    :undoc-members:\n    :s"
  },
  {
    "path": "docs/ref_phs_est.rst",
    "chars": 123,
    "preview": "Reference Phase Calculation Module\n==================================\n\n.. automodule:: pyrate.core.ref_phs_est\n   :membe"
  },
  {
    "path": "docs/refpixel.rst",
    "chars": 120,
    "preview": "Reference Pixel Calculation Module\n==================================\n\n.. automodule:: pyrate.core.refpixel\n   :members:"
  },
  {
    "path": "docs/roipac.rst",
    "chars": 79,
    "preview": "ROI_PAC Module\n==============\n\n.. automodule:: pyrate.core.roipac\n   :members:\n"
  },
  {
    "path": "docs/scripts.rst",
    "chars": 147,
    "preview": "PyRate Scripts\n==============\n\n.. toctree::\n   :maxdepth: 4\n\n   pyrate.conv2tif\n   pyrate.prepifg\n   pyrate.correct\n   p"
  },
  {
    "path": "docs/shared.rst",
    "chars": 76,
    "preview": "Shared Module\n=============\n\n.. automodule:: pyrate.core.shared\n   :members:"
  },
  {
    "path": "docs/stack.rst",
    "chars": 80,
    "preview": "Stacking Module\n===============\n\n.. automodule:: pyrate.core.stack\n   :members:\n"
  },
  {
    "path": "docs/timeseries.rst",
    "chars": 90,
    "preview": "Time Series Module\n==================\n\n.. automodule:: pyrate.core.timeseries\n   :members:"
  },
  {
    "path": "docs/troubleshooting.rst",
    "chars": 10996,
    "preview": "Troubleshooting\n===============\n\nSome common/known issues with `PyRate` that users may encounter are described below.\n\nI"
  },
  {
    "path": "docs/ubuntu.rst",
    "chars": 679,
    "preview": "Linux\n^^^^^\n\nThese instructions have been tested using Ubuntu 18.04. If using another\nLinux distribution, you will have "
  },
  {
    "path": "docs/usage.rst",
    "chars": 22486,
    "preview": "Usage\n=====\n\nConfiguration\n-------------\n\nVarious parameters are controlled by values given in a text-based configuratio"
  },
  {
    "path": "input_parameters.conf",
    "chars": 7129,
    "preview": "# PyRate configuration file for GAMMA-format interferograms\n#\n#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
  },
  {
    "path": "pyrate/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "pyrate/configuration.py",
    "chars": 19183,
    "preview": "#   This Python module is part of the PyRate software package.\n#\n#   Copyright 2022 Geoscience Australia\n#\n#   Licensed "
  },
  {
    "path": "pyrate/constants.py",
    "chars": 10845,
    "preview": "import os\nimport re\nfrom pathlib import Path\nimport numpy as np\n\nPYRATEPATH = Path(__file__).parent.parent\n\n\n__version__"
  },
  {
    "path": "pyrate/conv2tif.py",
    "chars": 4540,
    "preview": "#   This Python module is part of the PyRate software package.\n#\n#   Copyright 2022 Geoscience Australia\n#\n#   Licensed "
  },
  {
    "path": "pyrate/core/.coveragerc",
    "chars": 225,
    "preview": "[run]\nplugins = Cython.Coverage\nsource = pyrate\nomit = aps.py\nbranch = True\n\n[report]\nexclude_lines =\n    pragma: no cov"
  },
  {
    "path": "pyrate/core/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "pyrate/core/algorithm.py",
    "chars": 8279,
    "preview": "#   This Python module is part of the PyRate software package.\n#\n#   Copyright 2022 Geoscience Australia\n#\n#   Licensed "
  },
  {
    "path": "pyrate/core/aps.py",
    "chars": 16528,
    "preview": "#   This Python module is part of the PyRate software package.\n#\n#   Copyright 2022 Geoscience Australia\n#\n#   Licensed "
  },
  {
    "path": "pyrate/core/covariance.py",
    "chars": 12780,
    "preview": "#   This Python module is part of the PyRate software package.\n#\n#   Copyright 2022 Geoscience Australia\n#\n#   Licensed "
  },
  {
    "path": "pyrate/core/dem_error.py",
    "chars": 17115,
    "preview": "#   This Python module is part of the PyRate software package.\n#\n#   Copyright 2022 Geoscience Australia\n#\n#   Licensed "
  },
  {
    "path": "pyrate/core/gamma.py",
    "chars": 26996,
    "preview": "#   This Python module is part of the PyRate software package.\n#\n#   Copyright 2022 Geoscience Australia\n#\n#   Licensed "
  },
  {
    "path": "pyrate/core/gdal_python.py",
    "chars": 13675,
    "preview": "#   This Python module is part of the PyRate software package.\n#\n#   Copyright 2022 Geoscience Australia\n#\n#   Licensed "
  },
  {
    "path": "pyrate/core/geometry.py",
    "chars": 13891,
    "preview": "#   This Python module is part of the PyRate software package.\n#\n#   Copyright 2022 Geoscience Australia\n#\n#   Licensed "
  },
  {
    "path": "pyrate/core/ifgconstants.py",
    "chars": 4535,
    "preview": "#   This Python module is part of the PyRate software package.\n#\n#   Copyright 2022 Geoscience Australia\n#\n#   Licensed "
  },
  {
    "path": "pyrate/core/logger.py",
    "chars": 2021,
    "preview": "#   This Python module is part of the PyRate software package.\n#\n#   Copyright 2022 Geoscience Australia\n#\n#   Licensed "
  },
  {
    "path": "pyrate/core/mpiops.py",
    "chars": 4509,
    "preview": "#   This Python module is part of the PyRate software package.\n#\n#   Copyright 2022 Geoscience Australia\n#\n#   Licensed "
  },
  {
    "path": "pyrate/core/mst.py",
    "chars": 10713,
    "preview": "#   This Python module is part of the PyRate software package.\n#\n#   Copyright 2022 Geoscience Australia\n#\n#   Licensed "
  },
  {
    "path": "pyrate/core/orbital.py",
    "chars": 23535,
    "preview": "#   This Python module is part of the PyRate software package.\n#\n#   Copyright 2022 Geoscience Australia\n#\n#   Licensed "
  },
  {
    "path": "pyrate/core/phase_closure/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "pyrate/core/phase_closure/closure_check.py",
    "chars": 10605,
    "preview": "#   This Python module is part of the PyRate software package.\n#\n#   Copyright 2022 Geoscience Australia\n#\n#   Licensed "
  },
  {
    "path": "pyrate/core/phase_closure/collect_loops.py",
    "chars": 3640,
    "preview": "#   This Python module is part of the PyRate software package.\n#\n#   Copyright 2022 Geoscience Australia\n#\n#   Licensed "
  },
  {
    "path": "pyrate/core/phase_closure/correct_phase.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "pyrate/core/phase_closure/mst_closure.py",
    "chars": 6125,
    "preview": "#   This Python module is part of the PyRate software package.\n#\n#   Copyright 2022 Geoscience Australia\n#\n#   Licensed "
  },
  {
    "path": "pyrate/core/phase_closure/plot_closure.py",
    "chars": 3116,
    "preview": "#   This Python module is part of the PyRate software package.\n#\n#   Copyright 2022 Geoscience Australia\n#\n#   Licensed "
  },
  {
    "path": "pyrate/core/phase_closure/sum_closure.py",
    "chars": 9290,
    "preview": "#   This Python module is part of the PyRate software package.\n#\n#   Copyright 2022 Geoscience Australia\n#\n#   Licensed "
  },
  {
    "path": "pyrate/core/prepifg_helper.py",
    "chars": 14845,
    "preview": "#   This Python module is part of the PyRate software package\n#\n#   Copyright 2022 Geoscience Australia\n#\n#   Licensed u"
  },
  {
    "path": "pyrate/core/ref_phs_est.py",
    "chars": 10291,
    "preview": "#   This Python module is part of the PyRate software package.\n#\n#   Copyright 2022 Geoscience Australia\n#\n#   Licensed "
  },
  {
    "path": "pyrate/core/refpixel.py",
    "chars": 17694,
    "preview": "#   This Python module is part of the PyRate software package.\n#\n#   Copyright 2022 Geoscience Australia\n#\n#   Licensed "
  },
  {
    "path": "pyrate/core/roipac.py",
    "chars": 7820,
    "preview": "#   This Python module is part of the PyRate software package.\n#\n#   Copyright 2022 Geoscience Australia\n#\n#   Licensed "
  },
  {
    "path": "pyrate/core/shared.py",
    "chars": 47330,
    "preview": "#   This Python module is part of the PyRate software package.\n#\n#   Copyright 2022 Geoscience Australia\n#\n#   Licensed "
  },
  {
    "path": "pyrate/core/stack.py",
    "chars": 8926,
    "preview": "#   This Python module is part of the PyRate software package.\n#\n#   Copyright 2022 Geoscience Australia\n#\n#   Licensed "
  },
  {
    "path": "pyrate/core/timeseries.py",
    "chars": 16887,
    "preview": "#   This Python module is part of the PyRate software package.\n#\n#   Copyright 2022 Geoscience Australia\n#\n#   Licensed "
  },
  {
    "path": "pyrate/correct.py",
    "chars": 8739,
    "preview": "#   This Python module is part of the PyRate software package.\n#\n#   Copyright 2022 Geoscience Australia\n#\n#   Licensed "
  },
  {
    "path": "pyrate/default_parameters.py",
    "chars": 13605,
    "preview": "#   This Python module is part of the PyRate software package.\n#\n#   Copyright 2022 Geoscience Australia\n#\n#   Licensed "
  },
  {
    "path": "pyrate/main.py",
    "chars": 6236,
    "preview": "#   This Python module is part of the PyRate software package.\n#\n#   Copyright 2022 Geoscience Australia\n#\n#   Licensed "
  },
  {
    "path": "pyrate/merge.py",
    "chars": 15053,
    "preview": "#   This Python module is part of the PyRate software package.\n#\n#   Copyright 2022 Geoscience Australia\n#\n#   Licensed "
  },
  {
    "path": "pyrate/prepifg.py",
    "chars": 17342,
    "preview": "#   This Python module is part of the PyRate software package.\n#\n#   Copyright 2022 Geoscience Australia\n#\n#   Licensed "
  },
  {
    "path": "pytest.ini",
    "chars": 199,
    "preview": "[pytest]\nfilterwarnings =\n    ignore::DeprecationWarning\n\nmarkers =\n    slow: marks tests as slow (deselect with '-m \"no"
  },
  {
    "path": "requirements-dev.txt",
    "chars": 185,
    "preview": "ghp-import==0.5.5\nsphinx==3.0.3\nsphinx_rtd_theme==0.4.3\nsphinxcontrib-programoutput==0.16\nrecommonmark==0.6.0\nm2r2\nmpi4p"
  },
  {
    "path": "requirements-plot.txt",
    "chars": 46,
    "preview": "rasterio\nmatplotlib \nstatsmodels\nxarray\npylab\n"
  },
  {
    "path": "requirements-test.txt",
    "chars": 73,
    "preview": "pytest-cov==2.8.1\ncoverage==5.1\ncodecov==2.1.0\ntox==3.15.0\npytest==5.4.2\n"
  },
  {
    "path": "requirements.txt",
    "chars": 119,
    "preview": "GDAL\njoblib==1.0.0\nmpi4py==3.0.3\nnetworkx==2.5\nnumpy==1.19.4\npyproj==3.0.0\nscipy==1.5.4\nnumexpr==2.7.2\nnptyping==1.4.0\n"
  },
  {
    "path": "scripts/apt_install.sh",
    "chars": 339,
    "preview": "echo \"This script will install packages required by PyRate. Continue?\" \n    select yn in \"Yes\" \"No\"; do\n    case $yn in\n"
  },
  {
    "path": "scripts/ci_gdal_install.sh",
    "chars": 3210,
    "preview": "#!/bin/bash\n#\n# originally contributed by @rbuffat to Toblerity/Fiona\nset -e\n\nGDALOPTS=\"  --with-geos \\\n            --wi"
  },
  {
    "path": "scripts/ci_proj_install.sh",
    "chars": 510,
    "preview": "#!/bin/sh\nset -e\n\n# Create build dir if not exists\nif [ ! -d \"$PROJBUILD\" ]; then\n  mkdir $PROJBUILD;\nfi\n\nif [ ! -d \"$PR"
  },
  {
    "path": "scripts/create_html_documentation.sh",
    "chars": 380,
    "preview": "#!/bin/bash\nmodule purge\nmodule load python3/3.7.4\nmodule load gdal/3.0.2\nmodule load openmpi/4.0.2\nexport PYTHONPATH=/a"
  },
  {
    "path": "scripts/gdal_calc_local.py",
    "chars": 17099,
    "preview": "#! /usr/bin/python\n# -*- coding: utf-8 -*-\n#****************************************************************************"
  },
  {
    "path": "scripts/nci_install.sh",
    "chars": 373,
    "preview": "#!/bin/bash\nrm -rf  ~/PyRateVenv\nrm -rf  ~/PyRate\ngit clone https://github.com/GeoscienceAustralia/PyRate.git\nmodule pur"
  },
  {
    "path": "scripts/nci_load_modules.sh",
    "chars": 378,
    "preview": "#!bin/bash\nmodule purge\nmodule load python3/3.7.4\nmodule load gdal/3.0.2\nmodule load openmpi/4.0.2\n# Remove the prebuilt"
  },
  {
    "path": "scripts/nci_run_tests.sh",
    "chars": 258,
    "preview": "#!/bin/bash\nmodule purge\nmodule load python3/3.7.4\nmodule load gdal/3.0.2\nmodule load openmpi/4.0.2\nexport PYTHONPATH=/a"
  },
  {
    "path": "scripts/plot_ifgs.py",
    "chars": 5093,
    "preview": "#   This Python module is part of the PyRate software package.\n#\n#   Copyright 2022 Geoscience Australia\n#\n#   Licensed "
  },
  {
    "path": "scripts/prepifg.sh",
    "chars": 1603,
    "preview": "#!/usr/bin/env bash\n# inputs are extents, thresh, coherence file, coherence_threshold\n# coherence masking\n# gdal average"
  },
  {
    "path": "setup.cfg",
    "chars": 152,
    "preview": "# Inside of setup.cfg\n[metadata]\ndescription-file = README.rst\n\n[aliases]\ntest = pytest\n\n[tool:pytest]\nmarkers:\n  slow: "
  },
  {
    "path": "setup.py",
    "chars": 5641,
    "preview": "#   This Python module is part of the PyRate software package.\n#\n#   Copyright 2022 Geoscience Australia\n#\n#   Licensed "
  },
  {
    "path": "tests/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "tests/common.py",
    "chars": 25131,
    "preview": "#   This Python module is part of the PyRate software package.\n#\n#   Copyright 2022 Geoscience Australia\n#\n#   Licensed "
  },
  {
    "path": "tests/conftest.py",
    "chars": 4835,
    "preview": "#   This Python module is part of the PyRate software package.\n#\n#   Copyright 2022 Geoscience Australia\n#\n#   Licensed "
  },
  {
    "path": "tests/phase_closure/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "tests/phase_closure/common.py",
    "chars": 90,
    "preview": "class IfgDummy:\n    def __init__(self, ifg_path):\n        self.tmp_sampled_path = ifg_path"
  },
  {
    "path": "tests/phase_closure/conftest.py",
    "chars": 580,
    "preview": "from pathlib import Path\nimport pytest\nfrom pyrate import constants as C\nfrom tests.phase_closure.common import IfgDummy"
  },
  {
    "path": "tests/phase_closure/test_closure_check.py",
    "chars": 2533,
    "preview": "#   This Python module is part of the PyRate software package.\n#\n#   Copyright 2022 Geoscience Australia\n#\n#   Licensed "
  },
  {
    "path": "tests/phase_closure/test_collect_loops.py",
    "chars": 3206,
    "preview": "from typing import List\nfrom datetime import date\nimport pytest\nimport numpy as np\nimport networkx as nx\nfrom pyrate.cor"
  },
  {
    "path": "tests/phase_closure/test_mst_closure.py",
    "chars": 4688,
    "preview": "#   This Python module is part of the PyRate software package.\n#\n#   Copyright 2022 Geoscience Australia\n#\n#   Licensed "
  },
  {
    "path": "tests/phase_closure/test_plot_closure.py",
    "chars": 2226,
    "preview": "#   This Python module is part of the PyRate software package.\n#\n#   Copyright 2022 Geoscience Australia\n#\n#   Licensed "
  },
  {
    "path": "tests/phase_closure/test_sum_closure.py",
    "chars": 5221,
    "preview": "#   This Python module is part of the PyRate software package.\n#\n#   Copyright 2022 Geoscience Australia\n#\n#   Licensed "
  },
  {
    "path": "tests/test_algorithm.py",
    "chars": 8637,
    "preview": "#   This Python module is part of the PyRate software package.\n#\n#   Copyright 2022 Geoscience Australia\n#\n#   Licensed "
  },
  {
    "path": "tests/test_aps.py",
    "chars": 8856,
    "preview": "#   This Python module is part of the PyRate software package.\n#\n#   Copyright 2022 Geoscience Australia\n#\n#   Licensed "
  },
  {
    "path": "tests/test_constants.py",
    "chars": 1183,
    "preview": "import re\nfrom pathlib import Path\nimport pytest\nfrom pyrate.constants import twelve_digits_pattern, sixteen_digits_patt"
  },
  {
    "path": "tests/test_conv2tif.py",
    "chars": 4216,
    "preview": "#   This Python module is part of the PyRate software package.\n#\n#   Copyright 2022 Geoscience Australia\n#\n#   Licensed "
  },
  {
    "path": "tests/test_correct.py",
    "chars": 3410,
    "preview": "#   This Python module is part of the PyRate software package.\n#\n#   Copyright 2022 Geoscience Australia\n#\n#   Licensed "
  },
  {
    "path": "tests/test_covariance.py",
    "chars": 10012,
    "preview": "#   This Python module is part of the PyRate software package.\n#\n#   Copyright 2022 Geoscience Australia\n#\n#   Licensed "
  },
  {
    "path": "tests/test_data/cropA/baseline_30",
    "chars": 2010,
    "preview": "tests/test_data/cropA/geometry/20180106-20180130_VV_8rlks_base.par\ntests/test_data/cropA/geometry/20180106-20180319_VV_8"
  },
  {
    "path": "tests/test_data/cropA/coherence_30",
    "chars": 2400,
    "preview": "tests/test_data/cropA/geotiffs/cropA_20180106-20180130_VV_8rlks_flat_eqa_cc.tif\ntests/test_data/cropA/geotiffs/cropA_201"
  },
  {
    "path": "tests/test_data/cropA/geometry/20180106-20180130_VV_8rlks_base.par",
    "chars": 411,
    "preview": "initial_baseline(TCN):         -0.1536945       40.1145103        4.5090025   m   m   m\ninitial_baseline_rate:          "
  },
  {
    "path": "tests/test_data/cropA/geometry/20180106-20180130_VV_8rlks_bperp.par",
    "chars": 42116,
    "preview": "*** Calculate baseline components perpendicular and parallel to look vector ***\n*** Copyright 2005, Gamma Remote Sensing"
  },
  {
    "path": "tests/test_data/cropA/geometry/20180106-20180319_VV_8rlks_base.par",
    "chars": 411,
    "preview": "initial_baseline(TCN):         -0.0425811        3.6031274       -0.5126463   m   m   m\ninitial_baseline_rate:          "
  },
  {
    "path": "tests/test_data/cropA/geometry/20180106-20180319_VV_8rlks_bperp.par",
    "chars": 42116,
    "preview": "*** Calculate baseline components perpendicular and parallel to look vector ***\n*** Copyright 2005, Gamma Remote Sensing"
  },
  {
    "path": "tests/test_data/cropA/geometry/20180106-20180412_VV_8rlks_base.par",
    "chars": 411,
    "preview": "initial_baseline(TCN):         -3.3824897      -65.5423278       36.9516791   m   m   m\ninitial_baseline_rate:          "
  },
  {
    "path": "tests/test_data/cropA/geometry/20180106-20180412_VV_8rlks_bperp.par",
    "chars": 42116,
    "preview": "*** Calculate baseline components perpendicular and parallel to look vector ***\n*** Copyright 2005, Gamma Remote Sensing"
  },
  {
    "path": "tests/test_data/cropA/geometry/20180106-20180518_VV_8rlks_base.par",
    "chars": 411,
    "preview": "initial_baseline(TCN):          0.8185852      -15.9799853       28.0671376   m   m   m\ninitial_baseline_rate:          "
  },
  {
    "path": "tests/test_data/cropA/geometry/20180106-20180518_VV_8rlks_bperp.par",
    "chars": 42116,
    "preview": "*** Calculate baseline components perpendicular and parallel to look vector ***\n*** Copyright 2005, Gamma Remote Sensing"
  },
  {
    "path": "tests/test_data/cropA/geometry/20180130-20180307_VV_8rlks_base.par",
    "chars": 411,
    "preview": "initial_baseline(TCN):          0.6939756      -40.1971021       -5.6555867   m   m   m\ninitial_baseline_rate:          "
  },
  {
    "path": "tests/test_data/cropA/geometry/20180130-20180307_VV_8rlks_bperp.par",
    "chars": 42116,
    "preview": "*** Calculate baseline components perpendicular and parallel to look vector ***\n*** Copyright 2005, Gamma Remote Sensing"
  },
  {
    "path": "tests/test_data/cropA/geometry/20180130-20180412_VV_8rlks_base.par",
    "chars": 411,
    "preview": "initial_baseline(TCN):         -0.7080870     -105.5946431       32.4031046   m   m   m\ninitial_baseline_rate:          "
  },
  {
    "path": "tests/test_data/cropA/geometry/20180130-20180412_VV_8rlks_bperp.par",
    "chars": 42116,
    "preview": "*** Calculate baseline components perpendicular and parallel to look vector ***\n*** Copyright 2005, Gamma Remote Sensing"
  },
  {
    "path": "tests/test_data/cropA/geometry/20180307-20180319_VV_8rlks_base.par",
    "chars": 411,
    "preview": "initial_baseline(TCN):         -0.0000004        4.1283381        0.3230800   m   m   m\ninitial_baseline_rate:          "
  },
  {
    "path": "tests/test_data/cropA/geometry/20180307-20180319_VV_8rlks_bperp.par",
    "chars": 42116,
    "preview": "*** Calculate baseline components perpendicular and parallel to look vector ***\n*** Copyright 2005, Gamma Remote Sensing"
  },
  {
    "path": "tests/test_data/cropA/geometry/20180307-20180331_VV_8rlks_base.par",
    "chars": 411,
    "preview": "initial_baseline(TCN):         -0.1112816       -1.2495340        5.0924280   m   m   m\ninitial_baseline_rate:          "
  },
  {
    "path": "tests/test_data/cropA/geometry/20180307-20180331_VV_8rlks_bperp.par",
    "chars": 42116,
    "preview": "*** Calculate baseline components perpendicular and parallel to look vector ***\n*** Copyright 2005, Gamma Remote Sensing"
  },
  {
    "path": "tests/test_data/cropA/geometry/20180307-20180506_VV_8rlks_base.par",
    "chars": 411,
    "preview": "initial_baseline(TCN):         -0.0000004       -2.5497431       28.2483011   m   m   m\ninitial_baseline_rate:          "
  },
  {
    "path": "tests/test_data/cropA/geometry/20180307-20180506_VV_8rlks_bperp.par",
    "chars": 42116,
    "preview": "*** Calculate baseline components perpendicular and parallel to look vector ***\n*** Copyright 2005, Gamma Remote Sensing"
  },
  {
    "path": "tests/test_data/cropA/geometry/20180307-20180530_VV_8rlks_base.par",
    "chars": 411,
    "preview": "initial_baseline(TCN):         -0.6454202       33.7680109       43.0365483   m   m   m\ninitial_baseline_rate:          "
  },
  {
    "path": "tests/test_data/cropA/geometry/20180307-20180530_VV_8rlks_bperp.par",
    "chars": 42116,
    "preview": "*** Calculate baseline components perpendicular and parallel to look vector ***\n*** Copyright 2005, Gamma Remote Sensing"
  },
  {
    "path": "tests/test_data/cropA/geometry/20180307-20180611_VV_8rlks_base.par",
    "chars": 411,
    "preview": "initial_baseline(TCN):         -1.0202033      -42.5608037       28.9838632   m   m   m\ninitial_baseline_rate:          "
  },
  {
    "path": "tests/test_data/cropA/geometry/20180307-20180611_VV_8rlks_bperp.par",
    "chars": 42116,
    "preview": "*** Calculate baseline components perpendicular and parallel to look vector ***\n*** Copyright 2005, Gamma Remote Sensing"
  },
  {
    "path": "tests/test_data/cropA/geometry/20180319-20180331_VV_8rlks_base.par",
    "chars": 411,
    "preview": "initial_baseline(TCN):          0.0940080       -4.4095585        4.0878617   m   m   m\ninitial_baseline_rate:          "
  },
  {
    "path": "tests/test_data/cropA/geometry/20180319-20180331_VV_8rlks_bperp.par",
    "chars": 42116,
    "preview": "*** Calculate baseline components perpendicular and parallel to look vector ***\n*** Copyright 2005, Gamma Remote Sensing"
  },
  {
    "path": "tests/test_data/cropA/geometry/20180319-20180506_VV_8rlks_base.par",
    "chars": 411,
    "preview": "initial_baseline(TCN):          0.9353410       -5.3971995       27.0244745   m   m   m\ninitial_baseline_rate:          "
  },
  {
    "path": "tests/test_data/cropA/geometry/20180319-20180506_VV_8rlks_bperp.par",
    "chars": 42116,
    "preview": "*** Calculate baseline components perpendicular and parallel to look vector ***\n*** Copyright 2005, Gamma Remote Sensing"
  },
  {
    "path": "tests/test_data/cropA/geometry/20180319-20180518_VV_8rlks_base.par",
    "chars": 411,
    "preview": "initial_baseline(TCN):         -1.0633968      -19.5288097       28.5389506   m   m   m\ninitial_baseline_rate:          "
  },
  {
    "path": "tests/test_data/cropA/geometry/20180319-20180518_VV_8rlks_bperp.par",
    "chars": 42116,
    "preview": "*** Calculate baseline components perpendicular and parallel to look vector ***\n*** Copyright 2005, Gamma Remote Sensing"
  },
  {
    "path": "tests/test_data/cropA/geometry/20180319-20180530_VV_8rlks_base.par",
    "chars": 411,
    "preview": "initial_baseline(TCN):         -0.6579066       30.3023419       42.2468260   m   m   m\ninitial_baseline_rate:          "
  },
  {
    "path": "tests/test_data/cropA/geometry/20180319-20180530_VV_8rlks_bperp.par",
    "chars": 42116,
    "preview": "*** Calculate baseline components perpendicular and parallel to look vector ***\n*** Copyright 2005, Gamma Remote Sensing"
  },
  {
    "path": "tests/test_data/cropA/geometry/20180319-20180623_VV_8rlks_base.par",
    "chars": 411,
    "preview": "initial_baseline(TCN):          0.2737791      -19.7407601       42.8055396   m   m   m\ninitial_baseline_rate:          "
  },
  {
    "path": "tests/test_data/cropA/geometry/20180319-20180623_VV_8rlks_bperp.par",
    "chars": 42116,
    "preview": "*** Calculate baseline components perpendicular and parallel to look vector ***\n*** Copyright 2005, Gamma Remote Sensing"
  },
  {
    "path": "tests/test_data/cropA/geometry/20180331-20180412_VV_8rlks_base.par",
    "chars": 411,
    "preview": "initial_baseline(TCN):         -0.5207146      -64.6524710       33.3215888   m   m   m\ninitial_baseline_rate:          "
  },
  {
    "path": "tests/test_data/cropA/geometry/20180331-20180412_VV_8rlks_bperp.par",
    "chars": 42116,
    "preview": "*** Calculate baseline components perpendicular and parallel to look vector ***\n*** Copyright 2005, Gamma Remote Sensing"
  },
  {
    "path": "tests/test_data/cropA/geometry/20180331-20180506_VV_8rlks_base.par",
    "chars": 411,
    "preview": "initial_baseline(TCN):         -0.4776116       -0.7573620       22.7725658   m   m   m\ninitial_baseline_rate:          "
  },
  {
    "path": "tests/test_data/cropA/geometry/20180331-20180506_VV_8rlks_bperp.par",
    "chars": 42116,
    "preview": "*** Calculate baseline components perpendicular and parallel to look vector ***\n*** Copyright 2005, Gamma Remote Sensing"
  },
  {
    "path": "tests/test_data/cropA/geometry/20180331-20180518_VV_8rlks_base.par",
    "chars": 411,
    "preview": "initial_baseline(TCN):          0.2959757      -15.0330123       24.3922942   m   m   m\ninitial_baseline_rate:          "
  },
  {
    "path": "tests/test_data/cropA/geometry/20180331-20180518_VV_8rlks_bperp.par",
    "chars": 42116,
    "preview": "*** Calculate baseline components perpendicular and parallel to look vector ***\n*** Copyright 2005, Gamma Remote Sensing"
  },
  {
    "path": "tests/test_data/cropA/geometry/20180331-20180530_VV_8rlks_base.par",
    "chars": 411,
    "preview": "initial_baseline(TCN):         -0.6160465       34.5715540       38.2579471   m   m   m\ninitial_baseline_rate:          "
  },
  {
    "path": "tests/test_data/cropA/geometry/20180331-20180530_VV_8rlks_bperp.par",
    "chars": 42116,
    "preview": "*** Calculate baseline components perpendicular and parallel to look vector ***\n*** Copyright 2005, Gamma Remote Sensing"
  },
  {
    "path": "tests/test_data/cropA/geometry/20180331-20180623_VV_8rlks_base.par",
    "chars": 411,
    "preview": "initial_baseline(TCN):          0.2764284      -15.6218708       38.9224121   m   m   m\ninitial_baseline_rate:          "
  },
  {
    "path": "tests/test_data/cropA/geometry/20180331-20180623_VV_8rlks_bperp.par",
    "chars": 42116,
    "preview": "*** Calculate baseline components perpendicular and parallel to look vector ***\n*** Copyright 2005, Gamma Remote Sensing"
  },
  {
    "path": "tests/test_data/cropA/geometry/20180331-20180717_VV_8rlks_base.par",
    "chars": 411,
    "preview": "initial_baseline(TCN):          0.6757929       -6.1269114       33.0701755   m   m   m\ninitial_baseline_rate:          "
  },
  {
    "path": "tests/test_data/cropA/geometry/20180331-20180717_VV_8rlks_bperp.par",
    "chars": 42116,
    "preview": "*** Calculate baseline components perpendicular and parallel to look vector ***\n*** Copyright 2005, Gamma Remote Sensing"
  },
  {
    "path": "tests/test_data/cropA/geometry/20180412-20180506_VV_8rlks_base.par",
    "chars": 411,
    "preview": "initial_baseline(TCN):         -0.8598882       63.9985273      -10.6224613   m   m   m\ninitial_baseline_rate:          "
  },
  {
    "path": "tests/test_data/cropA/geometry/20180412-20180506_VV_8rlks_bperp.par",
    "chars": 42116,
    "preview": "*** Calculate baseline components perpendicular and parallel to look vector ***\n*** Copyright 2005, Gamma Remote Sensing"
  },
  {
    "path": "tests/test_data/cropA/geometry/20180412-20180518_VV_8rlks_base.par",
    "chars": 411,
    "preview": "initial_baseline(TCN):          0.2932894       49.7232694       -9.0026781   m   m   m\ninitial_baseline_rate:          "
  },
  {
    "path": "tests/test_data/cropA/geometry/20180412-20180518_VV_8rlks_bperp.par",
    "chars": 42116,
    "preview": "*** Calculate baseline components perpendicular and parallel to look vector ***\n*** Copyright 2005, Gamma Remote Sensing"
  },
  {
    "path": "tests/test_data/cropA/geometry/20180506-20180518_VV_8rlks_base.par",
    "chars": 411,
    "preview": "initial_baseline(TCN):         -0.4958283      -14.4402710        1.7338821   m   m   m\ninitial_baseline_rate:          "
  },
  {
    "path": "tests/test_data/cropA/geometry/20180506-20180518_VV_8rlks_bperp.par",
    "chars": 42116,
    "preview": "*** Calculate baseline components perpendicular and parallel to look vector ***\n*** Copyright 2005, Gamma Remote Sensing"
  },
  {
    "path": "tests/test_data/cropA/geometry/20180506-20180530_VV_8rlks_base.par",
    "chars": 411,
    "preview": "initial_baseline(TCN):         -1.1414793       35.2035164       15.5722874   m   m   m\ninitial_baseline_rate:          "
  },
  {
    "path": "tests/test_data/cropA/geometry/20180506-20180530_VV_8rlks_bperp.par",
    "chars": 42116,
    "preview": "*** Calculate baseline components perpendicular and parallel to look vector ***\n*** Copyright 2005, Gamma Remote Sensing"
  },
  {
    "path": "tests/test_data/cropA/geometry/20180506-20180611_VV_8rlks_base.par",
    "chars": 411,
    "preview": "initial_baseline(TCN):          0.4118799      -40.7471207        1.2559498   m   m   m\ninitial_baseline_rate:          "
  },
  {
    "path": "tests/test_data/cropA/geometry/20180506-20180611_VV_8rlks_bperp.par",
    "chars": 42116,
    "preview": "*** Calculate baseline components perpendicular and parallel to look vector ***\n*** Copyright 2005, Gamma Remote Sensing"
  },
  {
    "path": "tests/test_data/cropA/geometry/20180506-20180623_VV_8rlks_base.par",
    "chars": 411,
    "preview": "initial_baseline(TCN):         -0.5613989      -14.6282589       15.9816550   m   m   m\ninitial_baseline_rate:          "
  },
  {
    "path": "tests/test_data/cropA/geometry/20180506-20180623_VV_8rlks_bperp.par",
    "chars": 42116,
    "preview": "*** Calculate baseline components perpendicular and parallel to look vector ***\n*** Copyright 2005, Gamma Remote Sensing"
  },
  {
    "path": "tests/test_data/cropA/geometry/20180506-20180705_VV_8rlks_base.par",
    "chars": 411,
    "preview": "initial_baseline(TCN):          1.5504708       92.0622963        7.2392205   m   m   m\ninitial_baseline_rate:          "
  },
  {
    "path": "tests/test_data/cropA/geometry/20180506-20180705_VV_8rlks_bperp.par",
    "chars": 42116,
    "preview": "*** Calculate baseline components perpendicular and parallel to look vector ***\n*** Copyright 2005, Gamma Remote Sensing"
  },
  {
    "path": "tests/test_data/cropA/geometry/20180506-20180717_VV_8rlks_base.par",
    "chars": 411,
    "preview": "initial_baseline(TCN):         -0.2418971       -4.6591305        9.7953949   m   m   m\ninitial_baseline_rate:          "
  },
  {
    "path": "tests/test_data/cropA/geometry/20180506-20180717_VV_8rlks_bperp.par",
    "chars": 42116,
    "preview": "*** Calculate baseline components perpendicular and parallel to look vector ***\n*** Copyright 2005, Gamma Remote Sensing"
  },
  {
    "path": "tests/test_data/cropA/headers/cropA_20180106_VV_8rlks_eqa_dem.par",
    "chars": 873,
    "preview": "Gamma DIFF&GEO DEM/MAP parameter file\ntitle: dem\nDEM_projection:     EQA\ndata_format:        REAL*4\nDEM_hgt_offset:     "
  },
  {
    "path": "tests/test_data/cropA/headers/r20180106_VV_8rlks_mli.par",
    "chars": 3614,
    "preview": "Gamma Interferometric SAR Processor (ISP) - Image Parameter File\n\ntitle:     s1a-iw1-slc-vv-20180106t004006-20180106t004"
  },
  {
    "path": "tests/test_data/cropA/headers/r20180106_VV_slc.par",
    "chars": 3617,
    "preview": "Gamma Interferometric SAR Processor (ISP) - Image Parameter File\n\ntitle:     s1a-iw1-slc-vv-20180106t004006-20180106t004"
  },
  {
    "path": "tests/test_data/cropA/headers/r20180130_VV_8rlks_mli.par",
    "chars": 3614,
    "preview": "Gamma Interferometric SAR Processor (ISP) - Image Parameter File\n\ntitle:     s1a-iw1-slc-vv-20180130t004005-20180130t004"
  },
  {
    "path": "tests/test_data/cropA/headers/r20180130_VV_slc.par",
    "chars": 3617,
    "preview": "Gamma Interferometric SAR Processor (ISP) - Image Parameter File\n\ntitle:     s1a-iw1-slc-vv-20180130t004005-20180130t004"
  },
  {
    "path": "tests/test_data/cropA/headers/r20180307_VV_8rlks_mli.par",
    "chars": 3614,
    "preview": "Gamma Interferometric SAR Processor (ISP) - Image Parameter File\n\ntitle:     s1a-iw1-slc-vv-20180307t004004-20180307t004"
  },
  {
    "path": "tests/test_data/cropA/headers/r20180307_VV_slc.par",
    "chars": 3617,
    "preview": "Gamma Interferometric SAR Processor (ISP) - Image Parameter File\n\ntitle:     s1a-iw1-slc-vv-20180307t004004-20180307t004"
  },
  {
    "path": "tests/test_data/cropA/headers/r20180319_VV_8rlks_mli.par",
    "chars": 3614,
    "preview": "Gamma Interferometric SAR Processor (ISP) - Image Parameter File\n\ntitle:     s1a-iw1-slc-vv-20180319t004005-20180319t004"
  },
  {
    "path": "tests/test_data/cropA/headers/r20180319_VV_slc.par",
    "chars": 3617,
    "preview": "Gamma Interferometric SAR Processor (ISP) - Image Parameter File\n\ntitle:     s1a-iw1-slc-vv-20180319t004005-20180319t004"
  },
  {
    "path": "tests/test_data/cropA/headers/r20180331_VV_8rlks_mli.par",
    "chars": 3614,
    "preview": "Gamma Interferometric SAR Processor (ISP) - Image Parameter File\n\ntitle:     s1a-iw1-slc-vv-20180331t004005-20180331t004"
  },
  {
    "path": "tests/test_data/cropA/headers/r20180331_VV_slc.par",
    "chars": 3617,
    "preview": "Gamma Interferometric SAR Processor (ISP) - Image Parameter File\n\ntitle:     s1a-iw1-slc-vv-20180331t004005-20180331t004"
  },
  {
    "path": "tests/test_data/cropA/headers/r20180412_VV_8rlks_mli.par",
    "chars": 3614,
    "preview": "Gamma Interferometric SAR Processor (ISP) - Image Parameter File\n\ntitle:     s1a-iw1-slc-vv-20180412t004005-20180412t004"
  },
  {
    "path": "tests/test_data/cropA/headers/r20180412_VV_slc.par",
    "chars": 3617,
    "preview": "Gamma Interferometric SAR Processor (ISP) - Image Parameter File\n\ntitle:     s1a-iw1-slc-vv-20180412t004005-20180412t004"
  },
  {
    "path": "tests/test_data/cropA/headers/r20180506_VV_8rlks_mli.par",
    "chars": 3614,
    "preview": "Gamma Interferometric SAR Processor (ISP) - Image Parameter File\n\ntitle:     s1a-iw1-slc-vv-20180506t004006-20180506t004"
  }
]

// ... and 656 more files (download for full content)

About this extraction

This page contains the full source code of the GeoscienceAustralia/PyRate GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 856 files (5.7 MB), approximately 1.5M tokens, and a symbol index with 1108 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!