def testMisfitBox(self): ydata = num.zeros(9) ydata[3:6] = 1.0 deltat = 0.5 tr = trace.Trace(ydata=ydata, deltat=0.5, tmin=0.0) tshiftmin = -(tr.tmax - tr.tmin) * 2 tshiftmax = (tr.tmax - tr.tmin) * 2 tshifts = num.linspace( tshiftmin, tshiftmax, int(round((tshiftmax - tshiftmin) / deltat)) + 1) candidates = [] for tshift in tshifts: trc = tr.copy() trc.shift(tshift) candidates.append(trc) trace.MisfitSetup(norm=2, taper=trace.CosTaper(tr.tmin, tr.tmin, tr.tmax, tr.tmax), domain='time_domain')
def test_muliply_taper(self): taper = trace.CosTaper(0., 1., 2., 3.) taper2 = trace.MultiplyTaper([taper, taper]) y = num.ones(31) taper(y, 0., 0.1) taper(y, 0., 0.1) z = num.ones(31) taper2(z, 0., 0.1) assert numeq(y, z, 1e-6) assert taper.time_span() == taper2.time_span()
def testMisfitOfSameTracesDtDifferentShifted(self): """ Tests: Different length Different delta t Shifted L2-Norm L1-Norm time- and frequency-domain """ test_file = os.path.join(os.path.dirname(__file__), '../examples/1989.072.evt.mseed') p = pile.make_pile(test_file, show_progress=False) rt = p.all()[0] tt = rt.copy() # make downsampled, chopped copies: deltats = [0.5, 1.0, 2.0] tt.chop(tmin=rt.tmin + 10, tmax=rt.tmax - 15) tts = [tt.copy() for i in range(len(deltats))] [t.downsample_to(deltats[i]) for i, t in enumerate(tts)] # shift traces: t_shifts = [1.0, 0.49999, 0.5] for ts in t_shifts: tts_shifted = [t.copy() for t in tts] map(lambda x: x.shift(ts), tts_shifted) tts.extend(tts_shifted) a = rt.tmin d = rt.tmax b = a + (d - a) / 10 c = d - (d - a) / 10 taper = trace.CosTaper(a, b, c, d) fresponse = trace.FrequencyResponse() norms = [1, 2] domains = ['time_domain', 'frequency_domain', 'envelope', 'absolute'] setups = [ trace.MisfitSetup(norm=n, taper=taper, domain=domain, filter=fresponse) for domain in domains for n in norms ] for cand in tts: for setup in setups: m, n = rt.misfit(candidate=cand, setup=setup) self.assertNotEqual(m, None, 'misfit\'s m is None')
def post_process(self, engine, source, tr_syn): tr_syn = tr_syn.pyrocko_trace() nslc = self.codes config = self.misfit_config tmin_fit, tmax_fit, tfade, tfade_taper = \ self.get_taper_params(engine, source) ds = self.get_dataset() tobs, tsyn = self.get_pick_shift(engine, source) if None not in (tobs, tsyn): tobs_shift = tobs - tsyn else: tobs_shift = 0.0 tr_syn.extend(tmin_fit - tfade * 2.0, tmax_fit + tfade * 2.0, fillmethod='repeat') freqlimits = self.get_freqlimits() tr_syn = tr_syn.transfer(freqlimits=freqlimits, tfade=tfade) tr_syn.chop(tmin_fit - 2 * tfade, tmax_fit + 2 * tfade) tmin_obs, tmax_obs = self.get_cutout_timespan(tmin_fit + tobs_shift, tmax_fit + tobs_shift, tfade) try: tr_obs = ds.get_waveform( nslc, tinc_cache=1.0 / (config.fmin or 0.1 * config.fmax), tmin=tmin_fit + tobs_shift - tfade, tmax=tmax_fit + tobs_shift + tfade, tfade=tfade, freqlimits=freqlimits, deltat=tr_syn.deltat, cache=True, backazimuth=self.get_backazimuth_for_waveform()) if tobs_shift != 0.0: tr_obs = tr_obs.copy() tr_obs.shift(-tobs_shift) mr = misfit(tr_obs, tr_syn, taper=trace.CosTaper(tmin_fit - tfade_taper, tmin_fit, tmax_fit, tmax_fit + tfade_taper), domain=config.domain, exponent=config.norm_exponent, flip=self.flip_norm, result_mode=self._result_mode, tautoshift_max=config.tautoshift_max, autoshift_penalty_max=config.autoshift_penalty_max, subtargets=self._piggyback_subtargets) self._piggyback_subtargets = [] mr.tobs_shift = float(tobs_shift) mr.tsyn_pick = float_or_none(tsyn) return mr except NotFound as e: logger.debug(str(e)) raise gf.SeismosizerError('no waveform data, %s' % str(e))
def assemble_seismic_results(self, point): """ Assemble seismic traces for given point in solution space. Parameters ---------- point : :func:`pymc3.Point` Dictionary with model parameters Returns ------- List with :class:`heart.SeismicResult` """ assert self._seismic_flag logger.debug('Assembling seismic waveforms ...') if self._geodetic_flag: self._geodetic_flag = False reset_flag = True else: reset_flag = False syn_proc_traces = self.get_synthetics( point, outmode='stacked_traces')['seismic'] tmins = [tr.tmin for tr in syn_proc_traces] at = copy.deepcopy(self.config.seismic_config.arrival_taper) obs_proc_traces = heart.taper_filter_traces( self.data_traces, arrival_taper=at, filterer=self.config.seismic_config.filterer, tmins=tmins, outmode='traces') self.config.seismic_config.arrival_taper = None syn_filt_traces = self.get_synthetics( point, outmode='data')['seismic'] obs_filt_traces = heart.taper_filter_traces( self.data_traces, filterer=self.config.seismic_config.filterer, outmode='traces') factor = 2. for i, (trs, tro) in enumerate(zip(syn_filt_traces, obs_filt_traces)): trs.chop(tmin=tmins[i] - factor * at.fade, tmax=tmins[i] + factor * at.fade + at.duration) tro.chop(tmin=tmins[i] - factor * at.fade, tmax=tmins[i] + factor * at.fade + at.duration) self.config.seismic_config.arrival_taper = at results = [] for i, obstr in enumerate(obs_proc_traces): dtrace = obstr.copy() dtrace.set_ydata( (obstr.get_ydata() - syn_proc_traces[i].get_ydata())) taper = trace.CosTaper( tmins[i], tmins[i] + at.fade, tmins[i] + at.duration - at.fade, tmins[i] + at.duration) results.append(heart.SeismicResult( processed_obs=obstr, processed_syn=syn_proc_traces[i], processed_res=dtrace, filtered_obs=obs_filt_traces[i], filtered_syn=syn_filt_traces[i], taper=taper)) if reset_flag: self._geodetic_flag = True return results
def plot_waveforms(traces, event, stations, savedir, picks, show=True): fig = plt.figure(figsize=plot.mpl_papersize('a4', 'landscape')) tap_color_annot = (0.35, 0.35, 0.25) tap_color_edge = (0.85, 0.85, 0.80) waveform_color = scolor('aluminium5') misfit_color = scolor('scarletred1') ncomps = 3 k = 0 nstations = len(stations) ntraces = nstations * ncomps i = 0 for st in stations: for comp in st.channels: for tr in traces: if tr.station == st.station: if comp.name == tr.channel: # tr.downsample_to(0.05) # tr.highpass(4, 0.01) # tr.lowpass(4, 0.2) dtrace = tr i = i + 1 target = st tmin_fit = dtrace.tmin tmax_fit = dtrace.tmax tfade_taper = 1. / 0.2 taper = trace.CosTaper(tmin_fit - 20, tmin_fit, tmax_fit, tmax_fit + 30) k = k + 1 axes2 = fig.add_subplot(nstations / 3, nstations / 3, k) space = 0.5 space_factor = 1.0 + space axes2.set_axis_off() axes2.set_ylim(-1.05 * space_factor, 1.05) axes = axes2.twinx() axes.set_axis_off() bw_filter = trace.ButterworthResponse(corner=2, order=4, type='low') setup = trace.MisfitSetup(description='setup', norm=2, taper=taper, filter=bw_filter, domain='time_domain') abs_tr = dtrace.copy() abs_tr.set_ydata(abs(dtrace.get_ydata())) plot_cc(axes2, abs_tr, space, 0., num.max(abs_tr.get_ydata()), fc=light(misfit_color, 0.3), ec=misfit_color, zorder=4) plot_trace(axes, dtrace, color=waveform_color, lw=0.5, zorder=5) tmarks = [dtrace.tmin, dtrace.tmax] for tmark in tmarks: axes2.plot([tmark, tmark], [-0.9, 0.1], color=tap_color_annot) for tmark, text, ha, va in [ (tmarks[0], '$\,$ ' + str_duration(tmarks[0]), 'left', 'bottom'), (tmarks[1], '$\Delta$ ' + str_duration(tmarks[1] - tmarks[0]), 'right', 'bottom') ]: axes2.annotate(text, xy=(tmark, -0.9), xycoords='data', xytext=(fontsize * 0.4 * [-1, 1][ha == 'left'], fontsize * 0.2), textcoords='offset points', ha=ha, va=va, color=tap_color_annot, fontsize=fontsize, zorder=10) if picks is not None: for stp in picks["phases"]: phases_station = [] picks_station = [] if st.station == stp["station"]: phases_station.append(str(stp["phase"])) picks_station.append(event.time + float(stp["pick"])) picks_station.append(event.time) tmarks = picks_station for tmark in tmarks: axes2.plot([tmark, tmark], [-1, 1.], color="blue") for tmark, text, ha, va in [(tmarks, phases_station, 'left', 'bottom')]: try: axes2.annotate( text[0], xy=(tmark[0], -1.2), xycoords='data', xytext=(8 * 0.4 * [-1, 1][ha == 'left'], 8 * 0.2), textcoords='offset points', ha=ha, va=va, color=tap_color_annot, fontsize=8, zorder=10) except: pass infos = [] infos.append(target.network + "." + target.station + "." + dtrace.channel) dist = event.distance_to(target) azi = event.azibazi_to(target)[0] infos.append(str_dist(dist)) infos.append(u'%.0f\u00B0' % azi) axes2.annotate('\n'.join(infos), xy=(0., 1.), xycoords='axes fraction', xytext=(2., 2.), textcoords='offset points', ha='left', va='top', fontsize=fontsize, fontstyle='normal') if i / nstations == 1 or i / nstations == 2 or i / nstations == 3: fig.savefig(savedir + "waveforms_%s.png" % str(int(i / nstations)), dpi=100) if show is True: plt.show() else: plt.close() fig = plt.figure(figsize=plot.mpl_papersize('a4', 'landscape')) k = 0