|
|
@@ -106,9 +106,14 @@ class Exemplar(object): |
|
|
|
|
|
|
|
def peak_detect(data, delta): |
|
|
|
"""Simple min/max peak detection algorithm, taken from my code |
|
|
|
in the disagg.m from the 10-8-5 paper""" |
|
|
|
mins = []; |
|
|
|
maxs = []; |
|
|
|
in the disagg.m from the 10-8-5 paper. |
|
|
|
|
|
|
|
Returns an array of peaks: each peak is a tuple |
|
|
|
(n, p, is_max) |
|
|
|
where n is the row number in 'data', and p is 'data[n]', |
|
|
|
and is_max is True if this is a maximum, False if it's a minimum, |
|
|
|
""" |
|
|
|
peaks = []; |
|
|
|
cur_min = (None, np.inf) |
|
|
|
cur_max = (None, -np.inf) |
|
|
|
lookformax = False |
|
|
@@ -119,15 +124,15 @@ def peak_detect(data, delta): |
|
|
|
cur_min = (n, p) |
|
|
|
if lookformax: |
|
|
|
if p < (cur_max[1] - delta): |
|
|
|
maxs.append(cur_max) |
|
|
|
peaks.append((cur_max[0], cur_max[1], True)) |
|
|
|
cur_min = (n, p) |
|
|
|
lookformax = False |
|
|
|
else: |
|
|
|
if p > (cur_min[1] + delta): |
|
|
|
mins.append(cur_min) |
|
|
|
peaks.append((cur_min[0], cur_min[1], False)) |
|
|
|
cur_max = (n, p) |
|
|
|
lookformax = True |
|
|
|
return (mins, maxs) |
|
|
|
return peaks |
|
|
|
|
|
|
|
def timestamp_to_short_human(timestamp): |
|
|
|
dt = datetime_tz.datetime_tz.fromtimestamp(timestamp_to_seconds(timestamp)) |
|
|
@@ -164,11 +169,35 @@ def trainola_matcher(data, interval, args, insert_func, final_chunk): |
|
|
|
|
|
|
|
# Find the peaks using the column with the largest amplitude |
|
|
|
biggest = e.scale.index(max(e.scale)) |
|
|
|
peaks_minmax = peak_detect(corrs[biggest], 0.1) |
|
|
|
peaks = [ p[0] for p in peaks_minmax[1] ] |
|
|
|
|
|
|
|
# Now look at every peak |
|
|
|
for row in peaks: |
|
|
|
peaks = peak_detect(corrs[biggest], 0.1) |
|
|
|
|
|
|
|
# To try to reduce false positives, discard peaks where |
|
|
|
# there's a higher-magnitude peak (either min or max) within |
|
|
|
# one exemplar width nearby. |
|
|
|
good_peak_locations = [] |
|
|
|
for (i, (n, p, is_max)) in enumerate(peaks): |
|
|
|
if not is_max: |
|
|
|
continue |
|
|
|
ok = True |
|
|
|
# check up to 'e.count' rows before this one |
|
|
|
j = i-1 |
|
|
|
while ok and j >= 0 and peaks[j][0] > (n - e.count): |
|
|
|
if abs(peaks[j][1]) > abs(p): |
|
|
|
ok = False |
|
|
|
j -= 1 |
|
|
|
|
|
|
|
# check up to 'e.count' rows after this one |
|
|
|
j = i+1 |
|
|
|
while ok and j < len(peaks) and peaks[j][0] < (n + e.count): |
|
|
|
if abs(peaks[j][1]) > abs(p): |
|
|
|
ok = False |
|
|
|
j += 1 |
|
|
|
|
|
|
|
if ok: |
|
|
|
good_peak_locations.append(n) |
|
|
|
|
|
|
|
# Now look at all good peaks |
|
|
|
for row in good_peak_locations: |
|
|
|
# Correlation for each column must be close enough to 1. |
|
|
|
for (corr, scale) in zip(corrs, e.scale): |
|
|
|
# The accepted distance from 1 is based on the relative |
|
|
|