Ejemplo n.º 1
0
    def compute_A_b(self, window, win_idx, dsyn):
        """
        Calculate the matrix A and vector b based on one pair of
        observed data and synthetic data on a given window.

        :param window: data and window information
        :type window: :class:`pycmt3d.Window`
        :param win_idx: window index(a specific window)
        :type win_idx: integer
        :param dsyn: derivative synthetic data matrix
        :type dsyn: numpy.array
        :return:
        """
        npar = self.config.npar

        datalist = window.datalist
        obsd = datalist['obsd']
        synt = datalist['synt']
        npts = min(obsd.stats.npts, synt.stats.npts)
        win = [window.win_time[win_idx, 0], window.win_time[win_idx, 1]]

        istart = int(max(math.floor(win[0] / obsd.stats.delta), 1))
        iend = int(min(math.ceil(win[1] / obsd.stats.delta), npts))
        if istart > iend:
            raise ValueError("Check window for %s.%s.%s.%s" %
                             (window.station, window.network,
                              window.location, window.component))

        # station correction
        istart_d, iend_d, istart_s, iend_s, nshift, cc, dlnA, cc_amp_value = \
            self.apply_station_correction(obsd, synt, istart, iend)

        dt_synt = datalist['synt'].stats.delta
        dt_obsd = datalist['obsd'].stats.delta
        if abs(dt_synt - dt_obsd) > 0.0001:
            raise ValueError("Delta in synthetic and observed no the same")
        dt = dt_synt

        # hanning taper
        taper = construct_taper(iend_s - istart_s, taper_type=const.taper_type)

        A1 = np.zeros((npar, npar))
        b1 = np.zeros(npar)
        # compute A and b
        for j in range(npar):
            for i in range(0, j + 1):
                A1[i, j] = np.sum(taper * dsyn[i, istart_s:iend_s] *
                                  dsyn[j, istart_s:iend_s]) * dt
            b1[j] = np.sum(
                taper * (obsd.data[istart_d:iend_d] -
                         synt.data[istart_s:iend_s]) *
                dsyn[j, istart_s:iend_s]) * dt
        for j in range(npar):
            for i in range(j + 1, npar):
                A1[i, j] = A1[j, i]

        return [A1, b1]
Ejemplo n.º 2
0
    def calculate_var_one_trace(self, obsd, synt, win_time):
        """
        Calculate the variance reduction on a pair of obsd and 
        synt and windows

        :param obsd: observed data trace
        :type obsd: :class:`obspy.core.trace.Trace`
        :param synt: synthetic data trace
        :type synt: :class:`obspy.core.trace.Trace`
        :param win_time: [win_start, win_end]
        :type win_time: :class:`list` or :class:`numpy.array`
        :return:  waveform misfit reduction and observed data energy [v1, d1]
        :rtype: [float, float]
        """
        num_wins = win_time.shape[0]
        v1 = np.zeros(num_wins)
        d1 = np.zeros(num_wins)
        nshift_array = np.zeros(num_wins)
        cc_array = np.zeros(num_wins)
        dlnA_array = np.zeros(num_wins)
        cc_amp_value_array = np.zeros(num_wins)
        npts = min(obsd.stats.npts, synt.stats.npts)
        for _win_idx in range(win_time.shape[0]):
            tstart = win_time[_win_idx, 0]
            tend = win_time[_win_idx, 1]
            idx_start = int(max(math.floor(tstart / obsd.stats.delta), 1))
            idx_end = int(min(math.ceil(tend / obsd.stats.delta), 
                              obsd.stats.npts))

            istart_d, iend_d, istart, iend, nshift, cc, dlnA, cc_amp_value = \
                self.apply_station_correction(obsd, synt, idx_start, idx_end)

            taper = construct_taper(iend - istart)
            v1[_win_idx] = \
                np.sum(taper * (synt.data[istart:iend] - 
                                obsd.data[istart_d:iend_d]) ** 2)
            d1[_win_idx] = np.sum(taper * obsd.data[istart_d:iend_d] ** 2)
            nshift_array[_win_idx] = nshift
            cc_array[_win_idx] = cc
            dlnA_array[_win_idx] = dlnA
            cc_amp_value_array[_win_idx] = cc_amp_value
            #print "v1, idx:", v1[_win_idx], istart, iend, istart_d, \
            #iend_d, _win_idx, nshift
        return [v1, d1, nshift_array, cc_array, dlnA_array, 
                cc_amp_value_array]