修正幅值改变计算
This commit is contained in:
parent
40fdda6497
commit
60e245b1e3
@ -12,7 +12,6 @@
|
||||
提供数据处理前后的可视化对比,帮助理解数据变化
|
||||
绘制多条可用性趋势图,展示数据的可用区间、体动区间、低幅值区间等
|
||||
|
||||
todo: 使用mask 屏蔽无用区间
|
||||
|
||||
|
||||
# 低幅值区间规则标定与剔除
|
||||
@ -28,8 +27,10 @@ import numpy as np
|
||||
import signal_method
|
||||
import os
|
||||
from matplotlib import pyplot as plt
|
||||
|
||||
os.environ['DISPLAY'] = "localhost:10.0"
|
||||
|
||||
|
||||
def process_one_signal(samp_id, show=False):
|
||||
signal_path = list((org_signal_root_path / f"{samp_id}").glob("OrgBCG_Sync_*.txt"))
|
||||
if not signal_path:
|
||||
@ -69,12 +70,11 @@ def process_one_signal(samp_id, show=False):
|
||||
resp_data_1 = utils.downsample_signal_fast(original_signal=resp_data_0, original_fs=signal_fs, target_fs=resp_fs)
|
||||
resp_data_1 = utils.average_filter(raw_data=resp_data_1, sample_rate=resp_fs, window_size_sec=20)
|
||||
resp_data_2 = utils.butterworth(data=resp_data_1, _type=conf["resp_filter"]["filter_type"],
|
||||
low_cut=conf["resp_filter"]["low_cut"],
|
||||
high_cut=conf["resp_filter"]["high_cut"], order=conf["resp_filter"]["order"],
|
||||
sample_rate=resp_fs)
|
||||
low_cut=conf["resp_filter"]["low_cut"],
|
||||
high_cut=conf["resp_filter"]["high_cut"], order=conf["resp_filter"]["order"],
|
||||
sample_rate=resp_fs)
|
||||
print("Begin plotting signal data...")
|
||||
|
||||
|
||||
# fig = plt.figure(figsize=(12, 8))
|
||||
# # 绘制三个图raw_data、resp_data_1、resp_data_2
|
||||
# ax0 = fig.add_subplot(3, 1, 1)
|
||||
@ -116,7 +116,8 @@ def process_one_signal(samp_id, show=False):
|
||||
sampling_rate=resp_fs,
|
||||
**resp_low_amp_conf
|
||||
)
|
||||
print(f"resp_low_amp_mask_shape: {resp_low_amp_mask.shape}, num_low_amp: {np.sum(resp_low_amp_mask == 1)}, count_low_amp_positions: {len(resp_low_amp_position_list)}")
|
||||
print(
|
||||
f"resp_low_amp_mask_shape: {resp_low_amp_mask.shape}, num_low_amp: {np.sum(resp_low_amp_mask == 1)}, count_low_amp_positions: {len(resp_low_amp_position_list)}")
|
||||
else:
|
||||
resp_low_amp_mask, resp_low_amp_position_list = None, None
|
||||
print("resp_low_amp_mask is None")
|
||||
@ -129,7 +130,8 @@ def process_one_signal(samp_id, show=False):
|
||||
sampling_rate=resp_fs,
|
||||
**resp_movement_conf
|
||||
)
|
||||
print(f"resp_movement_mask_shape: {resp_movement_mask.shape}, num_movement: {np.sum(resp_movement_mask == 1)}, count_movement_positions: {len(resp_movement_position_list)}")
|
||||
print(
|
||||
f"resp_movement_mask_shape: {resp_movement_mask.shape}, num_movement: {np.sum(resp_movement_mask == 1)}, count_movement_positions: {len(resp_movement_position_list)}")
|
||||
else:
|
||||
resp_movement_mask, resp_movement_position_list = None, None
|
||||
print("resp_movement_mask is None")
|
||||
@ -144,11 +146,11 @@ def process_one_signal(samp_id, show=False):
|
||||
**resp_movement_revise_conf,
|
||||
verbose=False
|
||||
)
|
||||
print(f"After revise, resp_movement_mask_shape: {resp_movement_mask.shape}, num_movement: {np.sum(resp_movement_mask == 1)}, count_movement_positions: {len(resp_movement_position_list)}")
|
||||
print(
|
||||
f"After revise, resp_movement_mask_shape: {resp_movement_mask.shape}, num_movement: {np.sum(resp_movement_mask == 1)}, count_movement_positions: {len(resp_movement_position_list)}")
|
||||
else:
|
||||
print("resp_movement_mask revise is skipped")
|
||||
|
||||
|
||||
# 分析Resp的幅值突变区间
|
||||
resp_amp_change_conf = conf.get("resp_amp_change", None)
|
||||
if resp_amp_change_conf is not None and resp_movement_mask is not None:
|
||||
@ -159,13 +161,12 @@ def process_one_signal(samp_id, show=False):
|
||||
sampling_rate=resp_fs,
|
||||
**resp_amp_change_conf,
|
||||
verbose=True)
|
||||
print(f"amp_change_mask_shape: {resp_amp_change_mask.shape}, num_amp_change: {np.sum(resp_amp_change_mask == 1)}, count_amp_change_positions: {len(resp_amp_change_list)}")
|
||||
print(
|
||||
f"amp_change_mask_shape: {resp_amp_change_mask.shape}, num_amp_change: {np.sum(resp_amp_change_mask == 1)}, count_amp_change_positions: {len(resp_amp_change_list)}")
|
||||
else:
|
||||
resp_amp_change_mask = None
|
||||
print("amp_change_mask is None")
|
||||
|
||||
|
||||
|
||||
# 分析Bcg的低幅值区间
|
||||
bcg_low_amp_conf = conf.get("bcg_low_amp", None)
|
||||
if bcg_low_amp_conf is not None:
|
||||
@ -174,10 +175,12 @@ def process_one_signal(samp_id, show=False):
|
||||
sampling_rate=bcg_fs,
|
||||
**bcg_low_amp_conf
|
||||
)
|
||||
print(f"bcg_low_amp_mask_shape: {bcg_low_amp_mask.shape}, num_low_amp: {np.sum(bcg_low_amp_mask == 1)}, count_low_amp_positions: {len(bcg_low_amp_position_list)}")
|
||||
print(
|
||||
f"bcg_low_amp_mask_shape: {bcg_low_amp_mask.shape}, num_low_amp: {np.sum(bcg_low_amp_mask == 1)}, count_low_amp_positions: {len(bcg_low_amp_position_list)}")
|
||||
else:
|
||||
bcg_low_amp_mask, bcg_low_amp_position_list = None, None
|
||||
print("bcg_low_amp_mask is None")
|
||||
|
||||
# 分析Bcg的高幅值伪迹区间
|
||||
bcg_movement_conf = conf.get("bcg_movement", None)
|
||||
if bcg_movement_conf is not None:
|
||||
@ -186,48 +189,48 @@ def process_one_signal(samp_id, show=False):
|
||||
sampling_rate=bcg_fs,
|
||||
**bcg_movement_conf
|
||||
)
|
||||
print(f"bcg_movement_mask_shape: {bcg_movement_mask.shape}, num_movement: {np.sum(bcg_movement_mask == 1)}, count_movement_positions: {len(bcg_movement_position_list)}")
|
||||
print(
|
||||
f"bcg_movement_mask_shape: {bcg_movement_mask.shape}, num_movement: {np.sum(bcg_movement_mask == 1)}, count_movement_positions: {len(bcg_movement_position_list)}")
|
||||
else:
|
||||
bcg_movement_mask = None
|
||||
print("bcg_movement_mask is None")
|
||||
|
||||
# 分析Bcg的幅值突变区间
|
||||
if bcg_movement_mask is not None:
|
||||
bcg_amp_change_mask, bcg_amp_change_list = signal_method.position_based_sleep_recognition_v2(
|
||||
signal_data=bcg_data,
|
||||
movement_mask=bcg_movement_mask,
|
||||
sampling_rate=bcg_fs)
|
||||
print(f"bcg_amp_change_mask_shape: {bcg_amp_change_mask.shape}, num_amp_change: {np.sum(bcg_amp_change_mask == 1)}, count_amp_change_positions: {len(bcg_amp_change_list)}")
|
||||
print(
|
||||
f"bcg_amp_change_mask_shape: {bcg_amp_change_mask.shape}, num_amp_change: {np.sum(bcg_amp_change_mask == 1)}, count_amp_change_positions: {len(bcg_amp_change_list)}")
|
||||
else:
|
||||
bcg_amp_change_mask = None
|
||||
print("bcg_amp_change_mask is None")
|
||||
|
||||
|
||||
# 如果signal_data采样率过,进行降采样
|
||||
if signal_fs == 1000:
|
||||
signal_data = utils.downsample_signal_fast(original_signal=signal_data, original_fs=signal_fs, target_fs=100)
|
||||
signal_data_raw = utils.downsample_signal_fast(original_signal=signal_data_raw, original_fs=signal_fs, target_fs=100)
|
||||
signal_data_raw = utils.downsample_signal_fast(original_signal=signal_data_raw, original_fs=signal_fs,
|
||||
target_fs=100)
|
||||
signal_fs = 100
|
||||
|
||||
draw_tools.draw_signal_with_mask(samp_id=samp_id,
|
||||
signal_data=signal_data,
|
||||
signal_fs=signal_fs,
|
||||
resp_data=resp_data,
|
||||
resp_fs=resp_fs,
|
||||
bcg_data=bcg_data,
|
||||
bcg_fs=bcg_fs,
|
||||
signal_disable_mask=manual_disable_mask,
|
||||
resp_low_amp_mask=resp_low_amp_mask,
|
||||
resp_movement_mask=resp_movement_mask,
|
||||
resp_change_mask=resp_amp_change_mask,
|
||||
resp_sa_mask=event_mask,
|
||||
bcg_low_amp_mask=bcg_low_amp_mask,
|
||||
bcg_movement_mask=bcg_movement_mask,
|
||||
bcg_change_mask=bcg_amp_change_mask,
|
||||
show=show,
|
||||
save_path=save_samp_path / f"{samp_id}_Signal_Plots.png")
|
||||
|
||||
|
||||
|
||||
signal_data=signal_data,
|
||||
signal_fs=signal_fs,
|
||||
resp_data=resp_data,
|
||||
resp_fs=resp_fs,
|
||||
bcg_data=bcg_data,
|
||||
bcg_fs=bcg_fs,
|
||||
signal_disable_mask=manual_disable_mask,
|
||||
resp_low_amp_mask=resp_low_amp_mask,
|
||||
resp_movement_mask=resp_movement_mask,
|
||||
resp_change_mask=resp_amp_change_mask,
|
||||
resp_sa_mask=event_mask,
|
||||
bcg_low_amp_mask=bcg_low_amp_mask,
|
||||
bcg_movement_mask=bcg_movement_mask,
|
||||
bcg_change_mask=bcg_amp_change_mask,
|
||||
show=show,
|
||||
save_path=save_samp_path / f"{samp_id}_Signal_Plots.png")
|
||||
|
||||
# 复制事件文件 到保存路径
|
||||
sa_label_save_name = f"{samp_id}" + label_path.name
|
||||
@ -240,22 +243,21 @@ def process_one_signal(samp_id, show=False):
|
||||
"SA_Score": score_mask,
|
||||
"Disable_Label": manual_disable_mask,
|
||||
"Resp_LowAmp_Label": resp_low_amp_mask if resp_low_amp_mask is not None else np.zeros(signal_second, dtype=int),
|
||||
"Resp_Movement_Label": resp_movement_mask if resp_movement_mask is not None else np.zeros(signal_second, dtype=int),
|
||||
"Resp_AmpChange_Label": resp_amp_change_mask if resp_amp_change_mask is not None else np.zeros(signal_second, dtype=int),
|
||||
"Resp_Movement_Label": resp_movement_mask if resp_movement_mask is not None else np.zeros(signal_second,
|
||||
dtype=int),
|
||||
"Resp_AmpChange_Label": resp_amp_change_mask if resp_amp_change_mask is not None else np.zeros(signal_second,
|
||||
dtype=int),
|
||||
"Bcg_LowAmp_Label": bcg_low_amp_mask if bcg_low_amp_mask is not None else np.zeros(signal_second, dtype=int),
|
||||
"Bcg_Movement_Label": bcg_movement_mask if bcg_movement_mask is not None else np.zeros(signal_second, dtype=int),
|
||||
"Bcg_AmpChange_Label": bcg_amp_change_mask if bcg_amp_change_mask is not None else np.zeros(signal_second, dtype=int)
|
||||
"Bcg_Movement_Label": bcg_movement_mask if bcg_movement_mask is not None else np.zeros(signal_second,
|
||||
dtype=int),
|
||||
"Bcg_AmpChange_Label": bcg_amp_change_mask if bcg_amp_change_mask is not None else np.zeros(signal_second,
|
||||
dtype=int)
|
||||
}
|
||||
|
||||
mask_label_save_name = f"{samp_id}_Processed_Labels.csv"
|
||||
utils.save_process_label(save_path=save_samp_path / mask_label_save_name, save_dict=save_dict)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
yaml_path = Path("./dataset_config/HYS_config.yaml")
|
||||
disable_df_path = Path("./排除区间.xlsx")
|
||||
@ -280,4 +282,3 @@ if __name__ == '__main__':
|
||||
# print(f"Processing sample ID: {samp_id}")
|
||||
# process_one_signal(samp_id, show=False)
|
||||
# print(f"Finished processing sample ID: {samp_id}\n\n")
|
||||
|
||||
|
||||
@ -50,7 +50,7 @@ resp_movement_revise:
|
||||
min_duration_sec: 1
|
||||
|
||||
resp_amp_change:
|
||||
mav_calc_window_sec: 1
|
||||
mav_calc_window_sec: 4
|
||||
threshold_amplitude: 0.25
|
||||
threshold_energy: 0.4
|
||||
|
||||
|
||||
@ -602,8 +602,8 @@ def position_based_sleep_recognition_v3(signal_data, movement_mask, movement_lis
|
||||
if len(data_segment) % (mav_calc_window_sec * sampling_rate) != 0:
|
||||
data_segment = data_segment[:-(len(data_segment) % (mav_calc_window_sec * sampling_rate))]
|
||||
|
||||
mav_values = np.nanmax(data_segment.reshape(-1, mav_calc_window_sec * sampling_rate), axis=0) - np.nanmin(
|
||||
data_segment.reshape(-1, mav_calc_window_sec * sampling_rate))
|
||||
mav_values = np.nanmax(data_segment.reshape(-1, mav_calc_window_sec * sampling_rate), axis=1) - np.nanmin(
|
||||
data_segment.reshape(-1, mav_calc_window_sec * sampling_rate), axis=1)
|
||||
# 计算分位数
|
||||
q20 = np.nanpercentile(mav_values, 20)
|
||||
q80 = np.nanpercentile(mav_values, 80)
|
||||
@ -638,10 +638,12 @@ def position_based_sleep_recognition_v3(signal_data, movement_mask, movement_lis
|
||||
movement_end = movement_list[i][1]
|
||||
|
||||
# 避免过短的片段
|
||||
if movement_end - movement_start <= sampling_rate: # 小于1秒的片段不考虑
|
||||
if movement_end - movement_start <= 1: # 小于1秒的片段不考虑
|
||||
if verbose:
|
||||
print(
|
||||
f"Skipping movement segment {i + 1} due to insufficient length. movement start: {movement_start}, movement end: {movement_end}")
|
||||
pre_valid_start = pre_valid_start
|
||||
pre_valid_end = next_valid_end
|
||||
continue
|
||||
|
||||
# 计算前后片段的幅值和能量
|
||||
@ -665,7 +667,7 @@ def position_based_sleep_recognition_v3(signal_data, movement_mask, movement_lis
|
||||
# print(
|
||||
# f"Significant position change detected between segments {movement_start} and {movement_end}: left:{pre_valid_start}to{pre_valid_end} left_mav={left_mav:.2f}, right_mav={right_mav:.2f}, amplitude_change={amplitude_change:.2f}, left_energy={left_energy:.2f}, right_energy={right_energy:.2f}, energy_change={energy_change:.2f}")
|
||||
if verbose:
|
||||
print(f"Significant position change detected between segments {movement_start} and {movement_end}: left:{pre_valid_start}to{pre_valid_end} left_mav={left_mav:.2f}, right_mav={right_mav:.2f}, amplitude_change={amplitude_change:.2f}")
|
||||
print(f"Significant position change detected between segments {movement_start}s and {movement_end}:s left:{pre_valid_start}to{pre_valid_end} left_mav={left_mav:.2f}, right:{next_valid_start}to{next_valid_end} right_mav={right_mav:.2f}, amplitude_change={amplitude_change:.2f}")
|
||||
# 记录姿势变化发生的时间点 用当前分割的体动的起始位置和结束位置表示
|
||||
position_changes[movement_start:movement_end] = 1
|
||||
position_change_list.append(movement_list[i])
|
||||
|
||||
@ -222,7 +222,7 @@ def event_mask_2_list(mask, event_true=True):
|
||||
normal_2_event = -1
|
||||
_append = 1
|
||||
mask_start = np.where(np.diff(mask, prepend=_append, append=_append) == normal_2_event)[0]
|
||||
mask_end = np.where(np.diff(mask, prepend=_append, append=_append) == event_2_normal)[0] + 1
|
||||
mask_end = np.where(np.diff(mask, prepend=_append, append=_append) == event_2_normal)[0]
|
||||
event_list =[[start, end] for start, end in zip(mask_start, mask_end)]
|
||||
return event_list
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user