Skip to content

Commit

Permalink
Merge pull request #100 from eqcorrscan/cjhopp-declust-patch
Browse files Browse the repository at this point in the history
 Add 'metric' argument to Party.decluster()
  • Loading branch information
cjhopp authored Jun 19, 2017
2 parents 70c0da6 + b07b266 commit f1e0a9a
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 17 deletions.
34 changes: 26 additions & 8 deletions eqcorrscan/core/match_filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -410,18 +410,23 @@ def rethreshold(self, new_threshold, new_threshold_type='MAD'):
family.catalog = Catalog([d.event for d in family])
return self

def decluster(self, trig_int, timing='detect'):
def decluster(self, trig_int, timing='detect', metric='avg_cor'):
"""
De-cluster a Party of detections by enforcing a detection separation.
De-clustering occurs between events detected by different (or the same)
templates. If multiple detections occur within trig_int then the
detection with the highest average single-channel correlation
(calculated as the cross-correlation sum / number of channels used in
detection) will be maintained.
preferred detection will be determined by the metric argument. This
can be either the average single-station correlation coefficient which
is calculated as Detection.detect_val / Detection.no_chans, or the
raw cross channel correlation sum which is simply Detection.detect_val.
:type trig_int: float
:param trig_int: Minimum detection separation in seconds.
:type metric: str
:param metric: What metric to sort peaks by. Either 'avg_cor' which
takes the single station average correlation or 'cor_sum' which
takes the total correlation sum across all channels.
:type timing: str
:param timing:
Either 'detect' or 'origin' to decluster based on either the
Expand All @@ -444,11 +449,24 @@ def decluster(self, trig_int, timing='detect'):
for fam in self.families:
all_detections.extend(fam.detections)
if timing == 'detect':
detect_info = [(d.detect_time, d.detect_val)
for d in all_detections]
if metric == 'avg_cor':
detect_info = [(d.detect_time, d.detect_val / d.no_chans)
for d in all_detections]
elif metric == 'cor_sum':
detect_info = [(d.detect_time, d.detect_val)
for d in all_detections]
else:
raise MatchFilterError('metric is not cor_sum or avg_cor')
elif timing == 'origin':
detect_info = [(_get_origin(d.event).time, d.detect_val)
for d in all_detections]
if metric == 'avg_cor':
detect_info = [(_get_origin(d.event).time,
d.detect_val / d.no_chans)
for d in all_detections]
elif metric == 'cor_sum':
detect_info = [(_get_origin(d.event).time, d.detect_val)
for d in all_detections]
else:
raise MatchFilterError('metric is not cor_sum or avg_cor')
else:
raise MatchFilterError('timing is not detect or origin')
min_det = sorted([d[0] for d in detect_info])[0]
Expand Down
24 changes: 15 additions & 9 deletions eqcorrscan/tests/match_filter_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -696,15 +696,21 @@ def test_party_add(self):
def test_party_decluster(self):
"""Test the decluster method on party."""
for trig_int in [40, 15, 3600]:
declustered = self.party.copy().decluster(trig_int=trig_int)
declustered_dets = [d for family in declustered
for d in family.detections]
for det in declustered_dets:
time_difs = [abs(det.detect_time - d.detect_time)
for d in declustered_dets]
for dif in time_difs:
if dif != 0:
self.assertTrue(dif > trig_int)
for metric in ['avg_cor', 'cor_sum']:
declust = self.party.copy().decluster(trig_int=trig_int,
metric=metric)
declustered_dets = [d for family in declust
for d in family.detections]
for det in declustered_dets:
time_difs = [abs(det.detect_time - d.detect_time)
for d in declustered_dets]
for dif in time_difs:
if dif != 0:
self.assertTrue(dif > trig_int)
with self.assertRaises(MatchFilterError):
self.party.copy().decluster(trig_int=trig_int,
timing='origin',
metric=metric)

def test_party_lag_calc(self):
"""Test the lag-calc method on Party objects."""
Expand Down

0 comments on commit f1e0a9a

Please sign in to comment.