优化UI布局,新增自定义频率输入功能,调整相关信号处理逻辑

This commit is contained in:
2026-01-26 21:53:08 +08:00
parent 0935aefeb2
commit 9a5f1a5a54
6 changed files with 219 additions and 57 deletions

View File

@ -48,6 +48,7 @@ ButtonState = {
"radioButton_NTHO": False,
"radioButton_NABD": False,
"radioButton_custom": False,
"radioButton_customFreq": False,
"radioButton_freqTHO": False,
"radioButton_freqABD": False,
},
@ -71,6 +72,7 @@ ButtonState = {
"radioButton_NTHO": False,
"radioButton_NABD": False,
"radioButton_custom": False,
"radioButton_customFreq": False,
"radioButton_freqTHO": False,
"radioButton_freqABD": False,
}
@ -303,6 +305,7 @@ class MainWindow_approximately_align(QMainWindow):
self.ui.radioButton_custom.clicked.connect(self.__enableAlign__)
self.ui.radioButton_freqTHO.clicked.connect(self.__EstimateFrequencySelect__)
self.ui.radioButton_freqABD.clicked.connect(self.__EstimateFrequencySelect__)
self.ui.radioButton_customFreq.clicked.connect(self.__EstimateFrequencySelect__)
@overrides
def closeEvent(self, event):
@ -353,6 +356,7 @@ class MainWindow_approximately_align(QMainWindow):
self.ui.spinBox_SelectEpoch.setMinimum(0)
self.ui.radioButton_freqABD.setChecked(False)
self.ui.radioButton_freqTHO.setChecked(False)
self.ui.radioButton_customFreq.setChecked(False)
self.ui.radioButton_freqTHO.setText("备选1")
self.ui.radioButton_freqABD.setText("备选2")
@ -664,22 +668,22 @@ class MainWindow_approximately_align(QMainWindow):
response = self.data.estimate_frequency(tho_bias_list)
tho_y = response.data["estimate_y"]
tho_frequency = response.data["frequency"]
tho_frequency_ratio = response.data["frequency"]
tho_slope = response.data["slope"]
tho_intercept = response.data["intercept"]
response = self.data.estimate_frequency(abd_bias_list)
abd_y = response.data["estimate_y"]
abd_frequency = response.data["frequency"]
abd_frequency_ratio = response.data["frequency"]
abd_slope = response.data["slope"]
abd_intercept = response.data["intercept"]
result = self.__plot__(epoch_min, epoch_max, tho_bias_list, abd_bias_list, tho_y, abd_y,
tho_frequency, abd_frequency)
tho_frequency_ratio, abd_frequency_ratio)
Config["estimate"] = {}
Config["estimate"]["tho_frequency"] = tho_frequency
Config["estimate"]["tho_frequency"] = tho_frequency_ratio
Config["estimate"]["tho_slope"] = tho_slope
Config["estimate"]["tho_intercept"] = tho_intercept
Config["estimate"]["abd_frequency"] = abd_frequency
Config["estimate"]["abd_frequency"] = abd_frequency_ratio
Config["estimate"]["abd_slope"] = abd_slope
Config["estimate"]["abd_intercept"] = abd_intercept
@ -687,6 +691,7 @@ class MainWindow_approximately_align(QMainWindow):
self.ui.radioButton_freqABD.setText(str(Config["estimate"]["abd_frequency"] * Config["InputConfig"]["orgBcgFreq"]))
ButtonState["Current"]["radioButton_freqTHO"] = True
ButtonState["Current"]["radioButton_freqABD"] = True
ButtonState["Current"]["radioButton_customFreq"] = True
if not result.status:
PublicFunc.text_output(self.ui, "(1/1)" + result.info, Constants.TIPS_TYPE_ERROR)
@ -719,15 +724,30 @@ class MainWindow_approximately_align(QMainWindow):
def __EstimateFrequencySelect__(self):
PublicFunc.__disableAllButton__(self, ButtonState)
if self.ui.radioButton_freqTHO.isChecked():
frequency = Config["estimate"]["tho_frequency"]
Config["estimate_freq"] = frequency
frequency_ratio = Config["estimate"]["tho_frequency"]
Config["estimate_freq"] = frequency_ratio
Config["estimate_slope"] = Config["estimate"]["tho_slope"]
Config["estimate_intercept"] = Config["estimate"]["tho_intercept"]
elif self.ui.radioButton_freqABD.isChecked():
frequency = Config["estimate"]["abd_frequency"]
Config["estimate_freq"] = frequency
frequency_ratio = Config["estimate"]["abd_frequency"]
Config["estimate_freq"] = frequency_ratio
Config["estimate_slope"] = Config["estimate"]["abd_slope"]
Config["estimate_intercept"] = Config["estimate"]["abd_intercept"]
elif self.ui.radioButton_customFreq.isChecked():
# self.ui.lineEdit_customFreq.text()
try:
float(self.ui.lineEdit_customFreq.text())
except ValueError:
PublicFunc.msgbox_output(self, "自定义频率输入不合法,请输入数字类型数据!", Constants.MSGBOX_TYPE_ERROR)
PublicFunc.finish_operation(self, ButtonState)
return
frequency_ratio = float(self.ui.lineEdit_customFreq.text()) / Config["InputConfig"]["orgBcgFreq"]
Config["estimate_freq"] = frequency_ratio
Config["estimate_slope"] = None
Config["estimate_intercept"] = None
else:
return
@ -1046,12 +1066,12 @@ class MainWindow_approximately_align(QMainWindow):
return Result().success(info=Constants.DRAW_FINISHED)
def DrawAlignScatter(self, epoch_min, epoch_max, tho_bias_list, abd_bias_list, tho_y, abd_y,
tho_frequency, abd_frequency):
tho_frequency_ratio, abd_frequency_ratio):
try:
ax1 = self.fig.add_subplot(211)
ax1.scatter(linspace(epoch_min, epoch_max, len(tho_bias_list)), tho_bias_list, alpha=0.2)
ax1.plot(linspace(epoch_min, epoch_max, len(tho_bias_list)), tho_y, color='orange',
label=f"THO Frequency: {tho_frequency} Hz")
label=f"THO Frequency_ratio: {tho_frequency_ratio}")
ax1.axhline(y=0, color='red', linestyle='--', alpha=0.3)
ax1.set_xlabel("Epoch")
ax1.set_ylabel("Tho Bias / s")
@ -1061,7 +1081,7 @@ class MainWindow_approximately_align(QMainWindow):
ax2 = self.fig.add_subplot(212)
ax2.scatter(linspace(epoch_min, epoch_max, len(abd_bias_list)), abd_bias_list, alpha=0.2)
ax2.plot(linspace(epoch_min, epoch_max, len(abd_bias_list)), abd_y, color='orange',
label=f"ABD Frequency: {abd_frequency} Hz")
label=f"ABD Frequency_ratio: {abd_frequency_ratio}")
ax2.axhline(y=0, color='red', linestyle='--', alpha=0.3)
ax2.set_xlabel("Epoch")
ax2.set_ylabel("Abd Bias / s")
@ -1260,12 +1280,12 @@ class Data:
if Config["PSGConfig"]["PSGDelBase"]:
# 减去四秒钟平均滤波
self.processed_Tho = self.processed_Tho - convolve(
self.processed_Tho, ones(int(4 * temp_frequency)) / int(4 * temp_frequency), mode='same')
self.processed_Tho, ones(int(10 * temp_frequency)) / int(10 * temp_frequency), mode='same')
self.processed_Abd = self.processed_Abd - convolve(
self.processed_Abd, ones(int(4 * temp_frequency)) / int(4 * temp_frequency), mode='same')
self.processed_Abd, ones(int(10 * temp_frequency)) / int(10 * temp_frequency), mode='same')
if Config["orgBcgConfig"]["orgBcgDelBase"]:
self.processed_orgBcg = self.processed_orgBcg - convolve(
self.processed_orgBcg, ones(int(4 * temp_frequency)) / int(4 * temp_frequency), mode='same')
self.processed_orgBcg, ones(int(10 * temp_frequency)) / int(10 * temp_frequency), mode='same')
except Exception as e:
return Result().failure(
info=Constants.APPROXIMATELY_DELETE_BASE_FAILURE + Constants.FAILURE_REASON[
@ -1306,9 +1326,16 @@ class Data:
try:
# 用[::]完成
temp_frequency = Config["TempFrequency"]
self.processed_downsample_Tho = self.processed_Tho[::int(temp_frequency / Config["ApplyFrequency"])]
self.processed_downsample_Abd = self.processed_Abd[::int(temp_frequency / Config["ApplyFrequency"])]
self.processed_downsample_orgBcg = self.processed_orgBcg[::int(temp_frequency / Config["ApplyFrequency"])]
# self.processed_downsample_Tho = self.processed_Tho[::int(temp_frequency / Config["ApplyFrequency"])]
# self.processed_downsample_Abd = self.processed_Abd[::int(temp_frequency / Config["ApplyFrequency"])]
# self.processed_downsample_orgBcg = self.processed_orgBcg[::int(temp_frequency / Config["ApplyFrequency"])]
# 用resample完成
self.processed_downsample_Tho = resample(
self.processed_Tho, int(Config["PSG_seconds"] * Config["ApplyFrequency"]))
self.processed_downsample_Abd = resample(
self.processed_Abd, int(Config["PSG_seconds"] * Config["ApplyFrequency"]))
self.processed_downsample_orgBcg = resample(
self.processed_orgBcg, int(Config["orgBcg_seconds"] * Config["ApplyFrequency"]))
except Exception as e:
@ -1333,10 +1360,10 @@ class Data:
v = self.processed_downsample_orgBcg[
Config["orgBcgConfig"]["PreCut"]:len(self.processed_downsample_orgBcg) - Config["orgBcgConfig"][
"PostCut"]].copy()
a *= MULTIPLE_FACTOER
v *= MULTIPLE_FACTOER
a = a.astype(int64)
v = v.astype(int64)
# a *= MULTIPLE_FACTOER
# v *= MULTIPLE_FACTOER
# a = a.astype(int64)
# v = v.astype(int64)
tho_relate = correlate(a, v, mode='full')
tho_relate = tho_relate / (MULTIPLE_FACTOER ** 2)
tho_relate2 = - tho_relate
@ -1358,12 +1385,12 @@ class Data:
v = self.processed_downsample_orgBcg[
Config["orgBcgConfig"]["PreCut"]:len(self.processed_downsample_orgBcg) - Config["orgBcgConfig"][
"PostCut"]].copy()
a *= 100
v *= 100
a = a.astype(int64)
v = v.astype(int64)
# a *= 100
# v *= 100
# a = a.astype(int64)
# v = v.astype(int64)
abd_relate = correlate(a, v, mode='full')
abd_relate = abd_relate / 10000
# abd_relate = abd_relate / 10000
abd_relate2 = - abd_relate
result = {"abd_relate": abd_relate, "abd_relate2": abd_relate2}
@ -1397,7 +1424,7 @@ class Data:
# 获取epoch
try:
epoch_second = Params.APPROXIMATELY_ALIGN_CONFIG_NEW_CONTENT["Second_PerEpoch"]
epoch_min = max(0, Config["pos"] // epoch_second // Config["ApplyFrequency"] + 1)
epoch_min = max(0, Config["pos"] // (epoch_second * Config["ApplyFrequency"])) + 1
epoch_max = min(len(self.processed_downsample_Tho) // epoch_second // Config["ApplyFrequency"] - 1,
(len(self.processed_downsample_orgBcg) + Config["pos"]) // epoch_second // Config[
"ApplyFrequency"] - 1)
@ -1476,16 +1503,17 @@ class Data:
if slope != 0:
drift_rate = slope / epoch_second
# frequency = temp_freq * (1 - drift_rate)
frequency = 1 - drift_rate
# frequency_ratio = 1 - drift_rate
frequency_ratio = 1 / (1 + drift_rate)
else:
# frequency = float(temp_freq)
frequency = 1
frequency_ratio = 1
theilsen_y = theilsen.predict(X)
return Result().success(info=Constants.APPROXIMATELY_ESTIMATE_FREQUENCY_FINISHED,
data={"estimate_y": theilsen_y,
"frequency": frequency,
"frequency": frequency_ratio,
"slope": slope,
"intercept": theilsen.intercept_},
)