修正幅值改变计算
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 signal_method
|
||||||
import os
|
import os
|
||||||
from matplotlib import pyplot as plt
|
from matplotlib import pyplot as plt
|
||||||
|
|
||||||
os.environ['DISPLAY'] = "localhost:10.0"
|
os.environ['DISPLAY'] = "localhost:10.0"
|
||||||
|
|
||||||
|
|
||||||
def process_one_signal(samp_id, show=False):
|
def process_one_signal(samp_id, show=False):
|
||||||
signal_path = list((org_signal_root_path / f"{samp_id}").glob("OrgBCG_Sync_*.txt"))
|
signal_path = list((org_signal_root_path / f"{samp_id}").glob("OrgBCG_Sync_*.txt"))
|
||||||
if not signal_path:
|
if not signal_path:
|
||||||
@ -74,7 +75,6 @@ def process_one_signal(samp_id, show=False):
|
|||||||
sample_rate=resp_fs)
|
sample_rate=resp_fs)
|
||||||
print("Begin plotting signal data...")
|
print("Begin plotting signal data...")
|
||||||
|
|
||||||
|
|
||||||
# fig = plt.figure(figsize=(12, 8))
|
# fig = plt.figure(figsize=(12, 8))
|
||||||
# # 绘制三个图raw_data、resp_data_1、resp_data_2
|
# # 绘制三个图raw_data、resp_data_1、resp_data_2
|
||||||
# ax0 = fig.add_subplot(3, 1, 1)
|
# ax0 = fig.add_subplot(3, 1, 1)
|
||||||
@ -116,7 +116,8 @@ def process_one_signal(samp_id, show=False):
|
|||||||
sampling_rate=resp_fs,
|
sampling_rate=resp_fs,
|
||||||
**resp_low_amp_conf
|
**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:
|
else:
|
||||||
resp_low_amp_mask, resp_low_amp_position_list = None, None
|
resp_low_amp_mask, resp_low_amp_position_list = None, None
|
||||||
print("resp_low_amp_mask is None")
|
print("resp_low_amp_mask is None")
|
||||||
@ -129,7 +130,8 @@ def process_one_signal(samp_id, show=False):
|
|||||||
sampling_rate=resp_fs,
|
sampling_rate=resp_fs,
|
||||||
**resp_movement_conf
|
**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:
|
else:
|
||||||
resp_movement_mask, resp_movement_position_list = None, None
|
resp_movement_mask, resp_movement_position_list = None, None
|
||||||
print("resp_movement_mask is None")
|
print("resp_movement_mask is None")
|
||||||
@ -144,11 +146,11 @@ def process_one_signal(samp_id, show=False):
|
|||||||
**resp_movement_revise_conf,
|
**resp_movement_revise_conf,
|
||||||
verbose=False
|
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:
|
else:
|
||||||
print("resp_movement_mask revise is skipped")
|
print("resp_movement_mask revise is skipped")
|
||||||
|
|
||||||
|
|
||||||
# 分析Resp的幅值突变区间
|
# 分析Resp的幅值突变区间
|
||||||
resp_amp_change_conf = conf.get("resp_amp_change", None)
|
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:
|
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,
|
sampling_rate=resp_fs,
|
||||||
**resp_amp_change_conf,
|
**resp_amp_change_conf,
|
||||||
verbose=True)
|
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:
|
else:
|
||||||
resp_amp_change_mask = None
|
resp_amp_change_mask = None
|
||||||
print("amp_change_mask is None")
|
print("amp_change_mask is None")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# 分析Bcg的低幅值区间
|
# 分析Bcg的低幅值区间
|
||||||
bcg_low_amp_conf = conf.get("bcg_low_amp", None)
|
bcg_low_amp_conf = conf.get("bcg_low_amp", None)
|
||||||
if bcg_low_amp_conf is not 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,
|
sampling_rate=bcg_fs,
|
||||||
**bcg_low_amp_conf
|
**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:
|
else:
|
||||||
bcg_low_amp_mask, bcg_low_amp_position_list = None, None
|
bcg_low_amp_mask, bcg_low_amp_position_list = None, None
|
||||||
print("bcg_low_amp_mask is None")
|
print("bcg_low_amp_mask is None")
|
||||||
|
|
||||||
# 分析Bcg的高幅值伪迹区间
|
# 分析Bcg的高幅值伪迹区间
|
||||||
bcg_movement_conf = conf.get("bcg_movement", None)
|
bcg_movement_conf = conf.get("bcg_movement", None)
|
||||||
if bcg_movement_conf is not None:
|
if bcg_movement_conf is not None:
|
||||||
@ -186,26 +189,29 @@ def process_one_signal(samp_id, show=False):
|
|||||||
sampling_rate=bcg_fs,
|
sampling_rate=bcg_fs,
|
||||||
**bcg_movement_conf
|
**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:
|
else:
|
||||||
bcg_movement_mask = None
|
bcg_movement_mask = None
|
||||||
print("bcg_movement_mask is None")
|
print("bcg_movement_mask is None")
|
||||||
|
|
||||||
# 分析Bcg的幅值突变区间
|
# 分析Bcg的幅值突变区间
|
||||||
if bcg_movement_mask is not None:
|
if bcg_movement_mask is not None:
|
||||||
bcg_amp_change_mask, bcg_amp_change_list = signal_method.position_based_sleep_recognition_v2(
|
bcg_amp_change_mask, bcg_amp_change_list = signal_method.position_based_sleep_recognition_v2(
|
||||||
signal_data=bcg_data,
|
signal_data=bcg_data,
|
||||||
movement_mask=bcg_movement_mask,
|
movement_mask=bcg_movement_mask,
|
||||||
sampling_rate=bcg_fs)
|
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:
|
else:
|
||||||
bcg_amp_change_mask = None
|
bcg_amp_change_mask = None
|
||||||
print("bcg_amp_change_mask is None")
|
print("bcg_amp_change_mask is None")
|
||||||
|
|
||||||
|
|
||||||
# 如果signal_data采样率过,进行降采样
|
# 如果signal_data采样率过,进行降采样
|
||||||
if signal_fs == 1000:
|
if signal_fs == 1000:
|
||||||
signal_data = utils.downsample_signal_fast(original_signal=signal_data, original_fs=signal_fs, target_fs=100)
|
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
|
signal_fs = 100
|
||||||
|
|
||||||
draw_tools.draw_signal_with_mask(samp_id=samp_id,
|
draw_tools.draw_signal_with_mask(samp_id=samp_id,
|
||||||
@ -226,9 +232,6 @@ def process_one_signal(samp_id, show=False):
|
|||||||
show=show,
|
show=show,
|
||||||
save_path=save_samp_path / f"{samp_id}_Signal_Plots.png")
|
save_path=save_samp_path / f"{samp_id}_Signal_Plots.png")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# 复制事件文件 到保存路径
|
# 复制事件文件 到保存路径
|
||||||
sa_label_save_name = f"{samp_id}" + label_path.name
|
sa_label_save_name = f"{samp_id}" + label_path.name
|
||||||
shutil.copyfile(label_path, save_samp_path / sa_label_save_name)
|
shutil.copyfile(label_path, save_samp_path / sa_label_save_name)
|
||||||
@ -240,22 +243,21 @@ def process_one_signal(samp_id, show=False):
|
|||||||
"SA_Score": score_mask,
|
"SA_Score": score_mask,
|
||||||
"Disable_Label": manual_disable_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_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_Movement_Label": resp_movement_mask if resp_movement_mask is not None else np.zeros(signal_second,
|
||||||
"Resp_AmpChange_Label": resp_amp_change_mask if resp_amp_change_mask is not None else np.zeros(signal_second, dtype=int),
|
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_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_Movement_Label": bcg_movement_mask if bcg_movement_mask is not None else np.zeros(signal_second,
|
||||||
"Bcg_AmpChange_Label": bcg_amp_change_mask if bcg_amp_change_mask is not None else np.zeros(signal_second, dtype=int)
|
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"
|
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)
|
utils.save_process_label(save_path=save_samp_path / mask_label_save_name, save_dict=save_dict)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
yaml_path = Path("./dataset_config/HYS_config.yaml")
|
yaml_path = Path("./dataset_config/HYS_config.yaml")
|
||||||
disable_df_path = Path("./排除区间.xlsx")
|
disable_df_path = Path("./排除区间.xlsx")
|
||||||
@ -280,4 +282,3 @@ if __name__ == '__main__':
|
|||||||
# print(f"Processing sample ID: {samp_id}")
|
# print(f"Processing sample ID: {samp_id}")
|
||||||
# process_one_signal(samp_id, show=False)
|
# process_one_signal(samp_id, show=False)
|
||||||
# print(f"Finished processing sample ID: {samp_id}\n\n")
|
# print(f"Finished processing sample ID: {samp_id}\n\n")
|
||||||
|
|
||||||
|
|||||||
@ -50,7 +50,7 @@ resp_movement_revise:
|
|||||||
min_duration_sec: 1
|
min_duration_sec: 1
|
||||||
|
|
||||||
resp_amp_change:
|
resp_amp_change:
|
||||||
mav_calc_window_sec: 1
|
mav_calc_window_sec: 4
|
||||||
threshold_amplitude: 0.25
|
threshold_amplitude: 0.25
|
||||||
threshold_energy: 0.4
|
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:
|
if len(data_segment) % (mav_calc_window_sec * sampling_rate) != 0:
|
||||||
data_segment = data_segment[:-(len(data_segment) % (mav_calc_window_sec * sampling_rate))]
|
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(
|
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))
|
data_segment.reshape(-1, mav_calc_window_sec * sampling_rate), axis=1)
|
||||||
# 计算分位数
|
# 计算分位数
|
||||||
q20 = np.nanpercentile(mav_values, 20)
|
q20 = np.nanpercentile(mav_values, 20)
|
||||||
q80 = np.nanpercentile(mav_values, 80)
|
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]
|
movement_end = movement_list[i][1]
|
||||||
|
|
||||||
# 避免过短的片段
|
# 避免过短的片段
|
||||||
if movement_end - movement_start <= sampling_rate: # 小于1秒的片段不考虑
|
if movement_end - movement_start <= 1: # 小于1秒的片段不考虑
|
||||||
if verbose:
|
if verbose:
|
||||||
print(
|
print(
|
||||||
f"Skipping movement segment {i + 1} due to insufficient length. movement start: {movement_start}, movement end: {movement_end}")
|
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
|
continue
|
||||||
|
|
||||||
# 计算前后片段的幅值和能量
|
# 计算前后片段的幅值和能量
|
||||||
@ -665,7 +667,7 @@ def position_based_sleep_recognition_v3(signal_data, movement_mask, movement_lis
|
|||||||
# print(
|
# 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}")
|
# 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:
|
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_changes[movement_start:movement_end] = 1
|
||||||
position_change_list.append(movement_list[i])
|
position_change_list.append(movement_list[i])
|
||||||
|
|||||||
@ -222,7 +222,7 @@ def event_mask_2_list(mask, event_true=True):
|
|||||||
normal_2_event = -1
|
normal_2_event = -1
|
||||||
_append = 1
|
_append = 1
|
||||||
mask_start = np.where(np.diff(mask, prepend=_append, append=_append) == normal_2_event)[0]
|
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)]
|
event_list =[[start, end] for start, end in zip(mask_start, mask_end)]
|
||||||
return event_list
|
return event_list
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user