finish mov_avg
This commit is contained in:
@@ -46,6 +46,8 @@ class FilterDevApp(tk.Tk):
|
|||||||
self.canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH)
|
self.canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH)
|
||||||
NavigationToolbar2Tk(self.canvas, self.frame)
|
NavigationToolbar2Tk(self.canvas, self.frame)
|
||||||
|
|
||||||
|
self.focus_force()
|
||||||
|
|
||||||
def update_plot(self):
|
def update_plot(self):
|
||||||
if self.filter is None:
|
if self.filter is None:
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -3,4 +3,11 @@ SERVICE_UUID = "9f0dfdb2-e978-494c-8f15-68dbe8d28672"
|
|||||||
MILLIS_UUID = "abb92561-a809-453c-8c7c-71d3fff5b86e"
|
MILLIS_UUID = "abb92561-a809-453c-8c7c-71d3fff5b86e"
|
||||||
WEIGHT_UUID = "123e4567-e89b-12d3-a456-426614174000"
|
WEIGHT_UUID = "123e4567-e89b-12d3-a456-426614174000"
|
||||||
|
|
||||||
DEFAULT_CALIB = 307333.83
|
DEFAULT_CALIB = 307333.83
|
||||||
|
|
||||||
|
MOV_AVG_DEFAULTS = {
|
||||||
|
"window_size": 10,
|
||||||
|
"decimals": 1,
|
||||||
|
"reset_threshold": 0.5,
|
||||||
|
"ignore_samples": 2
|
||||||
|
}
|
||||||
@@ -33,7 +33,7 @@ class Filter:
|
|||||||
calib_factor = 100. / float(self.calib_entry.get())
|
calib_factor = 100. / float(self.calib_entry.get())
|
||||||
df = self.device.data
|
df = self.device.data
|
||||||
|
|
||||||
df = df[df['weights'] < 10e9]
|
df = df[df['weights'] < 10e8]
|
||||||
df['timestamps'] -= df['timestamps'].min()
|
df['timestamps'] -= df['timestamps'].min()
|
||||||
|
|
||||||
df['filtered'], df['filtered_calib'] = self.filter(df, calib_factor)
|
df['filtered'], df['filtered_calib'] = self.filter(df, calib_factor)
|
||||||
|
|||||||
@@ -1,21 +1,58 @@
|
|||||||
from tkinter import ttk
|
from statistics import mean
|
||||||
|
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
|
|
||||||
from .base import Filter
|
from .base import Filter
|
||||||
from ..gui import Slider
|
from ..gui import Slider
|
||||||
|
from ..config import MOV_AVG_DEFAULTS
|
||||||
|
|
||||||
class MovAvg(Filter):
|
class MovAvg(Filter):
|
||||||
|
|
||||||
def init_params(self, toolbar):
|
def init_params(self, toolbar):
|
||||||
self.param_map = {
|
self.param_map = {
|
||||||
"window_size": Slider(toolbar, "Window Size", 1, 100, 10, self.callback),
|
"window_size": Slider(toolbar, "Window Size", 1, 100,
|
||||||
"decimals": Slider(toolbar, "Decimals", 1, 5, 1, self.callback),
|
MOV_AVG_DEFAULTS['window_size'],
|
||||||
# "reset_threshold": Slider(self.toolbar, "Reset Threshold", 0.001, 0.1, 0.1, self.update),
|
self.callback),
|
||||||
|
"decimals": Slider(toolbar, "Decimals", 1, 5,
|
||||||
|
MOV_AVG_DEFAULTS['decimals'],
|
||||||
|
self.callback),
|
||||||
|
"reset_threshold": Slider(toolbar, "Reset Threshold", 0.01, 1,
|
||||||
|
MOV_AVG_DEFAULTS['reset_threshold'],
|
||||||
|
self.callback, float),
|
||||||
|
"ignore_samples": Slider(toolbar, "Ignore Samples before reset", 1, 10,
|
||||||
|
MOV_AVG_DEFAULTS['ignore_samples'],
|
||||||
|
self.callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
def filter(self, df: pd.DataFrame, calib_factor: float) -> pd.Series:
|
def filter(self, df: pd.DataFrame, calib_factor: float) -> pd.Series:
|
||||||
params = self._get_params()
|
params = self._get_params()
|
||||||
mov_avg = df['weights'].rolling(window=int(params['window_size'])).mean()
|
reset_threshold = params['reset_threshold'] / calib_factor
|
||||||
|
|
||||||
|
window = []
|
||||||
|
mov_avg = []
|
||||||
|
ignored_samples = 0
|
||||||
|
|
||||||
|
for w in df['weights']:
|
||||||
|
if len(window) < params['window_size']:
|
||||||
|
window.append(w)
|
||||||
|
mov_avg.append(mean(window))
|
||||||
|
else:
|
||||||
|
out_of_threshold = abs(mov_avg[-1] - w) > reset_threshold
|
||||||
|
if out_of_threshold and\
|
||||||
|
ignored_samples < params['ignore_samples']:
|
||||||
|
ignored_samples += 1
|
||||||
|
mov_avg.append(mov_avg[-1])
|
||||||
|
|
||||||
|
elif out_of_threshold:
|
||||||
|
ignored_samples = 0
|
||||||
|
window = [w]
|
||||||
|
mov_avg.append(w)
|
||||||
|
|
||||||
|
else:
|
||||||
|
ignored_samples = 0
|
||||||
|
window.append(w)
|
||||||
|
mov_avg.append(mean(window))
|
||||||
|
|
||||||
|
mov_avg = pd.Series(mov_avg)
|
||||||
mov_avg_calib = (mov_avg * calib_factor).round(int(params['decimals']))
|
mov_avg_calib = (mov_avg * calib_factor).round(int(params['decimals']))
|
||||||
return mov_avg, mov_avg_calib
|
return mov_avg, mov_avg_calib
|
||||||
|
|||||||
@@ -6,8 +6,10 @@ class Slider:
|
|||||||
label_text,
|
label_text,
|
||||||
from_, to,
|
from_, to,
|
||||||
initial_value,
|
initial_value,
|
||||||
command):
|
command,
|
||||||
|
dtype=int):
|
||||||
self.command = command
|
self.command = command
|
||||||
|
self.dtype = dtype
|
||||||
|
|
||||||
self.label = ttk.Label(parent, text=f"{label_text}: {int(initial_value)}")
|
self.label = ttk.Label(parent, text=f"{label_text}: {int(initial_value)}")
|
||||||
|
|
||||||
@@ -16,7 +18,8 @@ class Slider:
|
|||||||
|
|
||||||
def update(self, event=None):
|
def update(self, event=None):
|
||||||
value = self.slider.get()
|
value = self.slider.get()
|
||||||
self.label.config(text=f"{self.label.cget('text').split(':')[0]}: {int(value)}")
|
value_str = int(value) if self.dtype == int else f'{value:.02f}'
|
||||||
|
self.label.config(text=f"{self.label.cget('text').split(':')[0]}: {value_str}")
|
||||||
self.command()
|
self.command()
|
||||||
|
|
||||||
def get_value(self):
|
def get_value(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user