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]
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]