Browse Source

trainola: suppress peaks if larger ones are nearby

Might fix the problem Mark noticed where turn-off transients
are erroneously matching the drop that follows startup transients.
tags/nilmtools-1.4.4^0
Jim Paris 8 years ago
parent
commit
33c3586bea
1 changed files with 40 additions and 11 deletions
  1. +40
    -11
      nilmtools/trainola.py

+ 40
- 11
nilmtools/trainola.py View File

@@ -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


Loading…
Cancel
Save