diff --git a/func/Module_cut_pair_file.py b/func/Module_cut_pair_file.py
index 54581bf..1d8577b 100644
--- a/func/Module_cut_pair_file.py
+++ b/func/Module_cut_pair_file.py
@@ -1,6 +1,7 @@
+import traceback
from ast import literal_eval
from gc import collect
-from math import floor
+from math import floor, ceil
from pathlib import Path
from traceback import format_exc
@@ -26,12 +27,14 @@ ButtonState = {
"Default": {
"checkBox_roughCut": False,
"pushButton_deleteRoughCut": False,
- "pushButton_execute": True
+ "pushButton_execute": True,
+ "spinBox_OrgBCGShift": False
},
"Current": {
"checkBox_roughCut": False,
"pushButton_deleteRoughCut": False,
- "pushButton_execute": True
+ "pushButton_execute": True,
+ "spinBox_OrgBCGShift": False
}
}
@@ -84,6 +87,8 @@ class MainWindow_cut_PAIR_FILE(QMainWindow):
self.ui.pushButton_execute.clicked.connect(self.__slot_btn_execute__)
self.ui.checkBox_roughCut.stateChanged.connect(self.__change_approximate_align_mode__)
+ self.ui.spinBox_OrgBCGShift.setEnabled(False)
+
@overrides
def closeEvent(self, event):
@@ -131,6 +136,7 @@ class MainWindow_cut_PAIR_FILE(QMainWindow):
ButtonState["Default"]["pushButton_deleteRoughCut"] = True
self.ui.plainTextEdit_channel.setPlainText(', '.join(Config["ChannelInput"].keys()))
+ self.ui.spinBox_OrgBCGShift.setEnabled(True)
else:
# ChannelInput 移除OrgBCGCHannelInput
@@ -147,36 +153,7 @@ class MainWindow_cut_PAIR_FILE(QMainWindow):
Config["ChannelSave"][key] = Config["ChannelSave"][key].replace("RoughCut", "Sync")
ButtonState["Default"]["pushButton_deleteRoughCut"] = False
self.ui.plainTextEdit_channel.setPlainText(', '.join(Config["ChannelInput"].keys()))
-
-
- def __get_approximately_align_info__(self):
- time_bias = self.data.get_approximately_align_info()
- if time_bias is not None:
- info = "已成功获取粗对齐信息,时间偏移量为{:.3f}秒".format(time_bias)
- PublicFunc.text_output(self.ui, info, Constants.TIPS_TYPE_INFO)
- QApplication.processEvents()
- return True
- else:
- info = "获取粗对齐信息失败,系统将尝试计算粗对齐信息"
- PublicFunc.text_output(self.ui, info, Constants.TIPS_TYPE_WARNING)
- QApplication.processEvents()
-
- align_info = self.data.calc_approximately_align_info()
- if align_info is not None:
- info = "已成功计算粗对齐信息,切割点为:ECG前端去除{}样本点,ECG后端去除{}样本点,BCG前端去除{}样本点,BCG后端去除{}样本点".format(
- align_info["cut_index"]["front_ECG"],
- align_info["cut_index"]["back_ECG"],
- align_info["cut_index"]["front_BCG"],
- align_info["cut_index"]["back_BCG"]
- )
- PublicFunc.text_output(self.ui, info, Constants.TIPS_TYPE_INFO)
- QApplication.processEvents()
- return True
- else:
- info = "计算粗对齐信息失败,无法进行后续操作"
- PublicFunc.text_output(self.ui, info, Constants.TIPS_TYPE_ERROR)
- QApplication.processEvents()
- return False
+ self.ui.spinBox_OrgBCGShift.setEnabled(False)
def __slot_btn_execute__(self):
@@ -196,6 +173,7 @@ class MainWindow_cut_PAIR_FILE(QMainWindow):
else:
if self.ui.checkBox_roughCut.isChecked():
Config["BCGFreq"] = self.data.freq["OrgBCG"]
+ Config["ECGFreq"] = self.data.freq["ECG"]
PublicFunc.text_output(self.ui, "(1/5)" + result.info, Constants.TIPS_TYPE_INFO)
PublicFunc.finish_operation(self, ButtonState)
@@ -216,7 +194,7 @@ class MainWindow_cut_PAIR_FILE(QMainWindow):
if self.ui.checkBox_roughCut.isChecked():
# 获取或计算粗对齐信息
PublicFunc.progressbar_update(self, 3, 5, Constants.CUT_PAIR_FILE_GETTING_APPROXIMATE_ALIGN_INFO, 20)
- result_approximate = self.__get_approximately_align_info__()
+ result_approximate = self.data.get_approximately_align_info()
if not result_approximate:
PublicFunc.msgbox_output(self, Constants.CUT_PAIR_FILE_GETTING_APPROXIMATE_ALIGN_INFO_FAILURE, Constants.MSGBOX_TYPE_ERROR)
PublicFunc.finish_operation(self, ButtonState)
@@ -224,6 +202,15 @@ class MainWindow_cut_PAIR_FILE(QMainWindow):
else:
PublicFunc.text_output(self.ui, "(3/5)" + Constants.CUT_PAIR_FILE_GETTING_APPROXIMATE_ALIGN_INFO_FINISHED, Constants.TIPS_TYPE_INFO)
+ result_approximate = self.data.calc_approximately_align_info(int(self.ui.spinBox_OrgBCGShift.value()))
+ if not result_approximate.status:
+ PublicFunc.text_output(self.ui, "(3/5)" + result_approximate.info, Constants.TIPS_TYPE_ERROR)
+ PublicFunc.msgbox_output(self, result_approximate.info, Constants.MSGBOX_TYPE_ERROR)
+ PublicFunc.finish_operation(self, ButtonState)
+ return
+ else:
+ PublicFunc.text_output(self.ui, "(3/5)" + result_approximate.info, Constants.TIPS_TYPE_INFO)
+
PublicFunc.finish_operation(self, ButtonState)
# 切割数据
@@ -384,10 +371,11 @@ class Data:
self.startTime = read_csv(Path(Config["Path"]["InputPSGFolder"]) / Path((Config["StartTime"] + Config["EndWith"]["StartTime"])),
encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
- self.alignInfo = read_csv(Path(Config["Path"]["InputAlignInfo"]),
- encoding=Params.UTF8_ENCODING,
- header=None).to_numpy().reshape(-1)
- self.alignInfo = literal_eval(self.alignInfo[0])
+ if Path(Config["Path"]["InputAlignInfo"]).exists():
+ self.alignInfo = read_csv(Path(Config["Path"]["InputAlignInfo"]),
+ encoding=Params.UTF8_ENCODING,
+ header=None).to_numpy().reshape(-1)
+ self.alignInfo = literal_eval(self.alignInfo[0])
except Exception as e:
return Result().failure(info=Constants.INPUT_FAILURE +
@@ -402,18 +390,20 @@ class Data:
pos = df["pos"].values[-1]
ApplyFrequency = df["ApplyFrequency"].values[-1]
self.TimeBiasSecond = pos / ApplyFrequency
- return self.TimeBiasSecond
+ return Result().success(info=Constants.INPUT_FINISHED)
except Exception as e:
self.TimeBiasSecond = 0
- return None
+ traceback.print_exc()
+ return Result().failure(info=Constants.INPUT_FAILURE
+ + Constants.FAILURE_REASON["Get_Approximately_Align_Info_Exception"]
+ + "\n" + format_exc())
- def calc_approximately_align_info(self):
+ def calc_approximately_align_info(self, OrgBCGShift=0):
try:
# 获取BCG长度
BCG_freq = Config["BCGFreq"]
- BCG_second = len(self.raw["BCG"]) // BCG_freq
-
+ BCG_second = len(self.raw["OrgBCG"]) // BCG_freq
# 计算ECG长度
ECG_freq = Config["ECGFreq"]
@@ -424,19 +414,19 @@ class Data:
# 如果pos<0,表示BCG信号比ECG信号提前,需要在开头去除掉一部分BCG信号
if pos < 0:
- front_BCG = floor(-pos)
+ front_BCG = ceil(-pos) + OrgBCGShift
front_ECG = 0
else:
- front_BCG = 0
- front_ECG = floor(pos)
+ front_BCG = 0 + OrgBCGShift
+ front_ECG = ceil(pos)
# 计算结束位置
if (BCG_second - front_BCG) > (ECG_second - front_ECG):
- back_ECG = ECG_second + front_ECG
- back_BCG = back_ECG - floor(pos)
+ back_ECG = ECG_second + front_ECG - 1
+ back_BCG = back_ECG - ceil(pos)
else:
- back_BCG = BCG_second + front_BCG
- back_ECG = back_BCG + floor(pos)
+ back_BCG = BCG_second + front_BCG - 1
+ back_ECG = back_BCG + ceil(pos)
self.alignInfo = {
"cut_index": {
@@ -446,11 +436,14 @@ class Data:
"back_BCG": back_BCG * BCG_freq
}
}
- return self.alignInfo
+ return Result().success(info=Constants.CUT_PAIR_FILE_GETTING_APPROXIMATE_ALIGN_INFO_CALC_FINISHED)
except Exception as e:
- return None
+ traceback.print_exc()
+ print(e)
+ Result().failure(info=Constants.CUT_PAIR_FILE_GETTING_APPROXIMATE_ALIGN_INFO_FAILURE +
+ Constants.FAILURE_REASON["Calculate_Approximately_Align_Info_Exception"] + "\n" + format_exc())
def cut_data(self):
diff --git a/func/utils/Constants.py b/func/utils/Constants.py
index a89c877..41074d6 100644
--- a/func/utils/Constants.py
+++ b/func/utils/Constants.py
@@ -183,7 +183,9 @@ class Constants:
"res_BCG_Not_Exist": "(切割后BCG不存在)",
"cut_ECG_Not_Exist": "(切割后ECG不存在)",
"cut_Jpeak_Not_Exist": "(切割后J峰不存在)",
- "cut_Rpeak_Not_Exist": "(切割后R峰不存在)"
+ "cut_Rpeak_Not_Exist": "(切割后R峰不存在)",
+ "Get_Approximately_Align_Info_Exception": "(获取粗对齐信息异常)",
+ "Calculate_Approximately_Align_Info_Exception": "(计算粗对齐信息异常)"
}
# 数据粗同步
@@ -368,6 +370,7 @@ class Constants:
CUT_PAIR_FILE_GETTING_APPROXIMATE_ALIGN_INFO: str = "正在获取粗对齐信息"
CUT_PAIR_FILE_GETTING_APPROXIMATE_ALIGN_INFO_FAILURE: str = "获取粗对齐信息失败"
CUT_PAIR_FILE_GETTING_APPROXIMATE_ALIGN_INFO_FINISHED: str = "获取粗对齐信息完成"
+ CUT_PAIR_FILE_GETTING_APPROXIMATE_ALIGN_INFO_CALC_FINISHED: str = "计算粗对齐信息完成"
# 体动标注
diff --git a/ui/MainWindow/MainWindow_cut_PAIR_FILE.py b/ui/MainWindow/MainWindow_cut_PAIR_FILE.py
index 1a622fd..cd1296f 100644
--- a/ui/MainWindow/MainWindow_cut_PAIR_FILE.py
+++ b/ui/MainWindow/MainWindow_cut_PAIR_FILE.py
@@ -116,13 +116,21 @@ class Ui_MainWindow_cut_PAIR_FILE(object):
self.verticalLayout_5.addLayout(self.horizontalLayout_6)
- self.horizontalLayout_7 = QHBoxLayout()
- self.horizontalLayout_7.setObjectName(u"horizontalLayout_7")
- self.label_7 = QLabel(self.groupBox_2)
- self.label_7.setObjectName(u"label_7")
- self.label_7.setFont(font)
+ self.gridLayout_3 = QGridLayout()
+ self.gridLayout_3.setObjectName(u"gridLayout_3")
+ self.label = QLabel(self.groupBox_2)
+ self.label.setObjectName(u"label")
+ self.label.setFont(font)
- self.horizontalLayout_7.addWidget(self.label_7)
+ self.gridLayout_3.addWidget(self.label, 1, 0, 1, 1)
+
+ self.spinBox = QSpinBox(self.groupBox_2)
+ self.spinBox.setObjectName(u"spinBox")
+ self.spinBox.setFont(font)
+ self.spinBox.setMinimum(1)
+ self.spinBox.setMaximum(1000000)
+
+ self.gridLayout_3.addWidget(self.spinBox, 1, 1, 1, 1)
self.spinBox_ECGFreq = QSpinBox(self.groupBox_2)
self.spinBox_ECGFreq.setObjectName(u"spinBox_ECGFreq")
@@ -130,12 +138,30 @@ class Ui_MainWindow_cut_PAIR_FILE(object):
self.spinBox_ECGFreq.setMinimum(1)
self.spinBox_ECGFreq.setMaximum(1000000)
- self.horizontalLayout_7.addWidget(self.spinBox_ECGFreq)
+ self.gridLayout_3.addWidget(self.spinBox_ECGFreq, 0, 1, 1, 1)
- self.horizontalLayout_7.setStretch(0, 1)
- self.horizontalLayout_7.setStretch(1, 1)
+ self.label_7 = QLabel(self.groupBox_2)
+ self.label_7.setObjectName(u"label_7")
+ self.label_7.setFont(font)
- self.verticalLayout_5.addLayout(self.horizontalLayout_7)
+ self.gridLayout_3.addWidget(self.label_7, 0, 0, 1, 1)
+
+ self.label_3 = QLabel(self.groupBox_2)
+ self.label_3.setObjectName(u"label_3")
+ self.label_3.setFont(font2)
+
+ self.gridLayout_3.addWidget(self.label_3, 2, 0, 1, 1)
+
+ self.spinBox_OrgBCGShift = QSpinBox(self.groupBox_2)
+ self.spinBox_OrgBCGShift.setObjectName(u"spinBox_OrgBCGShift")
+ self.spinBox_OrgBCGShift.setFont(font)
+ self.spinBox_OrgBCGShift.setMinimum(-10000000)
+ self.spinBox_OrgBCGShift.setMaximum(10000000)
+
+ self.gridLayout_3.addWidget(self.spinBox_OrgBCGShift, 2, 1, 1, 1)
+
+
+ self.verticalLayout_5.addLayout(self.gridLayout_3)
self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding)
@@ -224,7 +250,9 @@ class Ui_MainWindow_cut_PAIR_FILE(object):
self.pushButton_deteleRougnCut.setText(QCoreApplication.translate("MainWindow_cut_PAIR_FILE", u"\u5220\u9664\u7c97\u5bf9\u9f50\u5207\u5272\u6587\u4ef6", None))
self.label_2.setText(QCoreApplication.translate("MainWindow_cut_PAIR_FILE", u"\u9700\u8981\u5207\u5272\u7684\u901a\u9053\u540d\uff1a", None))
self.label_6.setText(QCoreApplication.translate("MainWindow_cut_PAIR_FILE", u"\u9700\u8981\u6620\u5c04\u7684\u6807\u7b7e\uff1a", None))
+ self.label.setText(QCoreApplication.translate("MainWindow_cut_PAIR_FILE", u"BCG\u539f\u59cb\u91c7\u6837\u7387\uff1a", None))
self.label_7.setText(QCoreApplication.translate("MainWindow_cut_PAIR_FILE", u"\u6570\u636e\u7cbe\u540c\u6b65\u65f6ECG\u7684\u91c7\u6837\u7387\uff1a", None))
+ self.label_3.setText(QCoreApplication.translate("MainWindow_cut_PAIR_FILE", u"\u7c97\u5bf9\u9f50\u5fae\u8c03\u79d2\u6570(-\uff1a\u538b\u7535\u5de6\u79fb +\uff1a\u538b\u7535\u53f3\u79fb)", None))
self.label_show.setText(QCoreApplication.translate("MainWindow_cut_PAIR_FILE", u"\u70b9\u51fb\u6267\u884c\u4ee5\u5f00\u59cb...", None))
self.groupBox.setTitle(QCoreApplication.translate("MainWindow_cut_PAIR_FILE", u"\u65e5\u5fd7", None))
self.pushButton_execute.setText(QCoreApplication.translate("MainWindow_cut_PAIR_FILE", u"\u6267\u884c", None))
diff --git a/ui/MainWindow/MainWindow_cut_PAIR_FILE.ui b/ui/MainWindow/MainWindow_cut_PAIR_FILE.ui
index f021523..fbeedaf 100644
--- a/ui/MainWindow/MainWindow_cut_PAIR_FILE.ui
+++ b/ui/MainWindow/MainWindow_cut_PAIR_FILE.ui
@@ -125,33 +125,6 @@
-
-
-
-
-
-
- 12
-
-
-
- 数据精同步时ECG的采样率:
-
-
-
- -
-
-
-
- 12
-
-
-
- 1
-
-
- 1000000
-
-
-
-
@@ -179,6 +152,60 @@
+ -
+
+
+
+ 12
+
+
+
+ 1
+
+
+ 1000000
+
+
+
+ -
+
+
+
+ 12
+
+
+
+ 数据精同步时ECG的采样率:
+
+
+
+ -
+
+
+
+ 10
+
+
+
+ 粗对齐微调秒数(-:压电左移 +:压电右移)
+
+
+
+ -
+
+
+
+ 12
+
+
+
+ -10000000
+
+
+ 10000000
+
+
+
-