Ejemplo n.º 1
0
def _maxvar_vcm_calc(ifg_paths, params, preread_ifgs):
    """
    MPI wrapper for maxvar and vcmt computation
    """
    log.info('Calculating maxvar and vcm')
    process_indices = mpiops.array_split(range(len(ifg_paths)))

    def _get_r_dist(ifg_path):
        """
        Get RDIst class object
        """
        ifg = Ifg(ifg_path)
        ifg.open()
        r_dist = vcm_module.RDist(ifg)()
        ifg.close()
        return r_dist

    r_dist = mpiops.run_once(_get_r_dist, ifg_paths[0])
    prcs_ifgs = mpiops.array_split(ifg_paths)
    process_maxvar = []
    for n, i in enumerate(prcs_ifgs):
        log.info('Calculating maxvar for {} of process ifgs {} of '
                 'total {}'.format(n + 1, len(prcs_ifgs), len(ifg_paths)))
        process_maxvar.append(
            vcm_module.cvd(i,
                           params,
                           r_dist,
                           calc_alpha=True,
                           write_vals=True,
                           save_acg=True)[0])
    if mpiops.rank == MASTER_PROCESS:
        maxvar = np.empty(len(ifg_paths), dtype=np.float64)
        maxvar[process_indices] = process_maxvar
        for i in range(1, mpiops.size):  # pragma: no cover
            rank_indices = mpiops.array_split(range(len(ifg_paths)), i)
            this_process_ref_phs = np.empty(len(rank_indices),
                                            dtype=np.float64)
            mpiops.comm.Recv(this_process_ref_phs, source=i, tag=i)
            maxvar[rank_indices] = this_process_ref_phs
    else:  # pragma: no cover
        maxvar = np.empty(len(ifg_paths), dtype=np.float64)
        mpiops.comm.Send(np.array(process_maxvar, dtype=np.float64),
                         dest=MASTER_PROCESS,
                         tag=mpiops.rank)

    maxvar = mpiops.comm.bcast(maxvar, root=0)
    vcmt = mpiops.run_once(vcm_module.get_vcmt, preread_ifgs, maxvar)
    return maxvar, vcmt
Ejemplo n.º 2
0
def _orb_fit_calc(ifg_paths, params, preread_ifgs=None):
    """
    MPI wrapper for orbital fit correction
    """
    log.info('Calculating orbfit correction')

    if not params[cf.ORBITAL_FIT]:
        log.info('Orbital correction not required')
        return

    if preread_ifgs:  # don't check except for mpi tests
        # perform some general error/sanity checks
        log.info('Checking Orbital error correction status')
        if mpiops.run_once(shared.check_correction_status, preread_ifgs,
                           ifc.PYRATE_ORBITAL_ERROR):
            log.info('Finished Orbital error correction')
            return  # return if True condition returned

    if params[cf.ORBITAL_FIT_METHOD] == 1:
        prcs_ifgs = mpiops.array_split(ifg_paths)
        orbital.remove_orbital_error(prcs_ifgs, params, preread_ifgs)
    else:
        # Here we do all the multilooking in one process, but in memory
        # can use multiple processes if we write data to disc during
        # remove_orbital_error step
        # A performance comparison should be made for saving multilooked
        # files on disc vs in memory single process multilooking
        if mpiops.rank == MASTER_PROCESS:
            orbital.remove_orbital_error(ifg_paths, params, preread_ifgs)
    mpiops.comm.barrier()
    log.info('Finished Orbital error correction')
Ejemplo n.º 3
0
def _calc_svd_time_series(ifg_paths, params, preread_ifgs, tiles):
    """
    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 time series via SVD method for '
             'spatio-temporal filter')
    # copy params temporarily
    new_params = deepcopy(params)
    new_params[cf.TIME_SERIES_METHOD] = 2  # use SVD method

    process_tiles = mpiops.array_split(tiles)
    output_dir = params[cf.TMPDIR]

    nvels = None
    for t in process_tiles:
        log.info('Calculating time series for tile {} during aps '
                 'correction'.format(t.index))
        ifg_parts = [shared.IfgPart(p, t, preread_ifgs) for p in ifg_paths]
        mst_tile = np.load(
            os.path.join(output_dir, 'mst_mat_{}.npy'.format(t.index)))
        tsincr = time_series(ifg_parts, new_params, vcmt=None, mst=mst_tile)[0]
        np.save(file=os.path.join(output_dir,
                                  'tsincr_aps_{}.npy'.format(t.index)),
                arr=tsincr)
        nvels = tsincr.shape[2]

    nvels = mpiops.comm.bcast(nvels, root=0)
    # need to assemble tsincr from all processes
    tsincr_g = mpiops.run_once(_assemble_tsincr, ifg_paths, params,
                               preread_ifgs, tiles, nvels)
    log.info('Finished calculating time series for spatio-temporal filter')
    return tsincr_g
Ejemplo n.º 4
0
def process_ifgs(ifg_paths, params, rows, cols):
    """
    Top level function to perform PyRate workflow on given interferograms

    :param list ifg_paths: List of interferogram paths
    :param dict params: Dictionary of configuration parameters
    :param int rows: Number of sub-tiles in y direction
    :param int cols: Number of sub-tiles in x direction
    
    :return: refpt: tuple of reference pixel x and y position
    :rtype: tuple
    :return: maxvar: array of maximum variance values of interferograms
    :rtype: ndarray
    :return: vcmt: Variance-covariance matrix array
    :rtype: ndarray
    """
    if mpiops.size > 1:  # turn of multiprocessing during mpi jobs
        params[cf.PARALLEL] = False

    tiles = mpiops.run_once(get_tiles, ifg_paths[0], rows, cols)

    preread_ifgs = _create_ifg_dict(ifg_paths, params=params, tiles=tiles)

#    _mst_calc(ifg_paths, params, tiles, preread_ifgs)

    refpx, refpy = _ref_pixel_calc(ifg_paths, params)

    # TODO: remove weather model derived APS delay here (pyaps.py)

    # remove non ifg keys
    _ = [preread_ifgs.pop(k) for k in ['gt', 'epochlist', 'md', 'wkt']]

    _orb_fit_calc(ifg_paths, params, preread_ifgs)

    _ref_phase_estimation(ifg_paths, params, refpx, refpy, preread_ifgs)

    _mst_calc(ifg_paths, params, tiles, preread_ifgs)

    # spatio-temporal aps filter
    _wrap_spatio_temporal_filter(ifg_paths, params, tiles, preread_ifgs)

    maxvar, vcmt = _maxvar_vcm_calc(ifg_paths, params, preread_ifgs)

    # save phase data tiles as numpy array for timeseries and linrate calc
    shared.save_numpy_phase(ifg_paths, tiles, params)

    _timeseries_calc(ifg_paths, params, vcmt, tiles, preread_ifgs)

    _linrate_calc(ifg_paths, params, vcmt, tiles, preread_ifgs)

    log.info('PyRate workflow completed')
    return (refpx, refpy), maxvar, vcmt
Ejemplo n.º 5
0
def process_ifgs(ifg_paths, params, rows, cols):
    """
    Top level function to perform PyRate correction steps on given interferograms.

    :param ifg_paths: List of interferogram paths
    :param params: Parameters dictionary corresponding to config file
    :param rows: Number of rows to break each interferogram into
    :param cols: Number of columns to break each interferogram into
    
    :return xxxx
    """
    if mpiops.size > 1:
        params[cf.PARALLEL] = False

    tiles = mpiops.run_once(get_tiles, ifg_paths[0], rows, cols)
    preread_ifgs = create_ifg_dict(ifg_paths, params=params, tiles=tiles)

    mst_calc(ifg_paths, params, tiles, preread_ifgs)

    # Estimate reference pixel location
    refpx, refpy = ref_pixel_calc(ifg_paths, params)

    # remove APS delay here, and write aps delay removed ifgs to disc
    # TODO: fix PyAPS integration
    if PyAPS_INSTALLED and \
            aps_delay_required(ifg_paths, params):  # pragma: no cover
        # ifgs = aps.remove_aps_delay(ifg_paths, params)
        log.info('Finished APS delay correction')
        # make sure aps correction flags are consistent
        if params[cf.APS_CORRECTION]:
            check_aps_ifgs(ifg_paths)

    # Estimate and remove orbit errors
    orb_fit_calc(ifg_paths, params, preread_ifgs)

    # calc and remove reference phase
    ref_phase_estimation(ifg_paths, params, refpx, refpy)

    maxvar, vcmt = maxvar_vcm_calc(ifg_paths, params, preread_ifgs)
    save_numpy_phase(ifg_paths, tiles, params)

    if params[cf.TIME_SERIES_CAL]:
        timeseries_calc(ifg_paths, params, vcmt, tiles, preread_ifgs)

    # Calculate linear rate map
    linrate_calc(ifg_paths, params, vcmt, tiles, preread_ifgs)

    log.info('PyRate workflow completed')
    return (refpx, refpy), maxvar, vcmt
Ejemplo n.º 6
0
def spatio_temporal_filter(tsincr, ifg, params, preread_ifgs):
    """
    Applies a spatio-temporal filter to remove the atmospheric phase screen
    (APS) and saves the corrected interferograms. Before performing this step,
    the time series must be computed using the SVD method. This function then
    performs temporal and spatial filtering.

    :param ndarray tsincr: incremental time series array of size
                (ifg.shape, nepochs-1)
    :param list ifg: List of pyrate.shared.Ifg class objects.
    :param dict params: Dictionary of configuration parameter
    :param list tiles: List of pyrate.shared.Tile class objects
    :param dict preread_ifgs: Dictionary of shared.PrereadIfg class instances

    :return: None, corrected interferograms are saved to disk
    """
    epochlist = mpiops.run_once(get_epochs, preread_ifgs)[0]
    ts_lp = mpiops.run_once(temporal_low_pass_filter, tsincr, epochlist,
                            params)
    ts_hp = tsincr - ts_lp
    ts_aps = mpiops.run_once(spatial_low_pass_filter, ts_hp, ifg, params)
    tsincr -= ts_aps

    mpiops.run_once(_ts_to_ifgs, tsincr, preread_ifgs)
Ejemplo n.º 7
0
def test_prepifg_mpi(mpisync, get_config, tempdir, roipac_or_gamma, get_lks,
                     get_crop):
    from tests.common import TEST_CONF_ROIPAC, TEST_CONF_GAMMA
    from os.path import join, basename
    if roipac_or_gamma == 1:
        params = get_config(TEST_CONF_GAMMA)
    else:
        params = get_config(TEST_CONF_ROIPAC)
    outdir = mpiops.run_once(tempdir)
    params[cf.OUT_DIR] = outdir
    params[cf.PARALLEL] = False
    params[cf.IFG_LKSX], params[cf.IFG_LKSY] = get_lks, get_lks
    params[cf.IFG_CROP_OPT] = get_crop
    if roipac_or_gamma == 1:
        params[cf.IFG_FILE_LIST] = join(common.SML_TEST_GAMMA, 'ifms_17')
        params[cf.OBS_DIR] = common.SML_TEST_GAMMA
        params[cf.DEM_FILE] = common.SML_TEST_DEM_GAMMA
        params[cf.DEM_HEADER_FILE] = common.SML_TEST_DEM_HDR_GAMMA
    run_prepifg.main(params)

    if mpiops.rank == 0:
        if roipac_or_gamma == 1:
            params_s = get_config(TEST_CONF_GAMMA)
        else:
            params_s = get_config(TEST_CONF_ROIPAC)
        params_s[cf.OUT_DIR] = tempdir()
        params_s[cf.PARALLEL] = True
        params_s[cf.IFG_LKSX], params_s[cf.IFG_LKSY] = get_lks, get_lks
        params_s[cf.IFG_CROP_OPT] = get_crop
        if roipac_or_gamma == 1:
            base_unw_paths = glob.glob(join(common.SML_TEST_GAMMA,
                                            "*_utm.unw"))
            run_prepifg.gamma_prepifg(base_unw_paths, params_s)
        else:
            base_unw_paths = glob.glob(join(common.SML_TEST_OBS, "*.unw"))
            run_prepifg.roipac_prepifg(base_unw_paths, params_s)

        mpi_tifs = glob.glob(join(outdir, "*.tif"))
        serial_tifs = glob.glob(join(params[cf.OUT_DIR], "*.tif"))
        mpi_tifs.sort()
        serial_tifs.sort()
        # 17 geotifs, and 17 mlooked tifs
        assert len(mpi_tifs) == len(serial_tifs)
        for m_f, s_f in zip(mpi_tifs, serial_tifs):
            assert basename(m_f) == basename(s_f)

        shutil.rmtree(outdir)
        shutil.rmtree(params_s[cf.OUT_DIR])
Ejemplo n.º 8
0
def find_ref_pixel(ifg_paths, params):
    """
    Find reference pixel using MPI Parameters.

    :param ifg_paths: List of interferogram paths
    :param params: Parameters dictionary corresponding to config file

    :return Tuple of (refy, refx).
    """
    half_patch_size, thresh, grid = refpixel.ref_pixel_setup(ifg_paths, params)
    process_grid = mpiops.array_split(grid)
    save_ref_pixel_blocks(process_grid, half_patch_size, ifg_paths, params)
    mean_sds = refpixel.ref_pixel_mpi(process_grid, half_patch_size, ifg_paths,
                                      thresh, params)
    mean_sds = mpiops.comm.gather(mean_sds, root=0)
    if mpiops.rank == MASTER_PROCESS:
        mean_sds = np.hstack(mean_sds)
    return mpiops.run_once(refpixel.filter_means, mean_sds, grid)
Ejemplo n.º 9
0
def _ref_phase_estimation(ifg_paths, params, refpx, refpy, preread_ifgs=None):
    """
    Wrapper function for MPI-enabled reference phase estimation.
    Refer to documentation for ref_est_phs.estimate_ref_phase.
    """
    # perform some checks on existing ifgs
    #if preread_ifgs and mpiops.rank == MASTER_PROCESS:
    #TODO: implement MPI capability into ref_phs_est module and remove here
    if preread_ifgs:
        log.info('Checking reference phase estimation status')
        if mpiops.run_once(shared.check_correction_status, preread_ifgs,
                           ifc.PYRATE_REF_PHASE):
            log.info('Finished reference phase estimation')
            return  # return if True condition returned

    if params[cf.REF_EST_METHOD] == 1:
        # calculate phase sum for later use in ref phase method 1
        comp = _phase_sum(ifg_paths, params)
        log.info('Computing reference phase via method 1')
        process_ref_phs = _ref_phs_method1(ifg_paths, comp)
    elif params[cf.REF_EST_METHOD] == 2:
        log.info('Computing reference phase via method 2')
        process_ref_phs = _ref_phs_method2(ifg_paths, params, refpx, refpy)
    else:
        raise ConfigException('Ref phase estimation method must be 1 or 2')

    # Save reference phase numpy arrays to disk
    ref_phs_file = join(params[cf.TMPDIR], 'ref_phs.npy')
    if mpiops.rank == MASTER_PROCESS:
        ref_phs = np.zeros(len(ifg_paths), dtype=np.float64)
        process_indices = mpiops.array_split(range(len(ifg_paths)))
        ref_phs[process_indices] = process_ref_phs
        for r in range(1, mpiops.size):  # pragma: no cover
            process_indices = mpiops.array_split(range(len(ifg_paths)), r)
            this_process_ref_phs = np.zeros(shape=len(process_indices),
                                            dtype=np.float64)
            mpiops.comm.Recv(this_process_ref_phs, source=r, tag=r)
            ref_phs[process_indices] = this_process_ref_phs
        np.save(file=ref_phs_file, arr=ref_phs)
    else:  # pragma: no cover
        # send reference phase data to master process
        mpiops.comm.Send(process_ref_phs, dest=MASTER_PROCESS,
                         tag=mpiops.rank)
    log.info('Finished reference phase estimation')
Ejemplo n.º 10
0
def _ref_pixel_calc(ifg_paths, params):
    """
    Wrapper for reference pixel calculation
    """
    # unlikely, but possible the refpixel can be (0,0)
    # check if there is a pre-specified reference pixel coord
    refx = params[cf.REFX]
    ifg = Ifg(ifg_paths[0])
    ifg.open(readonly=True)
    if refx > ifg.ncols - 1:
        msg = ('Supplied reference pixel X coordinate is greater than '
               'the number of ifg columns: {}').format(refx)
        raise ValueError(msg)

    refy = params[cf.REFY]
    if refy > ifg.nrows - 1:
        msg = ('Supplied reference pixel Y coordinate is greater than '
               'the number of ifg rows: {}').format(refy)
        raise ValueError(msg)

    if refx <= 0 or refy <= 0:  # if either zero or negative
        log.info('Searching for best reference pixel location')

        half_patch_size, thresh, grid = refpixel.ref_pixel_setup(ifg_paths, 
                                                                 params)
        process_grid = mpiops.array_split(grid)
        refpixel.save_ref_pixel_blocks(process_grid, half_patch_size,
                                       ifg_paths, params)
        mean_sds = refpixel._ref_pixel_mpi(process_grid, half_patch_size,
                                           ifg_paths, thresh, params)
        mean_sds = mpiops.comm.gather(mean_sds, root=0)
        if mpiops.rank == MASTER_PROCESS:
            mean_sds = np.hstack(mean_sds)

        refy, refx = mpiops.run_once(refpixel.find_min_mean, mean_sds, grid)
        log.info('Selected reference pixel coordinate: '
                 '({}, {})'.format(refx, refy))
    else:  # pragma: no cover
        log.info('Reusing reference pixel from config file: '
                 '({}, {})'.format(refx, refy))
    ifg.close()
    return refx, refy
Ejemplo n.º 11
0
def maxvar_vcm_calc(ifg_paths, params, preread_ifgs):
    """
    MPI capable maxvar and vcmt computation.

    :param ifg_paths: List of interferogram paths
    :param params: Parameters dictionary corresponding to config file
    :param preread_ifgs: Dictionary containing interferogram characteristics for efficient computing

    :return maxvar: Array of shape (nifgs, 1)
    :return vcmt: Array of shape (nifgs, nifgs)
    """
    log.info('Calculating maxvar and vcm')
    process_indices = mpiops.array_split(range(len(ifg_paths)))
    prcs_ifgs = mpiops.array_split(ifg_paths)
    process_maxvar = []
    for n, i in enumerate(prcs_ifgs):
        log.info('Calculating maxvar for {} of process ifgs {} of '
                 'total {}'.format(n + 1, len(prcs_ifgs), len(ifg_paths)))
        # TODO: cvd calculation is still pretty slow - revisit
        process_maxvar.append(vcm_module.cvd(i, params)[0])
    if mpiops.rank == MASTER_PROCESS:
        maxvar = np.empty(len(ifg_paths), dtype=np.float64)
        maxvar[process_indices] = process_maxvar
        for i in range(1, mpiops.size):  # pragma: no cover
            rank_indices = mpiops.array_split(range(len(ifg_paths)), i)
            this_process_ref_phs = np.empty(len(rank_indices),
                                            dtype=np.float64)
            mpiops.comm.Recv(this_process_ref_phs, source=i, tag=i)
            maxvar[rank_indices] = this_process_ref_phs
    else:  # pragma: no cover
        maxvar = np.empty(len(ifg_paths), dtype=np.float64)
        mpiops.comm.Send(np.array(process_maxvar, dtype=np.float64),
                         dest=MASTER_PROCESS,
                         tag=mpiops.rank)

    maxvar = mpiops.comm.bcast(maxvar, root=0)
    vcmt = mpiops.run_once(vcm_module.get_vcmt, preread_ifgs, maxvar)
    return maxvar, vcmt
Ejemplo n.º 12
0
def _wrap_spatio_temporal_filter(ifg_paths, params, tiles, preread_ifgs):
    """
    A wrapper for the spatio-temporal filter so it can be tested.
    See docstring for spatio_temporal_filter.
    Required due to differences between Matlab and Python MST
    implementations.
    """
    if not params[cf.APSEST]:
        log.info('APS correction not required.')
        return

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

    tsincr = _calc_svd_time_series(ifg_paths, params, preread_ifgs, tiles)

    ifg = Ifg(ifg_paths[0])  # just grab any for parameters in slpfilter
    ifg.open()
    spatio_temporal_filter(tsincr, ifg, params, preread_ifgs)
    ifg.close()
Ejemplo n.º 13
0
def test_timeseries_linrate_mpi(mpisync, tempdir, modify_config,
                                ref_est_method, row_splits, col_splits,
                                get_crop, orbfit_lks, orbfit_method,
                                orbfit_degrees):
    params = modify_config
    outdir = mpiops.run_once(tempdir)
    params[cf.OUT_DIR] = outdir
    params[cf.TMPDIR] = os.path.join(params[cf.OUT_DIR], cf.TMPDIR)
    params[cf.DEM_HEADER_FILE] = SML_TEST_DEM_HDR_GAMMA
    params[cf.REF_EST_METHOD] = ref_est_method
    params[cf.IFG_CROP_OPT] = get_crop
    params[cf.ORBITAL_FIT_LOOKS_Y] = orbfit_lks
    params[cf.ORBITAL_FIT_LOOKS_X] = orbfit_lks
    params[cf.ORBITAL_FIT_METHOD] = orbfit_method
    params[cf.ORBITAL_FIT_DEGREE] = orbfit_degrees
    xlks, ylks, crop = cf.transform_params(params)
    if xlks * col_splits > 45 or ylks * row_splits > 70:
        print('skipping test because lks and col_splits are not compatible')
        return

    # skip some tests in travis to run CI faster
    if TRAVIS and (xlks % 2 or row_splits % 2 or col_splits % 2
                   or orbfit_lks % 2):
        print('Skipping in travis env for faster CI run')
        return
    print("xlks={}, ref_est_method={}, row_splits={}, col_splits={}, "
          "get_crop={}, orbfit_lks={}, orbfit_method={}, "
          "rank={}".format(xlks, ref_est_method, row_splits, col_splits,
                           get_crop, orbfit_lks, orbfit_method, orbfit_degrees,
                           mpiops.rank))

    base_unw_paths = cf.original_ifg_paths(params[cf.IFG_FILE_LIST])
    # dest_paths are tifs that have been geotif converted and multilooked
    dest_paths = cf.get_dest_paths(base_unw_paths, crop, params, xlks)

    # run prepifg, create the dest_paths files
    if mpiops.rank == 0:
        run_prepifg.gamma_prepifg(base_unw_paths, params)

    mpiops.comm.barrier()

    (refpx,
     refpy), maxvar, vcmt = run_pyrate.process_ifgs(ifg_paths=dest_paths,
                                                    params=params,
                                                    rows=row_splits,
                                                    cols=col_splits)

    tiles = mpiops.run_once(run_pyrate.get_tiles,
                            dest_paths[0],
                            rows=row_splits,
                            cols=col_splits)
    postprocessing.postprocess_linrate(row_splits, col_splits, params)
    postprocessing.postprocess_timeseries(row_splits, col_splits, params)
    ifgs_mpi_out_dir = params[cf.OUT_DIR]
    ifgs_mpi = small_data_setup(datafiles=dest_paths)

    # single process timeseries/linrate calculation
    if mpiops.rank == 0:
        params_old = modify_config
        params_old[cf.OUT_DIR] = tempdir()
        params_old[cf.REF_EST_METHOD] = ref_est_method
        params_old[cf.IFG_CROP_OPT] = get_crop
        params_old[cf.ORBITAL_FIT_LOOKS_Y] = orbfit_lks
        params_old[cf.ORBITAL_FIT_LOOKS_X] = orbfit_lks
        params_old[cf.ORBITAL_FIT_METHOD] = orbfit_method
        params_old[cf.ORBITAL_FIT_DEGREE] = orbfit_degrees
        xlks, ylks, crop = cf.transform_params(params_old)
        base_unw_paths = cf.original_ifg_paths(params_old[cf.IFG_FILE_LIST])
        dest_paths = cf.get_dest_paths(base_unw_paths, crop, params_old, xlks)
        run_prepifg.gamma_prepifg(base_unw_paths, params_old)

        ifgs = shared.pre_prepare_ifgs(dest_paths, params_old)
        mst_grid = tests.common.mst_calculation(dest_paths, params_old)
        refy, refx = refpixel.ref_pixel(ifgs, params_old)
        assert (refx == refpx) and (refy == refpy)  # both must match
        pyrate.orbital.remove_orbital_error(ifgs, params_old)
        ifgs = common.prepare_ifgs_without_phase(dest_paths, params_old)
        rpe.estimate_ref_phase(ifgs, params_old, refx, refy)
        ifgs = shared.pre_prepare_ifgs(dest_paths, params_old)
        maxvar_s = [vcm.cvd(i, params_old)[0] for i in ifgs]
        vcmt_s = vcm.get_vcmt(ifgs, maxvar)
        tsincr, tscum, _ = tests.common.compute_time_series(
            ifgs, mst_grid, params, vcmt)
        rate, error, samples = tests.common.calculate_linear_rate(
            ifgs, params_old, vcmt, mst_grid)
        mst_mpi = reconstruct_mst(ifgs[0].shape, tiles, params[cf.TMPDIR])
        np.testing.assert_array_almost_equal(mst_grid, mst_mpi)
        tsincr_mpi, tscum_mpi = reconstruct_times_series(
            ifgs[0].shape, tiles, params[cf.TMPDIR])

        rate_mpi, error_mpi, samples_mpi = \
            [reconstruct_linrate(ifgs[0].shape, tiles, params[cf.TMPDIR], t)
             for t in ['linrate', 'linerror', 'linsamples']]
        np.testing.assert_array_almost_equal(maxvar, maxvar_s)
        np.testing.assert_array_almost_equal(vcmt, vcmt_s)
        for i, j in zip(ifgs, ifgs_mpi):
            np.testing.assert_array_almost_equal(i.phase_data, j.phase_data)
        np.testing.assert_array_almost_equal(tsincr, tsincr_mpi, decimal=4)
        np.testing.assert_array_almost_equal(tscum, tscum_mpi, decimal=4)
        np.testing.assert_array_almost_equal(rate, rate_mpi, decimal=4)
        np.testing.assert_array_almost_equal(error, error_mpi, decimal=4)
        np.testing.assert_array_almost_equal(samples, samples_mpi, decimal=4)

        # assert linear rate output tifs are same
        _tifs_same(ifgs_mpi_out_dir, params_old[cf.OUT_DIR], 'linrate.tif')
        _tifs_same(ifgs_mpi_out_dir, params_old[cf.OUT_DIR], 'linerror.tif')
        _tifs_same(ifgs_mpi_out_dir, params_old[cf.OUT_DIR], 'linsamples.tif')

        # assert time series output tifs are same
        epochlist = algorithm.get_epochs(ifgs)[0]

        for i in range(tsincr.shape[2]):
            _tifs_same(ifgs_mpi_out_dir, params_old[cf.OUT_DIR],
                       'tsincr' + '_' + str(epochlist.dates[i + 1]) + ".tif")

        # 12 timeseries outputs
        assert i + 1 == tsincr.shape[2]
        shutil.rmtree(ifgs_mpi_out_dir)  # remove mpi out dir
        shutil.rmtree(params_old[cf.OUT_DIR])  # remove serial out dir