добавил подсчет по линейности

fft
Sergey Revyakin 2 weeks ago
parent 9d3fc41c4b
commit 04899fbb0d

@ -48,8 +48,7 @@ class DataBuffer:
# Допускаем небольшой обратный ход, чтобы не сбрасываться от микрошума.
self.dbfs_max_backstep_db = float(os.getenv('dbfs_max_backstep_db', 0.25))
# Минимум подряд "плавных" шагов перед учетом как устойчивого роста.
self.dbfs_min_trend_steps = int(os.getenv('dbfs_min_trend_steps', max(1, self.num_for_alarm)))
self.freq_tag = '' if freq_tag is None else str(freq_tag)
suffix = f'_{self.freq_tag}' if self.freq_tag else ''
@ -58,6 +57,12 @@ class DataBuffer:
self.mad_k_on = float(os.getenv('mad_k_on' + suffix, os.getenv('mad_k_on', 5.0)))
self.mad_k_off = float(os.getenv('mad_k_off' + suffix, os.getenv('mad_k_off', 2.5)))
self.mad_eps = float(os.getenv('mad_eps' + suffix, os.getenv('mad_eps', 0.05)))
self.dbfs_linear_offset_db = float(
os.getenv('dbfs_linear_offset_db' + suffix, os.getenv('dbfs_linear_offset_db', 0.0))
)
self.dbfs_linear_abs_median_scale = float(
os.getenv('dbfs_linear_abs_median_scale' + suffix, os.getenv('dbfs_linear_abs_median_scale', 0.0))
)
def get_buffer(self):
return self.buffer
@ -111,10 +116,14 @@ class DataBuffer:
self.buffer_medians[i] = med
self.buffer_mads[i] = float(self._calc_mad(self.buffer[i], med))
def get_linear_term(self, median_value):
median_value = float(median_value)
return self.dbfs_linear_offset_db + self.dbfs_linear_abs_median_scale * abs(median_value)
def get_threshold(self, channel_idx, k=None):
"""
Получить динамический порог в dB для канала:
threshold = median + k * MAD.
threshold = median + linear_term(median) + k * MAD.
До завершения инициализации возвращает None.
"""
if not self.check_init():
@ -123,7 +132,8 @@ class DataBuffer:
coef = self.mad_k_on if k is None else float(k)
baseline = float(self.buffer_medians[channel_idx])
mad = max(float(self.buffer_mads[channel_idx]), self.mad_eps)
return baseline + coef * mad
linear_term = self.get_linear_term(baseline)
return baseline + linear_term + coef * mad
def get_thresholds(self, k=None):
if not self.check_init():
@ -138,12 +148,18 @@ class DataBuffer:
freq_tag = self.freq_tag or 'unknown'
print(f'[threshold-update][{freq_tag}] now={now_str} updated_column={updated_column}')
for i in range(self.line_size):
baseline = float(self.buffer_medians[i])
mad = float(self.buffer_mads[i])
mad_eff = max(mad, self.mad_eps)
linear_term = self.get_linear_term(baseline)
threshold_on = self.get_threshold(i, self.mad_k_on)
threshold_off = self.get_threshold(i, self.mad_k_off)
packet_times = [self._format_ts(ts) for ts in self.buffer_timestamps[i]]
print(
f' ch={i} median={self.buffer_medians[i]:.6f} '
f'mad={self.buffer_mads[i]:.6f} '
f' ch={i} median={baseline:.6f} '
f'linear_term={linear_term:.6f} '
f'mad={mad:.6f} mad_eff={mad_eff:.6f} '
f'mad_term_on={self.mad_k_on * mad_eff:.6f} mad_term_off={self.mad_k_off * mad_eff:.6f} '
f'threshold_on={threshold_on:.6f} threshold_off={threshold_off:.6f} '
f'packet_times={packet_times}'
)
@ -222,7 +238,6 @@ class DataBuffer:
active_threshold = threshold_off if self.buffer_alarms[i] > 0 else threshold_on
exceeding = (
current >= active_threshold
and self.trend_streak[i] >= self.dbfs_min_trend_steps
)
if exceeding:

Loading…
Cancel
Save