完善了<体动标注>中体动选取区域的判别功能
This commit is contained in:
@ -9,13 +9,17 @@
|
|||||||
## TODO LIST:
|
## TODO LIST:
|
||||||
1、根据选定区域获取峰值时,将绘制的区域设置为有上限和下限的矩形,根据矩形获取到的横纵区域来计算峰值
|
1、根据选定区域获取峰值时,将绘制的区域设置为有上限和下限的矩形,根据矩形获取到的横纵区域来计算峰值
|
||||||
|
|
||||||
2、体动选取区域的判别尚未做的很完整,选中多个已有的体动的区域时可能会出现问题
|
~~2、体动选取区域的判别尚未做的很完整,选中多个已有的体动的区域时可能会出现问题~~
|
||||||
|
|
||||||
3、部分模块在导入失败后重新导入时会出现问题,已知模块有<人工纠正>、<体动标注>、<呼吸可用性及间期标注>、<睡眠呼吸暂停事件标注>,主要是涉及到按钮状态的设置,有待后续优化。当前将这些有涉及到的功能,禁止了导入数据后在不关闭界面的情况下直接重新导入
|
3、部分模块在导入失败后重新导入时会出现问题,已知模块有<人工纠正>、<体动标注>、<呼吸可用性及间期标注>、<睡眠呼吸暂停事件标注>,主要是涉及到按钮状态的设置,有待后续优化。当前将这些有涉及到的功能,禁止了导入数据后在不关闭界面的情况下直接重新导入
|
||||||
|
|
||||||
4、在J峰算法定位的时候滤波导致的信号偏移,导致之后的峰值坐标点与实际峰值出现偏移
|
4、在J峰算法定位的时候滤波导致的信号偏移,导致之后的峰值坐标点与实际峰值出现偏移
|
||||||
|
|
||||||
~~5、写一个脚本,用于直接从ConfigParams.py中读取文件命名规则,并直接自动化写入到一个markdown文件中。目的是方便文件命名的修改。~~
|
~~5、写一个脚本,用于直接从ConfigParams.py中读取文件命名规则,并直接自动化写入到一个markdown文件中。目的是方便文件命名的修改~~
|
||||||
|
|
||||||
|
6、<呼吸可用性及间期标注>的体动显示做一个和<BCG的质量标注>一样的可以根据勾选来显示需要显示的体动
|
||||||
|
|
||||||
|
7、各个模块中的检测父级文件夹是否存在的功能仍存在问题,无法正确创建文件夹
|
||||||
|
|
||||||
## 1、主菜单
|
## 1、主菜单
|
||||||
|
|
||||||
|
|||||||
@ -1041,7 +1041,6 @@ class Data:
|
|||||||
# 预重采样
|
# 预重采样
|
||||||
try:
|
try:
|
||||||
if Config["InputConfig"]["ThoFreq"] != Config["TempFrequency"]:
|
if Config["InputConfig"]["ThoFreq"] != Config["TempFrequency"]:
|
||||||
print(int(Config["InputConfig"]["ThoFreq"]), int(Config["TempFrequency"]))
|
|
||||||
self.processed_Tho = resample(self.processed_Tho,
|
self.processed_Tho = resample(self.processed_Tho,
|
||||||
int(Config["PSG_seconds"] * Config["TempFrequency"]))
|
int(Config["PSG_seconds"] * Config["TempFrequency"]))
|
||||||
|
|
||||||
|
|||||||
@ -9,7 +9,7 @@ from PySide6.QtWidgets import QMessageBox, QMainWindow, QApplication, QTableWidg
|
|||||||
from matplotlib import gridspec, patches
|
from matplotlib import gridspec, patches
|
||||||
from matplotlib.backends.backend_qt import NavigationToolbar2QT
|
from matplotlib.backends.backend_qt import NavigationToolbar2QT
|
||||||
from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg
|
from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg
|
||||||
from numpy import array
|
from numpy import array, append, sum as np_sum, nonzero
|
||||||
from numpy.fft import fft, fftfreq
|
from numpy.fft import fft, fftfreq
|
||||||
from overrides import overrides
|
from overrides import overrides
|
||||||
from pandas import read_csv, DataFrame, concat
|
from pandas import read_csv, DataFrame, concat
|
||||||
@ -655,7 +655,12 @@ class MainWindow_artifact_label(QMainWindow):
|
|||||||
def __slot_btn_label__(self):
|
def __slot_btn_label__(self):
|
||||||
sender = self.sender()
|
sender = self.sender()
|
||||||
flag = False
|
flag = False
|
||||||
select_row = array([]).astype(dict)
|
select_row = []
|
||||||
|
select_type = array([0, 0, 0, 0, 0])
|
||||||
|
flagf = False
|
||||||
|
flagb = False
|
||||||
|
start_time = 0
|
||||||
|
end_time = 0
|
||||||
|
|
||||||
if sender == self.ui.pushButton_type_1:
|
if sender == self.ui.pushButton_type_1:
|
||||||
type = 1
|
type = 1
|
||||||
@ -678,61 +683,149 @@ class MainWindow_artifact_label(QMainWindow):
|
|||||||
for index, row in self.data.df_Artifact_a.iterrows():
|
for index, row in self.data.df_Artifact_a.iterrows():
|
||||||
value_startTime = row['startTime']
|
value_startTime = row['startTime']
|
||||||
value_endTime = row['endTime']
|
value_endTime = row['endTime']
|
||||||
|
value_type = row['type']
|
||||||
|
|
||||||
# if ((value_endTime >= int(self.ui.lineEdit_start_time.text()) and value_startTime <= int(self.ui.lineEdit_start_time.text())) or
|
if ((value_startTime <= int(self.ui.lineEdit_end_time.text()) <= value_endTime) or
|
||||||
# (value_endTime >= int(self.ui.lineEdit_end_time.text()) and value_startTime <= int(self.ui.lineEdit_end_time.text())) or
|
(value_startTime <= int(self.ui.lineEdit_start_time.text()) <= value_endTime) or
|
||||||
# (value_startTime >= int(self.ui.lineEdit_start_time.text()) and value_endTime <= int(self.ui.lineEdit_end_time.text())) or
|
(value_startTime >= int(self.ui.lineEdit_start_time.text()) and value_endTime <= int(self.ui.lineEdit_end_time.text())) or
|
||||||
# (value_startTime <= int(self.ui.lineEdit_start_time.text()) and value_endTime >= int(self.ui.lineEdit_end_time.text()))):
|
(0 < (int(self.ui.lineEdit_start_time.text()) - value_endTime) <= (2 * Config["InputConfig"]["UseFreq"])) or
|
||||||
# select_row = append(select_row, row)
|
(0 < (value_startTime - int(self.ui.lineEdit_end_time.text())) <= (2 * Config["InputConfig"]["UseFreq"]))):
|
||||||
|
select_row.append(row.to_dict())
|
||||||
|
if row['type'] == 1:
|
||||||
|
select_type[0] = select_type[0] + 1
|
||||||
|
elif row['type'] == 2:
|
||||||
|
select_type[1] = select_type[1] + 1
|
||||||
|
elif row['type'] == 3:
|
||||||
|
select_type[2] = select_type[2] + 1
|
||||||
|
elif row['type'] == 4:
|
||||||
|
select_type[3] = select_type[3] + 1
|
||||||
|
elif row['type'] == 5:
|
||||||
|
select_type[4] = select_type[4] + 1
|
||||||
|
if (0 < (int(self.ui.lineEdit_start_time.text()) - value_endTime) <= (2 * Config["InputConfig"]["UseFreq"])) and (value_type == type):
|
||||||
|
flagf = True
|
||||||
|
if (0 < (value_startTime - int(self.ui.lineEdit_end_time.text())) <= (2 * Config["InputConfig"]["UseFreq"])) and (value_type == type):
|
||||||
|
flagb = True
|
||||||
|
|
||||||
# TODO:体动选取区域的判别尚未做的很完整,选中多个已有的体动的区域时可能会出现问题
|
count = np_sum(select_type >= 1)
|
||||||
if (type == 1 and row['type'] == 1) or (type == 2 and row['type'] == 2) or (type == 3 and row['type'] == 3):
|
if count >= 2 or (count == 1 and nonzero(select_type)[0][0] + 1 == type):
|
||||||
if ((value_startTime > int(self.ui.lineEdit_start_time.text()) and (value_startTime - int(self.ui.lineEdit_end_time.text()) <= 2 * Config["InputConfig"]["UseFreq"])) or
|
if count >= 2:
|
||||||
(value_endTime < int(self.ui.lineEdit_end_time.text()) and (int(self.ui.lineEdit_end_time.text()) - value_endTime <= 2 * Config["InputConfig"]["UseFreq"]))):
|
reply = QMessageBox.question(self, '确认',
|
||||||
reply = QMessageBox.question(self, '确认', '{}{},是否确认合并?'.format(Constants.ARTIFACT_LABEL_MERGE, row['number']), QMessageBox.Yes | QMessageBox.No,
|
'{}{}'.format(Constants.ARTIFACT_LABEL_MULTIPLE_ARTIFACT_COVER_OR_DELETE, [d["number"] for d in select_row]),
|
||||||
QMessageBox.No)
|
QMessageBox.Yes | QMessageBox.No,
|
||||||
if reply == QMessageBox.Yes:
|
QMessageBox.No)
|
||||||
self.data.df_Artifact_a.loc[self.data.df_Artifact_a['number'] == row['number'],
|
if reply == QMessageBox.No:
|
||||||
['number', 'type', 'startTime', 'endTime']] = [
|
return
|
||||||
int(row['number']),
|
|
||||||
int(type),
|
|
||||||
int(self.ui.lineEdit_start_time.text()) if int(self.ui.lineEdit_start_time.text()) < int(row['startTime']) else int(row['startTime']),
|
|
||||||
int(self.ui.lineEdit_end_time.text()) if int(self.ui.lineEdit_end_time.text()) > int(row['endTime']) else int(row['endTime'])
|
|
||||||
]
|
|
||||||
new_row = {'number': int(row['number']),
|
|
||||||
'type': int(type),
|
|
||||||
'startTime': int(self.ui.lineEdit_start_time.text()),
|
|
||||||
'endTime': int(self.ui.lineEdit_end_time.text())}
|
|
||||||
flag = True
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
return
|
|
||||||
if value_startTime <= int(self.ui.lineEdit_end_time.text()) and int(
|
|
||||||
self.ui.lineEdit_start_time.text()) <= value_endTime:
|
|
||||||
PublicFunc.msgbox_output(self, f"{Constants.ARTIFACT_LABEL_OVERLAPPING}{row['number']}", Constants.MSGBOX_TYPE_ERROR)
|
|
||||||
return
|
|
||||||
|
|
||||||
if not flag:
|
if flagf == True and flagb == False:
|
||||||
new_row = {'number': int(len(self.data.df_Artifact_a) + 1),
|
if type == 1 or type == 2 or type == 3:
|
||||||
'type': int(type),
|
PublicFunc.msgbox_output(self, Constants.ARTIFACT_LABEL_FRONT_TWO_SECONDS_MERGE,
|
||||||
'startTime': int(self.ui.lineEdit_start_time.text()),
|
Constants.MSGBOX_TYPE_INFO)
|
||||||
'endTime': int(self.ui.lineEdit_end_time.text())}
|
start_time = select_row[0]['startTime']
|
||||||
self.data.df_Artifact_a = concat([self.data.df_Artifact_a, DataFrame([new_row])], ignore_index=True)
|
end_time = int(self.ui.lineEdit_end_time.text())
|
||||||
sorted_part = self.data.df_Artifact_a[['type', 'startTime', 'endTime']].sort_values(by='startTime').reset_index(
|
elif type == 4 or type == 5:
|
||||||
|
PublicFunc.msgbox_output(self, Constants.ARTIFACT_LABEL_FRONT_TWO_SECONDS_WARNING,
|
||||||
|
Constants.MSGBOX_TYPE_INFO)
|
||||||
|
select_row = select_row[1:]
|
||||||
|
start_time = int(self.ui.lineEdit_start_time.text())
|
||||||
|
end_time = int(self.ui.lineEdit_end_time.text())
|
||||||
|
if flagf == False and flagb == True:
|
||||||
|
if type == 1 or type == 2 or type == 3:
|
||||||
|
PublicFunc.msgbox_output(self, Constants.ARTIFACT_LABEL_BACK_TWO_SECONDS_MERGE,
|
||||||
|
Constants.MSGBOX_TYPE_INFO)
|
||||||
|
start_time = int(self.ui.lineEdit_start_time.text())
|
||||||
|
end_time = select_row[-1]['endTime']
|
||||||
|
elif type == 4 or type == 5:
|
||||||
|
PublicFunc.msgbox_output(self, Constants.ARTIFACT_LABEL_BACK_TWO_SECONDS_WARNING,
|
||||||
|
Constants.MSGBOX_TYPE_INFO)
|
||||||
|
select_row = select_row[:-1]
|
||||||
|
start_time = int(self.ui.lineEdit_start_time.text())
|
||||||
|
end_time = int(self.ui.lineEdit_end_time.text())
|
||||||
|
if flagf == True and flagb == True:
|
||||||
|
if type == 1 or type == 2 or type == 3:
|
||||||
|
PublicFunc.msgbox_output(self, Constants.ARTIFACT_LABEL_FRONT_AND_BACK_TWO_SECONDS_MERGE,
|
||||||
|
Constants.MSGBOX_TYPE_INFO)
|
||||||
|
start_time = select_row[0]['startTime']
|
||||||
|
end_time = select_row[-1]['endTime']
|
||||||
|
elif type == 4 or type == 5:
|
||||||
|
PublicFunc.msgbox_output(self, Constants.ARTIFACT_LABEL_FRONT_AND_BACK_TWO_SECONDS_WARNING,
|
||||||
|
Constants.MSGBOX_TYPE_INFO)
|
||||||
|
select_row = select_row[1:-1]
|
||||||
|
start_time = int(self.ui.lineEdit_start_time.text())
|
||||||
|
end_time = int(self.ui.lineEdit_end_time.text())
|
||||||
|
if flagf == False and flagb == False:
|
||||||
|
start_time = int(self.ui.lineEdit_start_time.text())
|
||||||
|
end_time = int(self.ui.lineEdit_end_time.text())
|
||||||
|
|
||||||
|
for select_each_row in select_row:
|
||||||
|
self.data.df_Artifact_a = self.data.df_Artifact_a[self.data.df_Artifact_a['number'] != select_each_row["number"]]
|
||||||
|
else:
|
||||||
|
select_row = []
|
||||||
|
select_type = array([0, 0, 0, 0, 0])
|
||||||
|
for index, row in self.data.df_Artifact_a.iterrows():
|
||||||
|
value_startTime = row['startTime']
|
||||||
|
value_endTime = row['endTime']
|
||||||
|
value_type = row['type']
|
||||||
|
if ((value_startTime <= int(self.ui.lineEdit_end_time.text()) <= value_endTime) or
|
||||||
|
(value_startTime <= int(self.ui.lineEdit_start_time.text()) <= value_endTime) or
|
||||||
|
(value_startTime >= int(self.ui.lineEdit_start_time.text()) and value_endTime <= int(
|
||||||
|
self.ui.lineEdit_end_time.text()))):
|
||||||
|
select_row.append(row.to_dict())
|
||||||
|
if row['type'] == 1:
|
||||||
|
select_type[0] = select_type[0] + 1
|
||||||
|
elif row['type'] == 2:
|
||||||
|
select_type[1] = select_type[1] + 1
|
||||||
|
elif row['type'] == 3:
|
||||||
|
select_type[2] = select_type[2] + 1
|
||||||
|
elif row['type'] == 4:
|
||||||
|
select_type[3] = select_type[3] + 1
|
||||||
|
elif row['type'] == 5:
|
||||||
|
select_type[4] = select_type[4] + 1
|
||||||
|
|
||||||
|
count = np_sum(select_type >= 1)
|
||||||
|
|
||||||
|
if (count == 1 and nonzero(select_type)[0][0] + 1 != type):
|
||||||
|
reply = QMessageBox.question(self, '确认',
|
||||||
|
'{}{}'.format(Constants.ARTIFACT_LABEL_SINGLE_TYPE_NOT_EQUAL,
|
||||||
|
[d["number"] for d in select_row]),
|
||||||
|
QMessageBox.Yes | QMessageBox.No,
|
||||||
|
QMessageBox.No)
|
||||||
|
if reply == QMessageBox.No:
|
||||||
|
return
|
||||||
|
|
||||||
|
start_time = int(self.ui.lineEdit_start_time.text())
|
||||||
|
end_time = int(self.ui.lineEdit_end_time.text())
|
||||||
|
|
||||||
|
for select_each_row in select_row:
|
||||||
|
self.data.df_Artifact_a = self.data.df_Artifact_a[self.data.df_Artifact_a['number'] != select_each_row["number"]]
|
||||||
|
elif count == 0:
|
||||||
|
start_time = int(self.ui.lineEdit_start_time.text())
|
||||||
|
end_time = int(self.ui.lineEdit_end_time.text())
|
||||||
|
else:
|
||||||
|
raise ValueError("count值不存在")
|
||||||
|
|
||||||
|
new_row = {
|
||||||
|
'number': 1,
|
||||||
|
'type': int(type),
|
||||||
|
'startTime': start_time,
|
||||||
|
'endTime': end_time
|
||||||
|
}
|
||||||
|
|
||||||
|
self.data.df_Artifact_a = concat([self.data.df_Artifact_a, DataFrame([new_row])], ignore_index=True)
|
||||||
|
self.data.df_Artifact_a[['type', 'startTime', 'endTime']] = self.data.df_Artifact_a[['type', 'startTime', 'endTime']].sort_values(by='startTime').reset_index(
|
||||||
drop=True)
|
drop=True)
|
||||||
self.data.df_Artifact_a[['type', 'startTime', 'endTime']] = sorted_part
|
self.data.df_Artifact_a['number'] = range(1, len(self.data.df_Artifact_a) + 1)
|
||||||
|
|
||||||
self.update_tableWidget()
|
self.update_tableWidget()
|
||||||
self.update_Info()
|
self.update_Info()
|
||||||
self.__plot_artifact__()
|
self.__plot_artifact__()
|
||||||
|
|
||||||
target_row = self.data.df_Artifact_a[
|
target_row = self.data.df_Artifact_a[self.data.df_Artifact_a.eq(start_time).any(axis=1)]
|
||||||
self.data.df_Artifact_a.eq(int(self.ui.lineEdit_start_time.text())).any(axis=1)]
|
|
||||||
if not target_row.empty:
|
if not target_row.empty:
|
||||||
first_column_value = target_row.iloc[0, 0] # 获取第1列的值
|
first_column_value = target_row.iloc[0, 0] # 获取第1列的值
|
||||||
else:
|
else:
|
||||||
raise AttributeError()
|
raise AttributeError()
|
||||||
|
|
||||||
PublicFunc.text_output(self.ui, f"新增体动标签{first_column_value}, 类型{new_row['type']},从{int(self.ui.lineEdit_start_time.text())}ms到{int(self.ui.lineEdit_end_time.text())}ms", Constants.TIPS_TYPE_INFO)
|
PublicFunc.text_output(self.ui, f"新增体动标签{first_column_value}, 类型{new_row['type']},从{int(start_time)}ms到{int(end_time)}ms", Constants.TIPS_TYPE_INFO)
|
||||||
|
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
|
|||||||
@ -324,8 +324,14 @@ class Constants:
|
|||||||
ARTIFACT_LABEL_JUMP_ARTIFACT: str = "跳转到体动"
|
ARTIFACT_LABEL_JUMP_ARTIFACT: str = "跳转到体动"
|
||||||
ARTIFACT_LABEL_RECOVER_SCALE: str = "尺度恢复"
|
ARTIFACT_LABEL_RECOVER_SCALE: str = "尺度恢复"
|
||||||
ARTIFACT_LABEL_MISS_ARGS: str = "打标参数未填写"
|
ARTIFACT_LABEL_MISS_ARGS: str = "打标参数未填写"
|
||||||
ARTIFACT_LABEL_OVERLAPPING: str = "当前所打标的片段存在重合,重合片段序号:"
|
ARTIFACT_LABEL_MULTIPLE_ARTIFACT_COVER_OR_DELETE: str = "所选区域包含多种类型的体动,是否需要删除它们并使用新标注进行覆盖?所选区域中含有的体动序号:"
|
||||||
ARTIFACT_LABEL_MERGE: str = "当前所打标的片段距离附近片段不到2秒,片段序号:"
|
ARTIFACT_LABEL_FRONT_TWO_SECONDS_MERGE: str = "所选区域前2秒内有与当前标注相同类型的体动,将执行合并"
|
||||||
|
ARTIFACT_LABEL_BACK_TWO_SECONDS_MERGE: str = "所选区域后2秒内有与当前标注相同类型的体动,将执行合并"
|
||||||
|
ARTIFACT_LABEL_FRONT_AND_BACK_TWO_SECONDS_MERGE: str = "所选区域前后2秒内都有与当前标注相同类型的体动,将执行合并"
|
||||||
|
ARTIFACT_LABEL_FRONT_TWO_SECONDS_WARNING: str = "所选区域前2秒内有与当前标注相同类型的体动,仅进行提示"
|
||||||
|
ARTIFACT_LABEL_BACK_TWO_SECONDS_WARNING: str = "所选区域后2秒内有与当前标注相同类型的体动,仅进行提示"
|
||||||
|
ARTIFACT_LABEL_FRONT_AND_BACK_TWO_SECONDS_WARNING: str = "所选区域前后2秒内都有与当前标注相同类型的体动,仅进行提示"
|
||||||
|
ARTIFACT_LABEL_SINGLE_TYPE_NOT_EQUAL: str = "所选区域仅包含一种类型的体动,但其类型与当前标注的类型不匹配,是否需要删除它们并使用新标注覆盖?所选区域中含有的体动序号:"
|
||||||
ARTIFACT_LABEL_DELETE_ARTIFACT_SUCCESSFULLY: str = "体动被删除"
|
ARTIFACT_LABEL_DELETE_ARTIFACT_SUCCESSFULLY: str = "体动被删除"
|
||||||
ARTIFACT_LABEL_DELETE_ARTIFACT_FAILURE: str = "需要被删除的体动不存在"
|
ARTIFACT_LABEL_DELETE_ARTIFACT_FAILURE: str = "需要被删除的体动不存在"
|
||||||
ARTIFACT_LABEL_ACTION_LABEL: str = f"标注体动({Params.ARTIFACT_LABEL_ACTION_LABEL_ARTIFACT_SHORTCUT_KEY})"
|
ARTIFACT_LABEL_ACTION_LABEL: str = f"标注体动({Params.ARTIFACT_LABEL_ACTION_LABEL_ARTIFACT_SHORTCUT_KEY})"
|
||||||
|
|||||||
Reference in New Issue
Block a user