Commit b79a2036 authored by Marius Kriegerowski's avatar Marius Kriegerowski
Browse files

Merge branch 'master' of gitext.gfz-potsdam.de:heimann/lassie

parents 8b56a371 1f495736
......@@ -197,4 +197,8 @@ After the detection has finished have a look at the results using Pyrocko's
```bash
lassie snuffle config.yaml
```
Waveform data are loaded together with station meta data and detections.
Waveform data are loaded together with station meta data and detections as
event markers.
Rigtht-click and select `Panels->Lassie investigate` to open a snuffling which
can be used to re-run the detection on the `SMAX` trace with a different
threshold.
......@@ -6,3 +6,4 @@ from lassie.ifc import * # noqa
from lassie.core import * # noqa
from lassie.plot import * # noqa
from lassie.config import * # noqa
from lassie.snuffling import * # noqa
......@@ -2,6 +2,7 @@ import sys
import os
import logging
import os.path as op
import shutil
import numpy as num
......@@ -53,6 +54,8 @@ def scan(
if op.exists(config.detections_path):
if force:
os.unlink(config.detections_path)
shutil.rmtree('stackmax')
os.mkdir('stackmax')
else:
raise common.LassieError(
'detections file already exists: %s' % config.detections_path)
......@@ -250,9 +253,9 @@ def scan(
if stop_after_first:
return
tr_stackmax.chop(wmin, wmax)
io.save([tr_stackmax], 'stackmax/trace_%(tmin)s.mseed')
io.save([tr_stackmax], 'stackmax/trace_%(tmin_ms)s.mseed')
__all__ = [
......
......@@ -298,42 +298,11 @@ def plot_detection(
plt.show()
def snuffle(config):
receivers = config.get_receivers()
stations = set()
for r in receivers:
n, s, l = r.codes[:3]
stations.add(model.Station(lat=r.lat, lon=r.lon,
network=n, station=s, location=l))
markers = []
detections_path = config.detections_path
with open(config.detections_path, 'r') as f:
for line in f.readlines():
data = line.split()
i, t_d, t_t, apeak, latpeak, lonpeak, xpeak, ypeak, zpeak = data
lat, lon = orthodrome.ne_to_latlon(
float(latpeak), float(lonpeak), float(ypeak), float(xpeak))
t = util.str_to_time("%s %s" % (t_d, t_t))
label = "%s-%s" % (i, apeak)
e = model.Event(lat=lat, lon=lon, depth=float(zpeak)*1000.,
name=label, time=t)
m = gui_util.EventMarker(e)
markers.append(m)
trs = []
paths = config.data_paths
paths.append('stackmax')
p = pile.make_pile(paths=paths, fileformat='detect')
snuffler.snuffle(p, markers=markers, stations=stations)
__all__ = [
'map_geometry',
'map_gmt',
'plot_detection',
'plot_geometry_carthesian',
'plot_receivers',
'snuffle',
]
import copy
import numpy as num
from pyrocko import util, gui_util, model, orthodrome, pile, snuffler
from pyrocko.snuffling import Snuffling, Param, Choice, Switch
kind_default = '1 (green)'
def detections_to_event_markers(fn_detections):
markers = []
with open(fn_detections, 'r') as f:
for line in f.readlines():
data = line.split()
i, t_d, t_t, apeak, latpeak, lonpeak, xpeak, ypeak, zpeak = data
lat, lon = orthodrome.ne_to_latlon(
float(latpeak), float(lonpeak), float(ypeak), float(xpeak))
t = util.str_to_time("%s %s" % (t_d, t_t))
label = "%s-%s" % (i, apeak)
e = model.Event(lat=lat, lon=lon, depth=float(zpeak)*1000.,
name=label, time=t)
m = gui_util.EventMarker(e, kind=int(kind_default[0]))
markers.append(m)
return markers
class LassieSnuffling(Snuffling):
@property
def __doc__(self):
s = '''
<html>
<head>
<style type="text/css">
body { margin-left:10px };
</style>
</head>
<body>
<h2 style="test-align:center"> Scrutinize Lassie Performance and
Re-Detect</h2>
<p>
Adjust the detector <i>threshold</i>, press <i>run</i>. From every
instant, where the signal rises above <i>threshold</i>, a time length
of <i>tsearch</i> seconds is searched for a maximum. Detections are
added as event markers to the viewer. </p>
<p>
If you want to save the updated detections, it might be helpful to use
the marker table
(see <a href="http://pyrocko.org/v0.3/snuffler_tutorial.html"> Snuffler
Tutorial</a> at the bottom) to sort all markers by their kind.
</p>
<h3 style="test-align:center"> Compare Lassie Detections with Reference
Catalog</h3>
<p>
%s
</p>
</body>
</html>
''' % self.show_comparison.__doc__
return s
def __init__(self):
Snuffling.__init__(self)
self.config = None
def setup(self):
if self.config:
detector_default = self.config.detector_threshold
else:
detector_default = 100.
self.set_name('Lassie investigate')
self.add_parameter(Param('Tsearch', 'tsearch', 1., 0.01, 100))
self.add_parameter(Param(
'Detector threshold', 'detector_threshold', detector_default, 100.,
10000.))
self.add_parameter(Param(
'Detector deadtime [s]', 'detector_deadtime', 0, 0., 20.,
low_is_none=True))
self.add_parameter(Switch('Level Trace', 'level_trace', False))
self.add_parameter(Switch(
'Hold comparison figure', 'hold_figure', False))
self.add_parameter(Choice(
'new marker kind', 'marker_kind', kind_default,
['1 (green)', '2 (blue)', '3 (orange)', '4 (purple)', '5 (brown)',
'0 (red)']))
self.add_trigger('load reference', self.load_comparison)
self.add_trigger('show comparison', self.show_comparison)
self.add_trigger('remove comparison', self.remove_comparison)
# self.add_trigger('read Lassie config', self.fail)
self.set_live_update(True)
self.markers_compare = []
self.fig = None
def mycleanup(self):
viewer = self.get_viewer()
viewer.release_data(self._tickets)
viewer.remove_markers(self.detections)
self._tickets = []
self._markers = []
def call(self):
self.mycleanup()
self.detections = []
for traces in self.chopper_selected_traces(
trace_selector=lambda x: x.station == "SMAX",
fallback=True):
for tr_stackmax in traces:
tpeaks, apeaks = tr_stackmax.peaks(
self.detector_threshold, self.tsearch,
deadtime=self.detector_deadtime)
if self.level_trace:
ltrace = tr_stackmax.copy(data=False)
ltrace.set_ydata(
num.ones(
tr_stackmax.data_len()) * self.detector_threshold)
self.add_trace(ltrace)
for t, a in zip(tpeaks, apeaks):
e = model.Event(time=t, name=str(a))
self.detections.append(
gui_util.EventMarker(
event=e, kind=int(self.marker_kind[0])))
self.add_markers(self.detections)
if self.hold_figure:
self.show_comparison()
def load_comparison(self):
'''
For comparison in synthetic tests.
'''
fn = self.input_filename(caption='Select an event catalog')
kind_compare = 4
compare_events = model.load_events(fn)
markers = [gui_util.EventMarker(event=e, kind=kind_compare) for e in
compare_events]
self.markers_compare = markers
self.add_markers(self.markers_compare)
def remove_comparison(self):
'''Remove comparison markers from viewer.'''
self.get_viewer().remove_markers(self.markers_compare)
def filter_visible(self, markers):
vtmin, vtmax = self.get_viewer().get_time_range()
return filter(lambda x: vtmin < x.tmin < vtmax, markers)
def show_comparison(self):
'''
Iterates through reference catalog and searches for lassie detection
candidates in a time window of +- 1.5 seconds around the reference.
If multiple candidates are available selects the first as the matching
lassie detection for this reference.
This option requires the catalog to contain only pyrocko.model.Event
instances.
'''
scan_time = 3.
select_by = 'first'
if not self.markers_compare:
self.fail('No catalog to compare to')
markers_compare = self.filter_visible(self.markers_compare)
not_detected = []
detections_success = []
detections = copy.deepcopy(self.filter_visible(self.detections))
for i_m, mcompare in enumerate(markers_compare):
detection_times = num.array([d.tmin for d in detections])
i_want = num.where(num.abs(detection_times - mcompare.tmin) \
< (scan_time / 2.))[0]
if len(i_want) == 0:
not_detected.append(mcompare)
continue
candidates = [detections[i] for i in i_want]
# if select_by == 'first':
matched_marker = min(
candidates, key=lambda x: x.get_event().time)
# elif select_by == 'strongest':
# matched_marker = max(
# candidates, key=lambda x: float(x.get_event().name))
detections_success.append((matched_marker, i_m))
for c in candidates:
detections.remove(c)
if self.hold_figure and self.fig:
self.fig.clf()
else:
self.fig = self.figure()
ax = self.fig.add_subplot(111)
compare_events = map(lambda x: x.get_event(), markers_compare)
associated_events = [compare_events[a[1]] for a in detections_success]
magnitudes = [e.get_event().magnitude for e in markers_compare]
detected_magnitudes = [e.magnitude for e in associated_events]
bins = num.linspace(-1, max(magnitudes), 30)
ax.hist([detected_magnitudes, magnitudes], bins,
label=['Lassie', 'Reference'], alpha=0.7)
n_leftover_detections = len(detections)
n_undetected = len(not_detected)
ax.text(
0.05, 0.95, 'Other detections: %s\nNot detected: %s (%1.1f %%)' %
(n_leftover_detections, n_undetected,
(float(n_undetected)/len(markers_compare)*100.)),
transform=ax.transAxes)
ax.set_xlabel('Magnitude')
ax.set_ylabel('N detections')
ax.legend()
self.fig.canvas.draw()
def __snufflings__():
return [LassieSnuffling()]
def snuffle(config):
global _lassie_config
_lassie_config = copy.deepcopy(config)
def load_snuffling(win):
s = LassieSnuffling()
s.config = _lassie_config
s.setup()
win.pile_viewer.viewer.add_snuffling(s, reloaded=True)
s.detections = detections_to_event_markers(
_lassie_config.detections_path)
s.add_markers(s.detections)
receivers = config.get_receivers()
stations = set()
for r in receivers:
n, s, l = r.codes[:3]
stations.add(model.Station(lat=r.lat, lon=r.lon,
network=n, station=s, location=l))
paths = config.data_paths
paths.append('stackmax')
p = pile.make_pile(paths=paths, fileformat='detect')
snuffler.snuffle(p, stations=stations,
launch_hook=load_snuffling)
__all__ = [
'snuffle']
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment