Example #1
0
def _ts_to_ifgs(tsincr, preread_ifgs, params):
    """
    Function that converts an incremental displacement time series into
    interferometric phase observations. Used to re-construct an interferogram
    network from a time series.

    :param ndarray tsincr: incremental time series array of size
                (ifg.shape, nepochs-1)
    :param dict preread_ifgs: Dictionary of shared.PrereadIfg class instances

    :return: None, interferograms are saved to disk
    """
    log.debug('Reconstructing interferometric observations from time series')
    ifgs = list(OrderedDict(sorted(preread_ifgs.items())).values())
    _, 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)))
    num_ifgs_tuples = [(int(num), ifg) for num, ifg in num_ifgs_tuples]

    for i, ifg in num_ifgs_tuples:
        aps_correction_on_disc = MultiplePaths.aps_error_path(
            ifg.tmp_path, params)
        phase = np.sum(tsincr[:, :, index_first[i]:index_second[i]], axis=2)
        np.save(file=aps_correction_on_disc, arr=phase)
        _save_aps_corrected_phase(ifg.tmp_path, phase)
Example #2
0
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)
Example #3
0
    def test_aps_error_files_on_disc(self, slpfmethod, slpfcutoff, slpforder):
        self.params[cf.SLPF_METHOD] = slpfmethod
        self.params[cf.SLPF_CUTOFF] = slpfcutoff
        self.params[cf.SLPF_ORDER] = slpforder
        wrap_spatio_temporal_filter(self.params)

        # test_orb_errors_written
        aps_error_files = [
            MultiplePaths.aps_error_path(i, self.params)
            for i in self.ifg_paths
        ]
        assert all(p.exists() for p in aps_error_files)
        last_mod_times = [os.stat(o).st_mtime for o in aps_error_files]
        phase_prev = [i.phase_data for i in self.ifgs]

        # run aps error removal again
        wrap_spatio_temporal_filter(self.params)
        aps_error_files2 = [
            MultiplePaths.aps_error_path(i, self.params)
            for i in self.ifg_paths
        ]
        # if files are written again - times will change
        last_mod_times_2 = [os.stat(o).st_mtime for o in aps_error_files2]
        # test_aps_error_reused_if_params_unchanged
        assert all(a == b for a, b in zip(last_mod_times, last_mod_times_2))
        phase_now = [i.phase_data for i in self.ifgs]

        # run aps error correction once mroe
        wrap_spatio_temporal_filter(self.params)
        aps_error_files3 = [
            MultiplePaths.aps_error_path(i, self.params)
            for i in self.ifg_paths
        ]
        last_mod_times_3 = [os.stat(o).st_mtime for o in aps_error_files3]
        assert all(a == b for a, b in zip(last_mod_times, last_mod_times_3))
        phase_again = [i.phase_data for i in self.ifgs]
        np.testing.assert_array_equal(phase_prev, phase_now)
        np.testing.assert_array_equal(phase_prev, phase_again)
Example #4
0
def wrap_spatio_temporal_filter(params):
    """
    A wrapper for the spatio-temporal filter so it can be tested.
    See docstring for spatio_temporal_filter.
    """
    if params[cf.APSEST]:
        log.info('Doing APS spatio-temporal filtering')
    else:
        log.info('APS spatio-temporal filtering not required')
        return
    tiles = params[cf.TILES]
    preread_ifgs = params[cf.PREREAD_IFGS]
    ifg_paths = [
        ifg_path.tmp_sampled_path
        for ifg_path in params[cf.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_error_files_on_disc = [
        MultiplePaths.aps_error_path(i, params) for i in ifg_paths
    ]
    if all(a.exists() for a in aps_error_files_on_disc):
        log.warning("Reusing APS errors from previous run!!!")
        for ifg_path, a in mpiops.array_split(
                list(zip(ifg_paths, aps_error_files_on_disc))):
            phase = np.load(a)
            _save_aps_corrected_phase(ifg_path, phase)
    else:
        tsincr = _calc_svd_time_series(ifg_paths, params, preread_ifgs, tiles)
        mpiops.comm.barrier()

        spatio_temporal_filter(tsincr, ifg_paths, params, preread_ifgs)
    mpiops.comm.barrier()
    shared.save_numpy_phase(ifg_paths, params)
Example #5
0
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()