You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
195 lines
6.7 KiB
Python
195 lines
6.7 KiB
Python
import numpy as num
|
|
from pyrocko.gui.snuffling import Snuffling, Param, Choice, Switch
|
|
from pyrocko import orthodrome as ortho
|
|
from pyrocko import util
|
|
|
|
|
|
def station_key(tr):
|
|
return (tr.network, tr.station, tr.location)
|
|
|
|
|
|
class TracePlotter(Snuffling):
|
|
'''
|
|
<html>
|
|
<body>
|
|
<head>
|
|
<style type="text/css">
|
|
body { margin-left:10px };
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<h1 align="center">Plot Traces with Reduced Velocity</h1>
|
|
<p>
|
|
Use the <b>Reduction Velocity</b> to shift traces dependent on epicentral
|
|
distance to the activated event.
|
|
If <b>Auto-Run</b> is activated the figure is updated automatically when
|
|
modifying a value on the panel.<br>
|
|
When <b>saving a figure</b> accepted file endings are 'eps', 'png', 'jpeg',
|
|
'pdf', and 'svg'.
|
|
</body>
|
|
</html>
|
|
'''
|
|
def setup(self):
|
|
self.set_name("Plot Waveforms")
|
|
self.add_parameter(
|
|
Switch('Include Selected Markers', 'add_markers', False))
|
|
|
|
self.add_parameter(Switch('Fill positive', 'fill_between', False))
|
|
self.add_parameter(
|
|
Param(
|
|
'Reduction Velocity [km/s]',
|
|
't_red', 20., 1., 20., high_is_none=True))
|
|
|
|
self.add_parameter(Param(
|
|
'Amplitude Gain', 'yscale', 1., 0.1, 100.))
|
|
self.add_parameter(Choice(
|
|
'Pre-scale Amplitudes', 'ampl_scaler', 'trace min/max',
|
|
['total min/max', 'trace min/max', 'standard deviation']))
|
|
self.add_trigger('Save Last Figure', self.save)
|
|
self.set_live_update(False)
|
|
self.fig = None
|
|
|
|
def call(self):
|
|
|
|
self.cleanup()
|
|
viewer = self.get_viewer()
|
|
|
|
vtmin, vtmax = viewer.get_time_range()
|
|
pile = self.get_pile()
|
|
traces = [
|
|
tr for tr in pile.chopper(
|
|
tmin=vtmin, tmax=vtmax, trace_selector=viewer.trace_selector)]
|
|
|
|
event, stations = self.get_active_event_and_stations()
|
|
traces = [tr for trs in traces for tr in trs]
|
|
|
|
trace_nsls = {station_key(tr) for tr in traces}
|
|
stations = [s for s in self.get_stations() if
|
|
s.nsl() in trace_nsls]
|
|
|
|
distances = [
|
|
ortho.distance_accurate50m(event, s)/1000. for s in stations]
|
|
distances = dict(zip([s.nsl() for s in stations], distances))
|
|
|
|
matching_traces = [x for x in traces if util.match_nslc(
|
|
self.get_station_patterns(stations), x.nslc_id)]
|
|
if self.add_markers:
|
|
markers = self.get_markers()
|
|
markers = [
|
|
m for m in markers if m.tmax <= vtmax and
|
|
m.tmin >= vtmin and m.selected]
|
|
|
|
markers = dict(zip([tuple(m.nslc_ids) for m in markers], markers))
|
|
|
|
if self.fig is None or self.fframe.closed or not self._live_update:
|
|
self.fframe = self.pylab(get='figure_frame')
|
|
self.fig = self.fframe.gcf()
|
|
|
|
if self._live_update:
|
|
self.fig.clf()
|
|
|
|
maxd = max(distances.values())
|
|
mind = min(distances.values())
|
|
|
|
ymin = mind-0.06*(maxd-mind)
|
|
ymax = maxd+0.06*(maxd-mind)
|
|
ax = self.fig.add_subplot(111)
|
|
xmin = 9E9
|
|
xmax = -xmin
|
|
texts = []
|
|
manual_scale = 0.1 * (maxd-mind)*self.yscale
|
|
|
|
if self.ampl_scaler == 'total min/max':
|
|
max_trace = max(
|
|
matching_traces, key=lambda x: max(abs(x.get_ydata())))
|
|
|
|
tr_maxy = max(abs(max_trace.get_ydata()))
|
|
ampl_scale = float(tr_maxy)
|
|
|
|
for tr in matching_traces:
|
|
if viewer.highpass:
|
|
tr.highpass(4, viewer.highpass)
|
|
if viewer.lowpass:
|
|
tr.lowpass(4, viewer.lowpass)
|
|
if tr.nslc_id[:3] not in distances.keys():
|
|
continue
|
|
|
|
if self.t_red:
|
|
red = distances[tr.nslc_id[:3]]/self.t_red
|
|
else:
|
|
red = 0.
|
|
y_pos = distances[tr.nslc_id[:3]]
|
|
xdata = tr.get_xdata()-red-event.time
|
|
xmin = min(xmin, min(xdata))
|
|
xmax = max(xmax, max(xdata))
|
|
tr_ydata = tr.get_ydata()
|
|
if self.ampl_scaler == 'trace min/max':
|
|
ampl_scale = float(max(abs(tr_ydata)))
|
|
elif self.ampl_scaler == 'standard deviation':
|
|
ampl_scale = float(num.std(tr_ydata))
|
|
ydata = (tr_ydata/ampl_scale * manual_scale) + y_pos
|
|
ax.plot(xdata, ydata, c='black', linewidth=0.2)
|
|
|
|
if self.fill_between:
|
|
ax.fill_between(
|
|
xdata, y_pos, ydata, where=ydata > y_pos, color='black',
|
|
alpha=0.5)
|
|
|
|
texts.append(
|
|
ax.text(
|
|
xmax, y_pos, '%s.%s.%s.%s' % tr.nslc_id,
|
|
horizontalalignment='right', fontsize=6.))
|
|
|
|
if self.add_markers:
|
|
for ids, m in markers.items():
|
|
if m.match_nslc(tr.nslc_id) or ids == ():
|
|
c = m.select_color(m.color_b)
|
|
c = [ci/255. for ci in c]
|
|
t = m.tmin
|
|
x = [t-red-event.time, t-red-event.time]
|
|
y = [y_pos-(maxd-mind)*0.025, y_pos+(maxd-mind)*0.025]
|
|
ax.plot(x, y, linewidth=1, color=c)
|
|
label = m.get_label()
|
|
if not label:
|
|
label = ''
|
|
|
|
ax.text(x[1]-x[1]*0.005, y[1], label, color=c,
|
|
fontsize=6,
|
|
verticalalignment='top',
|
|
horizontalalignment='right')
|
|
|
|
for txt in texts:
|
|
txt.set_x(xmax)
|
|
|
|
vred_str = '= '+str(round(self.t_red, 2)) + 'km/s' if self.t_red \
|
|
else 'off'
|
|
|
|
ax.text(0.5, 0.01, 'time window: %s - %s | Reduction velocity %s' %
|
|
(util.tts(vtmin), util.tts(vtmax), vred_str),
|
|
verticalalignment='bottom', horizontalalignment='center',
|
|
transform=self.fig.transFigure)
|
|
|
|
ax.set_ylim([ymin, ymax])
|
|
ax.set_xlim([xmin, xmax])
|
|
ax.set_ylabel('Distance [km]')
|
|
ax.set_xlabel('(red.) Time [s]')
|
|
self.fig.canvas.draw()
|
|
|
|
def save(self):
|
|
fn = self.output_filename('Select Filename', 'snuffled_traces.png')
|
|
self.fig.savefig(fn, pad_inches=0.1, bbox_inches='tight', dpi=320)
|
|
|
|
def set_center_latlon(self):
|
|
self.lat_c, self.lon_c, self.z_c = self.center_lat_lon(
|
|
self.get_stations())
|
|
|
|
self.set_parameter('lat_c', self.lat_c)
|
|
self.set_parameter('lon_c', self.lon_c)
|
|
|
|
def get_station_patterns(self, stations):
|
|
return ['%s.%s.%s.*' % s.nsl() for s in stations]
|
|
|
|
|
|
def __snufflings__():
|
|
return [TracePlotter()]
|