def test_get_all_epochs(self): # test function to extract all dates from sequence of ifgs ifgs = small5_mock_ifgs() for i in ifgs: i.nodata_value = 0 dates = [date(2006, 8, 28), date(2006, 11, 6), date(2006, 12, 11), date(2007, 1, 15), date(2007, 3, 26), date(2007, 9, 17)] self.assertEqual(dates, sorted(set(get_all_epochs(ifgs))))
def get_network_design_matrix(ifgs, degree, offset): # pylint: disable=too-many-locals """ Returns larger-format design matrix for network error correction. The network design matrix includes rows which relate to those of NaN cells. :param list ifgs: List of Ifg class objects :param str degree: model to fit (PLANAR / QUADRATIC / PART_CUBIC) :param bool offset: True to include offset cols, otherwise False. :return: netdm: network design matrix :rtype: ndarray """ if degree not in [PLANAR, QUADRATIC, PART_CUBIC]: raise OrbitalError("Invalid degree argument") nifgs = len(ifgs) if nifgs < 1: # can feasibly do correction on a single Ifg/2 epochs raise OrbitalError("Invalid number of Ifgs: %s" % nifgs) # init sparse network design matrix nepochs = len(set(get_all_epochs(ifgs))) # no offsets: they are made separately below ncoef = _get_num_params(degree) shape = [ifgs[0].num_cells * nifgs, ncoef * nepochs] if offset: shape[1] += nifgs # add extra block for offset cols netdm = zeros(shape, dtype=float32) # calc location for individual design matrices dates = [ifg.master for ifg in ifgs] + [ifg.slave for ifg in ifgs] ids = master_slave_ids(dates) offset_col = nepochs * ncoef # base offset for the offset cols tmpdm = get_design_matrix(ifgs[0], degree, offset=False) # iteratively build up sparse matrix for i, ifg in enumerate(ifgs): rs = i * ifg.num_cells # starting row m = ids[ifg.master] * ncoef # start col for master s = ids[ifg.slave] * ncoef # start col for slave netdm[rs:rs + ifg.num_cells, m:m + ncoef] = -tmpdm netdm[rs:rs + ifg.num_cells, s:s + ncoef] = tmpdm # offsets are diagonal cols across the extra array block created above if offset: netdm[rs:rs + ifg.num_cells, offset_col + i] = 1 # init offset cols return netdm
def network_orbital_correction(ifgs, degree, offset, params, m_ifgs=None, preread_ifgs=None): """ This algorithm implements a network inversion to determine orbital corrections for a set of interferograms forming a connected network. Warning: This will write orbital error corrected phase_data to the ifgs. :param list ifgs: List of Ifg class objects reduced to a minimum spanning tree network :param str degree: model to fit (PLANAR / QUADRATIC / PART_CUBIC) :param bool offset: True to calculate the model using offsets :param dict params: dictionary of configuration parameters :param list m_ifgs: list of multilooked Ifg class objects (sequence must be multilooked versions of 'ifgs' arg) :param dict preread_ifgs: Dictionary containing information specifically for MPI jobs (optional) :return: None - interferogram phase data is updated and saved to disk """ # pylint: disable=too-many-locals, too-many-arguments src_ifgs = ifgs if m_ifgs is None else m_ifgs src_ifgs = mst.mst_from_ifgs(src_ifgs)[3] # use networkx mst vphase = vstack([i.phase_data.reshape((i.num_cells, 1)) for i in src_ifgs]) vphase = squeeze(vphase) B = get_network_design_matrix(src_ifgs, degree, offset) # filter NaNs out before getting model B = B[~isnan(vphase)] orbparams = dot(pinv(B, 1e-6), vphase[~isnan(vphase)]) ncoef = _get_num_params(degree) if preread_ifgs: temp_ifgs = OrderedDict(sorted(preread_ifgs.items())).values() ids = master_slave_ids(get_all_epochs(temp_ifgs)) else: ids = master_slave_ids(get_all_epochs(ifgs)) coefs = [ orbparams[i:i + ncoef] for i in range(0, len(set(ids)) * ncoef, ncoef) ] # create full res DM to expand determined coefficients into full res # orbital correction (eg. expand coarser model to full size) if preread_ifgs: temp_ifg = Ifg(ifgs[0]) # ifgs here are paths temp_ifg.open() dm = get_design_matrix(temp_ifg, degree, offset=False) temp_ifg.close() else: dm = get_design_matrix(ifgs[0], degree, offset=False) for i in ifgs: # open if not Ifg instance if isinstance(i, str): # pragma: no cover # are paths i = Ifg(i) i.open(readonly=False) shared.nan_and_mm_convert(i, params) _remove_network_orb_error(coefs, dm, i, ids, offset)
def network_correction(ifgs, degree, offset, params, m_ifgs=None, preread_ifgs=None): """ Calculates orbital correction model, removing this from the interferograms. .. warn:: This will write orbital error corrected phase_data in the interferograms. :param ifgs: Interferograms reduced to a minimum tree from prior MST calculations :param degree: PLANAR, QUADRATIC or PART_CUBIC :param offset: True to calculate the model using offsets :param params: Parameter dictionary :param m_ifgs: Multi-looked orbfit interferograms (sequence must be mlooked versions of 'ifgs' arg) :param preread_ifgs: Parameters dict corresponding to config file :return xxxx """ # pylint: disable=too-many-locals, too-many-arguments src_ifgs = ifgs if m_ifgs is None else m_ifgs src_ifgs = mst.mst_from_ifgs(src_ifgs)[3] # use networkx mst vphase = vstack([i.phase_data.reshape((i.num_cells, 1)) for i in src_ifgs]) vphase = squeeze(vphase) B = get_network_design_matrix(src_ifgs, degree, offset) # filter NaNs out before getting model B = B[~isnan(vphase)] orbparams = dot(pinv(B, 1e-6), vphase[~isnan(vphase)]) ncoef = _get_num_params(degree) if preread_ifgs: temp_ifgs = OrderedDict(sorted(preread_ifgs.items())).values() ids = master_slave_ids(get_all_epochs(temp_ifgs)) else: ids = master_slave_ids(get_all_epochs(ifgs)) coefs = [ orbparams[i:i + ncoef] for i in range(0, len(set(ids)) * ncoef, ncoef) ] # create full res DM to expand determined coefficients into full res # orbital correction (eg. expand coarser model to full size) if preread_ifgs: temp_ifg = Ifg(ifgs[0]) # ifgs here are paths temp_ifg.open() dm = get_design_matrix(temp_ifg, degree, offset=False) temp_ifg.close() else: dm = get_design_matrix(ifgs[0], degree, offset=False) # TODO: remove this import from tests suite from tests.common import MockIfg for i in ifgs: # open if not Ifg instance if not (isinstance(i, Ifg) or isinstance(i, MockIfg)): # pragma: no cover # are paths i = Ifg(i) i.open(readonly=False) shared.nan_and_mm_convert(i, params) _remove_networkx_error(coefs, dm, i, ids, offset)
def test_get_epoch_count(self): self.assertEqual(6, len(set(get_all_epochs(small5_mock_ifgs()))))