def _expand_corrections(ifgs, dm, params, ncoef, offsets): """ Convenience func returns model converted to data points. dm: design matrix (do not filter/remove nan cells) params: model parameters array from pinv() * dm ncoef: number of model coefficients (2 planar, 5 quadratic) offsets: True/False to calculate correction with offsets """ # NB: cannot work on singular ifgs due to date ID id/indexing requirement date_ids = get_date_ids(ifgs) corrections = [] for ifg in ifgs: jbm = date_ids[ifg.master] * ncoef # starting row index for master jbs = date_ids[ifg.slave] * ncoef # row start for slave par = params[jbs:jbs + ncoef] - params[jbm:jbm + ncoef] # estimate orbital correction effects # corresponds to "fullorb = B*parm + offset" in orbfwd.m cor = dm.dot(par).reshape(ifg.phase_data.shape) if offsets: off = np.ravel(ifg.phase_data - cor) # bring all ifgs to same base level cor -= nanmedian(off) corrections.append(cor) return corrections
def _est_ref_phs_method1(phase_data, comp): """ Convenience function for ref phs estimate method 1 parallelisation """ ifgv = np.ravel(phase_data, order='F') ifgv[comp == 1] = np.nan return nanmedian(ifgv)
def alt_orbital_correction(self, ifg, deg, offset): # almost an exact translation of MATLAB version data = ifg.phase_data.reshape(ifg.num_cells) dm = get_design_matrix(ifg, deg, offset)[~isnan(data)] fd = data[~isnan(data)].reshape((dm.shape[0], 1)) dmt = dm.T invNbb = inv(dmt.dot(dm)) orbparams = invNbb.dot(dmt.dot(fd)) alt_params = lstsq(dm, fd)[0] # FIXME: precision assert_array_almost_equal(orbparams, alt_params, decimal=2) dm2 = get_design_matrix(ifg, deg, offset) if offset: fullorb = np.reshape(np.dot(dm2[:, :-1], orbparams[:-1]), ifg.phase_data.shape) else: fullorb = np.reshape(np.dot(dm2, orbparams), ifg.phase_data.shape) offset_removal = nanmedian( np.reshape(ifg.phase_data - fullorb, (1, -1))) fwd_correction = fullorb - offset_removal # ifg.phase_data -= (fullorb - offset_removal) return ifg.phase_data - fwd_correction
def _remove_networkx_error(coefs, dm, ifg, ids, offset): orb = dm.dot(coefs[ids[ifg.slave]] - coefs[ids[ifg.master]]) orb = orb.reshape(ifg.shape) # offset estimation if offset: # bring all ifgs to same base level orb -= nanmedian(np.ravel(ifg.phase_data - orb)) ifg.phase_data -= orb # remove orbital error from the ifg # set orbfit tags after orbital error correction _save_orbital_error_corrected_phase(ifg)
def est_ref_phs_method1(phase_data, comp): """ Convenience function for ref phs estimate method 1 parallelisation. :param phase_data: xxxx :param comp: xxxx :return xxxx """ ifgv = np.ravel(phase_data, order='F') ifgv[comp == 1] = np.nan # reference phase ref_ph = nanmedian(ifgv) return ref_ph
def _remove_network_orb_error(coefs, dm, ifg, ids, offset): """ Convenience function to remove network orbital error from input interferograms """ orb = dm.dot(coefs[ids[ifg.slave]] - coefs[ids[ifg.master]]) orb = orb.reshape(ifg.shape) # offset estimation if offset: # bring all ifgs to same base level orb -= nanmedian(np.ravel(ifg.phase_data - orb)) # subtract orbital error from the ifg ifg.phase_data -= orb # set orbfit meta tag and save phase to file _save_orbital_error_corrected_phase(ifg)
def _est_ref_phs_method2(phase_data, half_chip_size, refpx, refpy, thresh): """ Convenience function for ref phs estimate method 2 parallelisation """ patch = phase_data[refpy - half_chip_size: refpy + half_chip_size + 1, refpx - half_chip_size: refpx + half_chip_size + 1] patch = np.reshape(patch, newshape=(-1, 1), order='F') nanfrac = np.sum(~np.isnan(patch)) if nanfrac < thresh: raise ReferencePhaseError('The data window at the reference pixel ' 'does not have enough valid observations. ' 'Actual = {}, Threshold = {}.'.format( nanfrac, thresh)) ref_ph = nanmedian(patch) return ref_ph
def est_ref_phs_method2(phase_data, half_chip_size, refpx, refpy, thresh): """ Convenience function for reference phase estimate method 2 parallelisation. :param phase_data: xxxx :param half_chip_size: xxxx :param refpx: xxxx :param refpy: xxxx :param thres: xxxx :return xxxx """ patch = phase_data[refpy - half_chip_size: refpy + half_chip_size + 1, refpx - half_chip_size: refpx + half_chip_size + 1] patch = np.reshape(patch, newshape=(-1, 1), order='F') if np.sum(~np.isnan(patch)) < thresh: raise ReferencePhaseError('The data window at the reference pixel ' 'does not have enough valid observations') ref_ph = nanmedian(patch) return ref_ph
def independent_orbital_correction(ifg, degree, offset, params): """ Calculates and removes an orbital error surface from a single independent interferogram. Warning: This will write orbital error corrected phase_data to the ifg. :param Ifg class instance ifg: the interferogram to be corrected :param str degree: model to fit (PLANAR / QUADRATIC / PART_CUBIC) :param bool offset: True to calculate the model using an offset :param dict params: dictionary of configuration parameters :return: None - interferogram phase data is updated and saved to disk """ ifg = shared.Ifg(ifg) if isinstance(ifg, str) else ifg if not ifg.is_open: ifg.open() shared.nan_and_mm_convert(ifg, params) # vectorise, keeping NODATA vphase = reshape(ifg.phase_data, ifg.num_cells) dm = get_design_matrix(ifg, degree, offset) # filter NaNs out before getting model clean_dm = dm[~isnan(vphase)] data = vphase[~isnan(vphase)] model = lstsq(clean_dm, data)[0] # first arg is the model params # calculate forward model & morph back to 2D if offset: fullorb = np.reshape(np.dot(dm[:, :-1], model[:-1]), ifg.phase_data.shape) else: fullorb = np.reshape(np.dot(dm, model), ifg.phase_data.shape) offset_removal = nanmedian(np.ravel(ifg.phase_data - fullorb)) # subtract orbital error from the ifg ifg.phase_data -= (fullorb - offset_removal) # set orbfit meta tag and save phase to file _save_orbital_error_corrected_phase(ifg) if ifg.open(): ifg.close()
def independent_correction(ifg, degree, offset, params): """ Calculates and removes orbital correction from an interferogram. .. warn:: This will write orbital error corrected phase_data in the interferograms. :param ifg: The interferogram to remove remove the orbital error from :param degree: PLANAR, QUADRATIC or PART_CUBIC :param offset: Boolean :param params: Parameter dictionary :return xxxx """ ifg = shared.Ifg(ifg) if isinstance(ifg, str) else ifg if not ifg.is_open: ifg.open() shared.nan_and_mm_convert(ifg, params) # vectorise, keeping NODATA vphase = reshape(ifg.phase_data, ifg.num_cells) dm = get_design_matrix(ifg, degree, offset) # filter NaNs out before getting model clean_dm = dm[~isnan(vphase)] data = vphase[~isnan(vphase)] model = lstsq(clean_dm, data)[0] # first arg is the model params # calculate forward model & morph back to 2D if offset: fullorb = np.reshape(np.dot(dm[:, :-1], model[:-1]), ifg.phase_data.shape) else: fullorb = np.reshape(np.dot(dm, model), ifg.phase_data.shape) offset_removal = nanmedian(np.ravel(ifg.phase_data - fullorb)) ifg.phase_data -= (fullorb - offset_removal) # set orbfit tags after orbital error correction _save_orbital_error_corrected_phase(ifg) if ifg.open(): ifg.close()