Exemple #1
0
    def __init_neighbours(self, ij_shift: np.ndarray,
                          coh_ps_len: int) -> np.ndarray:
        """In StaMPS the init value is zero, I use -1 (DEF_NEIGHBOUR_VAL). Because 0 is correct
        index value in Python, but not in Matlab. -1 is not index in Python"""
        def arange_neighbours_select_arr(i, ind):
            return ArrayUtils.arange_include_last(ij_shift[i, ind] - 2,
                                                  ij_shift[i, ind])

        def make_miss_middle_mask():
            miss_middle = np.ones((3, 3), dtype=bool)
            miss_middle[1, 1] = False

            return miss_middle

        neighbour_ind = np.ones(
            (MatlabUtils.max(ij_shift[:, 0]) + 1,
             MatlabUtils.max(ij_shift[:, 1]) + 1),
            self.__IND_ARRAY_TYPE) * self.__DEF_NEIGHBOUR_VAL
        miss_middle = make_miss_middle_mask()

        for i in range(coh_ps_len):
            start = arange_neighbours_select_arr(i, 0)
            end = arange_neighbours_select_arr(i, 1)

            # To get len(start) * len(end) array in Numpy we need to select it like that.
            # You can use neighbour_ind[start, :][:, end] but then you need to add values some other
            # way
            neighbours_val = neighbour_ind[np.ix_(start, end)]
            neighbours_val[(neighbours_val == self.__DEF_NEIGHBOUR_VAL)
                           & (miss_middle == True)] = i

            neighbour_ind[np.ix_(start, end)] = neighbours_val

        return neighbour_ind
Exemple #2
0
    def __get_nr_trial_wraps(self, bperp_meaned,
                             sort_ind_meaned) -> np.float64:
        # todo what is k?
        k = self.__ps_files.wavelength * self.__mean_range * np.sin(
            sort_ind_meaned) / 4 / math.pi
        max_k = self.__max_topo_err / k

        bperp_range = MatlabUtils.max(bperp_meaned) - MatlabUtils.min(
            bperp_meaned)

        # todo why such formula?
        return bperp_range * max_k / (2 * math.pi)
Exemple #3
0
    def __clap_filt_for_patch(self, ph, low_pass):
        """Combined Low-pass Adaptive Phase filtering on 1 patch.
        In StaMPS this is in separate function clap_filt_patch"""

        alpha = self.__clap_alpha
        beta = self.__clap_beta

        if len(low_pass) == 0:
            low_pass = np.zeros(len(ph))

        ph = np.nan_to_num(ph)

        # todo This ph_fft its very similar with PhEstGamma function clap_filt
        # todo There where problems (incorrect value) with this part when calling third time
        ph_fft = np.fft.fft2(ph)
        smooth_resp = np.abs(ph_fft)
        smooth_resp = np.fft.ifftshift(
            MatlabUtils.filter2(self.__gaussian_window,
                                np.fft.fftshift(smooth_resp)))
        smooth_resp_mean = np.median(smooth_resp.flatten())

        if smooth_resp_mean != 0:
            smooth_resp /= smooth_resp_mean

        smooth_resp = np.power(smooth_resp, alpha)

        smooth_resp -= 1
        smooth_resp[smooth_resp < 0] = 0

        G = smooth_resp * beta + low_pass
        ph_filt = np.fft.ifft2(np.multiply(ph_fft, G))

        return ph_filt
Exemple #4
0
    def __get_max_rand(self, da_max: np.ndarray, xy: np.ndarray):
        """This function finds variable that in StaMPS is called 'max_percent_rand'.

        In StaMPS this variable is read in parameters. But in this process we also change it a bit
        we calculate this here"""

        DEF_VAL = 20

        if self.__select_method is self._SelectMethod.DESINTY:
            # In Stamps min and max values are in separate arrays with a single element.
            patch_area = np.prod(MatlabUtils.max(xy) -
                                 MatlabUtils.min(xy)) / 1e6  # In km
            max_rand = DEF_VAL * patch_area / (len(da_max) - 1)
        else:
            max_rand = DEF_VAL

        return max_rand
Exemple #5
0
        def ph_path_loop():
            # In StaMPS this is the place where to delete 'ph_res' and 'ph_patch' that were found
            # from last process

            NR_PS = len(coh_thresh_ind)
            ph_patch = self.__zero_ph_array(NR_PS, data.nr_ifgs)

            # Similar logic with 'nr_i' ja 'nr_j' already exists in PsEstGamma process
            nr_i = MatlabUtils.max(self.__ps_est_gamma.grid_ij[:, 0])
            nr_j = MatlabUtils.max(self.__ps_est_gamma.grid_ij[:, 1])

            # In StaMPS this variable had '2' at the end of the name
            ph_filt = np.zeros(
                (self.__clap_win, self.__clap_win, data.nr_ifgs),
                np.complex128)

            for i in range(ph_patch.shape[0]):
                ps_ij = self.__ps_est_gamma.grid_ij[coh_thresh_ind[i], :]

                i_min, i_max = get_max_min(ps_ij[0] - 1, nr_i)
                j_min, j_max = get_max_min(ps_ij[1] - 1, nr_j)

                # If you don't make copy then changes are made also in ph_grid variable
                ph_bit = np.copy(
                    self.__ps_est_gamma.ph_grid[i_min:i_max + 1,
                                                j_min:j_max + 1, :])

                ps_bit_i = int(ps_ij[0] - i_min - 1)
                ps_bit_j = int(ps_ij[1] - j_min - 1)
                ph_bit[ps_bit_i, ps_bit_j, :] = 0

                # todo Some kind of JJS oversample update
                ph_bit_len = len(ph_bit) + 1
                ph_bit_ind_i = get_ph_bit_ind_array(ps_bit_i, ph_bit_len)
                ph_bit_ind_j = get_ph_bit_ind_array(ps_bit_j, ph_bit_len)
                ph_bit[ph_bit_ind_i, ph_bit_ind_j, 0] = 0

                # It is similar with PsEstGammas ph_flit process but still not the same
                for j in range(ph_patch.shape[1]):
                    ph_filt[:, :, j] = self.__clap_filt_for_patch(
                        ph_bit[:, :, j], self.__ps_est_gamma.low_pass)

                ph_patch[i, :] = np.squeeze(ph_filt[ps_bit_i, ps_bit_j, :])

            return ph_patch
Exemple #6
0
    def __set_internal_params(self):
        """In StaMPS these where saved with setparam and getparam.
        All values are that small_baseline_flag = 'N'.

        In StaMPS max_desinty_rand ja max_percent_rand where two seperate varaibles, there we get
        them using function __get_max_rand.
        """
        self.__slc_osf = 1
        self.__clap_alpha = 1
        self.__clap_beta = 0.3
        self.__clap_win = 32
        self.__select_method = self._SelectMethod.DESINTY  # DESINITY or PERCENT
        # todo Why is this here
        self.__gamma_stdev_reject = 0
        # TODO This is [] in Stamps
        self.__drop_ifg_index = np.array([])
        self.__low_coh_tresh = 31  # 31/100

        self.__gaussian_window = np.multiply(
            np.asmatrix(MatlabUtils.gausswin(7)),
            np.asmatrix(MatlabUtils.gausswin(7)).conj().transpose())
Exemple #7
0
    def ps_topofit_fun(phase: np.ndarray, bperp_meaned: np.ndarray, nr_trial_wraps: float):
        # To make sure that the results are correct we transform bperp_meaned into column matrix
        if (len(bperp_meaned.shape) == 1):
            bperp_meaned = ArrayUtils.to_col_matrix(bperp_meaned)

        # The result of get_nr_trial_wraps is not correct in this case, so we need to find it again
        bperp_range = np.amax(bperp_meaned) - np.amin(bperp_meaned)

        CONST = 8 * nr_trial_wraps  # todo what const? Why 8
        trial_multi_start = -np.ceil(CONST)
        trial_multi_end = np.ceil(CONST)
        trial_multi = ArrayUtils.arange_include_last(trial_multi_start, trial_multi_end, 1)

        trial_phase = bperp_meaned / bperp_range * math.pi / 4
        trial_phase = np.exp(np.outer(-1j * trial_phase, trial_multi))

        # In order to successfully multiply, we need to transform 'phase' array to column matrix
        phase = ArrayUtils.to_col_matrix(phase)
        phase_tile = np.tile(phase, (1, len(trial_multi)))
        phaser = np.multiply(trial_phase, phase_tile)

        phaser_sum = MatlabUtils.sum(phaser)

        phase_abs_sum = MatlabUtils.sum(np.abs(phase))
        trial_coherence = np.abs(phaser_sum) / phase_abs_sum
        trial_coherence_max_ind = np.where(trial_coherence == MatlabUtils.max(trial_coherence))

        k_0 = (math.pi / 4 / bperp_range) * trial_multi[trial_coherence_max_ind][0]

        re_phase = np.multiply(phase, np.exp(-1j * (k_0 * bperp_meaned)))
        phase_offset = MatlabUtils.sum(re_phase)
        re_phase = np.angle(re_phase * phase_offset.conjugate())
        weigth = np.abs(phase)
        bperp_meaned_weighted = weigth * bperp_meaned
        re_phase_weighted = weigth * re_phase
        # Numpy linalg functions work only with 2d array
        if len(bperp_meaned_weighted.shape) > 2:
            bperp_meaned_weighted = bperp_meaned_weighted[0]
        if len(re_phase_weighted.shape) > 2:
            re_phase_weighted = re_phase_weighted[0]

        mopt = np.linalg.lstsq(bperp_meaned_weighted, re_phase_weighted)[0][0]
        # In StaMPS k0
        k_0 = k_0 + mopt

        phase_residual = np.multiply(phase, np.exp(-1j * (k_0 * bperp_meaned)))
        phase_residual_sum = MatlabUtils.sum(phase_residual)
        # In StaMPS c0
        static_offset = np.angle(phase_residual_sum)
        # In StaMPS coh0
        coherence_0 = np.abs(phase_residual_sum) / MatlabUtils.sum(np.abs(phase_residual))

        return phase_residual, coherence_0, static_offset, k_0
Exemple #8
0
        def random_dist():
            NR_RAND_IFGS = nr_ps  # In StaMPS it is 300000
            random = np.random.RandomState(2005)

            rnd_ifgs = 2 * math.pi * random.rand(NR_RAND_IFGS, nr_ifgs)

            random_coherence = np.zeros((NR_RAND_IFGS, 1))
            for i in range(NR_RAND_IFGS - 1, 0, -1):
                phase = np.exp(1j * rnd_ifgs[i])
                # We need only coherence here
                _, coherence_0, _, _ = PsTopofit.ps_topofit_fun(
                    phase, bperp_meaned, nr_trial_wraps)
                random_coherence[i] = coherence_0[0]

            del rnd_ifgs

            hist, _ = MatlabUtils.hist(random_coherence, self.coherence_bins)

            rand_dist = hist

            return rand_dist, np.count_nonzero(hist)
Exemple #9
0
    def __get_min_coh_and_da_mean(
            self, coh_ps: np.ndarray, max_rand: float,
            data: __DataDTO) -> (np.ndarray, np.ndarray, bool):

        # Internal parameters because full names are bad to write and read all the time
        coherence_bins = self.__ps_est_gamma.coherence_bins
        rand_dist = self.__ps_est_gamma.rand_dist

        array_size = data.da_max.size - 1

        min_coh = np.zeros(array_size)
        # In StaMPS this is size(da_max, 1) what is same as length(da_max)
        da_mean = np.zeros(array_size)
        for i in range(array_size):
            # You can use np.all or np.logical here too. Bitwize isn't must
            coh_chunk = coh_ps[(data.da > data.da_max[i])
                               & (data.da <= data.da_max[i + 1])]

            da_mean[i] = np.mean(data.da[(data.da > data.da_max[i])
                                         & (data.da <= data.da_max[i + 1])])
            # Remove pixels that we could not find coherence
            coh_chunk = coh_chunk[coh_chunk != 0]
            # In StaMPS this is called 'Na'
            hist, _ = MatlabUtils.hist(coh_chunk, coherence_bins)

            hist_low_coh_sum = MatlabUtils.sum(hist[:self.__low_coh_tresh])
            rand_dist_low_coh_sum = MatlabUtils.sum(
                rand_dist[:self.__low_coh_tresh])
            nr = rand_dist * hist_low_coh_sum / rand_dist_low_coh_sum  # todo What does this 'nr' mean?

            # In StaMPS here is also possibility to make graph

            hist[hist == 0] = 1

            # Percent_rand calculate
            # np.flip allows to use one-dimencional arrays, thats why we don't use np.fliplr
            nr_cumsum = np.cumsum(np.flip(nr, axis=0), axis=0)
            if self.__select_method is self._SelectMethod.PERCENT:
                hist_cumsum = np.cumsum(np.flip(hist, axis=0), axis=0) * 100
                percent_rand = np.flip(np.divide(nr_cumsum, hist_cumsum),
                                       axis=0)
            else:
                percent_rand = np.flip(nr_cumsum, axis=0)

            ok_ind = np.where(percent_rand < max_rand)[0]

            if len(ok_ind) == 0:
                # When coherence is over limit
                min_coh[i] = 1
            else:
                # Here we don't need to add one to indexes because on 'ok_ind' array it is already
                # done. This means that all those 'magical constants' are that where in StaMPS

                min_fit_ind = MatlabUtils.min(ok_ind) - 3  # todo Why 3?

                if min_fit_ind <= 0:
                    min_coh[i] = np.nan
                else:
                    max_fit_ind = MatlabUtils.min(ok_ind) + 2  # todo Why 2?

                    # In StaMPS this is just constant 100. Not length of array.
                    if max_fit_ind > len(percent_rand) - 1:
                        max_fit_ind = len(percent_rand) - 1

                    x_cordinates = percent_rand[min_fit_ind:max_fit_ind + 1]

                    y_cordinates = ArrayUtils.arange_include_last(
                        (min_fit_ind + 1) * 0.01, (max_fit_ind + 1) * 0.01,
                        0.01)
                    min_coh[i] = MatlabUtils.polyfit_polyval(
                        x_cordinates, y_cordinates, 3, max_rand)

        # Check if min_coh is unusable (full of nan's
        # This is bit different on StaMPS. I find min_coh'i ja da_mean in same method and in
        # same time
        not_nan_ind = np.where(min_coh != np.nan)[0]
        is_min_coh_nan_array = sum(not_nan_ind) == 0
        # When there isn't differences then we don't need to take subsets of arrays
        if not is_min_coh_nan_array or (not_nan_ind == array_size):
            min_coh = min_coh[not_nan_ind]
            da_mean = da_mean[not_nan_ind]

        return min_coh, da_mean, is_min_coh_nan_array
Exemple #10
0
    def __clap_filt(self, ph: np.ndarray, low_pass: np.ndarray):
        """CLAP_FILT Combined Low-pass Adaptive Phase filtering.
        Variables nr_win, nr_pad where inputs in StaMPS but these were multiplied before inputing
        into function. Here it is done internally.
        Also clap_alpha ja clap_beta where inputs but in this case those are global class variables
        so we can use them and don't need for inputs"""
        def create_grid(nr_win: int):
            grid_array = ArrayUtils.arange_include_last(0, (nr_win / 2) - 1)
            grid_x, grid_y = np.meshgrid(grid_array, grid_array)
            grid = grid_x + grid_y

            return grid

        # todo What does wind_func mean? This isn't array of functions
        def make_wind_func(grid: np.ndarray):
            WIND_FUNC_TYPE = np.float64
            wind_func = np.array(np.append(grid, np.fliplr(grid), axis=1),
                                 WIND_FUNC_TYPE)
            wind_func = np.array(
                np.append(wind_func, np.flipud(wind_func), axis=0),
                WIND_FUNC_TYPE)
            # In order to prevent zeros in corners
            wind_func += 1e-6

            return wind_func

        def get_indexes(loop_index: int, inc: int, nr_win: int) -> (int, int):
            i1 = loop_index * inc
            # We don't do -1 because otherwise last element in array is not selected
            i2 = i1 + nr_win

            return i1, i2

        FILTERED_TYPE = np.complex128
        filtered = np.zeros(ph.shape, FILTERED_TYPE)

        ph = np.nan_to_num(ph)

        nr_win = int(self.__clap_win * 0.75)
        nr_pad = int(self.__clap_win * 0.25)

        ph_i_len = ph.shape[0] - 1
        ph_j_len = ph.shape[1] - 1
        nr_inc = int(np.floor(nr_win / 4))
        # Indices begin from zero on Python. That's why those values are greater than StaMPS
        nr_win_i = int(np.ceil(ph_i_len / nr_inc) - 3)
        nr_win_j = int(np.ceil(ph_j_len / nr_inc) - 3) + 1

        wind_func = make_wind_func(create_grid(nr_win))

        # To make transpose work like Matlab we need to convert those to matrix
        # todo: PsSelect has similar thing
        B = np.multiply(np.asmatrix(MatlabUtils.gausswin(7)),
                        np.asmatrix(MatlabUtils.gausswin(7)).transpose())

        nr_win_pad_sum = (nr_win + nr_pad)
        ph_bit = np.zeros((nr_win_pad_sum, nr_win_pad_sum), FILTERED_TYPE)
        # Todo: Refactor
        for i in range(nr_win_i):
            w_f = wind_func.copy()
            i1, i2 = get_indexes(i, nr_inc, nr_win)

            if i2 > ph_i_len:
                i_shift = i2 - ph_i_len - 1
                i2 = ph_i_len + 1
                i1 = ph_i_len - nr_win + 1
                w_f = np.append(np.zeros((i_shift, nr_win)),
                                w_f[:nr_win - i_shift, :],
                                axis=0).astype(FILTERED_TYPE)

            for j in range(nr_win_j):
                w_f2 = w_f
                j1, j2 = get_indexes(j, nr_inc, nr_win)

                if j2 > ph_j_len:
                    j_shift = j2 - ph_j_len - 1
                    # Because array lenghts, ph_i_len and ph_j_len, are already smaller and Numpy
                    # does not take last index when selecting, then we need to add one more
                    j2 = ph_j_len + 1
                    j1 = ph_j_len - nr_win + 1
                    w_f2 = np.append(np.zeros((nr_win, j_shift)),
                                     w_f2[:, :nr_win - j_shift],
                                     axis=1).astype(FILTERED_TYPE)

                ph_bit[:nr_win, :nr_win] = ph[i1:i2, j1:j2]

                ph_fft = np.fft.fft2(
                    ph_bit
                )  # todo Todo from fifth decimal point the values are not equal to Stamps result
                # ph_fft = fftw.interfaces.numpy_fft.fft2(ph_bit) #  todo Todo from fifth decimalpoint the values are not equal to Stamps result
                smooth_resp = np.abs(ph_fft)  # 'H' in Stamps
                smooth_resp = np.fft.ifftshift(
                    MatlabUtils.filter2(B, np.fft.ifftshift(smooth_resp)))
                # smooth_resp = fftw.interfaces.numpy_fft.ifftshift(
                #     MatlabUtils.filter2(B, fftw.interfaces.numpy_fft.ifftshift(smooth_resp)))
                mean_smooth_resp = np.median(smooth_resp)

                if mean_smooth_resp != 0:
                    smooth_resp /= mean_smooth_resp

                smooth_resp = np.power(smooth_resp, self.__clap_alpha)

                # todo Values under median to zero. Why that?
                smooth_resp -= 1
                smooth_resp[smooth_resp < 0] = 0

                # todo What is G?
                G = smooth_resp * self.__clap_beta + low_pass
                ph_filt = np.fft.ifft2(np.multiply(ph_fft, G))
                # ph_filt = fftw.interfaces.numpy_fft.ifft2(np.multiply(ph_fft, G))
                ph_filt = np.multiply(ph_filt[:nr_win, :nr_win], w_f2)

                filtered[i1:i2, j1:j2] += ph_filt

        return filtered
Exemple #11
0
    def __sw_loop(self, ph: np.ndarray, weights: np.ndarray,
                  low_pass: np.ndarray, bprep: np.ndarray, nr_ifgs: int,
                  nr_ps: int, nr_trial_wraps: float):

        SW_ARRAY_SHAPE = (nr_ps, 1)

        def zero_ps_array_cont():
            """Konstruktor tühja pusivpeegeladajate info massiivi loomiseks"""
            return np.zeros(SW_ARRAY_SHAPE)

        def get_ph_weight(bprep, k_ps, nr_ifgs, ph, weights):
            exped = np.exp(
                np.multiply((-1j * bprep), np.tile(k_ps, (1, nr_ifgs))))
            exp_tiled_weight_multi = np.multiply(
                exped, np.tile(weights, (1, nr_ifgs)))
            return np.multiply(ph, exp_tiled_weight_multi)

        def is_gamma_in_change_delta():
            return abs(gamma_change_delta) < self.__gamma_change_convergence

        def make_ph_grid(ph_grid_shape: tuple, grid_ij: np.ndarray,
                         weights: np.ndarray, loop_nr: int) -> np.ndarray:
            # np.complex128 is needed because this is the type that pydsm.relab.shiftdim returns.
            # ph_grid and ph_filt are needed to make again. Otherwise there are old values in those
            # arrays
            ph_grid = np.zeros(ph_grid_shape, np.complex128)
            for id in range(loop_nr):
                x_ind = int(grid_ij[id, 0]) - 1
                y_ind = int(grid_ij[id, 1]) - 1
                ph_grid[x_ind,
                        y_ind, :] += pydsm.relab.shiftdim(weights[id, :],
                                                          -1,
                                                          nargout=1)[0]

            return ph_grid

        def make_ph_filt(ph_grid_shape: tuple, ph_grid: np.ndarray,
                         loop_nr: int, low_pass: np.ndarray) -> np.ndarray:
            ph_filt = np.zeros(ph_grid_shape, np.complex128)
            for i in range(loop_nr):
                ph_filt[:, :, i] = self.__clap_filt(ph_grid[:, :, i], low_pass)

            return ph_filt

        def make_ph_path(ph_patch: np.ndarray, ph_filt: np.ndarray,
                         grid_ij: np.ndarray, loop_nr: int) -> np.ndarray:
            for i in range(loop_nr):
                x_ind = int(grid_ij[i, 0]) - 1
                y_ind = int(grid_ij[i, 1]) - 1
                ph_patch[i, :nr_ifgs] = np.squeeze(ph_filt[x_ind, y_ind, :])

            not_zero_patches_ind = np.nonzero(ph_patch)
            ph_patch[not_zero_patches_ind] = np.divide(
                ph_patch[not_zero_patches_ind],
                np.abs(ph_patch[not_zero_patches_ind]))

            return ph_patch

        nr_i = int(np.max(self.grid_ij[:, 0]))
        nr_j = int(np.max(self.grid_ij[:, 1]))
        PH_GRID_SHAPE = (nr_i, nr_j, nr_ifgs)

        coh_ps_result = zero_ps_array_cont()
        gamma_change = 0
        gamma_change_delta = np.inf

        ph_patch = np.zeros(ph.shape, np.complex128)

        k_ps = zero_ps_array_cont()

        # Est topo error
        # Initializing variables that are returned in the end
        c_ps = zero_ps_array_cont()
        n_opt = zero_ps_array_cont()
        ph_res = np.zeros((nr_ps, nr_ifgs))

        log_i = 0  # Used for logging to see how many cycles we have done
        self.__logger.debug("is_gamma_in_change_delta loop begin")
        while not is_gamma_in_change_delta():
            log_i += 1
            self.__logger.debug("gamma change loop i " + str(log_i))
            ph_weight = get_ph_weight(bprep, k_ps, nr_ifgs, ph, weights)

            ph_grid = make_ph_grid(PH_GRID_SHAPE, self.grid_ij, ph_weight,
                                   nr_ps)
            ph_filt = make_ph_filt(PH_GRID_SHAPE, ph_grid, nr_ifgs, low_pass)

            self.__logger.debug(
                "ph_filt found. first row: {0}, last row: {1}".format(
                    ph_filt[0], ph_filt[len(ph_filt) - 1]))

            ph_patch = make_ph_path(ph_patch, ph_filt, self.grid_ij, nr_ps)

            self.__logger.debug(
                "ph_patch found. first row: {0}, last row: {1}".format(
                    ph_patch[0], ph_patch[len(ph_patch) - 1]))

            del ph_filt

            # This is the slowest part in this process
            topofit = PsTopofit(SW_ARRAY_SHAPE, nr_ps, nr_ifgs)
            topofit.ps_topofit_loop(ph, ph_patch, bprep, nr_trial_wraps)
            k_ps = topofit.k_ps.copy()
            c_ps = topofit.c_ps.copy()
            coh_ps = topofit.coh_ps.copy()
            n_opt = topofit.n_opt.copy()
            ph_res = topofit.ph_res.copy()

            del topofit

            self.__logger.debug("topofit found")

            gamma_change_rms = np.sqrt(
                np.sum(np.power(coh_ps - coh_ps_result, 2) / nr_ps))
            gamma_change_delta = gamma_change_rms - gamma_change
            # Saving gamma and coherence that are returned later to temp variables
            gamma_change = gamma_change_rms
            coh_ps_result = coh_ps

            self.__logger.debug(
                "is_gamma_in_change_delta() and self.__filter_weighting: " +
                str(not is_gamma_in_change_delta()
                    and self.__filter_weighting == 'P-square'))
            if not is_gamma_in_change_delta(
            ) and self.__filter_weighting == 'P-square':
                # In Stamps it is named 'Na'
                hist, _ = MatlabUtils.hist(coh_ps, self.coherence_bins)
                self.__logger.debug("hist[0:3] " + str(hist[:3]))
                # The random values are transformed into real values here
                low_coh_thresh_ind = self.__low_coherence_thresh
                real_distr = np.sum(hist[:low_coh_thresh_ind]) / np.sum(
                    self.rand_dist[:low_coh_thresh_ind])
                self.rand_dist = self.rand_dist * real_distr

                hist[hist == 0] = 1
                p_rand = np.divide(self.rand_dist, hist)
                p_rand[:low_coh_thresh_ind] = 1
                p_rand[
                    self.
                    nr_max_nz_ind:] = 0  # In Stamps nr_max_nz_ind is incremented by one
                p_rand[p_rand > 1] = 1
                p_rand_added_ones = np.append(np.ones(7), p_rand)
                filtered = scipy.signal.lfilter(MatlabUtils.gausswin(7), [1],
                                                p_rand_added_ones)
                p_rand = filtered / np.sum(MatlabUtils.gausswin(7))
                p_rand = p_rand[7:]

                # Found that 'quadratic' is bit more accurate than 'cubic'
                p_rand = MatlabUtils.interp(np.append([1.0], p_rand), 10,
                                            'quadratic')[:-9]

                # Here we covert coh_ps to indexes array. astype is needed because in Numpy all
                # indexes must be int type.
                # reshape is needed because coh_ps is array of arrays.
                coh_ps_as_ind = np.round(coh_ps * 1000).astype(np.int)
                if len(coh_ps_as_ind.shape) > 1:
                    coh_ps_as_ind = np.squeeze(coh_ps_as_ind)
                # In Stamps this is 'Prand_ps'
                ps_rand = p_rand[coh_ps_as_ind].conj().transpose()

                weights = np.reshape(np.power(1 - ps_rand, 2), SW_ARRAY_SHAPE)

        return ph_patch, k_ps, c_ps, coh_ps_result, n_opt, ph_res, ph_grid, low_pass
Exemple #12
0
    def __drop_noisy(self, data: __DataDTO, selectable_ps: np.ndarray,
                     ifg_ind: np.ndarray,
                     edges: np.ndarray) -> (np.ndarray, np.ndarray):
        def get_ph_weed(bperp: np.ndarray, k_ps: np.ndarray, ph: np.ndarray,
                        c_ps: np.ndarray, master_nr: int):
            exped = np.exp(-1j * (k_ps * bperp.conj().transpose()))
            ph_weed = np.multiply(ph, exped)
            ph_weed = np.divide(ph_weed, np.abs(ph_weed))
            # Adding master noise. It is done when small_baseline_flag != 'y'. Reshape is needed
            # because 'c_ps' is array of array's
            ph_weed[:,
                    (master_nr - 1)] = np.exp(1j * c_ps).reshape(len(ph_weed))

            return ph_weed

        def get_time_deltas_in_days(index: int) -> np.ndarray:
            """For getting days in ints from date object"""
            return np.array([(ifg_dates[index] - ifg_dates[x]).days
                             for x in np.nditer(ifg_ind)])

        def get_dph_mean(dph_space, edges_len, weight_factor):
            repmat = np.matlib.repmat(weight_factor, edges_len, 1)
            dph_mean = np.sum(np.multiply(dph_space, repmat), axis=1)

            return dph_mean

        ph_filtered = data.ph[selectable_ps]
        k_ps_filtered = data.k_ps[selectable_ps]
        c_ps_filtered = data.c_ps[selectable_ps]
        bperp_meaned = data.bperp_meaned
        master_nr = data.master_nr
        ifg_dates = data.ifg_dates

        ph_weed = get_ph_weed(bperp_meaned, k_ps_filtered, ph_filtered,
                              c_ps_filtered, master_nr)

        dph_space = np.multiply(ph_weed[edges[:, 2] - 1],
                                ph_weed[edges[:, 1] - 1].conj())
        dph_space = dph_space[:, ifg_ind]

        #todo drop_ifg_index logic

        # This all is made when small_baseline_flag != 'y'

        dph_shape = (len(edges), len(ifg_ind))
        dph_smooth = np.zeros(dph_shape).astype(np.complex128)
        dph_smooth2 = np.zeros(dph_shape).astype(np.complex128)
        for i in range(len(ifg_ind)):
            time_delta = get_time_deltas_in_days(i)
            weight_factor = np.exp(-(np.power(time_delta, 2)) / 2 /
                                   math.pow(self.__time_win, 2))
            weight_factor = weight_factor / np.sum(weight_factor)

            dph_mean = get_dph_mean(dph_space, len(edges), weight_factor)

            repmat = np.matlib.repmat(
                ArrayUtils.to_col_matrix(dph_mean).conj(), 1, len(ifg_ind))
            dph_mean_adj = np.angle(np.multiply(dph_space, repmat))

            G = np.array([np.ones(len(ifg_ind)), time_delta]).transpose()
            # 'm' in Stamps
            weighted_least_sqrt = MatlabUtils.lscov(
                G,
                dph_mean_adj.conj().transpose(), weight_factor)
            #todo Find better name
            least_sqrt_G = np.asarray(
                (np.asmatrix(G) *
                 np.asmatrix(weighted_least_sqrt)).conj().transpose())
            dph_mean_adj = np.angle(np.exp(1j * (dph_mean_adj - least_sqrt_G)))
            # 'm2' in Stamps
            weighted_least_sqrt2 = MatlabUtils.lscov(
                G,
                dph_mean_adj.conj().transpose(), weight_factor)

            # We don't make transpose for weighted_least_sqrt because it doesn't
            # do anything in this case
            dph_smooth_val_exp = np.exp(
                1j * (weighted_least_sqrt[0, :] + weighted_least_sqrt2[0, :]))
            dph_smooth[:, i] = np.multiply(dph_mean, dph_smooth_val_exp)
            weight_factor[i] = 0  # Let's make ourselves as zero

            dph_smooth2[:, i] = get_dph_mean(dph_space, len(edges),
                                             weight_factor)

        dph_noise = np.angle(np.multiply(dph_space, dph_smooth2.conj()))
        ifg_var = np.var(dph_noise, 0)

        dph_noise = np.angle(np.multiply(dph_space, dph_smooth.conj()))
        K_weights = np.divide(1, ifg_var)
        K = MatlabUtils.lscov(bperp_meaned,
                              dph_noise.conj().transpose(),
                              K_weights).conj().transpose()
        dph_noise -= K * bperp_meaned.transpose()

        edge_std = MatlabUtils.std(dph_noise, axis=1)
        edge_max = np.max(np.abs(dph_noise), axis=1)

        return edge_std, edge_max
 def test_sum_single(self):
     self.assertEqual(MatlabUtils.sum(self.__single_row_array), 6)
 def test_sum_multi(self):
     np.testing.assert_array_equal(MatlabUtils.sum(self.__multi_row_array),
                                   np.array([5, 7, 9]))
 def test_min_single(self):
     self.assertEqual(MatlabUtils.min(self.__single_row_array), 1)
 def test_min_multi(self):
     np.testing.assert_array_equal(MatlabUtils.min(self.__multi_row_array),
                                   np.array([1, 2, 3]))
 def test_max_single(self):
     self.assertEqual(MatlabUtils.max(self.__single_row_array), 3)
 def test_max_multi(self):
     np.testing.assert_array_equal(MatlabUtils.max(self.__multi_row_array),
                                   np.array([4, 5, 6]))