def stream_collapse_tr(st): if not isinstance(st, Stream): raise InputError("'st' must be a 'obspy.core.stream.Stream' object") stream_new = Stream() # Generate sorted list of traces (no copy) # Sort order, id, starttime, endtime ids = [] for tr in st: if not tr.id in ids: ids.append(tr.id) for id in ids: print "new_trace id: %s" % id tr_new = Trace() tr_new.data = np.zeros(st[0].data.shape) # tr_new.stats = {} tr_new.stats_tr1 = {} tr_new.stats_tr2 = {} starttime1_list = [] starttime2_list = [] endtime1_list = [] endtime2_list = [] n_tr = 0 for tr in st: if tr.id == id: print tr.id if len(tr_new.data) != len(tr.data): lp = len(tr_new.data) - len(tr.data) print "lp: %d" % lp if lp > 0: left = np.ceil(lp / 2) right = lp - left cdata = np.append(np.zeros(left, dtype=tr.data.dtype), tr.data) tr.data = np.append(cdata, np.zeros(right, dtype=tr.data.dtype)) else: lp = -lp left = np.ceil(lp / 2) right = lp - left tr.data = tr.data[left:-right] print "len tr: %d" % len(tr) print "len tr_new: % d" % len(tr_new) tr_new.data += tr.data n_tr += 1 starttime1_list.append(tr.stats_tr1.starttime) starttime2_list.append(tr.stats_tr2.starttime) endtime1_list.append(tr.stats_tr1.endtime) endtime2_list.append(tr.stats_tr2.endtime) tr_new.stats.update(tr.stats) tr_new.stats_tr1.update(tr.stats_tr1) tr_new.stats_tr2.update(tr.stats_tr2) tr_new.data /= n_tr tr_new.stats['starttime1'] = starttime1_list tr_new.stats['starttime2'] = starttime2_list tr_new.stats['endtime1'] = endtime1_list tr_new.stats['endtime2'] = endtime2_list stream_new.append(tr_new) return stream_new
def conv_traces(tr1, tr2, normal=True): """ Convolve two Traces and merge their meta-information It convolves the data stored in two :class:`~obspy.core.trace.Trace` Objects in frequency domain. If ``normal==True`` the resulting correlation data are normalized by a factor of :func:`sqrt(||tr1.data||^2 x ||tr2.data||^2)` Meta-informations associated to the resulting Trace are obtained through: - Merging the original meta-informations of the two input traces according to the :func:`~miic.core.corr_fun.combine_stats` function. - Adding the original two `Stats` objects to the newly created :class:`~obspy.core.trace.Trace` object as: >>> conv_tr.stats_tr1 = tr1.stats >>> conv_tr.stats_tr2 = tr2.stats - Fixing: >>> conv_tr.stats['npts'] = '...number of correlation points...' >>> conv_tr.stats['starttime'] = tr2.stats['starttime'] - tr1.stats['starttime'] :type tr1: :class:`~obspy.core.trace.Trace` :param tr1: First Trace :type tr2: :class:`~obspy.core.trace.Trace` :param tr2: Second Trace :type normal: bool :param normal: Normalization flag :rtype: :class:`~obspy.core.trace.Trace` :return: **conv_tr**: Trace that stores convolved data and meta-information """ if not isinstance(tr1, Trace): raise TypeError("tr1 must be an obspy Trace object.") if not isinstance(tr2, Trace): raise TypeError("tr2 must be an obspy Trace object.") zerotime = UTCDateTime(1971, 1, 1, 0, 0, 0) conv_tr = Trace() # extend traces to the next power of 2 of the longest trace lt = pow(2, np.ceil(np.log2(np.max([tr1.stats['npts'], tr2.stats['npts']])))) s1 = extend(tr1.data, method='zeros', length='fixed',size=lt) s2 = extend(tr2.data, method='zeros', length='fixed',size=lt) # create the combined stats conv_tr.stats = combine_stats(tr1, tr2) conv_tr.stats_tr1 = tr1.stats conv_tr.stats_tr2 = tr2.stats conv_tr.stats_tr1.npts = min(tr1.stats.npts, tr2.stats.npts) conv_tr.stats_tr2.npts = min(tr1.stats.npts, tr2.stats.npts) if normal: denom = np.sqrt(np.dot(s1.astype(np.float64), s1.T) * np.dot(s2.astype(np.float64), s2.T)) else: denom = 1. # remaining offset in samples (just remove fractions of samples) roffset = np.round((tr2.stats.starttime - tr1.stats.starttime) * tr1.stats.sampling_rate) offset = (tr2.stats.starttime - tr1.stats.starttime) * \ tr1.stats.sampling_rate - roffset # remaining offset in seconds roffset /= tr1.stats.sampling_rate convData = _fftconvolve(s1[::-1], s2, offset) convData = np.multiply(convData, (1 / denom)) # set number of samples conv_tr.stats['npts'] = convData.shape[0] # time lag of the zero position, i.e. lag time of alignent t_offset_zeroleg = (float(convData.shape[0]) - 1.) / \ (2. * tr1.stats.sampling_rate) # set starttime conv_tr.stats['starttime'] = zerotime - t_offset_zeroleg + \ roffset conv_tr.data = convData return conv_tr
def conv_traces(tr1, tr2, normal=True): """ Convolve two Traces and merge their meta-information It convolves the data stored in two :class:`~obspy.core.trace.Trace` Objects in frequency domain. If ``normal==True`` the resulting correlation data are normalized by a factor of :func:`sqrt(||tr1.data||^2 x ||tr2.data||^2)` Meta-informations associated to the resulting Trace are obtained through: - Merging the original meta-informations of the two input traces according to the :func:`~miic.core.corr_fun.combine_stats` function. - Adding the original two `Stats` objects to the newly created :class:`~obspy.core.trace.Trace` object as: >>> conv_tr.stats_tr1 = tr1.stats >>> conv_tr.stats_tr2 = tr2.stats - Fixing: >>> conv_tr.stats['npts'] = '...number of correlation points...' >>> conv_tr.stats['starttime'] = tr2.stats['starttime'] - tr1.stats['starttime'] :type tr1: :class:`~obspy.core.trace.Trace` :param tr1: First Trace :type tr2: :class:`~obspy.core.trace.Trace` :param tr2: Second Trace :type normal: bool :param normal: Normalization flag :rtype: :class:`~obspy.core.trace.Trace` :return: **conv_tr**: Trace that stores convolved data and meta-information """ if not isinstance(tr1, Trace): raise TypeError("tr1 must be an obspy Trace object.") if not isinstance(tr2, Trace): raise TypeError("tr2 must be an obspy Trace object.") zerotime = UTCDateTime(1971, 1, 1, 0, 0, 0) conv_tr = Trace() # extend traces to the next power of 2 of the longest trace lt = pow(2, np.ceil(np.log2(np.max([tr1.stats['npts'], tr2.stats['npts']])))) s1 = extend(tr1.data, method='zeros', length='fixed',size=lt) s2 = extend(tr2.data, method='zeros', length='fixed',size=lt) # create the combined stats conv_tr.stats = combine_stats(tr1, tr2) conv_tr.stats_tr1 = tr1.stats conv_tr.stats_tr2 = tr2.stats conv_tr.stats_tr1.npts = min(tr1.stats.npts, tr2.stats.npts) conv_tr.stats_tr2.npts = min(tr1.stats.npts, tr2.stats.npts) if normal: denom = np.sqrt(np.dot(s1.astype(np.float64), s1.T) * np.dot(s2.astype(np.float64), s2.T)) else: denom = 1. # remaining offset in samples (just remove fractions of samples) roffset = np.round((tr2.stats.starttime - tr1.stats.starttime) * tr1.stats.sampling_rate) offset = (tr2.stats.starttime - tr1.stats.starttime) * \ tr1.stats.sampling_rate - roffset # remaining offset in seconds roffset /= tr1.stats.sampling_rate convData = _fftconvolve(s1[::-1], s2, offset) convData = np.multiply(convData, (1 / denom)) # set number of samples conv_tr.stats['npts'] = convData.shape[0] # time lag of the zero position, i.e. lag time of alignent t_offset_zeroleg = (float(convData.shape[0]) - 1.) / \ (2. * tr1.stats.sampling_rate) # set starttime conv_tr.stats['starttime'] = zerotime - t_offset_zeroleg + \ roffset conv_tr.data = convData return conv_tr