新增OrgBCG偏移微调功能,优化粗对齐信息获取和计算逻辑,调整UI布局和组件名称

This commit is contained in:
2025-12-18 21:20:35 +08:00
parent 6c688f26cf
commit af59f9d257
4 changed files with 141 additions and 90 deletions

View File

@ -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,6 +371,7 @@ 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)
if Path(Config["Path"]["InputAlignInfo"]).exists():
self.alignInfo = read_csv(Path(Config["Path"]["InputAlignInfo"]),
encoding=Params.UTF8_ENCODING,
header=None).to_numpy().reshape(-1)
@ -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):

View File

@ -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 = "计算粗对齐信息完成"
# 体动标注

View File

@ -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))

View File

@ -125,33 +125,6 @@
</item>
<item>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QLabel" name="label_7">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>数据精同步时ECG的采样率</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="spinBox_ECGFreq">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>1000000</number>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="font">
@ -179,6 +152,60 @@
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="spinBox_ECGFreq">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>1000000</number>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_7">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>数据精同步时ECG的采样率</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>粗对齐微调秒数(-:压电左移 +:压电右移)</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="spinBox_OrgBCGShift">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="minimum">
<number>-10000000</number>
</property>
<property name="maximum">
<number>10000000</number>
</property>
</widget>
</item>
</layout>
</item>
<item>